Compare commits
129 Commits
v0.18.0
...
AssetStudi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b66ec7467 | ||
|
|
0021cf221e | ||
|
|
c07dc59f51 | ||
|
|
d1bf0c5a37 | ||
|
|
6d5b633d55 | ||
|
|
6c3ff89dbf | ||
|
|
763f188afb | ||
|
|
553f0d94f3 | ||
|
|
80e6a1d074 | ||
|
|
6de33d0437 | ||
|
|
7ce8b8c8ae | ||
|
|
2d449ff4cd | ||
|
|
1d65096001 | ||
|
|
355c99c034 | ||
|
|
963cd6546b | ||
|
|
ae3b5169df | ||
|
|
521e2f3bbc | ||
|
|
f0a69025fe | ||
|
|
52b0a21181 | ||
|
|
be11fdf14f | ||
|
|
054906a426 | ||
|
|
35324083e1 | ||
|
|
36bd3c8342 | ||
|
|
c20c07b5f2 | ||
|
|
efca2a7557 | ||
|
|
6b41a36c7d | ||
|
|
35b24990c6 | ||
|
|
925f5c12a3 | ||
|
|
9c64f7f56d | ||
|
|
3c6b65f724 | ||
|
|
34819608c5 | ||
|
|
6f8f1a5a8a | ||
|
|
f0029520fb | ||
|
|
7b7eac62d8 | ||
|
|
3a25ed9ccd | ||
|
|
785eeb8665 | ||
|
|
fd50054edf | ||
|
|
a1ee61c542 | ||
|
|
12799da395 | ||
|
|
60426a4b9a | ||
|
|
3ea01ec9bc | ||
|
|
7da68aedff | ||
|
|
548f8a52cf | ||
|
|
24337f66f9 | ||
|
|
92a89db4e8 | ||
|
|
c11e085e2e | ||
|
|
55406553f6 | ||
|
|
b0a051fc47 | ||
|
|
97fa42742b | ||
|
|
97bdef0891 | ||
|
|
876bafdda1 | ||
|
|
66229e564a | ||
|
|
13f37ec260 | ||
|
|
a0c2a7bdfe | ||
|
|
0cc74b8c12 | ||
|
|
f077064a6a | ||
|
|
190cb68b07 | ||
|
|
3fa2ef1694 | ||
|
|
40e0bd0248 | ||
|
|
e1e43439c3 | ||
|
|
e8ca265a43 | ||
|
|
81ed77819a | ||
|
|
d1fed47f92 | ||
|
|
3b10a808d3 | ||
|
|
47d67e0a49 | ||
|
|
bc0e32efec | ||
|
|
db4eb30a27 | ||
|
|
9f918d0332 | ||
|
|
81cd6d79d0 | ||
|
|
9024e6a235 | ||
|
|
0b7b809285 | ||
|
|
f7e6d23084 | ||
|
|
6ea1ff3e96 | ||
|
|
185348d9b8 | ||
|
|
a8bb6c714b | ||
|
|
cc21d4fa4d | ||
|
|
e3e343320c | ||
|
|
1cdb0b762a | ||
|
|
02f64f3c97 | ||
|
|
58917ab7dc | ||
|
|
b7d21e5bd8 | ||
|
|
d7b4d415ca | ||
|
|
95f7d70419 | ||
|
|
4e93ea5a82 | ||
|
|
6608e76471 | ||
|
|
ff92d1784d | ||
|
|
064f5cbe57 | ||
|
|
59db27de3a | ||
|
|
0d4e7ba4ae | ||
|
|
3605bc0ff9 | ||
|
|
188ee088a2 | ||
|
|
341612be16 | ||
|
|
e16046d775 | ||
|
|
d2f69432e4 | ||
|
|
08d50a8013 | ||
|
|
7b1585eff0 | ||
|
|
70aa8bec59 | ||
|
|
18813b22c3 | ||
|
|
316837dfdf | ||
|
|
fca937e5e6 | ||
|
|
c2095c4e7a | ||
|
|
f253c868d4 | ||
|
|
8ccdd0fd4e | ||
|
|
bc92dfb77c | ||
|
|
c37e2e65b7 | ||
|
|
58ee2b8f1e | ||
|
|
c93d27d9a4 | ||
|
|
5a84a67955 | ||
|
|
fa332b45df | ||
|
|
348aea2be8 | ||
|
|
d52f192e75 | ||
|
|
81a1eeb2d1 | ||
|
|
05ea91ef5e | ||
|
|
e0d5e5c6b7 | ||
|
|
b439cfed66 | ||
|
|
573b87b570 | ||
|
|
585b69fb36 | ||
|
|
5e3fe1775f | ||
|
|
8704feb079 | ||
|
|
f54fe3492b | ||
|
|
6d953d774d | ||
|
|
f0a793bd3d | ||
|
|
d886bf1c5d | ||
|
|
1623981c0e | ||
|
|
2c860f004b | ||
|
|
a3f4c7a029 | ||
|
|
f86b5a97ac | ||
|
|
7e408a3667 | ||
|
|
6c515aee2e |
@@ -1,9 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
<TargetFrameworks>net472;net8.0;net8.0-windows;net9.0;net9.0-windows</TargetFrameworks>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Version>0.18.0.0</Version>
|
<Version>0.19.0.0</Version>
|
||||||
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
|
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace AssetStudio.PInvoke
|
|||||||
{
|
{
|
||||||
public static void PreloadDll(string dllName)
|
public static void PreloadDll(string dllName)
|
||||||
{
|
{
|
||||||
var localPath = Process.GetCurrentProcess().MainModule.FileName;
|
var localPath = Process.GetCurrentProcess().MainModule?.FileName;
|
||||||
var localDir = Path.GetDirectoryName(localPath);
|
var localDir = Path.GetDirectoryName(localPath);
|
||||||
|
|
||||||
// Not using OperatingSystem.Platform.
|
// Not using OperatingSystem.Platform.
|
||||||
@@ -35,7 +35,6 @@ namespace AssetStudio.PInvoke
|
|||||||
|
|
||||||
private static class Win32
|
private static class Win32
|
||||||
{
|
{
|
||||||
|
|
||||||
internal static void LoadDll(string dllDir, string dllName)
|
internal static void LoadDll(string dllDir, string dllName)
|
||||||
{
|
{
|
||||||
var dllFileName = $"{dllName}.dll";
|
var dllFileName = $"{dllName}.dll";
|
||||||
|
|||||||
@@ -1,26 +1,23 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
|
<TargetFrameworks>net472;net8.0;net8.0-windows;net9.0;net9.0-windows</TargetFrameworks>
|
||||||
<Version>0.18.0.0</Version>
|
<Version>0.19.0.0</Version>
|
||||||
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2023-2024</Copyright>
|
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2021-2025</Copyright>
|
||||||
<DebugType>embedded</DebugType>
|
<DebugType>embedded</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' != 'net472' ">
|
<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" />
|
||||||
<PackageReference Include="ZstdSharp.Port" Version="0.7.6" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
||||||
<PackageReference Include="System.Memory" Version="4.5.5" />
|
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
|
||||||
<PackageReference Include="System.IO.Compression" Version="4.0.0" />
|
<PackageReference Include="System.Text.Json" Version="9.0.8" />
|
||||||
<PackageReference Include="K4os.Compression.LZ4" Version="1.1.11" />
|
<PackageReference Include="Microsoft.Bcl.Numerics" Version="9.0.8" />
|
||||||
<PackageReference Include="ZstdSharp.Port" Version="0.6.5" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -5,66 +5,46 @@ using System.IO;
|
|||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Text.Json;
|
||||||
|
using AssetStudio.CustomOptions;
|
||||||
|
using AssetStudio.CustomOptions.Asmo;
|
||||||
using static AssetStudio.ImportHelper;
|
using static AssetStudio.ImportHelper;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public class AssetsManager
|
public class AssetsManager
|
||||||
{
|
{
|
||||||
public bool ZstdEnabled = true;
|
public bool LoadViaTypeTree = true;
|
||||||
public bool LoadingViaTypeTreeEnabled = true;
|
public bool MeshLazyLoad = true;
|
||||||
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
|
public ImportOptions Options = new ImportOptions();
|
||||||
|
public readonly List<Action<OptionsFile>> OptionLoaders = new List<Action<OptionsFile>>();
|
||||||
|
public readonly List<SerializedFile> AssetsFileList = new List<SerializedFile>();
|
||||||
|
|
||||||
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
||||||
internal ConcurrentDictionary<string, BinaryReader> resourceFileReaders = new ConcurrentDictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
|
internal ConcurrentDictionary<string, BinaryReader> resourceFileReaders = new ConcurrentDictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
private UnityVersion specifiedUnityVersion;
|
private readonly List<string> importFiles = new List<string>();
|
||||||
private List<string> importFiles = new List<string>();
|
private readonly HashSet<ClassIDType> filteredAssetTypesList = new HashSet<ClassIDType>();
|
||||||
private HashSet<ClassIDType> filteredAssetTypesList = new HashSet<ClassIDType>();
|
private readonly HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
private readonly HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
private readonly HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
public UnityVersion SpecifyUnityVersion
|
public AssetsManager()
|
||||||
{
|
{
|
||||||
get => specifiedUnityVersion;
|
OptionLoaders.Add(LoadImportOptions);
|
||||||
set
|
|
||||||
{
|
|
||||||
if (specifiedUnityVersion == value)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
specifiedUnityVersion = 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");
|
|
||||||
}
|
|
||||||
|
|
||||||
specifiedUnityVersion = value;
|
|
||||||
Logger.Info($"Specified Unity version: {specifiedUnityVersion}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAssetFilter(params ClassIDType[] classIDTypes)
|
public void SetAssetFilter(params ClassIDType[] classIDTypes)
|
||||||
{
|
{
|
||||||
if (filteredAssetTypesList.Count == 0)
|
filteredAssetTypesList.UnionWith(new[]
|
||||||
{
|
|
||||||
filteredAssetTypesList.UnionWith(new HashSet<ClassIDType>
|
|
||||||
{
|
{
|
||||||
ClassIDType.AssetBundle,
|
ClassIDType.AssetBundle,
|
||||||
ClassIDType.ResourceManager,
|
ClassIDType.ResourceManager,
|
||||||
ClassIDType.GameObject,
|
ClassIDType.GameObject,
|
||||||
ClassIDType.Transform,
|
ClassIDType.Transform,
|
||||||
|
ClassIDType.RectTransform,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (classIDTypes.Contains(ClassIDType.MonoBehaviour))
|
if (classIDTypes.Contains(ClassIDType.MonoBehaviour))
|
||||||
{
|
{
|
||||||
@@ -75,6 +55,23 @@ namespace AssetStudio
|
|||||||
filteredAssetTypesList.Add(ClassIDType.Texture2D);
|
filteredAssetTypesList.Add(ClassIDType.Texture2D);
|
||||||
filteredAssetTypesList.Add(ClassIDType.SpriteAtlas);
|
filteredAssetTypesList.Add(ClassIDType.SpriteAtlas);
|
||||||
}
|
}
|
||||||
|
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);
|
filteredAssetTypesList.UnionWith(classIDTypes);
|
||||||
}
|
}
|
||||||
@@ -84,32 +81,28 @@ namespace AssetStudio
|
|||||||
SetAssetFilter(classIDTypeList.ToArray());
|
SetAssetFilter(classIDTypeList.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadFilesAndFolders(params string[] path)
|
public void LoadFilesAndFolders(params string[] paths)
|
||||||
{
|
{
|
||||||
var pathList = new List<string>();
|
LoadFilesAndFolders(out _, paths.ToList());
|
||||||
pathList.AddRange(path);
|
|
||||||
LoadFilesAndFolders(out _, pathList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadFilesAndFolders(out string parentPath, params string[] path)
|
public void LoadFilesAndFolders(out string parentPath, params string[] paths)
|
||||||
{
|
{
|
||||||
var pathList = new List<string>();
|
LoadFilesAndFolders(out parentPath, paths.ToList());
|
||||||
pathList.AddRange(path);
|
|
||||||
LoadFilesAndFolders(out parentPath, pathList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadFilesAndFolders(out string parentPath, List<string> pathList)
|
public void LoadFilesAndFolders(out string parentPath, List<string> pathList)
|
||||||
{
|
{
|
||||||
var fileList = new List<string>();
|
var fileList = new List<string>();
|
||||||
bool filesInPath = false;
|
var filesInPath = false;
|
||||||
parentPath = "";
|
parentPath = "";
|
||||||
foreach (var path in pathList)
|
foreach (var path in pathList)
|
||||||
{
|
{
|
||||||
var fullPath = Path.GetFullPath(path);
|
var fullPath = Path.GetFullPath(path);
|
||||||
if (Directory.Exists(fullPath))
|
if (Directory.Exists(fullPath))
|
||||||
{
|
{
|
||||||
var parent = Directory.GetParent(fullPath).FullName;
|
var parent = Directory.GetParent(fullPath)?.FullName;
|
||||||
if (!filesInPath && (parentPath == "" || parentPath.Length > parent.Length))
|
if (!filesInPath && (parentPath == "" || parentPath?.Length > parent?.Length))
|
||||||
{
|
{
|
||||||
parentPath = parent;
|
parentPath = parent;
|
||||||
}
|
}
|
||||||
@@ -127,6 +120,8 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
MergeSplitAssets(parentPath);
|
MergeSplitAssets(parentPath);
|
||||||
}
|
}
|
||||||
|
LoadOptionFiles(fileList);
|
||||||
|
|
||||||
var toReadFile = ProcessingSplitFiles(fileList);
|
var toReadFile = ProcessingSplitFiles(fileList);
|
||||||
fileList.Clear();
|
fileList.Clear();
|
||||||
pathList.Clear();
|
pathList.Clear();
|
||||||
@@ -160,6 +155,8 @@ namespace AssetStudio
|
|||||||
importFilesHash.Clear();
|
importFilesHash.Clear();
|
||||||
noexistFiles.Clear();
|
noexistFiles.Clear();
|
||||||
assetsFileListHash.Clear();
|
assetsFileListHash.Clear();
|
||||||
|
if (AssetsFileList.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
ReadAssets();
|
ReadAssets();
|
||||||
ProcessAssets();
|
ProcessAssets();
|
||||||
@@ -171,12 +168,15 @@ namespace AssetStudio
|
|||||||
return LoadFile(reader);
|
return LoadFile(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadFile(FileReader reader)
|
private bool LoadFile(FileReader reader, bool fromZip = false)
|
||||||
{
|
{
|
||||||
switch (reader?.FileType)
|
if (reader == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (reader.FileType)
|
||||||
{
|
{
|
||||||
case FileType.AssetsFile:
|
case FileType.AssetsFile:
|
||||||
return LoadAssetsFile(reader);
|
return LoadAssetsFile(reader, fromZip);
|
||||||
case FileType.BundleFile:
|
case FileType.BundleFile:
|
||||||
return LoadBundleFile(reader);
|
return LoadBundleFile(reader);
|
||||||
case FileType.WebFile:
|
case FileType.WebFile:
|
||||||
@@ -191,22 +191,27 @@ namespace AssetStudio
|
|||||||
case FileType.ZipFile:
|
case FileType.ZipFile:
|
||||||
LoadZipFile(reader);
|
LoadZipFile(reader);
|
||||||
break;
|
break;
|
||||||
|
case FileType.ResourceFile when !fromZip:
|
||||||
|
reader.Dispose();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadAssetsFile(FileReader reader)
|
private bool LoadAssetsFile(FileReader reader, bool fromZip)
|
||||||
{
|
{
|
||||||
if (!assetsFileListHash.Contains(reader.FileName))
|
if (!assetsFileListHash.Contains(reader.FileName))
|
||||||
{
|
{
|
||||||
Logger.Info($"Loading {reader.FullPath}");
|
Logger.Info($"Loading \"{reader.FullPath}\"");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var assetsFile = new SerializedFile(reader, this);
|
var assetsFile = new SerializedFile(reader, this);
|
||||||
var dirName = Path.GetDirectoryName(reader.FullPath);
|
var dirName = Path.GetDirectoryName(reader.FullPath);
|
||||||
CheckStrippedVersion(assetsFile);
|
CheckStrippedVersion(assetsFile);
|
||||||
assetsFileList.Add(assetsFile);
|
AssetsFileList.Add(assetsFile);
|
||||||
assetsFileListHash.Add(assetsFile.fileName);
|
assetsFileListHash.Add(assetsFile.fileName);
|
||||||
|
if (fromZip)
|
||||||
|
return true;
|
||||||
|
|
||||||
foreach (var sharedFile in assetsFile.m_Externals)
|
foreach (var sharedFile in assetsFile.m_Externals)
|
||||||
{
|
{
|
||||||
@@ -233,6 +238,7 @@ namespace AssetStudio
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
noexistFiles.Add(sharedFilePath);
|
noexistFiles.Add(sharedFilePath);
|
||||||
|
Logger.Warning($"Dependency wasn't found: {sharedFilePath}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,13 +252,13 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Warning($"Failed to read assets file {reader.FullPath}\r\n{e}");
|
Logger.Warning($"Failed to read assets file \"{reader.FullPath}\"\n{e}");
|
||||||
reader.Dispose();
|
reader.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Info($"Skipping {reader.FullPath}");
|
Logger.Info($"Skipping \"{reader.FullPath}\"");
|
||||||
reader.Dispose();
|
reader.Dispose();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -268,39 +274,97 @@ namespace AssetStudio
|
|||||||
assetsFile.originalPath = originalPath;
|
assetsFile.originalPath = originalPath;
|
||||||
if (assetBundleUnityVer != null && assetsFile.header.m_Version < SerializedFileFormatVersion.Unknown_7)
|
if (assetBundleUnityVer != null && assetsFile.header.m_Version < SerializedFileFormatVersion.Unknown_7)
|
||||||
{
|
{
|
||||||
assetsFile.SetVersion(assetBundleUnityVer);
|
assetsFile.version = assetBundleUnityVer;
|
||||||
}
|
}
|
||||||
CheckStrippedVersion(assetsFile, assetBundleUnityVer);
|
CheckStrippedVersion(assetsFile, assetBundleUnityVer);
|
||||||
assetsFileList.Add(assetsFile);
|
AssetsFileList.Add(assetsFile);
|
||||||
assetsFileListHash.Add(assetsFile.fileName);
|
assetsFileListHash.Add(assetsFile.fileName);
|
||||||
}
|
}
|
||||||
catch (NotSupportedException e)
|
catch (NotSupportedException e)
|
||||||
{
|
{
|
||||||
Logger.Error(e.Message);
|
Logger.Error(e.Message);
|
||||||
resourceFileReaders.TryAdd(reader.FileName, reader);
|
reader.Dispose();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Warning($"Failed to read assets file {reader.FullPath} from {Path.GetFileName(originalPath)}\r\n{e}");
|
Logger.Warning($"Failed to read assets file \"{reader.FullPath}\" from {Path.GetFileName(originalPath)}\n{e}");
|
||||||
resourceFileReaders.TryAdd(reader.FileName, reader);
|
resourceFileReaders.TryAdd(reader.FileName, reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Info($"Skipping {originalPath} ({reader.FileName})");
|
Logger.Info($"Skipping \"{originalPath}\" ({reader.FileName})");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool LoadBundleFile(FileReader reader, string originalPath = null)
|
private bool LoadBundleFile(FileReader reader, string originalPath = null)
|
||||||
{
|
{
|
||||||
Logger.Info("Loading " + reader.FullPath);
|
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;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var bundleFile = new BundleFile(reader, ZstdEnabled, specifiedUnityVersion);
|
var bundleFile = new BundleFile(bundleReader, Options.BundleOptions);
|
||||||
|
isLoaded = LoadBundleFiles(bundleReader, bundleFile, originalPath);
|
||||||
|
if (!isLoaded)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (bundleFile.IsDataAfterBundle && isLoaded)
|
||||||
|
{
|
||||||
|
isLoaded = false;
|
||||||
|
bundleStream.Offset = reader.Position;
|
||||||
|
bundleReader = new FileReader($"{reader.FullPath}_0x{bundleStream.Offset:X}", bundleStream);
|
||||||
|
if (bundleReader.FileType != FileType.BundleFile)
|
||||||
|
{
|
||||||
|
Logger.Debug("Unknown data was detected after the end of the bundle.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (bundleReader.Position > 0)
|
||||||
|
{
|
||||||
|
bundleStream.Offset += bundleReader.Position;
|
||||||
|
bundleReader.FullPath = $"{reader.FullPath}_0x{bundleStream.Offset:X}";
|
||||||
|
bundleReader.FileName = $"{reader.FileName}_0x{bundleStream.Offset:X}";
|
||||||
|
}
|
||||||
|
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}\"";
|
||||||
|
if (originalPath != null)
|
||||||
|
{
|
||||||
|
str += $" from {Path.GetFileName(originalPath)}";
|
||||||
|
}
|
||||||
|
Logger.Warning($"{str}\n{e}");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (!isLoaded)
|
||||||
|
bundleReader.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool LoadBundleFiles(FileReader reader, BundleFile bundleFile, string originalPath = null)
|
||||||
|
{
|
||||||
foreach (var file in bundleFile.fileList)
|
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 dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
|
||||||
var subReader = new FileReader(dummyPath, file.stream);
|
var subReader = new FileReader(dummyPath, file.stream);
|
||||||
if (subReader.FileType == FileType.AssetsFile)
|
if (subReader.FileType == FileType.AssetsFile)
|
||||||
@@ -315,30 +379,10 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (NotSupportedException e)
|
|
||||||
{
|
|
||||||
Logger.Error(e.Message);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
var str = $"Error while reading bundle file {reader.FullPath}";
|
|
||||||
if (originalPath != null)
|
|
||||||
{
|
|
||||||
str += $" from {Path.GetFileName(originalPath)}";
|
|
||||||
}
|
|
||||||
Logger.Warning($"{str}\r\n{e}");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
reader.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadWebFile(FileReader reader)
|
private void LoadWebFile(FileReader reader)
|
||||||
{
|
{
|
||||||
Logger.Info("Loading " + reader.FullPath);
|
Logger.Info($"Loading \"{reader.FullPath}\"");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var webFile = new WebFile(reader);
|
var webFile = new WebFile(reader);
|
||||||
@@ -358,14 +402,14 @@ namespace AssetStudio
|
|||||||
LoadWebFile(subReader);
|
LoadWebFile(subReader);
|
||||||
break;
|
break;
|
||||||
case FileType.ResourceFile:
|
case FileType.ResourceFile:
|
||||||
resourceFileReaders[file.fileName] = subReader; //TODO
|
resourceFileReaders.TryAdd(file.fileName, subReader);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Error($"Error while reading web file {reader.FullPath}", e);
|
Logger.Error($"Error while reading web file \"{reader.FullPath}\"", e);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -402,15 +446,16 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
// merge split files and load the result
|
// merge split files and load the result
|
||||||
foreach (string basePath in splitFiles)
|
for (var i = 0; i < splitFiles.Count; i++)
|
||||||
{
|
{
|
||||||
|
var basePath = splitFiles[i].Replace("\\", "/");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Stream splitStream = new MemoryStream();
|
Stream splitStream = new MemoryStream();
|
||||||
int i = 0;
|
var j = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
string path = $"{basePath}.split{i++}";
|
string path = $"{basePath}.split{j++}";
|
||||||
ZipArchiveEntry entry = archive.GetEntry(path);
|
ZipArchiveEntry entry = archive.GetEntry(path);
|
||||||
if (entry == null)
|
if (entry == null)
|
||||||
break;
|
break;
|
||||||
@@ -421,11 +466,12 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
splitStream.Seek(0, SeekOrigin.Begin);
|
splitStream.Seek(0, SeekOrigin.Begin);
|
||||||
FileReader entryReader = new FileReader(basePath, splitStream);
|
FileReader entryReader = new FileReader(basePath, splitStream);
|
||||||
LoadFile(entryReader);
|
if (!LoadFile(entryReader, fromZip: true))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Warning($"Error while reading zip split file {basePath}\r\n{e}");
|
Logger.Warning($"Error while reading zip split file \"{basePath}\"\n{e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,6 +481,8 @@ namespace AssetStudio
|
|||||||
Progress.Reset();
|
Progress.Reset();
|
||||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||||
{
|
{
|
||||||
|
if (entry.Length == 0)
|
||||||
|
continue;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), reader.FileName, entry.FullName);
|
string dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), reader.FileName, entry.FullName);
|
||||||
@@ -449,7 +497,9 @@ namespace AssetStudio
|
|||||||
streamReader.Position = 0;
|
streamReader.Position = 0;
|
||||||
|
|
||||||
FileReader entryReader = new FileReader(dummyPath, streamReader);
|
FileReader entryReader = new FileReader(dummyPath, streamReader);
|
||||||
LoadFile(entryReader);
|
if (!LoadFile(entryReader, fromZip: true))
|
||||||
|
break;
|
||||||
|
|
||||||
if (entryReader.FileType == FileType.ResourceFile)
|
if (entryReader.FileType == FileType.ResourceFile)
|
||||||
{
|
{
|
||||||
entryReader.Position = 0;
|
entryReader.Position = 0;
|
||||||
@@ -459,7 +509,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Warning($"Error while reading zip entry {entry.FullName}\r\n{e}");
|
Logger.Warning($"Error while reading zip entry \"{entry.FullName}\"\n{e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -474,29 +524,92 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadOptionFiles(List<string> pathList)
|
||||||
|
{
|
||||||
|
if (pathList.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var optionFileIndexes = new List<int>();
|
||||||
|
for (var i = 0; i < pathList.Count; i++)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < optionFileIndexes.Count; i++)
|
||||||
|
{
|
||||||
|
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)
|
public void CheckStrippedVersion(SerializedFile assetsFile, UnityVersion bundleUnityVer = null)
|
||||||
{
|
{
|
||||||
if (assetsFile.version.IsStripped && specifiedUnityVersion == 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.";
|
var msg = "The asset's Unity version has been stripped, please set the version in the options.";
|
||||||
if (bundleUnityVer != null && !bundleUnityVer.IsStripped)
|
if (bundleUnityVer != null && !bundleUnityVer.IsStripped)
|
||||||
msg += $"\n\nAssumed Unity version based on asset bundle: {bundleUnityVer}";
|
msg += $"\n\nAssumed Unity version based on asset bundle: {bundleUnityVer}";
|
||||||
throw new NotSupportedException(msg);
|
throw new NotSupportedException(msg);
|
||||||
}
|
}
|
||||||
if (specifiedUnityVersion != null)
|
if (Options.CustomUnityVersion != null)
|
||||||
{
|
{
|
||||||
assetsFile.SetVersion(SpecifyUnityVersion);
|
assetsFile.version = Options.CustomUnityVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
foreach (var assetsFile in assetsFileList)
|
foreach (var assetsFile in AssetsFileList)
|
||||||
{
|
{
|
||||||
assetsFile.Objects.Clear();
|
assetsFile.Objects.Clear();
|
||||||
assetsFile.reader.Close();
|
assetsFile.reader.Close();
|
||||||
}
|
}
|
||||||
assetsFileList.Clear();
|
AssetsFileList.Clear();
|
||||||
|
|
||||||
foreach (var resourceFileReader in resourceFileReaders)
|
foreach (var resourceFileReader in resourceFileReaders)
|
||||||
{
|
{
|
||||||
@@ -511,11 +624,20 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
Logger.Info("Read assets...");
|
Logger.Info("Read assets...");
|
||||||
|
|
||||||
var progressCount = assetsFileList.Sum(x => x.m_Objects.Count);
|
var jsonOptions = new JsonSerializerOptions
|
||||||
int i = 0;
|
|
||||||
Progress.Reset();
|
|
||||||
foreach (var assetsFile in assetsFileList)
|
|
||||||
{
|
{
|
||||||
|
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;
|
||||||
|
Progress.Reset();
|
||||||
|
foreach (var assetsFile in AssetsFileList)
|
||||||
|
{
|
||||||
|
JsonConverterHelper.AssetsFile = assetsFile;
|
||||||
foreach (var objectInfo in assetsFile.m_Objects)
|
foreach (var objectInfo in assetsFile.m_Objects)
|
||||||
{
|
{
|
||||||
var objectReader = new ObjectReader(assetsFile.reader, assetsFile, objectInfo);
|
var objectReader = new ObjectReader(assetsFile.reader, assetsFile, objectInfo);
|
||||||
@@ -532,8 +654,8 @@ namespace AssetStudio
|
|||||||
obj = new Animation(objectReader);
|
obj = new Animation(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.AnimationClip:
|
case ClassIDType.AnimationClip:
|
||||||
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
|
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
|
||||||
? new AnimationClip(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader))
|
? new AnimationClip(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions, objectInfo)
|
||||||
: new AnimationClip(objectReader);
|
: new AnimationClip(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Animator:
|
case ClassIDType.Animator:
|
||||||
@@ -554,6 +676,9 @@ namespace AssetStudio
|
|||||||
case ClassIDType.Avatar:
|
case ClassIDType.Avatar:
|
||||||
obj = new Avatar(objectReader);
|
obj = new Avatar(objectReader);
|
||||||
break;
|
break;
|
||||||
|
case ClassIDType.BuildSettings:
|
||||||
|
obj = new BuildSettings(objectReader);
|
||||||
|
break;
|
||||||
case ClassIDType.Font:
|
case ClassIDType.Font:
|
||||||
obj = new Font(objectReader);
|
obj = new Font(objectReader);
|
||||||
break;
|
break;
|
||||||
@@ -561,7 +686,9 @@ namespace AssetStudio
|
|||||||
obj = new GameObject(objectReader);
|
obj = new GameObject(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Material:
|
case ClassIDType.Material:
|
||||||
obj = new Material(objectReader);
|
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
|
||||||
|
? new Material(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions)
|
||||||
|
: new Material(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Mesh:
|
case ClassIDType.Mesh:
|
||||||
obj = new Mesh(objectReader);
|
obj = new Mesh(objectReader);
|
||||||
@@ -607,13 +734,13 @@ namespace AssetStudio
|
|||||||
obj = new TextAsset(objectReader);
|
obj = new TextAsset(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Texture2D:
|
case ClassIDType.Texture2D:
|
||||||
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
|
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
|
||||||
? new Texture2D(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader))
|
? new Texture2D(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions)
|
||||||
: new Texture2D(objectReader);
|
: new Texture2D(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Texture2DArray:
|
case ClassIDType.Texture2DArray:
|
||||||
obj = objectReader.serializedType?.m_Type != null && LoadingViaTypeTreeEnabled
|
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
|
||||||
? new Texture2DArray(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader))
|
? new Texture2DArray(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions)
|
||||||
: new Texture2DArray(objectReader);
|
: new Texture2DArray(objectReader);
|
||||||
break;
|
break;
|
||||||
case ClassIDType.Transform:
|
case ClassIDType.Transform:
|
||||||
@@ -655,7 +782,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
Logger.Info("Process assets...");
|
Logger.Info("Process assets...");
|
||||||
|
|
||||||
foreach (var assetsFile in assetsFileList)
|
foreach (var assetsFile in AssetsFileList)
|
||||||
{
|
{
|
||||||
foreach (var obj in assetsFile.Objects)
|
foreach (var obj in assetsFile.Objects)
|
||||||
{
|
{
|
||||||
@@ -685,6 +812,34 @@ namespace AssetStudio
|
|||||||
case Animation m_Animation:
|
case Animation m_Animation:
|
||||||
m_GameObject.m_Animation = m_Animation;
|
m_GameObject.m_Animation = m_Animation;
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -699,16 +854,17 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
||||||
}
|
}
|
||||||
else if (m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlaOld))
|
else if (m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlasOld))
|
||||||
{
|
{
|
||||||
if (m_SpriteAtlaOld.m_IsVariant)
|
if (m_SpriteAtlasOld.m_IsVariant)
|
||||||
{
|
{
|
||||||
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Warning($"\"{m_Sprite.m_Name}\": Sprite loading error. SpriteAtlas with PathID: \"{m_Sprite.m_SpriteAtlas.m_PathID}\" was not found.");
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public enum BuildTarget
|
public enum BuildTarget
|
||||||
{
|
{
|
||||||
@@ -53,6 +48,18 @@ namespace AssetStudio
|
|||||||
PS5,
|
PS5,
|
||||||
EmbeddedLinux,
|
EmbeddedLinux,
|
||||||
QNX,
|
QNX,
|
||||||
|
VisionOS,
|
||||||
|
Switch2,
|
||||||
UnknownPlatform = 9999
|
UnknownPlatform = 9999
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum TuanjieBuildTarget
|
||||||
|
{
|
||||||
|
MiniGame = 47,
|
||||||
|
OpenHarmony,
|
||||||
|
HMIAndroid,
|
||||||
|
ArmLinux,
|
||||||
|
ArmLinuxServer,
|
||||||
|
VisionOS,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
43
AssetStudio/BundleCompression/Oodle/Oodle.cs
Normal file
43
AssetStudio/BundleCompression/Oodle/Oodle.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
// LzmaDecoder.cs
|
// LzmaDecoder.cs
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using AssetStudio;
|
||||||
|
|
||||||
namespace SevenZip.Compression.LZMA
|
namespace SevenZip.Compression.LZMA
|
||||||
{
|
{
|
||||||
@@ -247,6 +248,8 @@ namespace SevenZip.Compression.LZMA
|
|||||||
m_OutWindow.PutByte(b);
|
m_OutWindow.PutByte(b);
|
||||||
nowPos64++;
|
nowPos64++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Progress.Reset(index: 1);
|
||||||
while (nowPos64 < outSize64)
|
while (nowPos64 < outSize64)
|
||||||
{
|
{
|
||||||
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
|
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
|
||||||
@@ -338,6 +341,8 @@ namespace SevenZip.Compression.LZMA
|
|||||||
}
|
}
|
||||||
m_OutWindow.CopyBlock(rep0, len);
|
m_OutWindow.CopyBlock(rep0, len);
|
||||||
nowPos64 += len;
|
nowPos64 += len;
|
||||||
|
|
||||||
|
Progress.Report((int)(nowPos64 * 100f / outSize64), 100, index: 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,12 +2,11 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using SevenZip.Compression.LZMA;
|
using SevenZip.Compression.LZMA;
|
||||||
|
|
||||||
|
namespace BundleCompression.Lzma
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public static class SevenZipHelper
|
public static class SevenZipLzma
|
||||||
{
|
{
|
||||||
public static MemoryStream StreamDecompress(MemoryStream inStream)
|
public static MemoryStream DecompressStream(MemoryStream inStream)
|
||||||
{
|
{
|
||||||
var decoder = new Decoder();
|
var decoder = new Decoder();
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ namespace AssetStudio
|
|||||||
return newOutStream;
|
return newOutStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StreamDecompress(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize)
|
public static long DecompressStream(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize)
|
||||||
{
|
{
|
||||||
var basePosition = compressedStream.Position;
|
var basePosition = compressedStream.Position;
|
||||||
var decoder = new Decoder();
|
var decoder = new Decoder();
|
||||||
@@ -44,6 +43,7 @@ namespace AssetStudio
|
|||||||
decoder.SetDecoderProperties(properties);
|
decoder.SetDecoderProperties(properties);
|
||||||
decoder.Code(compressedStream, decompressedStream, compressedSize - 5, decompressedSize, null);
|
decoder.Code(compressedStream, decompressedStream, compressedSize - 5, decompressedSize, null);
|
||||||
compressedStream.Position = basePosition + compressedSize;
|
compressedStream.Position = basePosition + compressedSize;
|
||||||
|
return decompressedStream.Position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
65
AssetStudio/BundleDecompressionHelper.cs
Normal file
65
AssetStudio/BundleDecompressionHelper.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using K4os.Compression.LZ4;
|
using System;
|
||||||
using ZstdSharp;
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using AssetStudio.CustomOptions;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -19,8 +19,8 @@ namespace AssetStudio
|
|||||||
[Flags]
|
[Flags]
|
||||||
public enum CnEncryptionFlags
|
public enum CnEncryptionFlags
|
||||||
{
|
{
|
||||||
OldFlag = 0x200,
|
V1 = 0x200,
|
||||||
NewFlag = 0x400
|
V2_V3 = 0x1400,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
@@ -32,16 +32,21 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public enum CompressionType
|
public enum CompressionType
|
||||||
{
|
{
|
||||||
|
Auto = -1,
|
||||||
None,
|
None,
|
||||||
Lzma,
|
Lzma,
|
||||||
Lz4,
|
Lz4,
|
||||||
Lz4HC,
|
Lz4HC,
|
||||||
Lzham,
|
Lzham,
|
||||||
Custom,
|
Zstd, //custom
|
||||||
|
Oodle, //custom
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BundleFile
|
public class BundleFile
|
||||||
{
|
{
|
||||||
|
public readonly bool IsDataAfterBundle;
|
||||||
|
private readonly CustomBundleOptions _bundleOptions;
|
||||||
|
|
||||||
public class Header
|
public class Header
|
||||||
{
|
{
|
||||||
public string signature;
|
public string signature;
|
||||||
@@ -73,15 +78,17 @@ namespace AssetStudio
|
|||||||
private StorageBlock[] m_BlocksInfo;
|
private StorageBlock[] m_BlocksInfo;
|
||||||
private Node[] m_DirectoryInfo;
|
private Node[] m_DirectoryInfo;
|
||||||
|
|
||||||
public StreamFile[] fileList;
|
public List<StreamFile> fileList;
|
||||||
|
|
||||||
public BundleFile(FileReader reader, bool useZstd, UnityVersion specUnityVer = null)
|
public BundleFile(FileReader reader, CustomBundleOptions bundleOptions, bool isMultiBundle = false)
|
||||||
{
|
{
|
||||||
|
_bundleOptions = bundleOptions;
|
||||||
m_Header = new Header();
|
m_Header = new Header();
|
||||||
m_Header.signature = reader.ReadStringToNull();
|
m_Header.signature = reader.ReadStringToNull();
|
||||||
m_Header.version = reader.ReadUInt32();
|
m_Header.version = reader.ReadUInt32();
|
||||||
m_Header.unityVersion = reader.ReadStringToNull();
|
m_Header.unityVersion = reader.ReadStringToNull();
|
||||||
m_Header.unityRevision = new UnityVersion(reader.ReadStringToNull());
|
m_Header.unityRevision = UnityVersion.TryParse(reader.ReadStringToNull(), out var ver) ? ver : new UnityVersion();
|
||||||
|
|
||||||
switch (m_Header.signature)
|
switch (m_Header.signature)
|
||||||
{
|
{
|
||||||
case "UnityArchive":
|
case "UnityArchive":
|
||||||
@@ -93,58 +100,47 @@ namespace AssetStudio
|
|||||||
goto case "UnityFS";
|
goto case "UnityFS";
|
||||||
}
|
}
|
||||||
ReadHeaderAndBlocksInfo(reader);
|
ReadHeaderAndBlocksInfo(reader);
|
||||||
using (var blocksStream = CreateBlocksStream(reader.FullPath))
|
using (reader)
|
||||||
{
|
{
|
||||||
ReadBlocksAndDirectory(reader, blocksStream);
|
ReadFiles(ReadBlocksAndDirectory(reader));
|
||||||
ReadFiles(blocksStream, reader.FullPath);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "UnityFS":
|
case "UnityFS":
|
||||||
ReadHeader(reader);
|
ReadHeader(reader);
|
||||||
|
|
||||||
var isUnityCnEnc = false;
|
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 unityVer = m_Header.unityRevision;
|
||||||
if (specUnityVer != null)
|
var customUnityVer = _bundleOptions.Options.CustomUnityVersion;
|
||||||
|
if (customUnityVer != null)
|
||||||
{
|
{
|
||||||
if (!unityVer.IsStripped && specUnityVer != unityVer)
|
if (!unityVer.IsStripped && customUnityVer != unityVer)
|
||||||
{
|
{
|
||||||
Logger.Warning($"Detected Unity version is different from the specified one ({specUnityVer.FullVersion.Color(ColorConsole.BrightCyan)}).\n" +
|
Logger.Warning($"Detected Unity version is different from the specified one ({customUnityVer.FullVersion.Color(ColorConsole.BrightCyan)}).\n" +
|
||||||
$"Assets may load with errors.\n" +
|
$"Assets may load with errors.\n" +
|
||||||
$"It is recommended to specify the detected Unity version: {unityVer.FullVersion.Color(ColorConsole.BrightCyan)}");
|
$"It is recommended to specify the detected Unity version: {unityVer.FullVersion.Color(ColorConsole.BrightCyan)}");
|
||||||
}
|
}
|
||||||
unityVer = specUnityVer;
|
unityVer = customUnityVer;
|
||||||
}
|
|
||||||
|
|
||||||
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)))
|
|
||||||
{
|
|
||||||
isUnityCnEnc = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.OldFlag) != 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
isUnityCnEnc = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.NewFlag) != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isUnityCnEnc)
|
|
||||||
{
|
|
||||||
var msg = "Unsupported bundle file. ";
|
|
||||||
msg += specUnityVer != null
|
|
||||||
? "UnityCN encryption was detected or the specified Unity version is incorrect."
|
|
||||||
: "UnityCN encryption was detected.";
|
|
||||||
throw new NotSupportedException(msg);
|
|
||||||
}
|
}
|
||||||
|
UnityCnCheck(reader, unityVer);
|
||||||
|
|
||||||
ReadBlocksInfoAndDirectory(reader, unityVer);
|
ReadBlocksInfoAndDirectory(reader, unityVer);
|
||||||
using (var blocksStream = CreateBlocksStream(reader.FullPath))
|
|
||||||
|
if (IsUncompressedBundle && !IsDataAfterBundle && !isMultiBundle)
|
||||||
{
|
{
|
||||||
ReadBlocks(reader, blocksStream, useZstd);
|
Logger.Debug($"[Uncompressed bundle] BlockData count: {m_BlocksInfo.Length}");
|
||||||
ReadFiles(blocksStream, reader.FullPath);
|
ReadFiles(reader.BaseStream, reader.Position);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReadFiles(ReadBlocks(reader));
|
||||||
|
if (!IsDataAfterBundle)
|
||||||
|
reader.Close();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,7 +159,7 @@ namespace AssetStudio
|
|||||||
m_BlocksInfo = new StorageBlock[1];
|
m_BlocksInfo = new StorageBlock[1];
|
||||||
for (int i = 0; i < levelCount; i++)
|
for (int i = 0; i < levelCount; i++)
|
||||||
{
|
{
|
||||||
var storageBlock = new StorageBlock()
|
var storageBlock = new StorageBlock
|
||||||
{
|
{
|
||||||
compressedSize = reader.ReadUInt32(),
|
compressedSize = reader.ReadUInt32(),
|
||||||
uncompressedSize = reader.ReadUInt32(),
|
uncompressedSize = reader.ReadUInt32(),
|
||||||
@@ -186,23 +182,24 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private Stream CreateBlocksStream(string path)
|
private Stream CreateBlocksStream(string path)
|
||||||
{
|
{
|
||||||
Stream blocksStream;
|
|
||||||
var uncompressedSizeSum = m_BlocksInfo.Sum(x => x.uncompressedSize);
|
var uncompressedSizeSum = m_BlocksInfo.Sum(x => x.uncompressedSize);
|
||||||
if (uncompressedSizeSum >= int.MaxValue)
|
if (uncompressedSizeSum < int.MaxValue && !_bundleOptions.DecompressToDisk)
|
||||||
|
return new MemoryStream((int)uncompressedSizeSum);
|
||||||
|
|
||||||
|
if (!Directory.Exists(Path.GetDirectoryName(path)))
|
||||||
{
|
{
|
||||||
/*var memoryMappedFile = MemoryMappedFile.CreateNew(null, uncompressedSizeSum);
|
var tempDir = Path.Combine(Directory.GetCurrentDirectory(), "Studio_temp");
|
||||||
assetsDataStream = memoryMappedFile.CreateViewStream();*/
|
Directory.CreateDirectory(tempDir);
|
||||||
blocksStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
|
var filename = Path.GetFileName(path);
|
||||||
|
var hash = path.GetHashCode();
|
||||||
|
path = Path.Combine(tempDir, $"{filename}_{hash:X}");
|
||||||
}
|
}
|
||||||
else
|
return new TempFileStream(path + ".temp", FileMode.Create);
|
||||||
{
|
|
||||||
blocksStream = new MemoryStream((int)uncompressedSizeSum);
|
|
||||||
}
|
|
||||||
return blocksStream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadBlocksAndDirectory(FileReader reader, Stream blocksStream)
|
private Stream ReadBlocksAndDirectory(FileReader reader)
|
||||||
{
|
{
|
||||||
|
var blocksStream = CreateBlocksStream(reader.FullPath);
|
||||||
var isCompressed = m_Header.signature == "UnityWeb";
|
var isCompressed = m_Header.signature == "UnityWeb";
|
||||||
foreach (var blockInfo in m_BlocksInfo)
|
foreach (var blockInfo in m_BlocksInfo)
|
||||||
{
|
{
|
||||||
@@ -211,7 +208,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
using (var memoryStream = new MemoryStream(uncompressedBytes))
|
using (var memoryStream = new MemoryStream(uncompressedBytes))
|
||||||
{
|
{
|
||||||
using (var decompressStream = SevenZipHelper.StreamDecompress(memoryStream))
|
using (var decompressStream = BundleDecompressionHelper.DecompressLzmaStream(memoryStream))
|
||||||
{
|
{
|
||||||
uncompressedBytes = decompressStream.ToArray();
|
uncompressedBytes = decompressStream.ToArray();
|
||||||
}
|
}
|
||||||
@@ -220,10 +217,11 @@ namespace AssetStudio
|
|||||||
blocksStream.Write(uncompressedBytes, 0, uncompressedBytes.Length);
|
blocksStream.Write(uncompressedBytes, 0, uncompressedBytes.Length);
|
||||||
}
|
}
|
||||||
blocksStream.Position = 0;
|
blocksStream.Position = 0;
|
||||||
|
|
||||||
var blocksReader = new EndianBinaryReader(blocksStream);
|
var blocksReader = new EndianBinaryReader(blocksStream);
|
||||||
var nodesCount = blocksReader.ReadInt32();
|
var nodesCount = blocksReader.ReadInt32();
|
||||||
m_DirectoryInfo = new Node[nodesCount];
|
m_DirectoryInfo = new Node[nodesCount];
|
||||||
for (int i = 0; i < nodesCount; i++)
|
for (var i = 0; i < nodesCount; i++)
|
||||||
{
|
{
|
||||||
m_DirectoryInfo[i] = new Node
|
m_DirectoryInfo[i] = new Node
|
||||||
{
|
{
|
||||||
@@ -232,33 +230,27 @@ namespace AssetStudio
|
|||||||
size = blocksReader.ReadUInt32()
|
size = blocksReader.ReadUInt32()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return blocksStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReadFiles(Stream blocksStream, string path)
|
private void ReadFiles(Stream inputStream, long blocksOffset = 0)
|
||||||
{
|
{
|
||||||
fileList = new StreamFile[m_DirectoryInfo.Length];
|
fileList = new List<StreamFile>(m_DirectoryInfo.Length);
|
||||||
for (int i = 0; i < m_DirectoryInfo.Length; i++)
|
foreach (var node in m_DirectoryInfo)
|
||||||
{
|
{
|
||||||
var node = m_DirectoryInfo[i];
|
|
||||||
var file = new StreamFile();
|
var file = new StreamFile();
|
||||||
fileList[i] = file;
|
fileList.Add(file);
|
||||||
file.path = node.path;
|
file.path = node.path;
|
||||||
file.fileName = Path.GetFileName(node.path);
|
file.fileName = Path.GetFileName(node.path);
|
||||||
if (node.size >= int.MaxValue)
|
try
|
||||||
{
|
{
|
||||||
/*var memoryMappedFile = MemoryMappedFile.CreateNew(null, entryinfo_size);
|
file.stream = new OffsetStream(inputStream, node.offset + blocksOffset, node.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);
|
|
||||||
}
|
}
|
||||||
else
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
file.stream = new MemoryStream((int)node.size);
|
Logger.Warning($"Failed to access {file.fileName} file.\n{e}");
|
||||||
}
|
}
|
||||||
blocksStream.Position = node.offset;
|
|
||||||
blocksStream.CopyTo(file.stream, node.size);
|
|
||||||
file.stream.Position = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +266,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadBlocksInfoAndDirectory(FileReader reader, UnityVersion unityVer)
|
private void ReadBlocksInfoAndDirectory(FileReader reader, UnityVersion unityVer, bool silent = false)
|
||||||
{
|
{
|
||||||
byte[] blocksInfoBytes;
|
byte[] blocksInfoBytes;
|
||||||
|
|
||||||
@@ -295,52 +287,88 @@ 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)
|
if ((m_Header.flags & ArchiveFlags.BlocksInfoAtTheEnd) != 0)
|
||||||
{
|
{
|
||||||
var position = reader.Position;
|
var position = reader.Position;
|
||||||
reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
|
reader.Position = m_Header.size - compressedSize;
|
||||||
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
|
blocksInfoBytes = reader.ReadBytes(compressedSize);
|
||||||
reader.Position = position;
|
reader.Position = position;
|
||||||
}
|
}
|
||||||
else //0x40 BlocksAndDirectoryInfoCombined
|
else //0x40 BlocksAndDirectoryInfoCombined
|
||||||
{
|
{
|
||||||
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
|
blocksInfoBytes = reader.ReadBytes(compressedSize);
|
||||||
}
|
}
|
||||||
MemoryStream blocksInfoUncompressedStream;
|
|
||||||
var uncompressedSize = m_Header.uncompressedBlocksInfoSize;
|
var customBlockInfoCompression = _bundleOptions.CustomBlockInfoCompression;
|
||||||
var compressionType = (CompressionType)(m_Header.flags & ArchiveFlags.CompressionTypeMask);
|
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)
|
switch (compressionType)
|
||||||
{
|
{
|
||||||
case CompressionType.None:
|
case CompressionType.None:
|
||||||
{
|
{
|
||||||
blocksInfoUncompressedStream = new MemoryStream(blocksInfoBytes);
|
blocksInfoUncompressedStream = new MemoryStream(blocksInfoBytes);
|
||||||
|
numWrite = compressedSize;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CompressionType.Lzma:
|
case CompressionType.Lzma:
|
||||||
{
|
{
|
||||||
blocksInfoUncompressedStream = new MemoryStream((int) (uncompressedSize));
|
blocksInfoUncompressedStream = new MemoryStream(uncompressedSize);
|
||||||
using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
|
using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
|
||||||
{
|
{
|
||||||
SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompressedStream,
|
numWrite = (int)BundleDecompressionHelper.DecompressLzmaStream(blocksInfoCompressedStream, blocksInfoUncompressedStream, compressedSize, uncompressedSize, ref errorMsg);
|
||||||
m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
|
|
||||||
}
|
}
|
||||||
blocksInfoUncompressedStream.Position = 0;
|
blocksInfoUncompressedStream.Position = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CompressionType.Lz4:
|
case CompressionType.Lz4:
|
||||||
case CompressionType.Lz4HC:
|
case CompressionType.Lz4HC:
|
||||||
|
case CompressionType.Zstd:
|
||||||
|
case CompressionType.Oodle:
|
||||||
{
|
{
|
||||||
var uncompressedBytes = new byte[uncompressedSize];
|
var uncompressedBytes = new byte[uncompressedSize];
|
||||||
var numWrite = LZ4Codec.Decode(blocksInfoBytes, uncompressedBytes);
|
numWrite = BundleDecompressionHelper.DecompressBlock(compressionType, blocksInfoBytes, uncompressedBytes, ref errorMsg);
|
||||||
if (numWrite != uncompressedSize)
|
|
||||||
{
|
|
||||||
throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
|
|
||||||
}
|
|
||||||
blocksInfoUncompressedStream = new MemoryStream(uncompressedBytes);
|
blocksInfoUncompressedStream = new MemoryStream(uncompressedBytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CompressionType.Lzham:
|
||||||
|
throw new IOException($"Unsupported blockInfo compression type: {compressionType}.\n");
|
||||||
default:
|
default:
|
||||||
throw new IOException($"Unsupported block info compression type {compressionType}");
|
throw new IOException($"Unknown blockInfo compression type: {compressionType}.\nYou may try to specify the compression type manually.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
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(blocksInfoUncompressedStream))
|
||||||
@@ -348,7 +376,7 @@ namespace AssetStudio
|
|||||||
var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
|
var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
|
||||||
var blocksInfoCount = blocksInfoReader.ReadInt32();
|
var blocksInfoCount = blocksInfoReader.ReadInt32();
|
||||||
m_BlocksInfo = new StorageBlock[blocksInfoCount];
|
m_BlocksInfo = new StorageBlock[blocksInfoCount];
|
||||||
for (int i = 0; i < blocksInfoCount; i++)
|
for (var i = 0; i < blocksInfoCount; i++)
|
||||||
{
|
{
|
||||||
m_BlocksInfo[i] = new StorageBlock
|
m_BlocksInfo[i] = new StorageBlock
|
||||||
{
|
{
|
||||||
@@ -360,7 +388,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
var nodesCount = blocksInfoReader.ReadInt32();
|
var nodesCount = blocksInfoReader.ReadInt32();
|
||||||
m_DirectoryInfo = new Node[nodesCount];
|
m_DirectoryInfo = new Node[nodesCount];
|
||||||
for (int i = 0; i < nodesCount; i++)
|
for (var i = 0; i < nodesCount; i++)
|
||||||
{
|
{
|
||||||
m_DirectoryInfo[i] = new Node
|
m_DirectoryInfo[i] = new Node
|
||||||
{
|
{
|
||||||
@@ -377,75 +405,149 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadBlocks(FileReader reader, Stream blocksStream, bool useZstd)
|
private Stream ReadBlocks(FileReader reader)
|
||||||
{
|
{
|
||||||
var zstdCodec = new Decompressor();
|
var customBlockCompression = _bundleOptions.CustomBlockCompression;
|
||||||
var i = 0;
|
var blocksStream = CreateBlocksStream(reader.FullPath);
|
||||||
foreach (var blockInfo in m_BlocksInfo)
|
var blocksCompression = m_BlocksInfo.Max(x => (CompressionType)(x.flags & StorageBlockFlags.CompressionTypeMask));
|
||||||
{
|
var blockSize = (int)m_BlocksInfo.Max(x => x.uncompressedSize);
|
||||||
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
|
Logger.Debug($"BlockData compression: {blocksCompression}\n" +
|
||||||
switch (compressionType)
|
$"BlockData count: {m_BlocksInfo.Length}\n" +
|
||||||
{
|
$"BlockSize: {blockSize}");
|
||||||
case CompressionType.None:
|
|
||||||
{
|
|
||||||
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CompressionType.Lzma:
|
|
||||||
{
|
|
||||||
SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CompressionType.Lz4:
|
|
||||||
case CompressionType.Lz4HC:
|
|
||||||
case CompressionType.Custom:
|
|
||||||
{
|
|
||||||
var compressedSize = (int)blockInfo.compressedSize;
|
|
||||||
var compressedBytes = BigArrayPool<byte>.Shared.Rent(compressedSize);
|
|
||||||
_ = reader.Read(compressedBytes, 0, compressedSize);
|
|
||||||
var uncompressedSize = (int)blockInfo.uncompressedSize;
|
|
||||||
var uncompressedBytes = BigArrayPool<byte>.Shared.Rent(uncompressedSize);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var compTypeStr = compressionType.ToString();
|
|
||||||
if (compressionType == CompressionType.Custom)
|
|
||||||
{
|
|
||||||
compTypeStr = useZstd ? "Zstd" : "Lz4";
|
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
Logger.Debug($"Custom block compression type was detected. Trying to decompress as {compTypeStr} archive..");
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int numWrite;
|
if (customBlockCompression == CompressionType.Auto)
|
||||||
if (compressionType == CompressionType.Custom && useZstd)
|
|
||||||
{
|
{
|
||||||
numWrite = zstdCodec.Unwrap(compressedBytes, 0, compressedSize, uncompressedBytes, 0, uncompressedSize);
|
if (blocksCompression > CompressionType.Lzham && Enum.IsDefined(typeof(CompressionType), blocksCompression))
|
||||||
|
{
|
||||||
|
Logger.Warning($"Non-standard block compression type: {(int)blocksCompression}. Trying to decompress as {blocksCompression} archive..");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
numWrite = LZ4Codec.Decode(compressedBytes, 0, compressedSize, uncompressedBytes, 0, uncompressedSize);
|
Logger.Info($"Custom block compression type: {customBlockCompression}");
|
||||||
|
blocksCompression = customBlockCompression;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numWrite != uncompressedSize)
|
byte[] sharedCompressedBuff = null;
|
||||||
|
byte[] sharedUncompressedBuff = null;
|
||||||
|
if (blocksCompression > CompressionType.Lzma && blocksCompression != CompressionType.Lzham)
|
||||||
{
|
{
|
||||||
throw new IOException($"{compTypeStr} block decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
|
sharedCompressedBuff = BigArrayPool<byte>.Shared.Rent(blockSize);
|
||||||
|
sharedUncompressedBuff = BigArrayPool<byte>.Shared.Rent(blockSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (var i = 0; i < m_BlocksInfo.Length; i++)
|
||||||
|
{
|
||||||
|
var blockInfo = m_BlocksInfo[i];
|
||||||
|
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
|
||||||
|
|
||||||
|
if (customBlockCompression != CompressionType.Auto && compressionType > 0)
|
||||||
|
{
|
||||||
|
compressionType = customBlockCompression;
|
||||||
|
}
|
||||||
|
var debugMsg = $"[{i:D2}] Compression: {compressionType} | UncompressedSize: {blockInfo.uncompressedSize} | CompressedSize: {blockInfo.compressedSize} ";
|
||||||
|
|
||||||
|
long numWrite;
|
||||||
|
var errorMsg = string.Empty;
|
||||||
|
switch (compressionType)
|
||||||
|
{
|
||||||
|
case CompressionType.None:
|
||||||
|
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
|
||||||
|
numWrite = blockInfo.compressedSize;
|
||||||
|
break;
|
||||||
|
case CompressionType.Lzma:
|
||||||
|
numWrite = BundleDecompressionHelper.DecompressLzmaStream(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize, ref errorMsg);
|
||||||
|
break;
|
||||||
|
case CompressionType.Lz4:
|
||||||
|
case CompressionType.Lz4HC:
|
||||||
|
case CompressionType.Zstd:
|
||||||
|
case CompressionType.Oodle:
|
||||||
|
var compressedSize = (int)blockInfo.compressedSize;
|
||||||
|
var uncompressedSize = (int)blockInfo.uncompressedSize;
|
||||||
|
|
||||||
|
sharedCompressedBuff.AsSpan().Clear();
|
||||||
|
sharedUncompressedBuff.AsSpan().Clear();
|
||||||
|
|
||||||
|
var read = reader.Read(sharedCompressedBuff, 0, compressedSize);
|
||||||
|
debugMsg += $"(read: {read.ToString().ColorIf(read != compressedSize, ColorConsole.BrightRed)})";
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
blocksStream.Write(sharedUncompressedBuff, 0, uncompressedSize);
|
||||||
|
}
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
Logger.Debug(debugMsg);
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
blocksStream.Write(uncompressedBytes, 0, uncompressedSize);
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
BigArrayPool<byte>.Shared.Return(compressedBytes, clearArray: true);
|
if (sharedCompressedBuff != null)
|
||||||
BigArrayPool<byte>.Shared.Return(uncompressedBytes, clearArray: true);
|
BigArrayPool<byte>.Shared.Return(sharedCompressedBuff, clearArray: true);
|
||||||
|
|
||||||
|
if (sharedUncompressedBuff != null)
|
||||||
|
BigArrayPool<byte>.Shared.Return(sharedUncompressedBuff, clearArray: true);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
return blocksStream;
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
throw new IOException($"Unsupported block compression type {compressionType}");
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
blocksStream.Position = 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,6 +297,7 @@ namespace AssetStudio
|
|||||||
//void = 100011,
|
//void = 100011,
|
||||||
TilemapCollider2D = 19719996,
|
TilemapCollider2D = 19719996,
|
||||||
AssetImporterLog = 41386430,
|
AssetImporterLog = 41386430,
|
||||||
|
GraphicsStateCollection = 55640938,
|
||||||
VFXRenderer = 73398921,
|
VFXRenderer = 73398921,
|
||||||
SerializableManagedRefTestClass = 76251197,
|
SerializableManagedRefTestClass = 76251197,
|
||||||
Grid = 156049354,
|
Grid = 156049354,
|
||||||
@@ -309,9 +310,13 @@ namespace AssetStudio
|
|||||||
AssemblyDefinitionReferenceImporter = 294290339,
|
AssemblyDefinitionReferenceImporter = 294290339,
|
||||||
SiblingDerived = 334799969,
|
SiblingDerived = 334799969,
|
||||||
TestObjectWithSerializedMapStringNonAlignedStruct = 342846651,
|
TestObjectWithSerializedMapStringNonAlignedStruct = 342846651,
|
||||||
|
AudioResource = 355983997,
|
||||||
SubDerived = 367388927,
|
SubDerived = 367388927,
|
||||||
AssetImportInProgressProxy = 369655926,
|
AssetImportInProgressProxy = 369655926,
|
||||||
PluginBuildInfo = 382020655,
|
PluginBuildInfo = 382020655,
|
||||||
|
MemorySettings = 387306366,
|
||||||
|
BuildMetaDataImporter = 403037116,
|
||||||
|
BuildInstructionImporter = 403037117,
|
||||||
EditorProjectAccess = 426301858,
|
EditorProjectAccess = 426301858,
|
||||||
PrefabImporter = 468431735,
|
PrefabImporter = 468431735,
|
||||||
TestObjectWithSerializedArray = 478637458,
|
TestObjectWithSerializedArray = 478637458,
|
||||||
@@ -323,16 +328,22 @@ namespace AssetStudio
|
|||||||
AudioBuildInfo = 641289076,
|
AudioBuildInfo = 641289076,
|
||||||
CachedSpriteAtlasRuntimeData = 644342135,
|
CachedSpriteAtlasRuntimeData = 644342135,
|
||||||
RendererFake = 646504946,
|
RendererFake = 646504946,
|
||||||
|
MultiplayerManager = 655991488,
|
||||||
AssemblyDefinitionReferenceAsset = 662584278,
|
AssemblyDefinitionReferenceAsset = 662584278,
|
||||||
BuiltAssetBundleInfoSet = 668709126,
|
BuiltAssetBundleInfoSet = 668709126,
|
||||||
SpriteAtlas = 687078895,
|
SpriteAtlas = 687078895,
|
||||||
RayTracingShaderImporter = 747330370,
|
RayTracingShaderImporter = 747330370,
|
||||||
|
BuildArchiveImporter = 780535461,
|
||||||
|
PreviewImporter = 815301076,
|
||||||
RayTracingShader = 825902497,
|
RayTracingShader = 825902497,
|
||||||
LightingSettings = 850595691,
|
LightingSettings = 850595691,
|
||||||
PlatformModuleSetup = 877146078,
|
PlatformModuleSetup = 877146078,
|
||||||
VersionControlSettings = 890905787,
|
VersionControlSettings = 890905787,
|
||||||
|
CustomCollider2D = 893571522,
|
||||||
AimConstraint = 895512359,
|
AimConstraint = 895512359,
|
||||||
VFXManager = 937362698,
|
VFXManager = 937362698,
|
||||||
|
RoslynAnalyzerConfigAsset = 947337230,
|
||||||
|
RuleSetFileAsset = 954905827,
|
||||||
VisualEffectSubgraph = 994735392,
|
VisualEffectSubgraph = 994735392,
|
||||||
VisualEffectSubgraphOperator = 994735403,
|
VisualEffectSubgraphOperator = 994735403,
|
||||||
VisualEffectSubgraphBlock = 994735404,
|
VisualEffectSubgraphBlock = 994735404,
|
||||||
@@ -345,25 +356,40 @@ namespace AssetStudio
|
|||||||
LookAtConstraint = 1183024399,
|
LookAtConstraint = 1183024399,
|
||||||
SpriteAtlasImporter = 1210832254,
|
SpriteAtlasImporter = 1210832254,
|
||||||
MultiArtifactTestImporter = 1223240404,
|
MultiArtifactTestImporter = 1223240404,
|
||||||
|
AudioContainerElement = 1233149941,
|
||||||
GameObjectRecorder = 1268269756,
|
GameObjectRecorder = 1268269756,
|
||||||
|
AudioRandomContainer = 1307931743,
|
||||||
LightingDataAssetParent = 1325145578,
|
LightingDataAssetParent = 1325145578,
|
||||||
PresetManager = 1386491679,
|
PresetManager = 1386491679,
|
||||||
TestObjectWithSpecialLayoutTwo = 1392443030,
|
TestObjectWithSpecialLayoutTwo = 1392443030,
|
||||||
StreamingManager = 1403656975,
|
StreamingManager = 1403656975,
|
||||||
LowerResBlitTexture = 1480428607,
|
LowerResBlitTexture = 1480428607,
|
||||||
|
VideoBuildInfo = 1521398425,
|
||||||
|
C4DImporter = 1541671625,
|
||||||
StreamingController = 1542919678,
|
StreamingController = 1542919678,
|
||||||
RenderPassAttachment = 1571458007,
|
RenderPassAttachment = 1571458007,
|
||||||
TestObjectVectorPairStringBool = 1628831178,
|
TestObjectVectorPairStringBool = 1628831178,
|
||||||
|
ShaderContainer = 1557264870,
|
||||||
|
RoslynAdditionalFileAsset = 1597193336,
|
||||||
|
RoslynAdditionalFileImporter = 1642787288,
|
||||||
|
MultiplayerRolesData = 1652712579,
|
||||||
|
SceneRoots = 1660057539,
|
||||||
|
BrokenPrefabAsset = 1731078267,
|
||||||
|
AndroidAssetPackImporter = 1736697216,
|
||||||
|
VulkanDeviceFilterLists = 1740304944,
|
||||||
GridLayout = 1742807556,
|
GridLayout = 1742807556,
|
||||||
AssemblyDefinitionImporter = 1766753193,
|
AssemblyDefinitionImporter = 1766753193,
|
||||||
ParentConstraint = 1773428102,
|
ParentConstraint = 1773428102,
|
||||||
FakeComponent = 1803986026,
|
FakeComponent = 1803986026,
|
||||||
|
RuleSetFileImporter = 1777034230,
|
||||||
PositionConstraint = 1818360608,
|
PositionConstraint = 1818360608,
|
||||||
RotationConstraint = 1818360609,
|
RotationConstraint = 1818360609,
|
||||||
ScaleConstraint = 1818360610,
|
ScaleConstraint = 1818360610,
|
||||||
Tilemap = 1839735485,
|
Tilemap = 1839735485,
|
||||||
PackageManifest = 1896753125,
|
PackageManifest = 1896753125,
|
||||||
PackageManifestImporter = 1896753126,
|
PackageManifestImporter = 1896753126,
|
||||||
|
RoslynAnalyzerConfigImporter = 1903396204,
|
||||||
|
UIRenderer = 1931382933,
|
||||||
TerrainLayer = 1953259897,
|
TerrainLayer = 1953259897,
|
||||||
SpriteShapeRenderer = 1971053207,
|
SpriteShapeRenderer = 1971053207,
|
||||||
NativeObjectType = 1977754360,
|
NativeObjectType = 1977754360,
|
||||||
@@ -375,6 +401,7 @@ namespace AssetStudio
|
|||||||
VisualEffectObject = 2059678085,
|
VisualEffectObject = 2059678085,
|
||||||
VisualEffect = 2083052967,
|
VisualEffect = 2083052967,
|
||||||
LocalizationAsset = 2083778819,
|
LocalizationAsset = 2083778819,
|
||||||
ScriptedImporter = 2089858483
|
ScriptedImporter = 2089858483,
|
||||||
|
ShaderIncludeImporter = 2103361453,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,19 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public sealed class Animation : Behaviour
|
public sealed class Animation : Behaviour
|
||||||
{
|
{
|
||||||
public PPtr<AnimationClip>[] m_Animations;
|
public List<PPtr<AnimationClip>> m_Animations;
|
||||||
|
|
||||||
public Animation(ObjectReader reader) : base(reader)
|
public Animation(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
var m_Animation = new PPtr<AnimationClip>(reader);
|
var m_Animation = new PPtr<AnimationClip>(reader);
|
||||||
int numAnimations = reader.ReadInt32();
|
int numAnimations = reader.ReadInt32();
|
||||||
m_Animations = new PPtr<AnimationClip>[numAnimations];
|
m_Animations = new List<PPtr<AnimationClip>>();
|
||||||
for (int i = 0; i < numAnimations; i++)
|
for (var i = 0; i < numAnimations; i++)
|
||||||
{
|
{
|
||||||
m_Animations[i] = new PPtr<AnimationClip>(reader);
|
m_Animations.Add(new PPtr<AnimationClip>(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using Newtonsoft.Json;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -36,7 +35,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class AnimationCurve<T>
|
public class AnimationCurve<T>
|
||||||
{
|
{
|
||||||
public Keyframe<T>[] m_Curve;
|
public List<Keyframe<T>> m_Curve;
|
||||||
public int m_PreInfinity;
|
public int m_PreInfinity;
|
||||||
public int m_PostInfinity;
|
public int m_PostInfinity;
|
||||||
public int m_RotationOrder;
|
public int m_RotationOrder;
|
||||||
@@ -45,17 +44,16 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public AnimationCurve(ObjectReader reader, Func<T> readerFunc)
|
public AnimationCurve(ObjectReader reader, Func<T> readerFunc)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
|
||||||
int numCurves = reader.ReadInt32();
|
int numCurves = reader.ReadInt32();
|
||||||
m_Curve = new Keyframe<T>[numCurves];
|
m_Curve = new List<Keyframe<T>>();
|
||||||
for (int i = 0; i < numCurves; i++)
|
for (var i = 0; i < numCurves; i++)
|
||||||
{
|
{
|
||||||
m_Curve[i] = new Keyframe<T>(reader, readerFunc);
|
m_Curve.Add(new Keyframe<T>(reader, readerFunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_PreInfinity = reader.ReadInt32();
|
m_PreInfinity = reader.ReadInt32();
|
||||||
m_PostInfinity = reader.ReadInt32();
|
m_PostInfinity = reader.ReadInt32();
|
||||||
if (version >= (5, 3)) //5.3 and up
|
if (reader.version >= (5, 3)) //5.3 and up
|
||||||
{
|
{
|
||||||
m_RotationOrder = reader.ReadInt32();
|
m_RotationOrder = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -113,7 +111,7 @@ namespace AssetStudio
|
|||||||
var data = new List<float>();
|
var data = new List<float>();
|
||||||
for (var index = 0; index != end; index += chunkStride / 4)
|
for (var index = 0; index != end; index += chunkStride / 4)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < itemCountInChunk; ++i)
|
for (var i = 0; i < itemCountInChunk; ++i)
|
||||||
{
|
{
|
||||||
uint x = 0;
|
uint x = 0;
|
||||||
|
|
||||||
@@ -134,7 +132,6 @@ namespace AssetStudio
|
|||||||
data.Add(x / (scale * ((1 << m_BitSize) - 1)) + m_Start);
|
data.Add(x / (scale * ((1 << m_BitSize) - 1)) + m_Start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return data.ToArray();
|
return data.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,16 +158,16 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public int[] UnpackInts()
|
public int[] UnpackInts()
|
||||||
{
|
{
|
||||||
var data = new int[m_NumItems];
|
var data = new List<int>();
|
||||||
int indexPos = 0;
|
int indexPos = 0;
|
||||||
int bitPos = 0;
|
int bitPos = 0;
|
||||||
for (int i = 0; i < m_NumItems; i++)
|
for (var i = 0; i < m_NumItems; i++)
|
||||||
{
|
{
|
||||||
int bits = 0;
|
int bits = 0;
|
||||||
data[i] = 0;
|
int elem = 0;
|
||||||
while (bits < m_BitSize)
|
while (bits < m_BitSize)
|
||||||
{
|
{
|
||||||
data[i] |= (m_Data[indexPos] >> bitPos) << bits;
|
elem |= (m_Data[indexPos] >> bitPos) << bits;
|
||||||
int num = Math.Min(m_BitSize - bits, 8 - bitPos);
|
int num = Math.Min(m_BitSize - bits, 8 - bitPos);
|
||||||
bitPos += num;
|
bitPos += num;
|
||||||
bits += num;
|
bits += num;
|
||||||
@@ -180,9 +177,10 @@ namespace AssetStudio
|
|||||||
bitPos = 0;
|
bitPos = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data[i] &= (1 << m_BitSize) - 1;
|
elem &= (1 << m_BitSize) - 1;
|
||||||
|
data.Add(elem);
|
||||||
}
|
}
|
||||||
return data;
|
return data.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,11 +203,11 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public Quaternion[] UnpackQuats()
|
public Quaternion[] UnpackQuats()
|
||||||
{
|
{
|
||||||
var data = new Quaternion[m_NumItems];
|
var data = new List<Quaternion>();
|
||||||
int indexPos = 0;
|
int indexPos = 0;
|
||||||
int bitPos = 0;
|
int bitPos = 0;
|
||||||
|
|
||||||
for (int i = 0; i < m_NumItems; i++)
|
for (var i = 0; i < m_NumItems; i++)
|
||||||
{
|
{
|
||||||
uint flags = 0;
|
uint flags = 0;
|
||||||
|
|
||||||
@@ -228,10 +226,9 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
flags &= 7;
|
flags &= 7;
|
||||||
|
|
||||||
|
|
||||||
var q = new Quaternion();
|
var q = new Quaternion();
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
for (int j = 0; j < 4; j++)
|
for (var j = 0; j < 4; j++)
|
||||||
{
|
{
|
||||||
if ((flags & 3) != j)
|
if ((flags & 3) != j)
|
||||||
{
|
{
|
||||||
@@ -256,15 +253,13 @@ namespace AssetStudio
|
|||||||
sum += q[j] * q[j];
|
sum += q[j] * q[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastComponent = (int)(flags & 3);
|
int lastComponent = (int)(flags & 3);
|
||||||
q[lastComponent] = (float)Math.Sqrt(1 - sum);
|
q[lastComponent] = MathF.Sqrt(1 - sum);
|
||||||
if ((flags & 4) != 0u)
|
if ((flags & 4) != 0u)
|
||||||
q[lastComponent] = -q[lastComponent];
|
q[lastComponent] = -q[lastComponent];
|
||||||
data[i] = q;
|
data.Add(q);
|
||||||
}
|
}
|
||||||
|
return data.ToArray();
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,13 +312,12 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public FloatCurve(ObjectReader reader)
|
public FloatCurve(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
|
||||||
curve = new AnimationCurve<float>(reader, reader.ReadSingle);
|
curve = new AnimationCurve<float>(reader, reader.ReadSingle);
|
||||||
attribute = reader.ReadAlignedString();
|
attribute = reader.ReadAlignedString();
|
||||||
path = reader.ReadAlignedString();
|
path = reader.ReadAlignedString();
|
||||||
classID = (ClassIDType)reader.ReadInt32();
|
classID = (ClassIDType)reader.ReadInt32();
|
||||||
script = new PPtr<MonoScript>(reader);
|
script = new PPtr<MonoScript>(reader);
|
||||||
if (version >= (2022, 2)) //2022.2 and up
|
if (reader.version >= (2022, 2)) //2022.2 and up
|
||||||
{
|
{
|
||||||
flags = reader.ReadInt32();
|
flags = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -346,7 +340,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class PPtrCurve
|
public class PPtrCurve
|
||||||
{
|
{
|
||||||
public PPtrKeyframe[] curve;
|
public List<PPtrKeyframe> curve;
|
||||||
public string attribute;
|
public string attribute;
|
||||||
public string path;
|
public string path;
|
||||||
public int classID;
|
public int classID;
|
||||||
@@ -357,19 +351,18 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public PPtrCurve(ObjectReader reader)
|
public PPtrCurve(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
|
||||||
int numCurves = reader.ReadInt32();
|
int numCurves = reader.ReadInt32();
|
||||||
curve = new PPtrKeyframe[numCurves];
|
curve = new List<PPtrKeyframe>();
|
||||||
for (int i = 0; i < numCurves; i++)
|
for (var i = 0; i < numCurves; i++)
|
||||||
{
|
{
|
||||||
curve[i] = new PPtrKeyframe(reader);
|
curve.Add(new PPtrKeyframe(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
attribute = reader.ReadAlignedString();
|
attribute = reader.ReadAlignedString();
|
||||||
path = reader.ReadAlignedString();
|
path = reader.ReadAlignedString();
|
||||||
classID = reader.ReadInt32();
|
classID = reader.ReadInt32();
|
||||||
script = new PPtr<MonoScript>(reader);
|
script = new PPtr<MonoScript>(reader);
|
||||||
if (version >= (2022, 2)) //2022.2 and up
|
if (reader.version >= (2022, 2)) //2022.2 and up
|
||||||
{
|
{
|
||||||
flags = reader.ReadInt32();
|
flags = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -474,11 +467,12 @@ namespace AssetStudio
|
|||||||
m_LookAtWeight = reader.ReadVector4();
|
m_LookAtWeight = reader.ReadVector4();
|
||||||
|
|
||||||
int numGoals = reader.ReadInt32();
|
int numGoals = reader.ReadInt32();
|
||||||
m_GoalArray = new HumanGoal[numGoals];
|
var goalList = new List<HumanGoal>();
|
||||||
for (int i = 0; i < numGoals; i++)
|
for (var i = 0; i < numGoals; i++)
|
||||||
{
|
{
|
||||||
m_GoalArray[i] = new HumanGoal(reader);
|
goalList.Add(new HumanGoal(reader));
|
||||||
}
|
}
|
||||||
|
m_GoalArray = goalList.ToArray();
|
||||||
|
|
||||||
m_LeftHandPose = new HandPose(reader);
|
m_LeftHandPose = new HandPose(reader);
|
||||||
m_RightHandPose = new HandPose(reader);
|
m_RightHandPose = new HandPose(reader);
|
||||||
@@ -488,11 +482,14 @@ namespace AssetStudio
|
|||||||
if (version >= (5, 2))//5.2 and up
|
if (version >= (5, 2))//5.2 and up
|
||||||
{
|
{
|
||||||
int numTDof = reader.ReadInt32();
|
int numTDof = reader.ReadInt32();
|
||||||
m_TDoFArray = new Vector3[numTDof];
|
var tDoFList = new List<Vector3>();
|
||||||
for (int i = 0; i < numTDof; i++)
|
for (var i = 0; i < numTDof; i++)
|
||||||
{
|
{
|
||||||
m_TDoFArray[i] = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
|
tDoFList.Add(version >= (5, 4) //5.4 and up
|
||||||
|
? reader.ReadVector3()
|
||||||
|
: (Vector3) reader.ReadVector4());
|
||||||
}
|
}
|
||||||
|
m_TDoFArray = tDoFList.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -506,9 +503,19 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public StreamedClip(ObjectReader reader)
|
public StreamedClip(ObjectReader reader)
|
||||||
{
|
{
|
||||||
|
var version = reader.version;
|
||||||
data = reader.ReadUInt32Array();
|
data = reader.ReadUInt32Array();
|
||||||
|
if (version.IsInRange((2022, 3, 19), 2023) //2022.3.19f1 to 2023
|
||||||
|
|| version >= (2023, 2, 8)) //2023.2.8f1 and up
|
||||||
|
{
|
||||||
|
curveCount = reader.ReadUInt16();
|
||||||
|
var discreteCurveCount = reader.ReadUInt16();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
curveCount = reader.ReadUInt32();
|
curveCount = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class StreamedCurveKey
|
public class StreamedCurveKey
|
||||||
{
|
{
|
||||||
@@ -550,7 +557,7 @@ namespace AssetStudio
|
|||||||
public class StreamedFrame
|
public class StreamedFrame
|
||||||
{
|
{
|
||||||
public float time;
|
public float time;
|
||||||
public StreamedCurveKey[] keyList;
|
public List<StreamedCurveKey> keyList;
|
||||||
|
|
||||||
public StreamedFrame() { }
|
public StreamedFrame() { }
|
||||||
|
|
||||||
@@ -559,10 +566,10 @@ namespace AssetStudio
|
|||||||
time = reader.ReadSingle();
|
time = reader.ReadSingle();
|
||||||
|
|
||||||
int numKeys = reader.ReadInt32();
|
int numKeys = reader.ReadInt32();
|
||||||
keyList = new StreamedCurveKey[numKeys];
|
keyList = new List<StreamedCurveKey>();
|
||||||
for (int i = 0; i < numKeys; i++)
|
for (var i = 0; i < numKeys; i++)
|
||||||
{
|
{
|
||||||
keyList[i] = new StreamedCurveKey(reader);
|
keyList.Add(new StreamedCurveKey(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -580,12 +587,12 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int frameIndex = 2; frameIndex < frameList.Count - 1; frameIndex++)
|
for (var frameIndex = 2; frameIndex < frameList.Count - 1; frameIndex++)
|
||||||
{
|
{
|
||||||
var frame = frameList[frameIndex];
|
var frame = frameList[frameIndex];
|
||||||
foreach (var curveKey in frame.keyList)
|
foreach (var curveKey in frame.keyList)
|
||||||
{
|
{
|
||||||
for (int i = frameIndex - 1; i >= 0; i--)
|
for (var i = frameIndex - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var preFrame = frameList[i];
|
var preFrame = frameList[i];
|
||||||
var preCurveKey = preFrame.keyList.FirstOrDefault(x => x.index == curveKey.index);
|
var preCurveKey = preFrame.keyList.FirstOrDefault(x => x.index == curveKey.index);
|
||||||
@@ -644,9 +651,8 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public ValueConstant(ObjectReader reader)
|
public ValueConstant(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
|
||||||
m_ID = reader.ReadUInt32();
|
m_ID = reader.ReadUInt32();
|
||||||
if (version < (5, 5)) //5.5 down
|
if (reader.version < (5, 5)) //5.5 down
|
||||||
{
|
{
|
||||||
m_TypeID = reader.ReadUInt32();
|
m_TypeID = reader.ReadUInt32();
|
||||||
}
|
}
|
||||||
@@ -664,10 +670,50 @@ namespace AssetStudio
|
|||||||
public ValueArrayConstant(ObjectReader reader)
|
public ValueArrayConstant(ObjectReader reader)
|
||||||
{
|
{
|
||||||
int numVals = reader.ReadInt32();
|
int numVals = reader.ReadInt32();
|
||||||
m_ValueArray = new ValueConstant[numVals];
|
var valueList = new List<ValueConstant>();
|
||||||
for (int i = 0; i < numVals; i++)
|
for (var i = 0; i < numVals; i++)
|
||||||
{
|
{
|
||||||
m_ValueArray[i] = new ValueConstant(reader);
|
valueList.Add(new ValueConstant(reader));
|
||||||
|
}
|
||||||
|
m_ValueArray = valueList.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ACLClip //Tuanjie
|
||||||
|
{
|
||||||
|
public uint m_FrameCount;
|
||||||
|
public uint m_BoneCount;
|
||||||
|
public float m_SampleRate;
|
||||||
|
public uint m_CurveCount;
|
||||||
|
public byte[] m_Tracks;
|
||||||
|
public uint[] m_ACLDecoderMap;
|
||||||
|
public bool m_UseACLFastSampleMode;
|
||||||
|
|
||||||
|
public ACLClip() { }
|
||||||
|
|
||||||
|
public ACLClip(ObjectReader reader)
|
||||||
|
{
|
||||||
|
var version = reader.version;
|
||||||
|
m_FrameCount = reader.ReadUInt32();
|
||||||
|
m_BoneCount = reader.ReadUInt32();
|
||||||
|
m_SampleRate = reader.ReadSingle();
|
||||||
|
if (version >= (2022, 3, 55)) //2022.3.55t1(1.5.0) and up
|
||||||
|
{
|
||||||
|
m_CurveCount = reader.ReadUInt32();
|
||||||
|
}
|
||||||
|
m_Tracks = reader.ReadUInt8Array();
|
||||||
|
if (version >= (2022, 3, 61)) //2022.3.61t1(1.6.0) and up
|
||||||
|
{
|
||||||
|
reader.AlignStream();
|
||||||
|
}
|
||||||
|
m_ACLDecoderMap = reader.ReadUInt32Array();
|
||||||
|
if (version > (2022, 3, 55) || (version == (2022, 3, 55) && version.Build >= 4)) //2022.3.55t4(1.5.3) and up
|
||||||
|
{
|
||||||
|
m_UseACLFastSampleMode = reader.ReadBoolean();
|
||||||
|
if (version >= (2022, 3, 61)) //2022.3.61t1(1.6.0) and up
|
||||||
|
{
|
||||||
|
reader.AlignStream();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -690,6 +736,7 @@ namespace AssetStudio
|
|||||||
public DenseClip m_DenseClip;
|
public DenseClip m_DenseClip;
|
||||||
public ConstantClip m_ConstantClip;
|
public ConstantClip m_ConstantClip;
|
||||||
public ValueArrayConstant m_Binding;
|
public ValueArrayConstant m_Binding;
|
||||||
|
public ACLClip m_ACLClip;
|
||||||
|
|
||||||
public Clip() { }
|
public Clip() { }
|
||||||
|
|
||||||
@@ -706,6 +753,10 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
m_Binding = new ValueArrayConstant(reader);
|
m_Binding = new ValueArrayConstant(reader);
|
||||||
}
|
}
|
||||||
|
if (version.IsTuanjie && (version > (2022, 3, 48) || (version == (2022, 3, 48) && version.Build >= 3))) //2022.3.48t3(1.4.0) and up
|
||||||
|
{
|
||||||
|
m_ACLClip = new ACLClip(reader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnimationClipBindingConstant ConvertValueArrayToGenericBinding()
|
public AnimationClipBindingConstant ConvertValueArrayToGenericBinding()
|
||||||
@@ -713,7 +764,7 @@ namespace AssetStudio
|
|||||||
var bindings = new AnimationClipBindingConstant();
|
var bindings = new AnimationClipBindingConstant();
|
||||||
var genericBindings = new List<GenericBinding>();
|
var genericBindings = new List<GenericBinding>();
|
||||||
var values = m_Binding;
|
var values = m_Binding;
|
||||||
for (int i = 0; i < values.m_ValueArray.Length;)
|
for (var i = 0; i < values.m_ValueArray.Length;)
|
||||||
{
|
{
|
||||||
var curveID = values.m_ValueArray[i].m_ID;
|
var curveID = values.m_ValueArray[i].m_ID;
|
||||||
var curveTypeID = values.m_ValueArray[i].m_TypeID;
|
var curveTypeID = values.m_ValueArray[i].m_TypeID;
|
||||||
@@ -748,7 +799,7 @@ namespace AssetStudio
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bindings.genericBindings = genericBindings.ToArray();
|
bindings.genericBindings = genericBindings;
|
||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -829,11 +880,13 @@ namespace AssetStudio
|
|||||||
m_IndexArray = reader.ReadInt32Array();
|
m_IndexArray = reader.ReadInt32Array();
|
||||||
if (version < (4, 3)) //4.3 down
|
if (version < (4, 3)) //4.3 down
|
||||||
{
|
{
|
||||||
var m_AdditionalCurveIndexArray = reader.ReadInt32Array();
|
var m_AdditionalCurveIndexArrayNum = reader.ReadInt32();
|
||||||
|
reader.Position += m_AdditionalCurveIndexArrayNum * 4; //skip int[] m_AdditionalCurveIndexArray
|
||||||
}
|
}
|
||||||
int numDeltas = reader.ReadInt32();
|
int numDeltas = reader.ReadInt32();
|
||||||
|
reader.ThrowIfTooLarge(numDeltas * 8f);
|
||||||
m_ValueArrayDelta = new ValueDelta[numDeltas];
|
m_ValueArrayDelta = new ValueDelta[numDeltas];
|
||||||
for (int i = 0; i < numDeltas; i++)
|
for (var i = 0; i < numDeltas; i++)
|
||||||
{
|
{
|
||||||
m_ValueArrayDelta[i] = new ValueDelta(reader);
|
m_ValueArrayDelta[i] = new ValueDelta(reader);
|
||||||
}
|
}
|
||||||
@@ -872,6 +925,7 @@ namespace AssetStudio
|
|||||||
public byte customType;
|
public byte customType;
|
||||||
public byte isPPtrCurve;
|
public byte isPPtrCurve;
|
||||||
public byte isIntCurve;
|
public byte isIntCurve;
|
||||||
|
public byte isSerializeReferenceCurve;
|
||||||
|
|
||||||
public GenericBinding() { }
|
public GenericBinding() { }
|
||||||
|
|
||||||
@@ -895,31 +949,35 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
isIntCurve = reader.ReadByte();
|
isIntCurve = reader.ReadByte();
|
||||||
}
|
}
|
||||||
|
if (version >= (2022, 2)) //2022.2 and up
|
||||||
|
{
|
||||||
|
isSerializeReferenceCurve = reader.ReadByte();
|
||||||
|
}
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AnimationClipBindingConstant
|
public class AnimationClipBindingConstant
|
||||||
{
|
{
|
||||||
public GenericBinding[] genericBindings;
|
public List<GenericBinding> genericBindings;
|
||||||
public PPtr<Object>[] pptrCurveMapping;
|
public List<PPtr<Object>> pptrCurveMapping;
|
||||||
|
|
||||||
public AnimationClipBindingConstant() { }
|
public AnimationClipBindingConstant() { }
|
||||||
|
|
||||||
public AnimationClipBindingConstant(ObjectReader reader)
|
public AnimationClipBindingConstant(ObjectReader reader)
|
||||||
{
|
{
|
||||||
int numBindings = reader.ReadInt32();
|
int numBindings = reader.ReadInt32();
|
||||||
genericBindings = new GenericBinding[numBindings];
|
genericBindings = new List<GenericBinding>();
|
||||||
for (int i = 0; i < numBindings; i++)
|
for (var i = 0; i < numBindings; i++)
|
||||||
{
|
{
|
||||||
genericBindings[i] = new GenericBinding(reader);
|
genericBindings.Add(new GenericBinding(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numMappings = reader.ReadInt32();
|
int numMappings = reader.ReadInt32();
|
||||||
pptrCurveMapping = new PPtr<Object>[numMappings];
|
pptrCurveMapping = new List<PPtr<Object>>();
|
||||||
for (int i = 0; i < numMappings; i++)
|
for (var i = 0; i < numMappings; i++)
|
||||||
{
|
{
|
||||||
pptrCurveMapping[i] = new PPtr<Object>(reader);
|
pptrCurveMapping.Add(new PPtr<Object>(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -974,16 +1032,18 @@ namespace AssetStudio
|
|||||||
public AnimationEvent(ObjectReader reader)
|
public AnimationEvent(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
time = reader.ReadSingle();
|
time = reader.ReadSingle();
|
||||||
functionName = reader.ReadAlignedString();
|
functionName = reader.ReadAlignedString();
|
||||||
data = reader.ReadAlignedString();
|
data = reader.ReadAlignedString();
|
||||||
|
if (version >= (2, 6)) //2.6 and up
|
||||||
|
{
|
||||||
objectReferenceParameter = new PPtr<Object>(reader);
|
objectReferenceParameter = new PPtr<Object>(reader);
|
||||||
floatParameter = reader.ReadSingle();
|
floatParameter = reader.ReadSingle();
|
||||||
if (version >= 3) //3 and up
|
if (version >= 3) //3 and up
|
||||||
{
|
{
|
||||||
intParameter = reader.ReadInt32();
|
intParameter = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
messageOptions = reader.ReadInt32();
|
messageOptions = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1001,28 +1061,41 @@ namespace AssetStudio
|
|||||||
public bool m_Legacy;
|
public bool m_Legacy;
|
||||||
public bool m_Compressed;
|
public bool m_Compressed;
|
||||||
public bool m_UseHighQualityCurve;
|
public bool m_UseHighQualityCurve;
|
||||||
public QuaternionCurve[] m_RotationCurves;
|
public List<QuaternionCurve> m_RotationCurves;
|
||||||
public CompressedAnimationCurve[] m_CompressedRotationCurves;
|
public List<CompressedAnimationCurve> m_CompressedRotationCurves;
|
||||||
public Vector3Curve[] m_EulerCurves;
|
public List<Vector3Curve> m_EulerCurves;
|
||||||
public Vector3Curve[] m_PositionCurves;
|
public List<Vector3Curve> m_PositionCurves;
|
||||||
public Vector3Curve[] m_ScaleCurves;
|
public List<Vector3Curve> m_ScaleCurves;
|
||||||
public FloatCurve[] m_FloatCurves;
|
public List<FloatCurve> m_FloatCurves;
|
||||||
public PPtrCurve[] m_PPtrCurves;
|
public List<PPtrCurve> m_PPtrCurves;
|
||||||
public float m_SampleRate;
|
public float m_SampleRate;
|
||||||
public int m_WrapMode;
|
public int m_WrapMode;
|
||||||
public AABB m_Bounds;
|
public AABB m_Bounds;
|
||||||
public uint m_MuscleClipSize;
|
public uint m_MuscleClipSize;
|
||||||
public ClipMuscleConstant m_MuscleClip;
|
public ClipMuscleConstant m_MuscleClip;
|
||||||
public AnimationClipBindingConstant m_ClipBindingConstant;
|
public AnimationClipBindingConstant m_ClipBindingConstant;
|
||||||
public AnimationEvent[] m_Events;
|
public List<AnimationEvent> m_Events;
|
||||||
|
public byte[] m_AnimData;
|
||||||
|
public StreamingInfo m_StreamingInfo;
|
||||||
|
|
||||||
public AnimationClip() { }
|
public AnimationClip() { }
|
||||||
|
|
||||||
public AnimationClip(ObjectReader reader, IDictionary typeDict) : base(reader)
|
public AnimationClip(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions, ObjectInfo objInfo) : base(reader)
|
||||||
{
|
{
|
||||||
var parsedAnimClip = JsonConvert.DeserializeObject<AnimationClip>(JsonConvert.SerializeObject(typeDict));
|
var parsedAnimClip = JsonSerializer.Deserialize<AnimationClip>(type, jsonOptions);
|
||||||
m_AnimationType = parsedAnimClip.m_AnimationType;
|
m_AnimationType = parsedAnimClip.m_AnimationType;
|
||||||
|
if (version >= 5)//5.0 and up
|
||||||
|
{
|
||||||
m_Legacy = parsedAnimClip.m_Legacy;
|
m_Legacy = parsedAnimClip.m_Legacy;
|
||||||
|
}
|
||||||
|
else if (version >= 4)//4.0 and up
|
||||||
|
{
|
||||||
|
m_Legacy = m_AnimationType == AnimationType.Legacy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Legacy = true;
|
||||||
|
}
|
||||||
m_Compressed = parsedAnimClip.m_Compressed;
|
m_Compressed = parsedAnimClip.m_Compressed;
|
||||||
m_UseHighQualityCurve = parsedAnimClip.m_UseHighQualityCurve;
|
m_UseHighQualityCurve = parsedAnimClip.m_UseHighQualityCurve;
|
||||||
m_RotationCurves = parsedAnimClip.m_RotationCurves;
|
m_RotationCurves = parsedAnimClip.m_RotationCurves;
|
||||||
@@ -1039,8 +1112,31 @@ namespace AssetStudio
|
|||||||
m_MuscleClip = parsedAnimClip.m_MuscleClip;
|
m_MuscleClip = parsedAnimClip.m_MuscleClip;
|
||||||
m_ClipBindingConstant = parsedAnimClip.m_ClipBindingConstant;
|
m_ClipBindingConstant = parsedAnimClip.m_ClipBindingConstant;
|
||||||
m_Events = parsedAnimClip.m_Events;
|
m_Events = parsedAnimClip.m_Events;
|
||||||
|
if (!reader.version.IsTuanjie)
|
||||||
typeDict.Clear();
|
return;
|
||||||
|
m_AnimData = parsedAnimClip.m_AnimData;
|
||||||
|
m_StreamingInfo = parsedAnimClip.m_StreamingInfo;
|
||||||
|
if (!(m_AnimData?.Length > 0))
|
||||||
|
return;
|
||||||
|
m_MuscleClipSize = (uint)m_AnimData.Length;
|
||||||
|
using (var muscleStream = new MemoryStream(m_AnimData))
|
||||||
|
{
|
||||||
|
using (var muscleReader = new EndianBinaryReader(muscleStream, EndianType.LittleEndian))
|
||||||
|
{
|
||||||
|
var objReader = new ObjectReader(muscleReader, assetsFile, objInfo);
|
||||||
|
if (!m_Legacy)
|
||||||
|
{
|
||||||
|
_ = objReader.ReadUInt32();
|
||||||
|
m_MuscleClip = new ClipMuscleConstant(objReader);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_EulerCurves = Vector3CurveList(objReader);
|
||||||
|
m_PositionCurves = Vector3CurveList(objReader);
|
||||||
|
m_ScaleCurves = Vector3CurveList(objReader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AnimationClip(ObjectReader reader) : base(reader)
|
public AnimationClip(ObjectReader reader) : base(reader)
|
||||||
@@ -1052,84 +1148,107 @@ namespace AssetStudio
|
|||||||
else if (version >= 4)//4.0 and up
|
else if (version >= 4)//4.0 and up
|
||||||
{
|
{
|
||||||
m_AnimationType = (AnimationType)reader.ReadInt32();
|
m_AnimationType = (AnimationType)reader.ReadInt32();
|
||||||
if (m_AnimationType == AnimationType.Legacy)
|
m_Legacy = m_AnimationType == AnimationType.Legacy;
|
||||||
m_Legacy = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_Legacy = true;
|
m_Legacy = true;
|
||||||
}
|
}
|
||||||
|
if (version >= (2, 6)) //2.6 and up
|
||||||
|
{
|
||||||
m_Compressed = reader.ReadBoolean();
|
m_Compressed = reader.ReadBoolean();
|
||||||
|
}
|
||||||
if (version >= (4, 3))//4.3 and up
|
if (version >= (4, 3))//4.3 and up
|
||||||
{
|
{
|
||||||
m_UseHighQualityCurve = reader.ReadBoolean();
|
m_UseHighQualityCurve = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
int numRCurves = reader.ReadInt32();
|
int numRCurves = reader.ReadInt32();
|
||||||
m_RotationCurves = new QuaternionCurve[numRCurves];
|
m_RotationCurves = new List<QuaternionCurve>();
|
||||||
for (int i = 0; i < numRCurves; i++)
|
for (var i = 0; i < numRCurves; i++)
|
||||||
{
|
{
|
||||||
m_RotationCurves[i] = new QuaternionCurve(reader);
|
m_RotationCurves.Add(new QuaternionCurve(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version >= (2, 6)) //2.6 and up
|
||||||
|
{
|
||||||
int numCRCurves = reader.ReadInt32();
|
int numCRCurves = reader.ReadInt32();
|
||||||
m_CompressedRotationCurves = new CompressedAnimationCurve[numCRCurves];
|
m_CompressedRotationCurves = new List<CompressedAnimationCurve>();
|
||||||
for (int i = 0; i < numCRCurves; i++)
|
for (var i = 0; i < numCRCurves; i++)
|
||||||
{
|
{
|
||||||
m_CompressedRotationCurves[i] = new CompressedAnimationCurve(reader);
|
m_CompressedRotationCurves.Add(new CompressedAnimationCurve(reader));
|
||||||
}
|
|
||||||
|
|
||||||
if (version >= (5, 3))//5.3 and up
|
|
||||||
{
|
|
||||||
int numEulerCurves = reader.ReadInt32();
|
|
||||||
m_EulerCurves = new Vector3Curve[numEulerCurves];
|
|
||||||
for (int i = 0; i < numEulerCurves; i++)
|
|
||||||
{
|
|
||||||
m_EulerCurves[i] = new Vector3Curve(reader);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int numPCurves = reader.ReadInt32();
|
if (!version.IsTuanjie)
|
||||||
m_PositionCurves = new Vector3Curve[numPCurves];
|
|
||||||
for (int i = 0; i < numPCurves; i++)
|
|
||||||
{
|
{
|
||||||
m_PositionCurves[i] = new Vector3Curve(reader);
|
if (version >= (5, 3)) //5.3 and up
|
||||||
|
{
|
||||||
|
m_EulerCurves = Vector3CurveList(reader);
|
||||||
}
|
}
|
||||||
|
m_PositionCurves = Vector3CurveList(reader);
|
||||||
int numSCurves = reader.ReadInt32();
|
m_ScaleCurves = Vector3CurveList(reader);
|
||||||
m_ScaleCurves = new Vector3Curve[numSCurves];
|
|
||||||
for (int i = 0; i < numSCurves; i++)
|
|
||||||
{
|
|
||||||
m_ScaleCurves[i] = new Vector3Curve(reader);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int numFCurves = reader.ReadInt32();
|
int numFCurves = reader.ReadInt32();
|
||||||
m_FloatCurves = new FloatCurve[numFCurves];
|
m_FloatCurves = new List<FloatCurve>();
|
||||||
for (int i = 0; i < numFCurves; i++)
|
for (var i = 0; i < numFCurves; i++)
|
||||||
{
|
{
|
||||||
m_FloatCurves[i] = new FloatCurve(reader);
|
m_FloatCurves.Add(new FloatCurve(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version >= (4, 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
int numPtrCurves = reader.ReadInt32();
|
int numPtrCurves = reader.ReadInt32();
|
||||||
m_PPtrCurves = new PPtrCurve[numPtrCurves];
|
m_PPtrCurves = new List<PPtrCurve>();
|
||||||
for (int i = 0; i < numPtrCurves; i++)
|
for (var i = 0; i < numPtrCurves; i++)
|
||||||
{
|
{
|
||||||
m_PPtrCurves[i] = new PPtrCurve(reader);
|
m_PPtrCurves.Add(new PPtrCurve(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_SampleRate = reader.ReadSingle();
|
m_SampleRate = reader.ReadSingle();
|
||||||
|
if (version >= (2, 6)) //2.6 and up
|
||||||
|
{
|
||||||
m_WrapMode = reader.ReadInt32();
|
m_WrapMode = reader.ReadInt32();
|
||||||
|
}
|
||||||
if (version >= (3, 4)) //3.4 and up
|
if (version >= (3, 4)) //3.4 and up
|
||||||
{
|
{
|
||||||
m_Bounds = new AABB(reader);
|
m_Bounds = new AABB(reader);
|
||||||
}
|
}
|
||||||
if (version >= 4)//4.0 and up
|
if (version >= 4)//4.0 and up
|
||||||
{
|
{
|
||||||
m_MuscleClipSize = reader.ReadUInt32();
|
if (version.IsTuanjie && version >= (2022, 3, 61)) //2022.3.61t1(1.6.0) and up
|
||||||
|
{
|
||||||
|
m_EulerCurves = Vector3CurveList(reader);
|
||||||
|
m_PositionCurves = Vector3CurveList(reader);
|
||||||
|
m_ScaleCurves = Vector3CurveList(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_MuscleClipSize = reader.ReadUInt32(); //m_AnimDataSize (Tuanjie 1.0-1.5)
|
||||||
|
if (!version.IsTuanjie || version >= (2022, 3, 61))
|
||||||
|
{
|
||||||
m_MuscleClip = new ClipMuscleConstant(reader);
|
m_MuscleClip = new ClipMuscleConstant(reader);
|
||||||
|
if (version.IsTuanjie) //2022.3.61t1(1.6.0) and up
|
||||||
|
{
|
||||||
|
m_StreamingInfo = new StreamingInfo(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_MuscleClipSize > 0)
|
||||||
|
{
|
||||||
|
if (!m_Legacy)
|
||||||
|
{
|
||||||
|
_ = reader.ReadInt32();
|
||||||
|
m_MuscleClip = new ClipMuscleConstant(reader); //m_AnimData (Tuanjie 1.0-1.5)
|
||||||
|
m_StreamingInfo = new StreamingInfo(reader);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_EulerCurves = Vector3CurveList(reader);
|
||||||
|
m_PositionCurves = Vector3CurveList(reader);
|
||||||
|
m_ScaleCurves = Vector3CurveList(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version >= (4, 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
@@ -1142,15 +1261,42 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
int numEvents = reader.ReadInt32();
|
int numEvents = reader.ReadInt32();
|
||||||
m_Events = new AnimationEvent[numEvents];
|
m_Events = new List<AnimationEvent>();
|
||||||
for (int i = 0; i < numEvents; i++)
|
for (var i = 0; i < numEvents; i++)
|
||||||
{
|
{
|
||||||
m_Events[i] = new AnimationEvent(reader);
|
m_Events.Add(new AnimationEvent(reader));
|
||||||
}
|
}
|
||||||
if (version >= 2017) //2017 and up
|
if (version >= 2017) //2017 and up
|
||||||
{
|
{
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<Vector3Curve> Vector3CurveList(ObjectReader reader)
|
||||||
|
{
|
||||||
|
var curveNum = reader.ReadInt32();
|
||||||
|
var vector3Curve = new List<Vector3Curve>();
|
||||||
|
for (var i = 0; i < curveNum; i++)
|
||||||
|
{
|
||||||
|
vector3Curve.Add(new Vector3Curve(reader));
|
||||||
|
}
|
||||||
|
return vector3Curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EqComparer : IEqualityComparer<AnimationClip>
|
||||||
|
{
|
||||||
|
public bool Equals(AnimationClip clipA, AnimationClip clipB)
|
||||||
|
{
|
||||||
|
return clipA?.m_PathID == clipB?.m_PathID
|
||||||
|
&& clipA?.byteSize == clipB?.byteSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetHashCode(AnimationClip obj)
|
||||||
|
{
|
||||||
|
var result = obj.m_PathID * 31;
|
||||||
|
result = result * 31 + obj.byteSize;
|
||||||
|
return result.GetHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class Animator : Behaviour
|
public sealed class Animator : Behaviour
|
||||||
{
|
{
|
||||||
@@ -22,6 +17,12 @@ namespace AssetStudio
|
|||||||
var m_UpdateMode = reader.ReadInt32();
|
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();
|
var m_ApplyRootMotion = reader.ReadBoolean();
|
||||||
if (version == 4 && version.Minor >= 5) //4.5 and up - 5.0 down
|
if (version == 4 && version.Minor >= 5) //4.5 and up - 5.0 down
|
||||||
{
|
{
|
||||||
@@ -35,6 +36,10 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var m_StabilizeFeet = reader.ReadBoolean();
|
var m_StabilizeFeet = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
if (version >= (2023, 1)) //2023.1 and up
|
||||||
|
{
|
||||||
|
var m_AnimatePhysics = reader.ReadBoolean();
|
||||||
|
}
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -38,15 +35,15 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class SkeletonMask
|
public class SkeletonMask
|
||||||
{
|
{
|
||||||
public SkeletonMaskElement[] m_Data;
|
public List<SkeletonMaskElement> m_Data;
|
||||||
|
|
||||||
public SkeletonMask(ObjectReader reader)
|
public SkeletonMask(ObjectReader reader)
|
||||||
{
|
{
|
||||||
int numElements = reader.ReadInt32();
|
int numElements = reader.ReadInt32();
|
||||||
m_Data = new SkeletonMaskElement[numElements];
|
m_Data = new List<SkeletonMaskElement>();
|
||||||
for (int i = 0; i < numElements; i++)
|
for (var i = 0; i < numElements; i++)
|
||||||
{
|
{
|
||||||
m_Data[i] = new SkeletonMaskElement(reader);
|
m_Data.Add(new SkeletonMaskElement(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,11 +121,12 @@ namespace AssetStudio
|
|||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
int numConditions = reader.ReadInt32();
|
int numConditions = reader.ReadInt32();
|
||||||
m_ConditionConstantArray = new ConditionConstant[numConditions];
|
var conditionConstantList = new List<ConditionConstant>();
|
||||||
for (int i = 0; i < numConditions; i++)
|
for (var i = 0; i < numConditions; i++)
|
||||||
{
|
{
|
||||||
m_ConditionConstantArray[i] = new ConditionConstant(reader);
|
conditionConstantList.Add(new ConditionConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_ConditionConstantArray = conditionConstantList.ToArray();
|
||||||
|
|
||||||
m_DestinationState = reader.ReadUInt32();
|
m_DestinationState = reader.ReadUInt32();
|
||||||
if (version >= 5) //5.0 and up
|
if (version >= 5) //5.0 and up
|
||||||
@@ -201,11 +199,12 @@ namespace AssetStudio
|
|||||||
m_ChildPairAvgMagInvArray = reader.ReadSingleArray();
|
m_ChildPairAvgMagInvArray = reader.ReadSingleArray();
|
||||||
|
|
||||||
int numNeighbours = reader.ReadInt32();
|
int numNeighbours = reader.ReadInt32();
|
||||||
m_ChildNeighborListArray = new MotionNeighborList[numNeighbours];
|
var childNeighborLists = new List<MotionNeighborList>();
|
||||||
for (int i = 0; i < numNeighbours; i++)
|
for (var i = 0; i < numNeighbours; i++)
|
||||||
{
|
{
|
||||||
m_ChildNeighborListArray[i] = new MotionNeighborList(reader);
|
childNeighborLists.Add(new MotionNeighborList(reader));
|
||||||
}
|
}
|
||||||
|
m_ChildNeighborListArray = childNeighborLists.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,11 +304,12 @@ namespace AssetStudio
|
|||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
int numNodes = reader.ReadInt32();
|
int numNodes = reader.ReadInt32();
|
||||||
m_NodeArray = new BlendTreeNodeConstant[numNodes];
|
var nodeList = new List<BlendTreeNodeConstant>();
|
||||||
for (int i = 0; i < numNodes; i++)
|
for (var i = 0; i < numNodes; i++)
|
||||||
{
|
{
|
||||||
m_NodeArray[i] = new BlendTreeNodeConstant(reader);
|
nodeList.Add(new BlendTreeNodeConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_NodeArray = nodeList.ToArray();
|
||||||
|
|
||||||
if (version < (4, 5)) //4.5 down
|
if (version < (4, 5)) //4.5 down
|
||||||
{
|
{
|
||||||
@@ -343,31 +343,34 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
int numTransistions = reader.ReadInt32();
|
int numTransitions = reader.ReadInt32();
|
||||||
m_TransitionConstantArray = new TransitionConstant[numTransistions];
|
var transitionConstantList = new List<TransitionConstant>();
|
||||||
for (int i = 0; i < numTransistions; i++)
|
for (var i = 0; i < numTransitions; i++)
|
||||||
{
|
{
|
||||||
m_TransitionConstantArray[i] = new TransitionConstant(reader);
|
transitionConstantList.Add(new TransitionConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_TransitionConstantArray = transitionConstantList.ToArray();
|
||||||
|
|
||||||
m_BlendTreeConstantIndexArray = reader.ReadInt32Array();
|
m_BlendTreeConstantIndexArray = reader.ReadInt32Array();
|
||||||
|
|
||||||
if (version < (5, 2)) //5.2 down
|
if (version < (5, 2)) //5.2 down
|
||||||
{
|
{
|
||||||
int numInfos = reader.ReadInt32();
|
int numInfos = reader.ReadInt32();
|
||||||
m_LeafInfoArray = new LeafInfoConstant[numInfos];
|
var leafInfoList = new List<LeafInfoConstant>();
|
||||||
for (int i = 0; i < numInfos; i++)
|
for (var i = 0; i < numInfos; i++)
|
||||||
{
|
{
|
||||||
m_LeafInfoArray[i] = new LeafInfoConstant(reader);
|
leafInfoList.Add(new LeafInfoConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_LeafInfoArray = leafInfoList.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
int numBlends = reader.ReadInt32();
|
int numBlends = reader.ReadInt32();
|
||||||
m_BlendTreeConstantArray = new BlendTreeConstant[numBlends];
|
var blendTreeConstantList = new List<BlendTreeConstant>();
|
||||||
for (int i = 0; i < numBlends; i++)
|
for (var i = 0; i < numBlends; i++)
|
||||||
{
|
{
|
||||||
m_BlendTreeConstantArray[i] = new BlendTreeConstant(reader);
|
blendTreeConstantList.Add(new BlendTreeConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_BlendTreeConstantArray = blendTreeConstantList.ToArray();
|
||||||
|
|
||||||
m_NameID = reader.ReadUInt32();
|
m_NameID = reader.ReadUInt32();
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version >= (4, 3)) //4.3 and up
|
||||||
@@ -423,11 +426,12 @@ namespace AssetStudio
|
|||||||
m_Destination = reader.ReadUInt32();
|
m_Destination = reader.ReadUInt32();
|
||||||
|
|
||||||
int numConditions = reader.ReadInt32();
|
int numConditions = reader.ReadInt32();
|
||||||
m_ConditionConstantArray = new ConditionConstant[numConditions];
|
var conditionConstantList = new List<ConditionConstant>();
|
||||||
for (int i = 0; i < numConditions; i++)
|
for (var i = 0; i < numConditions; i++)
|
||||||
{
|
{
|
||||||
m_ConditionConstantArray[i] = new ConditionConstant(reader);
|
conditionConstantList.Add(new ConditionConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_ConditionConstantArray = conditionConstantList.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,11 +444,12 @@ namespace AssetStudio
|
|||||||
public SelectorStateConstant(ObjectReader reader)
|
public SelectorStateConstant(ObjectReader reader)
|
||||||
{
|
{
|
||||||
int numTransitions = reader.ReadInt32();
|
int numTransitions = reader.ReadInt32();
|
||||||
m_TransitionConstantArray = new SelectorTransitionConstant[numTransitions];
|
var transitionConstantList = new List<SelectorTransitionConstant>();
|
||||||
for (int i = 0; i < numTransitions; i++)
|
for (var i = 0; i < numTransitions; i++)
|
||||||
{
|
{
|
||||||
m_TransitionConstantArray[i] = new SelectorTransitionConstant(reader);
|
transitionConstantList.Add(new SelectorTransitionConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_TransitionConstantArray = transitionConstantList.ToArray();
|
||||||
|
|
||||||
m_FullPathID = reader.ReadUInt32();
|
m_FullPathID = reader.ReadUInt32();
|
||||||
m_isEntry = reader.ReadBoolean();
|
m_isEntry = reader.ReadBoolean();
|
||||||
@@ -465,27 +470,30 @@ namespace AssetStudio
|
|||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
int numStates = reader.ReadInt32();
|
int numStates = reader.ReadInt32();
|
||||||
m_StateConstantArray = new StateConstant[numStates];
|
var stateConstantList = new List<StateConstant>();
|
||||||
for (int i = 0; i < numStates; i++)
|
for (var i = 0; i < numStates; i++)
|
||||||
{
|
{
|
||||||
m_StateConstantArray[i] = new StateConstant(reader);
|
stateConstantList.Add(new StateConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_StateConstantArray = stateConstantList.ToArray();
|
||||||
|
|
||||||
int numAnyStates = reader.ReadInt32();
|
int numAnyStates = reader.ReadInt32();
|
||||||
m_AnyStateTransitionConstantArray = new TransitionConstant[numAnyStates];
|
var anyStateTransitionConstantList = new List<TransitionConstant>();
|
||||||
for (int i = 0; i < numAnyStates; i++)
|
for (var i = 0; i < numAnyStates; i++)
|
||||||
{
|
{
|
||||||
m_AnyStateTransitionConstantArray[i] = new TransitionConstant(reader);
|
anyStateTransitionConstantList.Add(new TransitionConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_AnyStateTransitionConstantArray = anyStateTransitionConstantList.ToArray();
|
||||||
|
|
||||||
if (version >= 5) //5.0 and up
|
if (version >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
int numSelectors = reader.ReadInt32();
|
int numSelectors = reader.ReadInt32();
|
||||||
m_SelectorStateConstantArray = new SelectorStateConstant[numSelectors];
|
var selectorStateConstantList = new List<SelectorStateConstant>();
|
||||||
for (int i = 0; i < numSelectors; i++)
|
for (var i = 0; i < numSelectors; i++)
|
||||||
{
|
{
|
||||||
m_SelectorStateConstantArray[i] = new SelectorStateConstant(reader);
|
selectorStateConstantList.Add(new SelectorStateConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_SelectorStateConstantArray = selectorStateConstantList.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_DefaultState = reader.ReadUInt32();
|
m_DefaultState = reader.ReadUInt32();
|
||||||
@@ -502,6 +510,7 @@ namespace AssetStudio
|
|||||||
public Vector3[] m_PositionValues;
|
public Vector3[] m_PositionValues;
|
||||||
public Vector4[] m_QuaternionValues;
|
public Vector4[] m_QuaternionValues;
|
||||||
public Vector3[] m_ScaleValues;
|
public Vector3[] m_ScaleValues;
|
||||||
|
public int[] m_EntityIdValues;
|
||||||
|
|
||||||
public ValueArray(ObjectReader reader)
|
public ValueArray(ObjectReader reader)
|
||||||
{
|
{
|
||||||
@@ -522,20 +531,26 @@ namespace AssetStudio
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
int numPosValues = reader.ReadInt32();
|
int numPosValues = reader.ReadInt32();
|
||||||
m_PositionValues = new Vector3[numPosValues];
|
var positionValuesList = new List<Vector3>();
|
||||||
for (int i = 0; i < numPosValues; i++)
|
for (var i = 0; i < numPosValues; i++)
|
||||||
{
|
{
|
||||||
m_PositionValues[i] = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
|
positionValuesList.Add(version >= (5, 4) //5.4 and up
|
||||||
|
? reader.ReadVector3()
|
||||||
|
: (Vector3)reader.ReadVector4());
|
||||||
}
|
}
|
||||||
|
m_PositionValues = positionValuesList.ToArray();
|
||||||
|
|
||||||
m_QuaternionValues = reader.ReadVector4Array();
|
m_QuaternionValues = reader.ReadVector4Array();
|
||||||
|
|
||||||
int numScaleValues = reader.ReadInt32();
|
int numScaleValues = reader.ReadInt32();
|
||||||
m_ScaleValues = new Vector3[numScaleValues];
|
var scaleValuesList = new List<Vector3>();
|
||||||
for (int i = 0; i < numScaleValues; i++)
|
for (var i = 0; i < numScaleValues; i++)
|
||||||
{
|
{
|
||||||
m_ScaleValues[i] = version >= (5, 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
|
scaleValuesList.Add(version >= (5, 4) //5.4 and up
|
||||||
|
? reader.ReadVector3()
|
||||||
|
: (Vector3)reader.ReadVector4());
|
||||||
}
|
}
|
||||||
|
m_ScaleValues = scaleValuesList.ToArray();
|
||||||
|
|
||||||
if (version >= (5, 5)) //5.5 and up
|
if (version >= (5, 5)) //5.5 and up
|
||||||
{
|
{
|
||||||
@@ -543,6 +558,10 @@ namespace AssetStudio
|
|||||||
m_IntValues = reader.ReadInt32Array();
|
m_IntValues = reader.ReadInt32Array();
|
||||||
m_BoolValues = reader.ReadBooleanArray();
|
m_BoolValues = reader.ReadBooleanArray();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
if (version >= (6000, 2)) //6000.2 and up
|
||||||
|
{
|
||||||
|
m_EntityIdValues = reader.ReadInt32Array();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,18 +577,20 @@ namespace AssetStudio
|
|||||||
public ControllerConstant(ObjectReader reader)
|
public ControllerConstant(ObjectReader reader)
|
||||||
{
|
{
|
||||||
int numLayers = reader.ReadInt32();
|
int numLayers = reader.ReadInt32();
|
||||||
m_LayerArray = new LayerConstant[numLayers];
|
var layerList = new List<LayerConstant>();
|
||||||
for (int i = 0; i < numLayers; i++)
|
for (var i = 0; i < numLayers; i++)
|
||||||
{
|
{
|
||||||
m_LayerArray[i] = new LayerConstant(reader);
|
layerList.Add(new LayerConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_LayerArray = layerList.ToArray();
|
||||||
|
|
||||||
int numStates = reader.ReadInt32();
|
int numStates = reader.ReadInt32();
|
||||||
m_StateMachineArray = new StateMachineConstant[numStates];
|
var stateMachineList = new List<StateMachineConstant>();
|
||||||
for (int i = 0; i < numStates; i++)
|
for (var i = 0; i < numStates; i++)
|
||||||
{
|
{
|
||||||
m_StateMachineArray[i] = new StateMachineConstant(reader);
|
stateMachineList.Add(new StateMachineConstant(reader));
|
||||||
}
|
}
|
||||||
|
m_StateMachineArray = stateMachineList.ToArray();
|
||||||
|
|
||||||
m_Values = new ValueArrayConstant(reader);
|
m_Values = new ValueArrayConstant(reader);
|
||||||
m_DefaultValues = new ValueArray(reader);
|
m_DefaultValues = new ValueArray(reader);
|
||||||
@@ -578,7 +599,8 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public sealed class AnimatorController : RuntimeAnimatorController
|
public sealed class AnimatorController : RuntimeAnimatorController
|
||||||
{
|
{
|
||||||
public PPtr<AnimationClip>[] m_AnimationClips;
|
public List<PPtr<AnimationClip>> m_AnimationClips;
|
||||||
|
public List<KeyValuePair<uint, string>> m_TOS;
|
||||||
|
|
||||||
public AnimatorController(ObjectReader reader) : base(reader)
|
public AnimatorController(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
@@ -586,17 +608,17 @@ namespace AssetStudio
|
|||||||
var m_Controller = new ControllerConstant(reader);
|
var m_Controller = new ControllerConstant(reader);
|
||||||
|
|
||||||
int tosSize = reader.ReadInt32();
|
int tosSize = reader.ReadInt32();
|
||||||
var m_TOS = new KeyValuePair<uint, string>[tosSize];
|
m_TOS = new List<KeyValuePair<uint, string>>();
|
||||||
for (int i = 0; i < tosSize; i++)
|
for (var i = 0; i < tosSize; i++)
|
||||||
{
|
{
|
||||||
m_TOS[i] = new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString());
|
m_TOS.Add(new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numClips = reader.ReadInt32();
|
int numClips = reader.ReadInt32();
|
||||||
m_AnimationClips = new PPtr<AnimationClip>[numClips];
|
m_AnimationClips = new List<PPtr<AnimationClip>>();
|
||||||
for (int i = 0; i < numClips; i++)
|
for (var i = 0; i < numClips; i++)
|
||||||
{
|
{
|
||||||
m_AnimationClips[i] = new PPtr<AnimationClip>(reader);
|
m_AnimationClips.Add(new PPtr<AnimationClip>(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -20,17 +17,17 @@ namespace AssetStudio
|
|||||||
public sealed class AnimatorOverrideController : RuntimeAnimatorController
|
public sealed class AnimatorOverrideController : RuntimeAnimatorController
|
||||||
{
|
{
|
||||||
public PPtr<RuntimeAnimatorController> m_Controller;
|
public PPtr<RuntimeAnimatorController> m_Controller;
|
||||||
public AnimationClipOverride[] m_Clips;
|
public List<AnimationClipOverride> m_Clips;
|
||||||
|
|
||||||
public AnimatorOverrideController(ObjectReader reader) : base(reader)
|
public AnimatorOverrideController(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
|
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
|
||||||
|
|
||||||
int numOverrides = reader.ReadInt32();
|
int numOverrides = reader.ReadInt32();
|
||||||
m_Clips = new AnimationClipOverride[numOverrides];
|
m_Clips = new List<AnimationClipOverride>();
|
||||||
for (int i = 0; i < numOverrides; i++)
|
for (var i = 0; i < numOverrides; i++)
|
||||||
{
|
{
|
||||||
m_Clips[i] = new AnimationClipOverride(reader);
|
m_Clips.Add(new AnimationClipOverride(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public sealed class AssetBundle : NamedObject
|
public sealed class AssetBundle : NamedObject
|
||||||
{
|
{
|
||||||
public PPtr<Object>[] m_PreloadTable;
|
public List<PPtr<Object>> m_PreloadTable;
|
||||||
public KeyValuePair<string, AssetInfo>[] m_Container;
|
public List<KeyValuePair<string, AssetInfo>> m_Container;
|
||||||
public string m_AssetBundleName;
|
public string m_AssetBundleName;
|
||||||
public string[] m_Dependencies;
|
public string[] m_Dependencies;
|
||||||
public bool m_IsStreamedSceneAssetBundle;
|
public bool m_IsStreamedSceneAssetBundle;
|
||||||
@@ -27,17 +27,17 @@ namespace AssetStudio
|
|||||||
public AssetBundle(ObjectReader reader) : base(reader)
|
public AssetBundle(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
var m_PreloadTableSize = reader.ReadInt32();
|
var m_PreloadTableSize = reader.ReadInt32();
|
||||||
m_PreloadTable = new PPtr<Object>[m_PreloadTableSize];
|
m_PreloadTable = new List<PPtr<Object>>();
|
||||||
for (var i = 0; i < m_PreloadTableSize; i++)
|
for (var i = 0; i < m_PreloadTableSize; i++)
|
||||||
{
|
{
|
||||||
m_PreloadTable[i] = new PPtr<Object>(reader);
|
m_PreloadTable.Add(new PPtr<Object>(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
var m_ContainerSize = reader.ReadInt32();
|
var m_ContainerSize = reader.ReadInt32();
|
||||||
m_Container = new KeyValuePair<string, AssetInfo>[m_ContainerSize];
|
m_Container = new List<KeyValuePair<string, AssetInfo>>();
|
||||||
for (var i = 0; i < m_ContainerSize; i++)
|
for (var i = 0; i < m_ContainerSize; i++)
|
||||||
{
|
{
|
||||||
m_Container[i] = new KeyValuePair<string, AssetInfo>(reader.ReadAlignedString(), new AssetInfo(reader));
|
m_Container.Add(new KeyValuePair<string, AssetInfo>(reader.ReadAlignedString(), new AssetInfo(reader)));
|
||||||
}
|
}
|
||||||
|
|
||||||
var m_MainAsset = new AssetInfo(reader);
|
var m_MainAsset = new AssetInfo(reader);
|
||||||
@@ -61,13 +61,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
m_AssetBundleName = reader.ReadAlignedString();
|
m_AssetBundleName = reader.ReadAlignedString();
|
||||||
|
|
||||||
var m_DependenciesSize = reader.ReadInt32();
|
m_Dependencies = reader.ReadStringArray();
|
||||||
m_Dependencies = new string[m_DependenciesSize];
|
|
||||||
|
|
||||||
for (var i = 0; i < m_DependenciesSize; i++)
|
|
||||||
{
|
|
||||||
m_Dependencies[i] = reader.ReadAlignedString();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_IsStreamedSceneAssetBundle = reader.ReadBoolean();
|
m_IsStreamedSceneAssetBundle = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class AudioClip : NamedObject
|
public sealed class AudioClip : NamedObject
|
||||||
{
|
{
|
||||||
@@ -36,11 +30,19 @@ namespace AssetStudio
|
|||||||
if (version < 5)
|
if (version < 5)
|
||||||
{
|
{
|
||||||
m_Format = reader.ReadInt32();
|
m_Format = reader.ReadInt32();
|
||||||
|
if (version >= (2, 6)) //2.6 to 5
|
||||||
|
{
|
||||||
m_Type = (FMODSoundType)reader.ReadInt32();
|
m_Type = (FMODSoundType)reader.ReadInt32();
|
||||||
m_3D = reader.ReadBoolean();
|
m_3D = reader.ReadBoolean();
|
||||||
m_UseHardware = reader.ReadBoolean();
|
m_UseHardware = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
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
|
if (version >= (3, 2)) //3.2.0 to 5
|
||||||
{
|
{
|
||||||
int m_Stream = reader.ReadInt32();
|
int m_Stream = reader.ReadInt32();
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class Skeleton
|
public class Skeleton
|
||||||
{
|
{
|
||||||
public Node[] m_Node;
|
public List<Node> m_Node;
|
||||||
public uint[] m_ID;
|
public uint[] m_ID;
|
||||||
public Axes[] m_AxesArray;
|
public Axes[] m_AxesArray;
|
||||||
|
|
||||||
@@ -74,34 +74,35 @@ namespace AssetStudio
|
|||||||
public Skeleton(ObjectReader reader)
|
public Skeleton(ObjectReader reader)
|
||||||
{
|
{
|
||||||
int numNodes = reader.ReadInt32();
|
int numNodes = reader.ReadInt32();
|
||||||
m_Node = new Node[numNodes];
|
m_Node = new List<Node>();
|
||||||
for (int i = 0; i < numNodes; i++)
|
for (var i = 0; i < numNodes; i++)
|
||||||
{
|
{
|
||||||
m_Node[i] = new Node(reader);
|
m_Node.Add(new Node(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ID = reader.ReadUInt32Array();
|
m_ID = reader.ReadUInt32Array();
|
||||||
|
|
||||||
int numAxes = reader.ReadInt32();
|
int numAxes = reader.ReadInt32();
|
||||||
m_AxesArray = new Axes[numAxes];
|
var axesList = new List<Axes>();
|
||||||
for (int i = 0; i < numAxes; i++)
|
for (var i = 0; i < numAxes; i++)
|
||||||
{
|
{
|
||||||
m_AxesArray[i] = new Axes(reader);
|
axesList.Add(new Axes(reader));
|
||||||
}
|
}
|
||||||
|
m_AxesArray = axesList.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SkeletonPose
|
public class SkeletonPose
|
||||||
{
|
{
|
||||||
public xform[] m_X;
|
public List<xform> m_X;
|
||||||
|
|
||||||
public SkeletonPose(ObjectReader reader)
|
public SkeletonPose(ObjectReader reader)
|
||||||
{
|
{
|
||||||
int numXforms = reader.ReadInt32();
|
int numXforms = reader.ReadInt32();
|
||||||
m_X = new xform[numXforms];
|
m_X = new List<xform>();
|
||||||
for (int i = 0; i < numXforms; i++)
|
for (var i = 0; i < numXforms; i++)
|
||||||
{
|
{
|
||||||
m_X[i] = new xform(reader);
|
m_X.Add(new xform(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,7 +164,7 @@ namespace AssetStudio
|
|||||||
public SkeletonPose m_SkeletonPose;
|
public SkeletonPose m_SkeletonPose;
|
||||||
public Hand m_LeftHand;
|
public Hand m_LeftHand;
|
||||||
public Hand m_RightHand;
|
public Hand m_RightHand;
|
||||||
public Handle[] m_Handles;
|
public List<Handle> m_Handles;
|
||||||
public Collider[] m_ColliderArray;
|
public Collider[] m_ColliderArray;
|
||||||
public int[] m_HumanBoneIndex;
|
public int[] m_HumanBoneIndex;
|
||||||
public float[] m_HumanBoneMass;
|
public float[] m_HumanBoneMass;
|
||||||
@@ -192,18 +193,19 @@ namespace AssetStudio
|
|||||||
if (version < (2018, 2)) //2018.2 down
|
if (version < (2018, 2)) //2018.2 down
|
||||||
{
|
{
|
||||||
int numHandles = reader.ReadInt32();
|
int numHandles = reader.ReadInt32();
|
||||||
m_Handles = new Handle[numHandles];
|
m_Handles = new List<Handle>();
|
||||||
for (int i = 0; i < numHandles; i++)
|
for (var i = 0; i < numHandles; i++)
|
||||||
{
|
{
|
||||||
m_Handles[i] = new Handle(reader);
|
m_Handles.Add(new Handle(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numColliders = reader.ReadInt32();
|
int numColliders = reader.ReadInt32();
|
||||||
m_ColliderArray = new Collider[numColliders];
|
var colliderList = new List<Collider>();
|
||||||
for (int i = 0; i < numColliders; i++)
|
for (var i = 0; i < numColliders; i++)
|
||||||
{
|
{
|
||||||
m_ColliderArray[i] = new Collider(reader);
|
colliderList.Add(new Collider(reader));
|
||||||
}
|
}
|
||||||
|
m_ColliderArray = colliderList.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_HumanBoneIndex = reader.ReadInt32Array();
|
m_HumanBoneIndex = reader.ReadInt32Array();
|
||||||
@@ -287,7 +289,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public uint m_AvatarSize;
|
public uint m_AvatarSize;
|
||||||
public AvatarConstant m_Avatar;
|
public AvatarConstant m_Avatar;
|
||||||
public KeyValuePair<uint, string>[] m_TOS;
|
public List<KeyValuePair<uint, string>> m_TOS;
|
||||||
|
|
||||||
public Avatar(ObjectReader reader) : base(reader)
|
public Avatar(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
@@ -295,10 +297,10 @@ namespace AssetStudio
|
|||||||
m_Avatar = new AvatarConstant(reader);
|
m_Avatar = new AvatarConstant(reader);
|
||||||
|
|
||||||
int numTOS = reader.ReadInt32();
|
int numTOS = reader.ReadInt32();
|
||||||
m_TOS = new KeyValuePair<uint, string>[numTOS];
|
m_TOS = new List<KeyValuePair<uint, string>>();
|
||||||
for (int i = 0; i < numTOS; i++)
|
for (var i = 0; i < numTOS; i++)
|
||||||
{
|
{
|
||||||
m_TOS[i] = new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString());
|
m_TOS.Add(new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//HumanDescription m_HumanDescription 2019 and up
|
//HumanDescription m_HumanDescription 2019 and up
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public abstract class Behaviour : Component
|
public abstract class Behaviour : Component
|
||||||
{
|
{
|
||||||
public byte m_Enabled;
|
public byte m_Enabled;
|
||||||
|
|
||||||
|
public Behaviour() { }
|
||||||
|
|
||||||
protected Behaviour(ObjectReader reader) : base(reader)
|
protected Behaviour(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
m_Enabled = reader.ReadByte();
|
m_Enabled = reader.ReadByte();
|
||||||
|
|||||||
@@ -1,24 +1,20 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class BuildSettings : Object
|
public sealed class BuildSettings : Object
|
||||||
{
|
{
|
||||||
public string m_Version;
|
public string[] levels;
|
||||||
|
public string[] scenes;
|
||||||
|
|
||||||
public BuildSettings(ObjectReader reader) : base(reader)
|
public BuildSettings(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
var levels = reader.ReadStringArray();
|
if (reader.version < (5, 1)) //5.1 down
|
||||||
|
{
|
||||||
var hasRenderTexture = reader.ReadBoolean();
|
levels = reader.ReadStringArray();
|
||||||
var hasPROVersion = reader.ReadBoolean();
|
}
|
||||||
var hasPublishingRights = reader.ReadBoolean();
|
else
|
||||||
var hasShadows = reader.ReadBoolean();
|
{
|
||||||
|
scenes = reader.ReadStringArray();
|
||||||
m_Version = reader.ReadAlignedString();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public abstract class Component : EditorExtension
|
public abstract class Component : EditorExtension
|
||||||
{
|
{
|
||||||
public PPtr<GameObject> m_GameObject;
|
public PPtr<GameObject> m_GameObject;
|
||||||
|
|
||||||
|
public Component() { }
|
||||||
|
|
||||||
protected Component(ObjectReader reader) : base(reader)
|
protected Component(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
m_GameObject = new PPtr<GameObject>(reader);
|
m_GameObject = new PPtr<GameObject>(reader);
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public abstract class EditorExtension : Object
|
public abstract class EditorExtension : Object
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class Font : NamedObject
|
public sealed class Font : NamedObject
|
||||||
{
|
{
|
||||||
@@ -23,12 +18,12 @@ namespace AssetStudio
|
|||||||
var m_CharacterPadding = reader.ReadInt32();
|
var m_CharacterPadding = reader.ReadInt32();
|
||||||
var m_ConvertCase = reader.ReadInt32();
|
var m_ConvertCase = reader.ReadInt32();
|
||||||
int m_CharacterRects_size = reader.ReadInt32();
|
int m_CharacterRects_size = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_CharacterRects_size; i++)
|
for (var i = 0; i < m_CharacterRects_size; i++)
|
||||||
{
|
{
|
||||||
reader.Position += 44;//CharacterInfo data 41
|
reader.Position += 44;//CharacterInfo data 41
|
||||||
}
|
}
|
||||||
int m_KerningValues_size = reader.ReadInt32();
|
int m_KerningValues_size = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_KerningValues_size; i++)
|
for (var i = 0; i < m_KerningValues_size; i++)
|
||||||
{
|
{
|
||||||
reader.Position += 8;
|
reader.Position += 8;
|
||||||
}
|
}
|
||||||
@@ -55,7 +50,7 @@ namespace AssetStudio
|
|||||||
if (version <= 3)
|
if (version <= 3)
|
||||||
{
|
{
|
||||||
int m_PerCharacterKerning_size = reader.ReadInt32();
|
int m_PerCharacterKerning_size = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_PerCharacterKerning_size; i++)
|
for (var i = 0; i < m_PerCharacterKerning_size; i++)
|
||||||
{
|
{
|
||||||
int first = reader.ReadInt32();
|
int first = reader.ReadInt32();
|
||||||
float second = reader.ReadSingle();
|
float second = reader.ReadSingle();
|
||||||
@@ -71,7 +66,7 @@ namespace AssetStudio
|
|||||||
var m_DefaultMaterial = new PPtr<Material>(reader);
|
var m_DefaultMaterial = new PPtr<Material>(reader);
|
||||||
|
|
||||||
int m_CharacterRects_size = reader.ReadInt32();
|
int m_CharacterRects_size = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_CharacterRects_size; i++)
|
for (var i = 0; i < m_CharacterRects_size; i++)
|
||||||
{
|
{
|
||||||
int index = reader.ReadInt32();
|
int index = reader.ReadInt32();
|
||||||
//Rectf uv
|
//Rectf uv
|
||||||
@@ -96,7 +91,7 @@ namespace AssetStudio
|
|||||||
var m_Texture = new PPtr<Texture>(reader);
|
var m_Texture = new PPtr<Texture>(reader);
|
||||||
|
|
||||||
int m_KerningValues_size = reader.ReadInt32();
|
int m_KerningValues_size = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_KerningValues_size; i++)
|
for (var i = 0; i < m_KerningValues_size; i++)
|
||||||
{
|
{
|
||||||
int pairfirst = reader.ReadInt16();
|
int pairfirst = reader.ReadInt16();
|
||||||
int pairsecond = reader.ReadInt16();
|
int pairsecond = reader.ReadInt16();
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace AssetStudio
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public class GLTextureSettings
|
public class GLTextureSettings
|
||||||
{
|
{
|
||||||
@@ -6,6 +8,8 @@
|
|||||||
public int m_Aniso;
|
public int m_Aniso;
|
||||||
public float m_MipBias;
|
public float m_MipBias;
|
||||||
public int m_WrapMode;
|
public int m_WrapMode;
|
||||||
|
[JsonInclude]
|
||||||
|
private int m_WrapU { set => m_WrapMode = value; }
|
||||||
|
|
||||||
public GLTextureSettings() { }
|
public GLTextureSettings() { }
|
||||||
|
|
||||||
@@ -19,8 +23,8 @@
|
|||||||
if (version >= 2017)//2017.x and up
|
if (version >= 2017)//2017.x and up
|
||||||
{
|
{
|
||||||
m_WrapMode = reader.ReadInt32(); //m_WrapU
|
m_WrapMode = reader.ReadInt32(); //m_WrapU
|
||||||
int m_WrapV = reader.ReadInt32();
|
var m_WrapV = reader.ReadInt32();
|
||||||
int m_WrapW = reader.ReadInt32();
|
var m_WrapW = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
using System.Text.Json.Serialization;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public sealed class GameObject : EditorExtension
|
public sealed class GameObject : EditorExtension
|
||||||
{
|
{
|
||||||
public PPtr<Component>[] m_Components;
|
public List<PPtr<Component>> m_Components;
|
||||||
public string m_Name;
|
public string m_Name;
|
||||||
|
|
||||||
public Transform m_Transform;
|
public Transform m_Transform;
|
||||||
@@ -16,21 +14,28 @@ namespace AssetStudio
|
|||||||
public SkinnedMeshRenderer m_SkinnedMeshRenderer;
|
public SkinnedMeshRenderer m_SkinnedMeshRenderer;
|
||||||
public Animator m_Animator;
|
public Animator m_Animator;
|
||||||
public Animation m_Animation;
|
public Animation m_Animation;
|
||||||
|
[JsonIgnore]
|
||||||
|
public CubismModel CubismModel;
|
||||||
|
|
||||||
public GameObject(ObjectReader reader) : base(reader)
|
public GameObject(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
int m_Component_size = reader.ReadInt32();
|
var m_ComponentSize = reader.ReadInt32();
|
||||||
m_Components = new PPtr<Component>[m_Component_size];
|
m_Components = new List<PPtr<Component>>();
|
||||||
for (int i = 0; i < m_Component_size; i++)
|
for (var i = 0; i < m_ComponentSize; i++)
|
||||||
{
|
{
|
||||||
if (version < (5, 5)) //5.5 down
|
if (version < (5, 5)) //5.5 down
|
||||||
{
|
{
|
||||||
int first = reader.ReadInt32();
|
var first = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
m_Components[i] = new PPtr<Component>(reader);
|
m_Components.Add(new PPtr<Component>(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
var m_Layer = reader.ReadInt32();
|
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();
|
m_Name = reader.ReadAlignedString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -8,6 +9,8 @@ namespace AssetStudio
|
|||||||
public Vector2 m_Scale;
|
public Vector2 m_Scale;
|
||||||
public Vector2 m_Offset;
|
public Vector2 m_Offset;
|
||||||
|
|
||||||
|
public UnityTexEnv() { }
|
||||||
|
|
||||||
public UnityTexEnv(ObjectReader reader)
|
public UnityTexEnv(ObjectReader reader)
|
||||||
{
|
{
|
||||||
m_Texture = new PPtr<Texture>(reader);
|
m_Texture = new PPtr<Texture>(reader);
|
||||||
@@ -18,44 +21,46 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class UnityPropertySheet
|
public class UnityPropertySheet
|
||||||
{
|
{
|
||||||
public KeyValuePair<string, UnityTexEnv>[] m_TexEnvs;
|
public List<KeyValuePair<string, UnityTexEnv>> m_TexEnvs;
|
||||||
public KeyValuePair<string, int>[] m_Ints;
|
public List<KeyValuePair<string, int>> m_Ints;
|
||||||
public KeyValuePair<string, float>[] m_Floats;
|
public List<KeyValuePair<string, float>> m_Floats;
|
||||||
public KeyValuePair<string, Color>[] m_Colors;
|
public List<KeyValuePair<string, Color>> m_Colors;
|
||||||
|
|
||||||
|
public UnityPropertySheet() { }
|
||||||
|
|
||||||
public UnityPropertySheet(ObjectReader reader)
|
public UnityPropertySheet(ObjectReader reader)
|
||||||
{
|
{
|
||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
int m_TexEnvsSize = reader.ReadInt32();
|
int m_TexEnvsSize = reader.ReadInt32();
|
||||||
m_TexEnvs = new KeyValuePair<string, UnityTexEnv>[m_TexEnvsSize];
|
m_TexEnvs = new List<KeyValuePair<string, UnityTexEnv>>();
|
||||||
for (int i = 0; i < m_TexEnvsSize; i++)
|
for (var i = 0; i < m_TexEnvsSize; i++)
|
||||||
{
|
{
|
||||||
m_TexEnvs[i] = new KeyValuePair<string, UnityTexEnv>(reader.ReadAlignedString(), new UnityTexEnv(reader));
|
m_TexEnvs.Add(new KeyValuePair<string, UnityTexEnv>(reader.ReadAlignedString(), new UnityTexEnv(reader)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2021) //2021.1 and up
|
if (version >= 2021) //2021.1 and up
|
||||||
{
|
{
|
||||||
int m_IntsSize = reader.ReadInt32();
|
int m_IntsSize = reader.ReadInt32();
|
||||||
m_Ints = new KeyValuePair<string, int>[m_IntsSize];
|
m_Ints = new List<KeyValuePair<string, int>>();
|
||||||
for (int i = 0; i < m_IntsSize; i++)
|
for (var i = 0; i < m_IntsSize; i++)
|
||||||
{
|
{
|
||||||
m_Ints[i] = new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32());
|
m_Ints.Add(new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_FloatsSize = reader.ReadInt32();
|
int m_FloatsSize = reader.ReadInt32();
|
||||||
m_Floats = new KeyValuePair<string, float>[m_FloatsSize];
|
m_Floats = new List<KeyValuePair<string, float>>();
|
||||||
for (int i = 0; i < m_FloatsSize; i++)
|
for (var i = 0; i < m_FloatsSize; i++)
|
||||||
{
|
{
|
||||||
m_Floats[i] = new KeyValuePair<string, float>(reader.ReadAlignedString(), reader.ReadSingle());
|
m_Floats.Add(new KeyValuePair<string, float>(reader.ReadAlignedString(), reader.ReadSingle()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_ColorsSize = reader.ReadInt32();
|
int m_ColorsSize = reader.ReadInt32();
|
||||||
m_Colors = new KeyValuePair<string, Color>[m_ColorsSize];
|
m_Colors = new List<KeyValuePair<string, Color>>();
|
||||||
for (int i = 0; i < m_ColorsSize; i++)
|
for (var i = 0; i < m_ColorsSize; i++)
|
||||||
{
|
{
|
||||||
m_Colors[i] = new KeyValuePair<string, Color>(reader.ReadAlignedString(), reader.ReadColor4());
|
m_Colors.Add(new KeyValuePair<string, Color>(reader.ReadAlignedString(), reader.ReadColor4()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,21 +70,30 @@ namespace AssetStudio
|
|||||||
public PPtr<Shader> m_Shader;
|
public PPtr<Shader> m_Shader;
|
||||||
public UnityPropertySheet m_SavedProperties;
|
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)
|
public Material(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
m_Shader = new PPtr<Shader>(reader);
|
m_Shader = new PPtr<Shader>(reader);
|
||||||
|
|
||||||
if (version == 4 && version.Minor >= 1) //4.x
|
if (version == 4 && version.Minor >= 1) //4.1 - 4.7.2
|
||||||
{
|
{
|
||||||
var m_ShaderKeywords = reader.ReadStringArray();
|
var m_ShaderKeywords = reader.ReadStringArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2021, 3)) //2021.3 and up
|
if (version >= (2021, 2, 18)) //2021.2.18 and up
|
||||||
{
|
{
|
||||||
var m_ValidKeywords = reader.ReadStringArray();
|
var m_ValidKeywords = reader.ReadStringArray();
|
||||||
var m_InvalidKeywords = reader.ReadStringArray();
|
var m_InvalidKeywords = reader.ReadStringArray();
|
||||||
}
|
}
|
||||||
else if (version >= 5) //5.0 ~ 2021.2
|
else if (version >= 5) //5.0 - 2021.2.17
|
||||||
{
|
{
|
||||||
var m_ShaderKeywords = reader.ReadAlignedString();
|
var m_ShaderKeywords = reader.ReadAlignedString();
|
||||||
}
|
}
|
||||||
@@ -104,7 +118,7 @@ namespace AssetStudio
|
|||||||
if (version >= (5, 1)) //5.1 and up
|
if (version >= (5, 1)) //5.1 and up
|
||||||
{
|
{
|
||||||
var stringTagMapSize = reader.ReadInt32();
|
var stringTagMapSize = reader.ReadInt32();
|
||||||
for (int i = 0; i < stringTagMapSize; i++)
|
for (var i = 0; i < stringTagMapSize; i++)
|
||||||
{
|
{
|
||||||
var first = reader.ReadAlignedString();
|
var first = reader.ReadAlignedString();
|
||||||
var second = reader.ReadAlignedString();
|
var second = reader.ReadAlignedString();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Buffers.Binary;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -123,8 +124,8 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public uint m_CurrentChannels;
|
public uint m_CurrentChannels;
|
||||||
public uint m_VertexCount;
|
public uint m_VertexCount;
|
||||||
public ChannelInfo[] m_Channels;
|
public List<ChannelInfo> m_Channels;
|
||||||
public StreamInfo[] m_Streams;
|
public List<StreamInfo> m_Streams;
|
||||||
public byte[] m_DataSize;
|
public byte[] m_DataSize;
|
||||||
|
|
||||||
public VertexData(ObjectReader reader)
|
public VertexData(ObjectReader reader)
|
||||||
@@ -141,27 +142,23 @@ namespace AssetStudio
|
|||||||
if (version >= 4) //4.0 and up
|
if (version >= 4) //4.0 and up
|
||||||
{
|
{
|
||||||
var m_ChannelsSize = reader.ReadInt32();
|
var m_ChannelsSize = reader.ReadInt32();
|
||||||
m_Channels = new ChannelInfo[m_ChannelsSize];
|
m_Channels = new List<ChannelInfo>();
|
||||||
for (int i = 0; i < m_ChannelsSize; i++)
|
for (var i = 0; i < m_ChannelsSize; i++)
|
||||||
{
|
{
|
||||||
m_Channels[i] = new ChannelInfo(reader);
|
m_Channels.Add(new ChannelInfo(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 5) //5.0 down
|
if (version < 5) //5.0 down
|
||||||
{
|
{
|
||||||
if (version < 4)
|
var streamCount = version < 4 //4.0 down
|
||||||
{
|
? 4
|
||||||
m_Streams = new StreamInfo[4];
|
: reader.ReadInt32();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_Streams = new StreamInfo[reader.ReadInt32()];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < m_Streams.Length; i++)
|
m_Streams = new List<StreamInfo>();
|
||||||
|
for (var i = 0; i < streamCount; i++)
|
||||||
{
|
{
|
||||||
m_Streams[i] = new StreamInfo(reader);
|
m_Streams.Add(new StreamInfo(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 4) //4.0 down
|
if (version < 4) //4.0 down
|
||||||
@@ -181,13 +178,13 @@ namespace AssetStudio
|
|||||||
private void GetStreams(UnityVersion version)
|
private void GetStreams(UnityVersion version)
|
||||||
{
|
{
|
||||||
var streamCount = m_Channels.Max(x => x.stream) + 1;
|
var streamCount = m_Channels.Max(x => x.stream) + 1;
|
||||||
m_Streams = new StreamInfo[streamCount];
|
m_Streams = new List<StreamInfo>();
|
||||||
uint offset = 0;
|
uint offset = 0;
|
||||||
for (int s = 0; s < streamCount; s++)
|
for (var s = 0; s < streamCount; s++)
|
||||||
{
|
{
|
||||||
uint chnMask = 0;
|
uint chnMask = 0;
|
||||||
uint stride = 0;
|
uint stride = 0;
|
||||||
for (int chn = 0; chn < m_Channels.Length; chn++)
|
for (var chn = 0; chn < m_Channels.Count; chn++)
|
||||||
{
|
{
|
||||||
var m_Channel = m_Channels[chn];
|
var m_Channel = m_Channels[chn];
|
||||||
if (m_Channel.stream == s)
|
if (m_Channel.stream == s)
|
||||||
@@ -199,14 +196,14 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_Streams[s] = new StreamInfo
|
m_Streams.Add(new StreamInfo
|
||||||
{
|
{
|
||||||
channelMask = chnMask,
|
channelMask = chnMask,
|
||||||
offset = offset,
|
offset = offset,
|
||||||
stride = stride,
|
stride = stride,
|
||||||
dividerOp = 0,
|
dividerOp = 0,
|
||||||
frequency = 0
|
frequency = 0
|
||||||
};
|
});
|
||||||
offset += m_VertexCount * stride;
|
offset += m_VertexCount * stride;
|
||||||
//static size_t AlignStreamSize (size_t size) { return (size + (kVertexStreamAlign-1)) & ~(kVertexStreamAlign-1); }
|
//static size_t AlignStreamSize (size_t size) { return (size + (kVertexStreamAlign-1)) & ~(kVertexStreamAlign-1); }
|
||||||
offset = (offset + (16u - 1u)) & ~(16u - 1u);
|
offset = (offset + (16u - 1u)) & ~(16u - 1u);
|
||||||
@@ -215,17 +212,17 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private void GetChannels(UnityVersion version)
|
private void GetChannels(UnityVersion version)
|
||||||
{
|
{
|
||||||
m_Channels = new ChannelInfo[6];
|
m_Channels = new List<ChannelInfo>(6);
|
||||||
for (int i = 0; i < 6; i++)
|
for (var i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
m_Channels[i] = new ChannelInfo();
|
m_Channels.Add(new ChannelInfo());
|
||||||
}
|
}
|
||||||
for (var s = 0; s < m_Streams.Length; s++)
|
for (var s = 0; s < m_Streams.Count; s++)
|
||||||
{
|
{
|
||||||
var m_Stream = m_Streams[s];
|
var m_Stream = m_Streams[s];
|
||||||
var channelMask = new BitArray(new[] { (int)m_Stream.channelMask });
|
var channelMask = new BitArray(new[] { (int)m_Stream.channelMask });
|
||||||
byte offset = 0;
|
byte offset = 0;
|
||||||
for (int i = 0; i < 6; i++)
|
for (var i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
if (channelMask.Get(i))
|
if (channelMask.Get(i))
|
||||||
{
|
{
|
||||||
@@ -344,8 +341,8 @@ namespace AssetStudio
|
|||||||
public class BlendShapeData
|
public class BlendShapeData
|
||||||
{
|
{
|
||||||
public BlendShapeVertex[] vertices;
|
public BlendShapeVertex[] vertices;
|
||||||
public MeshBlendShape[] shapes;
|
public List<MeshBlendShape> shapes;
|
||||||
public MeshBlendShapeChannel[] channels;
|
public List<MeshBlendShapeChannel> channels;
|
||||||
public float[] fullWeights;
|
public float[] fullWeights;
|
||||||
|
|
||||||
public BlendShapeData(ObjectReader reader)
|
public BlendShapeData(ObjectReader reader)
|
||||||
@@ -355,24 +352,25 @@ namespace AssetStudio
|
|||||||
if (version >= (4, 3)) //4.3 and up
|
if (version >= (4, 3)) //4.3 and up
|
||||||
{
|
{
|
||||||
int numVerts = reader.ReadInt32();
|
int numVerts = reader.ReadInt32();
|
||||||
|
reader.ThrowIfTooLarge(numVerts * 40f);
|
||||||
vertices = new BlendShapeVertex[numVerts];
|
vertices = new BlendShapeVertex[numVerts];
|
||||||
for (int i = 0; i < numVerts; i++)
|
for (var i = 0; i < numVerts; i++)
|
||||||
{
|
{
|
||||||
vertices[i] = new BlendShapeVertex(reader);
|
vertices[i] = new BlendShapeVertex(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
int numShapes = reader.ReadInt32();
|
int numShapes = reader.ReadInt32();
|
||||||
shapes = new MeshBlendShape[numShapes];
|
shapes = new List<MeshBlendShape>();
|
||||||
for (int i = 0; i < numShapes; i++)
|
for (var i = 0; i < numShapes; i++)
|
||||||
{
|
{
|
||||||
shapes[i] = new MeshBlendShape(reader);
|
shapes.Add(new MeshBlendShape(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numChannels = reader.ReadInt32();
|
int numChannels = reader.ReadInt32();
|
||||||
channels = new MeshBlendShapeChannel[numChannels];
|
channels = new List<MeshBlendShapeChannel>();
|
||||||
for (int i = 0; i < numChannels; i++)
|
for (var i = 0; i < numChannels; i++)
|
||||||
{
|
{
|
||||||
channels[i] = new MeshBlendShapeChannel(reader);
|
channels.Add(new MeshBlendShapeChannel(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
fullWeights = reader.ReadSingleArray();
|
fullWeights = reader.ReadSingleArray();
|
||||||
@@ -380,17 +378,17 @@ namespace AssetStudio
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var m_ShapesSize = reader.ReadInt32();
|
var m_ShapesSize = reader.ReadInt32();
|
||||||
var m_Shapes = new MeshBlendShape[m_ShapesSize];
|
var m_Shapes = new List<MeshBlendShape>();
|
||||||
for (int i = 0; i < m_ShapesSize; i++)
|
for (var i = 0; i < m_ShapesSize; i++)
|
||||||
{
|
{
|
||||||
m_Shapes[i] = new MeshBlendShape(reader);
|
m_Shapes.Add(new MeshBlendShape(reader));
|
||||||
}
|
}
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
var m_ShapeVerticesSize = reader.ReadInt32();
|
var m_ShapeVerticesSize = reader.ReadInt32();
|
||||||
var m_ShapeVertices = new BlendShapeVertex[m_ShapeVerticesSize]; //MeshBlendShapeVertex
|
reader.ThrowIfTooLarge(m_ShapeVerticesSize * 40f);
|
||||||
for (int i = 0; i < m_ShapeVerticesSize; i++)
|
for (var i = 0; i < m_ShapeVerticesSize; i++)
|
||||||
{
|
{
|
||||||
m_ShapeVertices[i] = new BlendShapeVertex(reader);
|
var m_ShapeVertices = new BlendShapeVertex(reader); //MeshBlendShapeVertex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -444,10 +442,109 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class VGPackedHierarchyNode
|
||||||
|
{
|
||||||
|
public Vector4[] LODBounds = new Vector4[8];
|
||||||
|
public Vector3[] AABBCenter = new Vector3[8];
|
||||||
|
public uint[] MinLODError_MaxParentLODError = new uint[8];
|
||||||
|
public Vector3[] AABBExtent = new Vector3[8];
|
||||||
|
public uint[] ChildStartIndex = new uint[8];
|
||||||
|
public uint[] PageIndex_PageCount_PageBlockCount = new uint[8];
|
||||||
|
|
||||||
|
public VGPackedHierarchyNode(BinaryReader reader)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
LODBounds[i] = reader.ReadVector4();
|
||||||
|
AABBCenter[i] = reader.ReadVector3();
|
||||||
|
MinLODError_MaxParentLODError[i] = reader.ReadUInt32();
|
||||||
|
AABBExtent[i] = reader.ReadVector3();
|
||||||
|
ChildStartIndex[i] = reader.ReadUInt32();
|
||||||
|
PageIndex_PageCount_PageBlockCount[i] = reader.ReadUInt32();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VGPageStreamingInfo
|
||||||
|
{
|
||||||
|
public uint offset;
|
||||||
|
public uint wholeSize;
|
||||||
|
public uint dataSize;
|
||||||
|
public uint dependencyOffset;
|
||||||
|
public uint dependencyCount;
|
||||||
|
public uint flags;
|
||||||
|
|
||||||
|
public VGPageStreamingInfo(BinaryReader reader)
|
||||||
|
{
|
||||||
|
offset = reader.ReadUInt32();
|
||||||
|
wholeSize = reader.ReadUInt32();
|
||||||
|
dataSize = reader.ReadUInt32();
|
||||||
|
dependencyOffset = reader.ReadUInt32();
|
||||||
|
dependencyCount = reader.ReadUInt32();
|
||||||
|
flags = reader.ReadUInt32();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SharedClusterData //Tuanjie
|
||||||
|
{
|
||||||
|
public SharedClusterData(ObjectReader reader, byte rev)
|
||||||
|
{
|
||||||
|
var m_LightmapUseUV1 = reader.ReadInt32();
|
||||||
|
var m_fileScale = reader.ReadSingle();
|
||||||
|
if (rev == 1)
|
||||||
|
{
|
||||||
|
var NumInputTriangles = reader.ReadUInt32();
|
||||||
|
var NumInputVertices = reader.ReadUInt32();
|
||||||
|
var NumInputMeshes = reader.ReadUInt16();
|
||||||
|
var NumInputTexCoords = reader.ReadUInt16();
|
||||||
|
var ResourceFlags = reader.ReadUInt32();
|
||||||
|
}
|
||||||
|
var rootClusterPageSize = reader.ReadInt32();
|
||||||
|
reader.Position += rootClusterPageSize; //skip byte[] rootClusterPage
|
||||||
|
if (rev == 1)
|
||||||
|
{
|
||||||
|
var imposterAtlasSize = reader.ReadInt32();
|
||||||
|
reader.Position += imposterAtlasSize * 2; //skip ushort[] imposterAtlas
|
||||||
|
}
|
||||||
|
var hierarchyNodesSize = reader.ReadInt32();
|
||||||
|
for (var i = 0; i < hierarchyNodesSize; i++)
|
||||||
|
{
|
||||||
|
var hierarchyNode = new VGPackedHierarchyNode(reader);
|
||||||
|
}
|
||||||
|
if (rev == 1)
|
||||||
|
{
|
||||||
|
var hierarchyRootOffsetsSize = reader.ReadInt32();
|
||||||
|
reader.Position += hierarchyRootOffsetsSize * 4; //skip uint[] hierarchyRootOffsets
|
||||||
|
}
|
||||||
|
var pageStreamingInfosSize = reader.ReadInt32();
|
||||||
|
for (var i = 0; i < pageStreamingInfosSize; i++)
|
||||||
|
{
|
||||||
|
var pageStreamingInfo = new VGPageStreamingInfo(reader);
|
||||||
|
}
|
||||||
|
var pageIndicesOfDependenciesSize = reader.ReadInt32();
|
||||||
|
reader.Position += pageIndicesOfDependenciesSize * 4; //skip uint[] pageIndicesOfDependencies
|
||||||
|
if (rev == 2)
|
||||||
|
{
|
||||||
|
var inputTrianglesCount = reader.ReadUInt32();
|
||||||
|
var inputVerticesCount = reader.ReadUInt32();
|
||||||
|
var inputMeshesCount = reader.ReadUInt16();
|
||||||
|
var inputTexCoordsCount = reader.ReadUInt16();
|
||||||
|
var resourceFlags = reader.ReadUInt32();
|
||||||
|
var imposterAtlasSize = reader.ReadInt32();
|
||||||
|
reader.Position += imposterAtlasSize * 2; //skip ushort[] imposterAtlas
|
||||||
|
var hierarchyRootOffsetsSize = reader.ReadInt32();
|
||||||
|
reader.Position += hierarchyRootOffsetsSize * 4; //skip uint[] hierarchyRootOffsets
|
||||||
|
}
|
||||||
|
var streamableClusterPageSize = reader.ReadInt32();
|
||||||
|
reader.Position += streamableClusterPageSize; //skip byte[] streamableClusterPageSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class Mesh : NamedObject
|
public sealed class Mesh : NamedObject
|
||||||
{
|
{
|
||||||
|
private bool isLoaded;
|
||||||
private bool m_Use16BitIndices = true;
|
private bool m_Use16BitIndices = true;
|
||||||
public SubMesh[] m_SubMeshes;
|
public List<SubMesh> m_SubMeshes;
|
||||||
private uint[] m_IndexBuffer;
|
private uint[] m_IndexBuffer;
|
||||||
public BlendShapeData m_Shapes;
|
public BlendShapeData m_Shapes;
|
||||||
public Matrix4x4[] m_BindPose;
|
public Matrix4x4[] m_BindPose;
|
||||||
@@ -466,6 +563,7 @@ namespace AssetStudio
|
|||||||
public float[] m_UV6;
|
public float[] m_UV6;
|
||||||
public float[] m_UV7;
|
public float[] m_UV7;
|
||||||
public float[] m_Tangents;
|
public float[] m_Tangents;
|
||||||
|
private bool m_HasVirtualGeometryMesh;
|
||||||
private VertexData m_VertexData;
|
private VertexData m_VertexData;
|
||||||
private CompressedMesh m_CompressedMesh;
|
private CompressedMesh m_CompressedMesh;
|
||||||
private StreamingInfo m_StreamData;
|
private StreamingInfo m_StreamData;
|
||||||
@@ -481,28 +579,30 @@ namespace AssetStudio
|
|||||||
|
|
||||||
if (version <= (2, 5)) //2.5 and down
|
if (version <= (2, 5)) //2.5 and down
|
||||||
{
|
{
|
||||||
int m_IndexBuffer_size = reader.ReadInt32();
|
int m_IndexBufferSize = reader.ReadInt32();
|
||||||
|
|
||||||
if (m_Use16BitIndices)
|
if (m_Use16BitIndices)
|
||||||
{
|
{
|
||||||
m_IndexBuffer = new uint[m_IndexBuffer_size / 2];
|
var indexBufferList = new List<uint>();
|
||||||
for (int i = 0; i < m_IndexBuffer_size / 2; i++)
|
for (var i = 0; i < m_IndexBufferSize / 2; i++)
|
||||||
{
|
{
|
||||||
m_IndexBuffer[i] = reader.ReadUInt16();
|
indexBufferList.Add(reader.ReadUInt16());
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
m_IndexBuffer = indexBufferList.ToArray();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_IndexBuffer = reader.ReadUInt32Array(m_IndexBuffer_size / 4);
|
m_IndexBuffer = reader.ReadUInt32Array(m_IndexBufferSize / 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_SubMeshesSize = reader.ReadInt32();
|
int m_SubMeshesSize = reader.ReadInt32();
|
||||||
m_SubMeshes = new SubMesh[m_SubMeshesSize];
|
m_SubMeshes = new List<SubMesh>();
|
||||||
for (int i = 0; i < m_SubMeshesSize; i++)
|
for (var i = 0; i < m_SubMeshesSize; i++)
|
||||||
{
|
{
|
||||||
m_SubMeshes[i] = new SubMesh(reader);
|
m_SubMeshes.Add(new SubMesh(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 1)) //4.1 and up
|
if (version >= (4, 1)) //4.1 and up
|
||||||
@@ -522,13 +622,13 @@ namespace AssetStudio
|
|||||||
if (version >= 2019) //2019 and up
|
if (version >= 2019) //2019 and up
|
||||||
{
|
{
|
||||||
var m_BonesAABBSize = reader.ReadInt32();
|
var m_BonesAABBSize = reader.ReadInt32();
|
||||||
var m_BonesAABB = new MinMaxAABB[m_BonesAABBSize];
|
for (var i = 0; i < m_BonesAABBSize; i++)
|
||||||
for (int i = 0; i < m_BonesAABBSize; i++)
|
|
||||||
{
|
{
|
||||||
m_BonesAABB[i] = new MinMaxAABB(reader);
|
var m_BonesAABB = new MinMaxAABB(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
var m_VariableBoneCountWeights = reader.ReadUInt32Array();
|
var m_VariableBoneCountWeightsSize = reader.ReadInt32();
|
||||||
|
reader.Position += m_VariableBoneCountWeightsSize * 4; //skip uint[] m_VariableBoneCountWeights
|
||||||
}
|
}
|
||||||
|
|
||||||
var m_MeshCompression = reader.ReadByte();
|
var m_MeshCompression = reader.ReadByte();
|
||||||
@@ -542,30 +642,49 @@ namespace AssetStudio
|
|||||||
var m_KeepVertices = reader.ReadBoolean();
|
var m_KeepVertices = reader.ReadBoolean();
|
||||||
var m_KeepIndices = reader.ReadBoolean();
|
var m_KeepIndices = reader.ReadBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version.IsTuanjie)
|
||||||
|
{
|
||||||
|
if (version < (2022, 3, 48) || (version == (2022, 3, 48) && version.Build < 3)) //2022.3.48t3(1.4.0) down
|
||||||
|
{
|
||||||
|
_ = new SharedClusterData(reader, rev: 1);
|
||||||
|
}
|
||||||
|
else if (version < (2022, 3, 61) || (version == (2022, 3, 61) && version.Build < 2)) //2022.3.48t3(1.4.0) - 2022.3.61t1(1.6.0)
|
||||||
|
{
|
||||||
|
_ = new SharedClusterData(reader, rev: 2);
|
||||||
|
}
|
||||||
|
else //2022.3.61t2(1.6.1) and up
|
||||||
|
{
|
||||||
|
reader.AlignStream();
|
||||||
|
_ = new SharedClusterData(reader, rev: 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
//Unity fixed it in 2017.3.1p1 and later versions
|
//Unity fixed it in 2017.3.1p1 and later versions
|
||||||
if (version >= (2017, 4) //2017.4
|
if (version >= (2017, 4) //2017.4
|
||||||
|| version == (2017, 3, 1) && buildType.IsPatch //fixed after 2017.3.1px
|
|| version == (2017, 3, 1) && version.IsPatch //fixed after 2017.3.1px
|
||||||
|| version == (2017, 3) && m_MeshCompression == 0)//2017.3.xfx with no compression
|
|| version == (2017, 3) && m_MeshCompression == 0) //2017.3.xfx with no compression
|
||||||
{
|
{
|
||||||
var m_IndexFormat = reader.ReadInt32();
|
var m_IndexFormat = reader.ReadInt32();
|
||||||
m_Use16BitIndices = m_IndexFormat == 0;
|
m_Use16BitIndices = m_IndexFormat == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_IndexBuffer_size = reader.ReadInt32();
|
int m_IndexBufferSize = reader.ReadInt32();
|
||||||
if (m_Use16BitIndices)
|
if (m_Use16BitIndices)
|
||||||
{
|
{
|
||||||
m_IndexBuffer = new uint[m_IndexBuffer_size / 2];
|
var indexBufferList = new List<uint>();
|
||||||
for (int i = 0; i < m_IndexBuffer_size / 2; i++)
|
for (var i = 0; i < m_IndexBufferSize / 2; i++)
|
||||||
{
|
{
|
||||||
m_IndexBuffer[i] = reader.ReadUInt16();
|
indexBufferList.Add(reader.ReadUInt16());
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
m_IndexBuffer = indexBufferList.ToArray();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_IndexBuffer = reader.ReadUInt32Array(m_IndexBuffer_size / 4);
|
m_IndexBuffer = reader.ReadUInt32Array(m_IndexBufferSize / 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,8 +693,10 @@ namespace AssetStudio
|
|||||||
m_VertexCount = reader.ReadInt32();
|
m_VertexCount = reader.ReadInt32();
|
||||||
m_Vertices = reader.ReadSingleArray(m_VertexCount * 3); //Vector3
|
m_Vertices = reader.ReadSingleArray(m_VertexCount * 3); //Vector3
|
||||||
|
|
||||||
m_Skin = new BoneWeights4[reader.ReadInt32()];
|
var numSkin = reader.ReadInt32();
|
||||||
for (int s = 0; s < m_Skin.Length; s++)
|
reader.ThrowIfTooLarge(numSkin * 32f);
|
||||||
|
m_Skin = new BoneWeights4[numSkin];
|
||||||
|
for (var s = 0; s < numSkin; s++)
|
||||||
{
|
{
|
||||||
m_Skin[s] = new BoneWeights4(reader);
|
m_Skin[s] = new BoneWeights4(reader);
|
||||||
}
|
}
|
||||||
@@ -588,10 +709,11 @@ namespace AssetStudio
|
|||||||
|
|
||||||
if (version <= (2, 5)) //2.5 and down
|
if (version <= (2, 5)) //2.5 and down
|
||||||
{
|
{
|
||||||
int m_TangentSpace_size = reader.ReadInt32();
|
int m_TangentSpaceSize = reader.ReadInt32();
|
||||||
m_Normals = new float[m_TangentSpace_size * 3];
|
reader.ThrowIfTooLarge(m_TangentSpaceSize * 28f);
|
||||||
m_Tangents = new float[m_TangentSpace_size * 4];
|
m_Normals = new float[m_TangentSpaceSize * 3];
|
||||||
for (int v = 0; v < m_TangentSpace_size; v++)
|
m_Tangents = new float[m_TangentSpaceSize * 4];
|
||||||
|
for (var v = 0; v < m_TangentSpaceSize; v++)
|
||||||
{
|
{
|
||||||
m_Normals[v * 3] = reader.ReadSingle();
|
m_Normals[v * 3] = reader.ReadSingle();
|
||||||
m_Normals[v * 3 + 1] = reader.ReadSingle();
|
m_Normals[v * 3 + 1] = reader.ReadSingle();
|
||||||
@@ -613,8 +735,10 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
if (version < (2018, 2)) //2018.2 down
|
if (version < (2018, 2)) //2018.2 down
|
||||||
{
|
{
|
||||||
m_Skin = new BoneWeights4[reader.ReadInt32()];
|
var numSkin = reader.ReadInt32();
|
||||||
for (int s = 0; s < m_Skin.Length; s++)
|
reader.ThrowIfTooLarge(numSkin * 32f);
|
||||||
|
m_Skin = new BoneWeights4[numSkin];
|
||||||
|
for (var s = 0; s < numSkin; s++)
|
||||||
{
|
{
|
||||||
m_Skin[s] = new BoneWeights4(reader);
|
m_Skin[s] = new BoneWeights4(reader);
|
||||||
}
|
}
|
||||||
@@ -637,15 +761,16 @@ namespace AssetStudio
|
|||||||
|
|
||||||
if (version <= (3, 4)) //3.4.2 and earlier
|
if (version <= (3, 4)) //3.4.2 and earlier
|
||||||
{
|
{
|
||||||
int m_Colors_size = reader.ReadInt32();
|
int m_ColorsSize = reader.ReadInt32();
|
||||||
m_Colors = new float[m_Colors_size * 4];
|
var m_ColorsList = new List<float>();
|
||||||
for (int v = 0; v < m_Colors_size * 4; v++)
|
for (var v = 0; v < m_ColorsSize * 4; v++)
|
||||||
{
|
{
|
||||||
m_Colors[v] = (float)reader.ReadByte() / 0xFF;
|
m_ColorsList.Add((float)reader.ReadByte() / 0xFF);
|
||||||
}
|
}
|
||||||
|
m_Colors = m_ColorsList.ToArray();
|
||||||
|
|
||||||
int m_CollisionTriangles_size = reader.ReadInt32();
|
int m_CollisionTrianglesSize = reader.ReadInt32();
|
||||||
reader.Position += m_CollisionTriangles_size * 4; //UInt32 indices
|
reader.Position += m_CollisionTrianglesSize * 4; //UInt32 indices
|
||||||
int m_CollisionVertexCount = reader.ReadInt32();
|
int m_CollisionVertexCount = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -658,9 +783,12 @@ namespace AssetStudio
|
|||||||
|
|
||||||
if (version >= 5) //5.0 and up
|
if (version >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
var m_BakedConvexCollisionMesh = reader.ReadUInt8Array();
|
var m_BakedConvexCollisionMeshSize = reader.ReadInt32();
|
||||||
|
reader.Position += m_BakedConvexCollisionMeshSize; //skip byte[] m_BakedConvexCollisionMesh
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
var m_BakedTriangleCollisionMesh = reader.ReadUInt8Array();
|
|
||||||
|
var m_BakedTriangleCollisionMeshSize = reader.ReadInt32();
|
||||||
|
reader.Position += m_BakedTriangleCollisionMeshSize; //skip byte[] m_BakedTriangleCollisionMesh
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -677,17 +805,32 @@ namespace AssetStudio
|
|||||||
m_StreamData = new StreamingInfo(reader);
|
m_StreamData = new StreamingInfo(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version.IsTuanjie && (version > (2022, 3, 2) || (version == (2022, 3, 2) && version.Build >= 13))) //2022.3.2t13(1.2.0) and up
|
||||||
|
{
|
||||||
|
var m_GenerateGeometryBuffer = reader.ReadBoolean();
|
||||||
|
m_HasVirtualGeometryMesh = reader.ReadBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
//m_MeshLodInfo = new MeshLodInfo(reader) //6000.2 and up
|
||||||
|
|
||||||
|
if (!assetsFile.assetsManager.MeshLazyLoad)
|
||||||
ProcessData();
|
ProcessData();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessData()
|
public void ProcessData()
|
||||||
{
|
{
|
||||||
|
if (isLoaded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var isStreamedDataSize = false;
|
||||||
if (!string.IsNullOrEmpty(m_StreamData?.path))
|
if (!string.IsNullOrEmpty(m_StreamData?.path))
|
||||||
{
|
{
|
||||||
if (m_VertexData.m_VertexCount > 0)
|
if (m_VertexData.m_VertexCount > 0)
|
||||||
{
|
{
|
||||||
|
m_VertexData.m_DataSize = BigArrayPool<byte>.Shared.Rent((int)m_StreamData.size);
|
||||||
var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
|
var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
|
||||||
m_VertexData.m_DataSize = resourceReader.GetData();
|
resourceReader.GetData(m_VertexData.m_DataSize);
|
||||||
|
isStreamedDataSize = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (version >= (3, 5)) //3.5 and up
|
if (version >= (3, 5)) //3.5 and up
|
||||||
@@ -700,14 +843,28 @@ namespace AssetStudio
|
|||||||
DecompressCompressedMesh();
|
DecompressCompressedMesh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_IndexBuffer.Length == 0)
|
||||||
|
{
|
||||||
|
var msg = m_HasVirtualGeometryMesh
|
||||||
|
? "Unsupported mesh type: Virtual Geometry"
|
||||||
|
: "Cannot process empty mesh";
|
||||||
|
Logger.Warning($"{msg} | PathID: {m_PathID} | Name: \"{m_Name}\"");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
GetTriangles();
|
GetTriangles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLoaded = true;
|
||||||
|
if (isStreamedDataSize)
|
||||||
|
BigArrayPool<byte>.Shared.Return(m_VertexData.m_DataSize, clearArray: true);
|
||||||
|
}
|
||||||
|
|
||||||
private void ReadVertexData()
|
private void ReadVertexData()
|
||||||
{
|
{
|
||||||
m_VertexCount = (int)m_VertexData.m_VertexCount;
|
m_VertexCount = (int)m_VertexData.m_VertexCount;
|
||||||
|
|
||||||
for (var chn = 0; chn < m_VertexData.m_Channels.Length; chn++)
|
for (var chn = 0; chn < m_VertexData.m_Channels.Count; chn++)
|
||||||
{
|
{
|
||||||
var m_Channel = m_VertexData.m_Channels[chn];
|
var m_Channel = m_VertexData.m_Channels[chn];
|
||||||
if (m_Channel.dimension > 0)
|
if (m_Channel.dimension > 0)
|
||||||
@@ -724,13 +881,14 @@ namespace AssetStudio
|
|||||||
var vertexFormat = MeshHelper.ToVertexFormat(m_Channel.format, version);
|
var vertexFormat = MeshHelper.ToVertexFormat(m_Channel.format, version);
|
||||||
var componentByteSize = (int)MeshHelper.GetFormatSize(vertexFormat);
|
var componentByteSize = (int)MeshHelper.GetFormatSize(vertexFormat);
|
||||||
var componentBytes = new byte[m_VertexCount * m_Channel.dimension * componentByteSize];
|
var componentBytes = new byte[m_VertexCount * m_Channel.dimension * componentByteSize];
|
||||||
for (int v = 0; v < m_VertexCount; v++)
|
for (var v = 0; v < m_VertexCount; v++)
|
||||||
{
|
{
|
||||||
var vertexOffset = (int)m_Stream.offset + m_Channel.offset + (int)m_Stream.stride * v;
|
var vertexOffset = (int)m_Stream.offset + m_Channel.offset + (int)m_Stream.stride * v;
|
||||||
for (int d = 0; d < m_Channel.dimension; d++)
|
for (var d = 0; d < m_Channel.dimension; d++)
|
||||||
{
|
{
|
||||||
var componentOffset = vertexOffset + componentByteSize * d;
|
var componentOffset = vertexOffset + componentByteSize * d;
|
||||||
Buffer.BlockCopy(m_VertexData.m_DataSize, componentOffset, componentBytes, componentByteSize * (v * m_Channel.dimension + d), componentByteSize);
|
var dstOffset = componentByteSize * (v * m_Channel.dimension + d);
|
||||||
|
m_VertexData.m_DataSize.AsSpan(componentOffset, componentByteSize).CopyTo(componentBytes.AsSpan(dstOffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,10 +896,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < componentBytes.Length / componentByteSize; i++)
|
for (var i = 0; i < componentBytes.Length / componentByteSize; i++)
|
||||||
{
|
{
|
||||||
var buff = new byte[componentByteSize];
|
componentBytes.AsSpan(i * componentByteSize, componentByteSize).Reverse();
|
||||||
Buffer.BlockCopy(componentBytes, i * componentByteSize, buff, 0, componentByteSize);
|
|
||||||
buff = buff.Reverse().ToArray();
|
|
||||||
Buffer.BlockCopy(buff, 0, componentBytes, i * componentByteSize, componentByteSize);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,9 +953,9 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
InitMSkin();
|
InitMSkin();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < m_VertexCount; i++)
|
for (var i = 0; i < m_VertexCount; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < m_Channel.dimension; j++)
|
for (var j = 0; j < m_Channel.dimension; j++)
|
||||||
{
|
{
|
||||||
m_Skin[i].weight[j] = componentsFloatArray[i * m_Channel.dimension + j];
|
m_Skin[i].weight[j] = componentsFloatArray[i * m_Channel.dimension + j];
|
||||||
}
|
}
|
||||||
@@ -810,15 +965,25 @@ namespace AssetStudio
|
|||||||
if (m_Skin == null)
|
if (m_Skin == null)
|
||||||
{
|
{
|
||||||
InitMSkin();
|
InitMSkin();
|
||||||
}
|
if (m_Channel.dimension == 1)
|
||||||
for (int i = 0; i < m_VertexCount; i++)
|
|
||||||
{
|
{
|
||||||
for (int j = 0; j < m_Channel.dimension; j++)
|
for (var i = 0; i < m_VertexCount; i++)
|
||||||
|
{
|
||||||
|
m_Skin[i].weight[0] = 1f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = 0; i < m_VertexCount; i++)
|
||||||
|
{
|
||||||
|
for (var j = 0; j < m_Channel.dimension; j++)
|
||||||
{
|
{
|
||||||
m_Skin[i].boneIndex[j] = componentsIntArray[i * m_Channel.dimension + j];
|
m_Skin[i].boneIndex[j] = componentsIntArray[i * m_Channel.dimension + j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
Logger.Warning($"Unknown vertex attribute: {chn}");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -856,6 +1021,9 @@ namespace AssetStudio
|
|||||||
case 7: //kShaderChannelTangent
|
case 7: //kShaderChannelTangent
|
||||||
m_Tangents = componentsFloatArray;
|
m_Tangents = componentsFloatArray;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
Logger.Warning($"Unknown vertex attribute: {chn}");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -883,7 +1051,7 @@ namespace AssetStudio
|
|||||||
const int kMaxTexCoordShaderChannels = 8;
|
const int kMaxTexCoordShaderChannels = 8;
|
||||||
|
|
||||||
int uvSrcOffset = 0;
|
int uvSrcOffset = 0;
|
||||||
for (int uv = 0; uv < kMaxTexCoordShaderChannels; uv++)
|
for (var uv = 0; uv < kMaxTexCoordShaderChannels; uv++)
|
||||||
{
|
{
|
||||||
var texCoordBits = m_UVInfo >> (uv * kInfoBitsPerUV);
|
var texCoordBits = m_UVInfo >> (uv * kInfoBitsPerUV);
|
||||||
texCoordBits &= (1u << kInfoBitsPerUV) - 1u;
|
texCoordBits &= (1u << kInfoBitsPerUV) - 1u;
|
||||||
@@ -912,11 +1080,9 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
m_BindPose = new Matrix4x4[m_CompressedMesh.m_BindPoses.m_NumItems / 16];
|
m_BindPose = new Matrix4x4[m_CompressedMesh.m_BindPoses.m_NumItems / 16];
|
||||||
var m_BindPoses_Unpacked = m_CompressedMesh.m_BindPoses.UnpackFloats(16, 4 * 16);
|
var m_BindPoses_Unpacked = m_CompressedMesh.m_BindPoses.UnpackFloats(16, 4 * 16);
|
||||||
var buffer = new float[16];
|
for (var i = 0; i < m_BindPose.Length; i++)
|
||||||
for (int i = 0; i < m_BindPose.Length; i++)
|
|
||||||
{
|
{
|
||||||
Array.Copy(m_BindPoses_Unpacked, i * 16, buffer, 0, 16);
|
m_BindPose[i] = new Matrix4x4(m_BindPoses_Unpacked.AsSpan(i * 16, 16));
|
||||||
m_BindPose[i] = new Matrix4x4(buffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -926,14 +1092,14 @@ namespace AssetStudio
|
|||||||
var normalData = m_CompressedMesh.m_Normals.UnpackFloats(2, 4 * 2);
|
var normalData = m_CompressedMesh.m_Normals.UnpackFloats(2, 4 * 2);
|
||||||
var signs = m_CompressedMesh.m_NormalSigns.UnpackInts();
|
var signs = m_CompressedMesh.m_NormalSigns.UnpackInts();
|
||||||
m_Normals = new float[m_CompressedMesh.m_Normals.m_NumItems / 2 * 3];
|
m_Normals = new float[m_CompressedMesh.m_Normals.m_NumItems / 2 * 3];
|
||||||
for (int i = 0; i < m_CompressedMesh.m_Normals.m_NumItems / 2; ++i)
|
for (var i = 0; i < m_CompressedMesh.m_Normals.m_NumItems / 2; ++i)
|
||||||
{
|
{
|
||||||
var x = normalData[i * 2 + 0];
|
var x = normalData[i * 2 + 0];
|
||||||
var y = normalData[i * 2 + 1];
|
var y = normalData[i * 2 + 1];
|
||||||
var zsqr = 1 - x * x - y * y;
|
var zsqr = 1 - x * x - y * y;
|
||||||
float z;
|
float z;
|
||||||
if (zsqr >= 0f)
|
if (zsqr >= 0f)
|
||||||
z = (float)Math.Sqrt(zsqr);
|
z = MathF.Sqrt(zsqr);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
z = 0;
|
z = 0;
|
||||||
@@ -956,14 +1122,14 @@ namespace AssetStudio
|
|||||||
var tangentData = m_CompressedMesh.m_Tangents.UnpackFloats(2, 4 * 2);
|
var tangentData = m_CompressedMesh.m_Tangents.UnpackFloats(2, 4 * 2);
|
||||||
var signs = m_CompressedMesh.m_TangentSigns.UnpackInts();
|
var signs = m_CompressedMesh.m_TangentSigns.UnpackInts();
|
||||||
m_Tangents = new float[m_CompressedMesh.m_Tangents.m_NumItems / 2 * 4];
|
m_Tangents = new float[m_CompressedMesh.m_Tangents.m_NumItems / 2 * 4];
|
||||||
for (int i = 0; i < m_CompressedMesh.m_Tangents.m_NumItems / 2; ++i)
|
for (var i = 0; i < m_CompressedMesh.m_Tangents.m_NumItems / 2; ++i)
|
||||||
{
|
{
|
||||||
var x = tangentData[i * 2 + 0];
|
var x = tangentData[i * 2 + 0];
|
||||||
var y = tangentData[i * 2 + 1];
|
var y = tangentData[i * 2 + 1];
|
||||||
var zsqr = 1 - x * x - y * y;
|
var zsqr = 1 - x * x - y * y;
|
||||||
float z;
|
float z;
|
||||||
if (zsqr >= 0f)
|
if (zsqr >= 0f)
|
||||||
z = (float)Math.Sqrt(zsqr);
|
z = MathF.Sqrt(zsqr);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
z = 0;
|
z = 0;
|
||||||
@@ -1003,7 +1169,7 @@ namespace AssetStudio
|
|||||||
int j = 0;
|
int j = 0;
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
for (int i = 0; i < m_CompressedMesh.m_Weights.m_NumItems; i++)
|
for (var i = 0; i < m_CompressedMesh.m_Weights.m_NumItems; i++)
|
||||||
{
|
{
|
||||||
//read bone index and weight.
|
//read bone index and weight.
|
||||||
m_Skin[bonePos].weight[j] = weights[i] / 31.0f;
|
m_Skin[bonePos].weight[j] = weights[i] / 31.0f;
|
||||||
@@ -1047,7 +1213,7 @@ namespace AssetStudio
|
|||||||
m_CompressedMesh.m_Colors.m_BitSize /= 4;
|
m_CompressedMesh.m_Colors.m_BitSize /= 4;
|
||||||
var tempColors = m_CompressedMesh.m_Colors.UnpackInts();
|
var tempColors = m_CompressedMesh.m_Colors.UnpackInts();
|
||||||
m_Colors = new float[m_CompressedMesh.m_Colors.m_NumItems];
|
m_Colors = new float[m_CompressedMesh.m_Colors.m_NumItems];
|
||||||
for (int v = 0; v < m_CompressedMesh.m_Colors.m_NumItems; v++)
|
for (var v = 0; v < m_CompressedMesh.m_Colors.m_NumItems; v++)
|
||||||
{
|
{
|
||||||
m_Colors[v] = tempColors[v] / 255f;
|
m_Colors[v] = tempColors[v] / 255f;
|
||||||
}
|
}
|
||||||
@@ -1067,7 +1233,7 @@ namespace AssetStudio
|
|||||||
var topology = m_SubMesh.topology;
|
var topology = m_SubMesh.topology;
|
||||||
if (topology == GfxPrimitiveType.Triangles)
|
if (topology == GfxPrimitiveType.Triangles)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < indexCount; i += 3)
|
for (var i = 0; i < indexCount; i += 3)
|
||||||
{
|
{
|
||||||
m_Indices.Add(m_IndexBuffer[firstIndex + i]);
|
m_Indices.Add(m_IndexBuffer[firstIndex + i]);
|
||||||
m_Indices.Add(m_IndexBuffer[firstIndex + i + 1]);
|
m_Indices.Add(m_IndexBuffer[firstIndex + i + 1]);
|
||||||
@@ -1078,7 +1244,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
// de-stripify :
|
// de-stripify :
|
||||||
uint triIndex = 0;
|
uint triIndex = 0;
|
||||||
for (int i = 0; i < indexCount - 2; i++)
|
for (var i = 0; i < indexCount - 2; i++)
|
||||||
{
|
{
|
||||||
var a = m_IndexBuffer[firstIndex + i];
|
var a = m_IndexBuffer[firstIndex + i];
|
||||||
var b = m_IndexBuffer[firstIndex + i + 1];
|
var b = m_IndexBuffer[firstIndex + i + 1];
|
||||||
@@ -1107,7 +1273,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
else if (topology == GfxPrimitiveType.Quads)
|
else if (topology == GfxPrimitiveType.Quads)
|
||||||
{
|
{
|
||||||
for (int q = 0; q < indexCount; q += 4)
|
for (var q = 0; q < indexCount; q += 4)
|
||||||
{
|
{
|
||||||
m_Indices.Add(m_IndexBuffer[firstIndex + q]);
|
m_Indices.Add(m_IndexBuffer[firstIndex + q]);
|
||||||
m_Indices.Add(m_IndexBuffer[firstIndex + q + 1]);
|
m_Indices.Add(m_IndexBuffer[firstIndex + q + 1]);
|
||||||
@@ -1129,7 +1295,7 @@ namespace AssetStudio
|
|||||||
private void InitMSkin()
|
private void InitMSkin()
|
||||||
{
|
{
|
||||||
m_Skin = new BoneWeights4[m_VertexCount];
|
m_Skin = new BoneWeights4[m_VertexCount];
|
||||||
for (int i = 0; i < m_VertexCount; i++)
|
for (var i = 0; i < m_VertexCount; i++)
|
||||||
{
|
{
|
||||||
m_Skin[i] = new BoneWeights4();
|
m_Skin[i] = new BoneWeights4();
|
||||||
}
|
}
|
||||||
@@ -1332,15 +1498,19 @@ namespace AssetStudio
|
|||||||
var size = GetFormatSize(format);
|
var size = GetFormatSize(format);
|
||||||
var len = inputBytes.Length / size;
|
var len = inputBytes.Length / size;
|
||||||
var result = new float[len];
|
var result = new float[len];
|
||||||
for (int i = 0; i < len; i++)
|
for (var i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case VertexFormat.Float:
|
case VertexFormat.Float:
|
||||||
|
#if NET
|
||||||
|
result[i] = BinaryPrimitives.ReadSingleLittleEndian(inputBytes.AsSpan(i * 4));
|
||||||
|
#else
|
||||||
result[i] = BitConverter.ToSingle(inputBytes, i * 4);
|
result[i] = BitConverter.ToSingle(inputBytes, i * 4);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case VertexFormat.Float16:
|
case VertexFormat.Float16:
|
||||||
result[i] = Half.ToHalf(inputBytes, i * 2);
|
result[i] = (float)HalfHelper.ToHalf(inputBytes, i * 2);
|
||||||
break;
|
break;
|
||||||
case VertexFormat.UNorm8:
|
case VertexFormat.UNorm8:
|
||||||
result[i] = inputBytes[i] / 255f;
|
result[i] = inputBytes[i] / 255f;
|
||||||
@@ -1349,22 +1519,22 @@ namespace AssetStudio
|
|||||||
result[i] = Math.Max((sbyte)inputBytes[i] / 127f, -1f);
|
result[i] = Math.Max((sbyte)inputBytes[i] / 127f, -1f);
|
||||||
break;
|
break;
|
||||||
case VertexFormat.UNorm16:
|
case VertexFormat.UNorm16:
|
||||||
result[i] = BitConverter.ToUInt16(inputBytes, i * 2) / 65535f;
|
result[i] = BinaryPrimitives.ReadUInt16LittleEndian(inputBytes.AsSpan(i * 2)) / 65535f;
|
||||||
break;
|
break;
|
||||||
case VertexFormat.SNorm16:
|
case VertexFormat.SNorm16:
|
||||||
result[i] = Math.Max(BitConverter.ToInt16(inputBytes, i * 2) / 32767f, -1f);
|
result[i] = Math.Max(BinaryPrimitives.ReadInt16LittleEndian(inputBytes.AsSpan(i * 2)) / 32767f, -1f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] BytesToIntArray(byte[] inputBytes, VertexFormat format)
|
public static int[] BytesToIntArray(ReadOnlySpan<byte> inputBytes, VertexFormat format)
|
||||||
{
|
{
|
||||||
var size = GetFormatSize(format);
|
var size = GetFormatSize(format);
|
||||||
var len = inputBytes.Length / size;
|
var len = inputBytes.Length / size;
|
||||||
var result = new int[len];
|
var result = new int[len];
|
||||||
for (int i = 0; i < len; i++)
|
for (var i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
@@ -1373,12 +1543,16 @@ namespace AssetStudio
|
|||||||
result[i] = inputBytes[i];
|
result[i] = inputBytes[i];
|
||||||
break;
|
break;
|
||||||
case VertexFormat.UInt16:
|
case VertexFormat.UInt16:
|
||||||
|
result[i] = BinaryPrimitives.ReadUInt16LittleEndian(inputBytes.Slice(i * 2));
|
||||||
|
break;
|
||||||
case VertexFormat.SInt16:
|
case VertexFormat.SInt16:
|
||||||
result[i] = BitConverter.ToInt16(inputBytes, i * 2);
|
result[i] = BinaryPrimitives.ReadInt16LittleEndian(inputBytes.Slice(i * 2));
|
||||||
break;
|
break;
|
||||||
case VertexFormat.UInt32:
|
case VertexFormat.UInt32:
|
||||||
|
result[i] = (int)BinaryPrimitives.ReadUInt32LittleEndian(inputBytes.Slice(i * 4));
|
||||||
|
break;
|
||||||
case VertexFormat.SInt32:
|
case VertexFormat.SInt32:
|
||||||
result[i] = BitConverter.ToInt32(inputBytes, i * 4);
|
result[i] = BinaryPrimitives.ReadInt32LittleEndian(inputBytes.Slice(i * 4));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class MeshFilter : Component
|
public sealed class MeshFilter : Component
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class MeshRenderer : Renderer
|
public sealed class MeshRenderer : Renderer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class MonoBehaviour : Behaviour
|
public class MonoBehaviour : Behaviour
|
||||||
{
|
{
|
||||||
public PPtr<MonoScript> m_Script;
|
public PPtr<MonoScript> m_Script;
|
||||||
public string m_Name;
|
public string m_Name;
|
||||||
|
|
||||||
|
public MonoBehaviour() { }
|
||||||
|
|
||||||
public MonoBehaviour(ObjectReader reader) : base(reader)
|
public MonoBehaviour(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
m_Script = new PPtr<MonoScript>(reader);
|
m_Script = new PPtr<MonoScript>(reader);
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class MonoScript : NamedObject
|
public sealed class MonoScript : NamedObject
|
||||||
{
|
{
|
||||||
@@ -16,7 +11,7 @@ namespace AssetStudio
|
|||||||
if (version >= (3, 4)) //3.4 and up
|
if (version >= (3, 4)) //3.4 and up
|
||||||
{
|
{
|
||||||
var m_ExecutionOrder = reader.ReadInt32();
|
var m_ExecutionOrder = reader.ReadInt32();
|
||||||
}
|
|
||||||
if (version < 5) //5.0 down
|
if (version < 5) //5.0 down
|
||||||
{
|
{
|
||||||
var m_PropertiesHash = reader.ReadUInt32();
|
var m_PropertiesHash = reader.ReadUInt32();
|
||||||
@@ -25,6 +20,8 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var m_PropertiesHash = reader.ReadBytes(16);
|
var m_PropertiesHash = reader.ReadBytes(16);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (version < 3) //3.0 down
|
if (version < 3) //3.0 down
|
||||||
{
|
{
|
||||||
var m_PathName = reader.ReadAlignedString();
|
var m_PathName = reader.ReadAlignedString();
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class MovieTexture : Texture
|
public sealed class MovieTexture : Texture
|
||||||
{
|
{
|
||||||
@@ -11,6 +6,8 @@ namespace AssetStudio
|
|||||||
public PPtr<AudioClip> m_AudioClip;
|
public PPtr<AudioClip> m_AudioClip;
|
||||||
|
|
||||||
public MovieTexture(ObjectReader reader) : base(reader)
|
public MovieTexture(ObjectReader reader) : base(reader)
|
||||||
|
{
|
||||||
|
if (reader.version < (2019, 3)) //2019.3 down
|
||||||
{
|
{
|
||||||
var m_Loop = reader.ReadBoolean();
|
var m_Loop = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
@@ -18,4 +15,5 @@ namespace AssetStudio
|
|||||||
m_MovieData = reader.ReadUInt8Array();
|
m_MovieData = reader.ReadUInt8Array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public class NamedObject : EditorExtension
|
public class NamedObject : EditorExtension
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using Newtonsoft.Json;
|
using System.Collections.Specialized;
|
||||||
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
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -12,13 +15,31 @@ namespace AssetStudio
|
|||||||
public long m_PathID;
|
public long m_PathID;
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public UnityVersion version;
|
public UnityVersion version;
|
||||||
protected BuildType buildType;
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public BuildTarget platform;
|
public BuildTarget platform;
|
||||||
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||||
public ClassIDType type;
|
public ClassIDType type;
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public SerializedType serializedType;
|
public SerializedType serializedType;
|
||||||
|
public int classID;
|
||||||
public uint byteSize;
|
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() { }
|
||||||
|
|
||||||
@@ -30,9 +51,9 @@ namespace AssetStudio
|
|||||||
type = reader.type;
|
type = reader.type;
|
||||||
m_PathID = reader.m_PathID;
|
m_PathID = reader.m_PathID;
|
||||||
version = reader.version;
|
version = reader.version;
|
||||||
buildType = reader.buildType;
|
|
||||||
platform = reader.platform;
|
platform = reader.platform;
|
||||||
serializedType = reader.serializedType;
|
serializedType = reader.serializedType;
|
||||||
|
classID = reader.classID;
|
||||||
byteSize = reader.byteSize;
|
byteSize = reader.byteSize;
|
||||||
|
|
||||||
if (platform == BuildTarget.NoTarget)
|
if (platform == BuildTarget.NoTarget)
|
||||||
@@ -41,57 +62,67 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Dump()
|
|
||||||
{
|
|
||||||
if (serializedType?.m_Type != null)
|
|
||||||
{
|
|
||||||
return TypeTreeHelper.ReadTypeString(serializedType.m_Type, reader);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Dump(TypeTree m_Type)
|
|
||||||
{
|
|
||||||
if (m_Type != null)
|
|
||||||
{
|
|
||||||
return TypeTreeHelper.ReadTypeString(m_Type, reader);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string DumpObject()
|
public string DumpObject()
|
||||||
{
|
{
|
||||||
string str = null;
|
string str = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
str = JsonConvert.SerializeObject(this, new JsonSerializerSettings
|
if (this is Mesh m_Mesh)
|
||||||
{
|
{
|
||||||
Formatting = Formatting.Indented,
|
m_Mesh.ProcessData();
|
||||||
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
}
|
||||||
}).Replace(" ", " ");
|
|
||||||
|
str = JsonSerializer.Deserialize<JsonObject>(JsonSerializer.SerializeToUtf8Bytes(this, GetType(), jsonOptions))
|
||||||
|
.ToJsonString(jsonOptions).Replace(" ", " ");
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrderedDictionary ToType()
|
public string Dump(TypeTree m_Type = null)
|
||||||
{
|
{
|
||||||
if (serializedType?.m_Type != null)
|
m_Type = m_Type ?? serializedType?.m_Type;
|
||||||
{
|
if (m_Type == null)
|
||||||
return TypeTreeHelper.ReadType(serializedType.m_Type, reader);
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
return TypeTreeHelper.ReadTypeString(m_Type, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrderedDictionary ToType(TypeTree m_Type)
|
public OrderedDictionary ToType(TypeTree m_Type = null)
|
||||||
{
|
|
||||||
if (m_Type != null)
|
|
||||||
{
|
{
|
||||||
|
m_Type = m_Type ?? serializedType?.m_Type;
|
||||||
|
if (m_Type == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
return TypeTreeHelper.ReadType(m_Type, reader);
|
return TypeTreeHelper.ReadType(m_Type, reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JsonDocument ToJsonDoc(TypeTree m_Type = null)
|
||||||
|
{
|
||||||
|
var typeDict = ToType(m_Type);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (typeDict != null)
|
||||||
|
{
|
||||||
|
return JsonSerializer.SerializeToDocument(typeDict, jsonOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this is Mesh m_Mesh)
|
||||||
|
{
|
||||||
|
m_Mesh.ProcessData();
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonSerializer.SerializeToDocument(this, GetType(), jsonOptions);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -6,9 +7,16 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public int m_FileID;
|
public int m_FileID;
|
||||||
public long m_PathID;
|
public long m_PathID;
|
||||||
|
public string Name => _assetsFile != null && TryGet(out var result) ? result.Name : string.Empty;
|
||||||
|
|
||||||
private SerializedFile _assetsFile;
|
|
||||||
private int _index = -2; //-2 - Prepare, -1 - Missing
|
private int _index = -2; //-2 - Prepare, -1 - Missing
|
||||||
|
private SerializedFile _assetsFile;
|
||||||
|
[JsonIgnore]
|
||||||
|
public SerializedFile AssetsFile
|
||||||
|
{
|
||||||
|
get => _assetsFile;
|
||||||
|
set => _assetsFile = value;
|
||||||
|
}
|
||||||
|
|
||||||
public PPtr(ObjectReader reader)
|
public PPtr(ObjectReader reader)
|
||||||
{
|
{
|
||||||
@@ -31,7 +39,7 @@ namespace AssetStudio
|
|||||||
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 assetsManager = _assetsFile.assetsManager;
|
||||||
var assetsFileList = assetsManager.assetsFileList;
|
var assetsFileList = assetsManager.AssetsFileList;
|
||||||
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
||||||
|
|
||||||
if (_index == -2)
|
if (_index == -2)
|
||||||
@@ -58,7 +66,7 @@ namespace AssetStudio
|
|||||||
public bool TryGet(out T result, SerializedFile assetsFile = null)
|
public bool TryGet(out T result, SerializedFile assetsFile = null)
|
||||||
{
|
{
|
||||||
_assetsFile = _assetsFile ?? assetsFile;
|
_assetsFile = _assetsFile ?? assetsFile;
|
||||||
if (TryGetAssetsFile(out var sourceFile))
|
if (!IsNull && TryGetAssetsFile(out var sourceFile))
|
||||||
{
|
{
|
||||||
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
||||||
{
|
{
|
||||||
@@ -77,7 +85,7 @@ namespace AssetStudio
|
|||||||
public bool TryGet<T2>(out T2 result, SerializedFile assetsFile = null) where T2 : Object
|
public bool TryGet<T2>(out T2 result, SerializedFile assetsFile = null) where T2 : Object
|
||||||
{
|
{
|
||||||
_assetsFile = _assetsFile ?? assetsFile;
|
_assetsFile = _assetsFile ?? assetsFile;
|
||||||
if (TryGetAssetsFile(out var sourceFile))
|
if (!IsNull && TryGetAssetsFile(out var sourceFile))
|
||||||
{
|
{
|
||||||
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
||||||
{
|
{
|
||||||
@@ -118,7 +126,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
var assetsManager = _assetsFile.assetsManager;
|
var assetsManager = _assetsFile.assetsManager;
|
||||||
var assetsFileList = assetsManager.assetsFileList;
|
var assetsFileList = assetsManager.AssetsFileList;
|
||||||
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
||||||
|
|
||||||
if (!assetsFileIndexCache.TryGetValue(name, out _index))
|
if (!assetsFileIndexCache.TryGetValue(name, out _index))
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class PlayerSettings : Object
|
public sealed class PlayerSettings : Object
|
||||||
{
|
{
|
||||||
@@ -11,6 +6,8 @@ namespace AssetStudio
|
|||||||
public string productName;
|
public string productName;
|
||||||
|
|
||||||
public PlayerSettings(ObjectReader reader) : base(reader)
|
public PlayerSettings(ObjectReader reader) : base(reader)
|
||||||
|
{
|
||||||
|
if (version >= (3, 0))
|
||||||
{
|
{
|
||||||
if (version >= (5, 4)) //5.4.0 and up
|
if (version >= (5, 4)) //5.4.0 and up
|
||||||
{
|
{
|
||||||
@@ -44,6 +41,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var accelerometerFrequency = reader.ReadInt32();
|
var accelerometerFrequency = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
companyName = reader.ReadAlignedString();
|
companyName = reader.ReadAlignedString();
|
||||||
productName = reader.ReadAlignedString();
|
productName = reader.ReadAlignedString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
namespace AssetStudio
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public sealed class PreloadData : NamedObject
|
public sealed class PreloadData : NamedObject
|
||||||
{
|
{
|
||||||
public PPtr<Object>[] m_Assets;
|
public List<PPtr<Object>> m_Assets;
|
||||||
|
|
||||||
public PreloadData(ObjectReader reader) : base(reader)
|
public PreloadData(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
var m_PreloadTableSize = reader.ReadInt32();
|
var m_PreloadTableSize = reader.ReadInt32();
|
||||||
m_Assets = new PPtr<Object>[m_PreloadTableSize];
|
m_Assets = new List<PPtr<Object>>();
|
||||||
for (var i = 0; i < m_PreloadTableSize; i++)
|
for (var i = 0; i < m_PreloadTableSize; i++)
|
||||||
{
|
{
|
||||||
m_Assets[i] = new PPtr<Object>(reader);
|
m_Assets.Add(new PPtr<Object>(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class RectTransform : Transform
|
public sealed class RectTransform : Transform
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -19,7 +16,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public abstract class Renderer : Component
|
public abstract class Renderer : Component
|
||||||
{
|
{
|
||||||
public PPtr<Material>[] m_Materials;
|
public List<PPtr<Material>> m_Materials;
|
||||||
public StaticBatchInfo m_StaticBatchInfo;
|
public StaticBatchInfo m_StaticBatchInfo;
|
||||||
public uint[] m_SubsetIndices;
|
public uint[] m_SubsetIndices;
|
||||||
|
|
||||||
@@ -58,7 +55,36 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
var m_RayTraceProcedural = reader.ReadByte();
|
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();
|
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();
|
||||||
|
if (version >= (6000, 2)) //6000.2 and up
|
||||||
|
{
|
||||||
|
var m_ForceMeshLod = reader.ReadInt16();
|
||||||
|
reader.AlignStream();
|
||||||
|
var m_MeshLodSelectionBias = reader.ReadSingle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -94,10 +120,10 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
var m_MaterialsSize = reader.ReadInt32();
|
var m_MaterialsSize = reader.ReadInt32();
|
||||||
m_Materials = new PPtr<Material>[m_MaterialsSize];
|
m_Materials = new List<PPtr<Material>>();
|
||||||
for (int i = 0; i < m_MaterialsSize; i++)
|
for (var i = 0; i < m_MaterialsSize; i++)
|
||||||
{
|
{
|
||||||
m_Materials[i] = new PPtr<Material>(reader);
|
m_Materials.Add(new PPtr<Material>(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 3) //3.0 down
|
if (version < 3) //3.0 down
|
||||||
@@ -128,7 +154,7 @@ namespace AssetStudio
|
|||||||
var m_UseLightProbes = reader.ReadBoolean();
|
var m_UseLightProbes = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
if (version >= 5)//5.0 and up
|
if (version >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
var m_ReflectionProbeUsage = reader.ReadInt32();
|
var m_ReflectionProbeUsage = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
@@ -144,12 +170,21 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var m_SortingLayerID = reader.ReadUInt32();
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
//SInt16 m_SortingLayer 5.6 and up
|
|
||||||
var m_SortingOrder = reader.ReadInt16();
|
var m_SortingOrder = reader.ReadInt16();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
|
if (version >= (6000, 3)) //6000.3 and up
|
||||||
|
{
|
||||||
|
var m_MaskInteraction = reader.ReadInt32();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public class ResourceManager : Object
|
public class ResourceManager : Object
|
||||||
{
|
{
|
||||||
public KeyValuePair<string, PPtr<Object>>[] m_Container;
|
public List<KeyValuePair<string, PPtr<Object>>> m_Container;
|
||||||
|
|
||||||
public ResourceManager(ObjectReader reader) : base(reader)
|
public ResourceManager(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
var m_ContainerSize = reader.ReadInt32();
|
var m_ContainerSize = reader.ReadInt32();
|
||||||
m_Container = new KeyValuePair<string, PPtr<Object>>[m_ContainerSize];
|
m_Container = new List<KeyValuePair<string, PPtr<Object>>>();
|
||||||
for (int i = 0; i < m_ContainerSize; i++)
|
for (var i = 0; i < m_ContainerSize; i++)
|
||||||
{
|
{
|
||||||
m_Container[i] = new KeyValuePair<string, PPtr<Object>>(reader.ReadAlignedString(), new PPtr<Object>(reader));
|
m_Container.Add(new KeyValuePair<string, PPtr<Object>>(reader.ReadAlignedString(), new PPtr<Object>(reader)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public abstract class RuntimeAnimatorController : NamedObject
|
public abstract class RuntimeAnimatorController : NamedObject
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class StructParameter
|
public class StructParameter
|
||||||
{
|
{
|
||||||
public MatrixParameter[] m_MatrixParams;
|
public List<MatrixParameter> m_MatrixParams;
|
||||||
public VectorParameter[] m_VectorParams;
|
public List<VectorParameter> m_VectorParams;
|
||||||
|
|
||||||
public StructParameter(BinaryReader reader)
|
public StructParameter(BinaryReader reader)
|
||||||
{
|
{
|
||||||
@@ -28,17 +28,17 @@ namespace AssetStudio
|
|||||||
var m_StructSize = reader.ReadInt32();
|
var m_StructSize = reader.ReadInt32();
|
||||||
|
|
||||||
int numVectorParams = reader.ReadInt32();
|
int numVectorParams = reader.ReadInt32();
|
||||||
m_VectorParams = new VectorParameter[numVectorParams];
|
m_VectorParams = new List<VectorParameter>();
|
||||||
for (int i = 0; i < numVectorParams; i++)
|
for (var i = 0; i < numVectorParams; i++)
|
||||||
{
|
{
|
||||||
m_VectorParams[i] = new VectorParameter(reader);
|
m_VectorParams.Add(new VectorParameter(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numMatrixParams = reader.ReadInt32();
|
int numMatrixParams = reader.ReadInt32();
|
||||||
m_MatrixParams = new MatrixParameter[numMatrixParams];
|
m_MatrixParams = new List<MatrixParameter>();
|
||||||
for (int i = 0; i < numMatrixParams; i++)
|
for (var i = 0; i < numMatrixParams; i++)
|
||||||
{
|
{
|
||||||
m_MatrixParams[i] = new MatrixParameter(reader);
|
m_MatrixParams.Add(new MatrixParameter(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,15 +112,15 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class SerializedProperties
|
public class SerializedProperties
|
||||||
{
|
{
|
||||||
public SerializedProperty[] m_Props;
|
public List<SerializedProperty> m_Props;
|
||||||
|
|
||||||
public SerializedProperties(BinaryReader reader)
|
public SerializedProperties(BinaryReader reader)
|
||||||
{
|
{
|
||||||
int numProps = reader.ReadInt32();
|
int numProps = reader.ReadInt32();
|
||||||
m_Props = new SerializedProperty[numProps];
|
m_Props = new List<SerializedProperty>();
|
||||||
for (int i = 0; i < numProps; i++)
|
for (var i = 0; i < numProps; i++)
|
||||||
{
|
{
|
||||||
m_Props[i] = new SerializedProperty(reader);
|
m_Props.Add(new SerializedProperty(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_Name = reader.ReadAlignedString();
|
m_Name = reader.ReadAlignedString();
|
||||||
rtBlend = new SerializedShaderRTBlendState[8];
|
rtBlend = new SerializedShaderRTBlendState[8];
|
||||||
for (int i = 0; i < 8; i++)
|
for (var i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
rtBlend[i] = new SerializedShaderRTBlendState(reader);
|
rtBlend[i] = new SerializedShaderRTBlendState(reader);
|
||||||
}
|
}
|
||||||
@@ -290,16 +290,16 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class ParserBindChannels
|
public class ParserBindChannels
|
||||||
{
|
{
|
||||||
public ShaderBindChannel[] m_Channels;
|
public List<ShaderBindChannel> m_Channels;
|
||||||
public uint m_SourceMap;
|
public uint m_SourceMap;
|
||||||
|
|
||||||
public ParserBindChannels(BinaryReader reader)
|
public ParserBindChannels(BinaryReader reader)
|
||||||
{
|
{
|
||||||
int numChannels = reader.ReadInt32();
|
int numChannels = reader.ReadInt32();
|
||||||
m_Channels = new ShaderBindChannel[numChannels];
|
m_Channels = new List<ShaderBindChannel>();
|
||||||
for (int i = 0; i < numChannels; i++)
|
for (var i = 0; i < numChannels; i++)
|
||||||
{
|
{
|
||||||
m_Channels[i] = new ShaderBindChannel(reader);
|
m_Channels.Add(new ShaderBindChannel(reader));
|
||||||
}
|
}
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
@@ -390,9 +390,9 @@ namespace AssetStudio
|
|||||||
public class ConstantBuffer
|
public class ConstantBuffer
|
||||||
{
|
{
|
||||||
public int m_NameIndex;
|
public int m_NameIndex;
|
||||||
public MatrixParameter[] m_MatrixParams;
|
public List<MatrixParameter> m_MatrixParams;
|
||||||
public VectorParameter[] m_VectorParams;
|
public List<VectorParameter> m_VectorParams;
|
||||||
public StructParameter[] m_StructParams;
|
public List<StructParameter> m_StructParams;
|
||||||
public int m_Size;
|
public int m_Size;
|
||||||
public bool m_IsPartialCB;
|
public bool m_IsPartialCB;
|
||||||
|
|
||||||
@@ -403,25 +403,25 @@ namespace AssetStudio
|
|||||||
m_NameIndex = reader.ReadInt32();
|
m_NameIndex = reader.ReadInt32();
|
||||||
|
|
||||||
int numMatrixParams = reader.ReadInt32();
|
int numMatrixParams = reader.ReadInt32();
|
||||||
m_MatrixParams = new MatrixParameter[numMatrixParams];
|
m_MatrixParams = new List<MatrixParameter>();
|
||||||
for (int i = 0; i < numMatrixParams; i++)
|
for (var i = 0; i < numMatrixParams; i++)
|
||||||
{
|
{
|
||||||
m_MatrixParams[i] = new MatrixParameter(reader);
|
m_MatrixParams.Add(new MatrixParameter(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numVectorParams = reader.ReadInt32();
|
int numVectorParams = reader.ReadInt32();
|
||||||
m_VectorParams = new VectorParameter[numVectorParams];
|
m_VectorParams = new List<VectorParameter>();
|
||||||
for (int i = 0; i < numVectorParams; i++)
|
for (var i = 0; i < numVectorParams; i++)
|
||||||
{
|
{
|
||||||
m_VectorParams[i] = new VectorParameter(reader);
|
m_VectorParams.Add(new VectorParameter(reader));
|
||||||
}
|
}
|
||||||
if (version >= (2017, 3)) //2017.3 and up
|
if (version >= (2017, 3)) //2017.3 and up
|
||||||
{
|
{
|
||||||
int numStructParams = reader.ReadInt32();
|
int numStructParams = reader.ReadInt32();
|
||||||
m_StructParams = new StructParameter[numStructParams];
|
m_StructParams = new List<StructParameter>();
|
||||||
for (int i = 0; i < numStructParams; i++)
|
for (var i = 0; i < numStructParams; i++)
|
||||||
{
|
{
|
||||||
m_StructParams[i] = new StructParameter(reader);
|
m_StructParams.Add(new StructParameter(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_Size = reader.ReadInt32();
|
m_Size = reader.ReadInt32();
|
||||||
@@ -488,71 +488,74 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class SerializedProgramParameters
|
public class SerializedProgramParameters
|
||||||
{
|
{
|
||||||
public VectorParameter[] m_VectorParams;
|
public List<VectorParameter> m_VectorParams;
|
||||||
public MatrixParameter[] m_MatrixParams;
|
public List<MatrixParameter> m_MatrixParams;
|
||||||
public TextureParameter[] m_TextureParams;
|
public List<TextureParameter> m_TextureParams;
|
||||||
public BufferBinding[] m_BufferParams;
|
public List<BufferBinding> m_BufferParams;
|
||||||
public ConstantBuffer[] m_ConstantBuffers;
|
public List<ConstantBuffer> m_ConstantBuffers;
|
||||||
public BufferBinding[] m_ConstantBufferBindings;
|
public List<BufferBinding> m_ConstantBufferBindings;
|
||||||
public UAVParameter[] m_UAVParams;
|
public List<UAVParameter> m_UAVParams;
|
||||||
public SamplerParameter[] m_Samplers;
|
public List<SamplerParameter> m_Samplers;
|
||||||
|
|
||||||
public SerializedProgramParameters(ObjectReader reader)
|
public SerializedProgramParameters(ObjectReader reader)
|
||||||
{
|
{
|
||||||
int numVectorParams = reader.ReadInt32();
|
int numVectorParams = reader.ReadInt32();
|
||||||
m_VectorParams = new VectorParameter[numVectorParams];
|
m_VectorParams = new List<VectorParameter>();
|
||||||
for (int i = 0; i < numVectorParams; i++)
|
for (var i = 0; i < numVectorParams; i++)
|
||||||
{
|
{
|
||||||
m_VectorParams[i] = new VectorParameter(reader);
|
m_VectorParams.Add(new VectorParameter(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numMatrixParams = reader.ReadInt32();
|
int numMatrixParams = reader.ReadInt32();
|
||||||
m_MatrixParams = new MatrixParameter[numMatrixParams];
|
m_MatrixParams = new List<MatrixParameter>();
|
||||||
for (int i = 0; i < numMatrixParams; i++)
|
for (var i = 0; i < numMatrixParams; i++)
|
||||||
{
|
{
|
||||||
m_MatrixParams[i] = new MatrixParameter(reader);
|
m_MatrixParams.Add(new MatrixParameter(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numTextureParams = reader.ReadInt32();
|
int numTextureParams = reader.ReadInt32();
|
||||||
m_TextureParams = new TextureParameter[numTextureParams];
|
m_TextureParams = new List<TextureParameter>();
|
||||||
for (int i = 0; i < numTextureParams; i++)
|
for (var i = 0; i < numTextureParams; i++)
|
||||||
{
|
{
|
||||||
m_TextureParams[i] = new TextureParameter(reader);
|
m_TextureParams.Add(new TextureParameter(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numBufferParams = reader.ReadInt32();
|
int numBufferParams = reader.ReadInt32();
|
||||||
m_BufferParams = new BufferBinding[numBufferParams];
|
m_BufferParams = new List<BufferBinding>();
|
||||||
for (int i = 0; i < numBufferParams; i++)
|
for (var i = 0; i < numBufferParams; i++)
|
||||||
{
|
{
|
||||||
m_BufferParams[i] = new BufferBinding(reader);
|
m_BufferParams.Add(new BufferBinding(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numConstantBuffers = reader.ReadInt32();
|
int numConstantBuffers = reader.ReadInt32();
|
||||||
m_ConstantBuffers = new ConstantBuffer[numConstantBuffers];
|
m_ConstantBuffers = new List<ConstantBuffer>();
|
||||||
for (int i = 0; i < numConstantBuffers; i++)
|
for (var i = 0; i < numConstantBuffers; i++)
|
||||||
{
|
{
|
||||||
m_ConstantBuffers[i] = new ConstantBuffer(reader);
|
m_ConstantBuffers.Add(new ConstantBuffer(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numConstantBufferBindings = reader.ReadInt32();
|
int numConstantBufferBindings = reader.ReadInt32();
|
||||||
m_ConstantBufferBindings = new BufferBinding[numConstantBufferBindings];
|
m_ConstantBufferBindings = new List<BufferBinding>();
|
||||||
for (int i = 0; i < numConstantBufferBindings; i++)
|
for (var i = 0; i < numConstantBufferBindings; i++)
|
||||||
{
|
{
|
||||||
m_ConstantBufferBindings[i] = new BufferBinding(reader);
|
m_ConstantBufferBindings.Add(new BufferBinding(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numUAVParams = reader.ReadInt32();
|
int numUAVParams = reader.ReadInt32();
|
||||||
m_UAVParams = new UAVParameter[numUAVParams];
|
m_UAVParams = new List<UAVParameter>();
|
||||||
for (int i = 0; i < numUAVParams; i++)
|
for (var i = 0; i < numUAVParams; i++)
|
||||||
{
|
{
|
||||||
m_UAVParams[i] = new UAVParameter(reader);
|
m_UAVParams.Add(new UAVParameter(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
int numSamplers = reader.ReadInt32();
|
if (reader.version >= 2017) //2017 and up
|
||||||
m_Samplers = new SamplerParameter[numSamplers];
|
|
||||||
for (int i = 0; i < numSamplers; i++)
|
|
||||||
{
|
{
|
||||||
m_Samplers[i] = new SamplerParameter(reader);
|
int numSamplers = reader.ReadInt32();
|
||||||
|
m_Samplers = new List<SamplerParameter>();
|
||||||
|
for (var i = 0; i < numSamplers; i++)
|
||||||
|
{
|
||||||
|
m_Samplers.Add(new SamplerParameter(reader));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -564,15 +567,7 @@ namespace AssetStudio
|
|||||||
public ushort[] m_KeywordIndices;
|
public ushort[] m_KeywordIndices;
|
||||||
public sbyte m_ShaderHardwareTier;
|
public sbyte m_ShaderHardwareTier;
|
||||||
public ShaderGpuProgramType m_GpuProgramType;
|
public ShaderGpuProgramType m_GpuProgramType;
|
||||||
public SerializedProgramParameters m_Parameters;
|
public SerializedProgramParameters m_Parameters; // nested since 2020.3.2f1 and up; 2021.1.1f1 and up
|
||||||
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)
|
public SerializedSubProgram(ObjectReader reader)
|
||||||
{
|
{
|
||||||
@@ -601,72 +596,7 @@ namespace AssetStudio
|
|||||||
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
|
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
if (version.IsInRange((2020, 3, 2), 2021) //2020.3.2f1 and up
|
|
||||||
|| version >= (2021, 1, 1)) //2021.1.1f1 and up
|
|
||||||
{
|
|
||||||
m_Parameters = new SerializedProgramParameters(reader);
|
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 >= 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 >= (2017, 2)) //2017.2 and up
|
if (version >= (2017, 2)) //2017.2 and up
|
||||||
{
|
{
|
||||||
@@ -684,7 +614,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class SerializedProgram
|
public class SerializedProgram
|
||||||
{
|
{
|
||||||
public SerializedSubProgram[] m_SubPrograms;
|
public List<SerializedSubProgram> m_SubPrograms;
|
||||||
public SerializedProgramParameters m_CommonParameters;
|
public SerializedProgramParameters m_CommonParameters;
|
||||||
public ushort[] m_SerializedKeywordStateMask;
|
public ushort[] m_SerializedKeywordStateMask;
|
||||||
|
|
||||||
@@ -693,10 +623,10 @@ namespace AssetStudio
|
|||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
int numSubPrograms = reader.ReadInt32();
|
int numSubPrograms = reader.ReadInt32();
|
||||||
m_SubPrograms = new SerializedSubProgram[numSubPrograms];
|
m_SubPrograms = new List<SerializedSubProgram>();
|
||||||
for (int i = 0; i < numSubPrograms; i++)
|
for (var i = 0; i < numSubPrograms; i++)
|
||||||
{
|
{
|
||||||
m_SubPrograms[i] = new SerializedSubProgram(reader);
|
m_SubPrograms.Add(new SerializedSubProgram(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version.IsInRange((2020, 3, 2), 2021) //2020.3.2f1 and up
|
if (version.IsInRange((2020, 3, 2), 2021) //2020.3.2f1 and up
|
||||||
@@ -722,11 +652,11 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class SerializedPass
|
public class SerializedPass
|
||||||
{
|
{
|
||||||
public Hash128[] m_EditorDataHash;
|
public List<Hash128> m_EditorDataHash;
|
||||||
public byte[] m_Platforms;
|
public byte[] m_Platforms;
|
||||||
public ushort[] m_LocalKeywordMask;
|
public ushort[] m_LocalKeywordMask;
|
||||||
public ushort[] m_GlobalKeywordMask;
|
public ushort[] m_GlobalKeywordMask;
|
||||||
public KeyValuePair<string, int>[] m_NameIndices;
|
public List<KeyValuePair<string, int>> m_NameIndices;
|
||||||
public PassType m_Type;
|
public PassType m_Type;
|
||||||
public SerializedShaderState m_State;
|
public SerializedShaderState m_State;
|
||||||
public uint m_ProgramMask;
|
public uint m_ProgramMask;
|
||||||
@@ -750,10 +680,10 @@ namespace AssetStudio
|
|||||||
if (version >= (2020, 2)) //2020.2 and up
|
if (version >= (2020, 2)) //2020.2 and up
|
||||||
{
|
{
|
||||||
int numEditorDataHash = reader.ReadInt32();
|
int numEditorDataHash = reader.ReadInt32();
|
||||||
m_EditorDataHash = new Hash128[numEditorDataHash];
|
m_EditorDataHash = new List<Hash128>();
|
||||||
for (int i = 0; i < numEditorDataHash; i++)
|
for (var i = 0; i < numEditorDataHash; i++)
|
||||||
{
|
{
|
||||||
m_EditorDataHash[i] = new Hash128(reader);
|
m_EditorDataHash.Add(new Hash128(reader));
|
||||||
}
|
}
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
m_Platforms = reader.ReadUInt8Array();
|
m_Platforms = reader.ReadUInt8Array();
|
||||||
@@ -768,10 +698,10 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
int numIndices = reader.ReadInt32();
|
int numIndices = reader.ReadInt32();
|
||||||
m_NameIndices = new KeyValuePair<string, int>[numIndices];
|
m_NameIndices = new List<KeyValuePair<string, int>>();
|
||||||
for (int i = 0; i < numIndices; i++)
|
for (var i = 0; i < numIndices; i++)
|
||||||
{
|
{
|
||||||
m_NameIndices[i] = new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32());
|
m_NameIndices.Add(new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32()));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Type = (PassType)reader.ReadInt32();
|
m_Type = (PassType)reader.ReadInt32();
|
||||||
@@ -806,32 +736,32 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public class SerializedTagMap
|
public class SerializedTagMap
|
||||||
{
|
{
|
||||||
public KeyValuePair<string, string>[] tags;
|
public List<KeyValuePair<string, string>> tags;
|
||||||
|
|
||||||
public SerializedTagMap(BinaryReader reader)
|
public SerializedTagMap(BinaryReader reader)
|
||||||
{
|
{
|
||||||
int numTags = reader.ReadInt32();
|
int numTags = reader.ReadInt32();
|
||||||
tags = new KeyValuePair<string, string>[numTags];
|
tags = new List<KeyValuePair<string, string>>();
|
||||||
for (int i = 0; i < numTags; i++)
|
for (var i = 0; i < numTags; i++)
|
||||||
{
|
{
|
||||||
tags[i] = new KeyValuePair<string, string>(reader.ReadAlignedString(), reader.ReadAlignedString());
|
tags.Add(new KeyValuePair<string, string>(reader.ReadAlignedString(), reader.ReadAlignedString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SerializedSubShader
|
public class SerializedSubShader
|
||||||
{
|
{
|
||||||
public SerializedPass[] m_Passes;
|
public List<SerializedPass> m_Passes;
|
||||||
public SerializedTagMap m_Tags;
|
public SerializedTagMap m_Tags;
|
||||||
public int m_LOD;
|
public int m_LOD;
|
||||||
|
|
||||||
public SerializedSubShader(ObjectReader reader)
|
public SerializedSubShader(ObjectReader reader)
|
||||||
{
|
{
|
||||||
int numPasses = reader.ReadInt32();
|
int numPasses = reader.ReadInt32();
|
||||||
m_Passes = new SerializedPass[numPasses];
|
m_Passes = new List<SerializedPass>();
|
||||||
for (int i = 0; i < numPasses; i++)
|
for (var i = 0; i < numPasses; i++)
|
||||||
{
|
{
|
||||||
m_Passes[i] = new SerializedPass(reader);
|
m_Passes.Add(new SerializedPass(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Tags = new SerializedTagMap(reader);
|
m_Tags = new SerializedTagMap(reader);
|
||||||
@@ -866,14 +796,14 @@ namespace AssetStudio
|
|||||||
public class SerializedShader
|
public class SerializedShader
|
||||||
{
|
{
|
||||||
public SerializedProperties m_PropInfo;
|
public SerializedProperties m_PropInfo;
|
||||||
public SerializedSubShader[] m_SubShaders;
|
public List<SerializedSubShader> m_SubShaders;
|
||||||
public string[] m_KeywordNames;
|
public string[] m_KeywordNames;
|
||||||
public byte[] m_KeywordFlags;
|
public byte[] m_KeywordFlags;
|
||||||
public string m_Name;
|
public string m_Name;
|
||||||
public string m_CustomEditorName;
|
public string m_CustomEditorName;
|
||||||
public string m_FallbackName;
|
public string m_FallbackName;
|
||||||
public SerializedShaderDependency[] m_Dependencies;
|
public List<SerializedShaderDependency> m_Dependencies;
|
||||||
public SerializedCustomEditorForRenderPipeline[] m_CustomEditorForRenderPipelines;
|
public List<SerializedCustomEditorForRenderPipeline> m_CustomEditorForRenderPipelines;
|
||||||
public bool m_DisableNoSubshadersMessage;
|
public bool m_DisableNoSubshadersMessage;
|
||||||
|
|
||||||
public SerializedShader(ObjectReader reader)
|
public SerializedShader(ObjectReader reader)
|
||||||
@@ -883,10 +813,10 @@ namespace AssetStudio
|
|||||||
m_PropInfo = new SerializedProperties(reader);
|
m_PropInfo = new SerializedProperties(reader);
|
||||||
|
|
||||||
int numSubShaders = reader.ReadInt32();
|
int numSubShaders = reader.ReadInt32();
|
||||||
m_SubShaders = new SerializedSubShader[numSubShaders];
|
m_SubShaders = new List<SerializedSubShader>();
|
||||||
for (int i = 0; i < numSubShaders; i++)
|
for (var i = 0; i < numSubShaders; i++)
|
||||||
{
|
{
|
||||||
m_SubShaders[i] = new SerializedSubShader(reader);
|
m_SubShaders.Add(new SerializedSubShader(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (2021, 2)) //2021.2 and up
|
if (version >= (2021, 2)) //2021.2 and up
|
||||||
@@ -901,19 +831,19 @@ namespace AssetStudio
|
|||||||
m_FallbackName = reader.ReadAlignedString();
|
m_FallbackName = reader.ReadAlignedString();
|
||||||
|
|
||||||
int numDependencies = reader.ReadInt32();
|
int numDependencies = reader.ReadInt32();
|
||||||
m_Dependencies = new SerializedShaderDependency[numDependencies];
|
m_Dependencies = new List<SerializedShaderDependency>();
|
||||||
for (int i = 0; i < numDependencies; i++)
|
for (var i = 0; i < numDependencies; i++)
|
||||||
{
|
{
|
||||||
m_Dependencies[i] = new SerializedShaderDependency(reader);
|
m_Dependencies.Add(new SerializedShaderDependency(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2021) //2021.1 and up
|
if (version >= 2021) //2021.1 and up
|
||||||
{
|
{
|
||||||
int m_CustomEditorForRenderPipelinesSize = reader.ReadInt32();
|
int m_CustomEditorForRenderPipelinesSize = reader.ReadInt32();
|
||||||
m_CustomEditorForRenderPipelines = new SerializedCustomEditorForRenderPipeline[m_CustomEditorForRenderPipelinesSize];
|
m_CustomEditorForRenderPipelines = new List<SerializedCustomEditorForRenderPipeline>();
|
||||||
for (int i = 0; i < m_CustomEditorForRenderPipelinesSize; i++)
|
for (var i = 0; i < m_CustomEditorForRenderPipelinesSize; i++)
|
||||||
{
|
{
|
||||||
m_CustomEditorForRenderPipelines[i] = new SerializedCustomEditorForRenderPipeline(reader);
|
m_CustomEditorForRenderPipelines.Add(new SerializedCustomEditorForRenderPipeline(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -988,18 +918,18 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
|
||||||
var m_DependenciesCount = reader.ReadInt32();
|
var m_DependenciesCount = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_DependenciesCount; i++)
|
for (var i = 0; i < m_DependenciesCount; i++)
|
||||||
{
|
{
|
||||||
new PPtr<Shader>(reader);
|
var m_Dependencies = new PPtr<Shader>(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= 2018)
|
if (version >= 2018)
|
||||||
{
|
{
|
||||||
var m_NonModifiableTexturesCount = reader.ReadInt32();
|
var m_NonModifiableTexturesCount = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_NonModifiableTexturesCount; i++)
|
for (var i = 0; i < m_NonModifiableTexturesCount; i++)
|
||||||
{
|
{
|
||||||
var first = reader.ReadAlignedString();
|
var first = reader.ReadAlignedString();
|
||||||
new PPtr<Texture>(reader);
|
var second = new PPtr<Texture>(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public sealed class SkinnedMeshRenderer : Renderer
|
public sealed class SkinnedMeshRenderer : Renderer
|
||||||
{
|
{
|
||||||
public PPtr<Mesh> m_Mesh;
|
public PPtr<Mesh> m_Mesh;
|
||||||
public PPtr<Transform>[] m_Bones;
|
public List<PPtr<Transform>> m_Bones;
|
||||||
public float[] m_BlendShapeWeights;
|
public float[] m_BlendShapeWeights;
|
||||||
|
|
||||||
public SkinnedMeshRenderer(ObjectReader reader) : base(reader)
|
public SkinnedMeshRenderer(ObjectReader reader) : base(reader)
|
||||||
@@ -25,10 +22,11 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_Mesh = new PPtr<Mesh>(reader);
|
m_Mesh = new PPtr<Mesh>(reader);
|
||||||
|
|
||||||
m_Bones = new PPtr<Transform>[reader.ReadInt32()];
|
var numBones = reader.ReadInt32();
|
||||||
for (int b = 0; b < m_Bones.Length; b++)
|
m_Bones = new List<PPtr<Transform>>();
|
||||||
|
for (var b = 0; b < numBones; b++)
|
||||||
{
|
{
|
||||||
m_Bones[b] = new PPtr<Transform>(reader);
|
m_Bones.Add(new PPtr<Transform>(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (4, 3)) //4.3 and up
|
if (version >= (4, 3)) //4.3 and up
|
||||||
|
|||||||
@@ -79,11 +79,11 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public PPtr<Texture2D> texture;
|
public PPtr<Texture2D> texture;
|
||||||
public PPtr<Texture2D> alphaTexture;
|
public PPtr<Texture2D> alphaTexture;
|
||||||
public SecondarySpriteTexture[] secondaryTextures;
|
public List<SecondarySpriteTexture> secondaryTextures;
|
||||||
public SubMesh[] m_SubMeshes;
|
public List<SubMesh> m_SubMeshes;
|
||||||
public byte[] m_IndexBuffer;
|
public byte[] m_IndexBuffer;
|
||||||
public VertexData m_VertexData;
|
public VertexData m_VertexData;
|
||||||
public SpriteVertex[] vertices;
|
public List<SpriteVertex> vertices;
|
||||||
public ushort[] indices;
|
public ushort[] indices;
|
||||||
public Matrix4x4[] m_Bindpose;
|
public Matrix4x4[] m_Bindpose;
|
||||||
public BoneWeights4[] m_SourceSkin;
|
public BoneWeights4[] m_SourceSkin;
|
||||||
@@ -99,28 +99,25 @@ namespace AssetStudio
|
|||||||
var version = reader.version;
|
var version = reader.version;
|
||||||
|
|
||||||
texture = new PPtr<Texture2D>(reader);
|
texture = new PPtr<Texture2D>(reader);
|
||||||
if (version >= (5, 2)) //5.2 and up
|
alphaTexture = version >= (5, 2) ? new PPtr<Texture2D>(reader) : new PPtr<Texture2D>(); //5.2 and up
|
||||||
{
|
|
||||||
alphaTexture = new PPtr<Texture2D>(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version >= 2019) //2019 and up
|
if (version >= 2019) //2019 and up
|
||||||
{
|
{
|
||||||
var secondaryTexturesSize = reader.ReadInt32();
|
var secondaryTexturesSize = reader.ReadInt32();
|
||||||
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
|
secondaryTextures = new List<SecondarySpriteTexture>();
|
||||||
for (int i = 0; i < secondaryTexturesSize; i++)
|
for (var i = 0; i < secondaryTexturesSize; i++)
|
||||||
{
|
{
|
||||||
secondaryTextures[i] = new SecondarySpriteTexture(reader);
|
secondaryTextures.Add(new SecondarySpriteTexture(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= (5, 6)) //5.6 and up
|
if (version >= (5, 6)) //5.6 and up
|
||||||
{
|
{
|
||||||
var m_SubMeshesSize = reader.ReadInt32();
|
var m_SubMeshesSize = reader.ReadInt32();
|
||||||
m_SubMeshes = new SubMesh[m_SubMeshesSize];
|
m_SubMeshes = new List<SubMesh>();
|
||||||
for (int i = 0; i < m_SubMeshesSize; i++)
|
for (var i = 0; i < m_SubMeshesSize; i++)
|
||||||
{
|
{
|
||||||
m_SubMeshes[i] = new SubMesh(reader);
|
m_SubMeshes.Add(new SubMesh(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_IndexBuffer = reader.ReadUInt8Array();
|
m_IndexBuffer = reader.ReadUInt8Array();
|
||||||
@@ -131,10 +128,10 @@ namespace AssetStudio
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var verticesSize = reader.ReadInt32();
|
var verticesSize = reader.ReadInt32();
|
||||||
vertices = new SpriteVertex[verticesSize];
|
vertices = new List<SpriteVertex>();
|
||||||
for (int i = 0; i < verticesSize; i++)
|
for (var i = 0; i < verticesSize; i++)
|
||||||
{
|
{
|
||||||
vertices[i] = new SpriteVertex(reader);
|
vertices.Add(new SpriteVertex(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
indices = reader.ReadUInt16Array();
|
indices = reader.ReadUInt16Array();
|
||||||
@@ -148,7 +145,9 @@ namespace AssetStudio
|
|||||||
if (version < (2018, 2)) //2018.2 down
|
if (version < (2018, 2)) //2018.2 down
|
||||||
{
|
{
|
||||||
var m_SourceSkinSize = reader.ReadInt32();
|
var m_SourceSkinSize = reader.ReadInt32();
|
||||||
for (int i = 0; i < m_SourceSkinSize; i++)
|
reader.ThrowIfTooLarge(m_SourceSkinSize * 32f);
|
||||||
|
m_SourceSkin = new BoneWeights4[m_SourceSkinSize];
|
||||||
|
for (var i = 0; i < m_SourceSkinSize; i++)
|
||||||
{
|
{
|
||||||
m_SourceSkin[i] = new BoneWeights4(reader);
|
m_SourceSkin[i] = new BoneWeights4(reader);
|
||||||
}
|
}
|
||||||
@@ -204,7 +203,7 @@ namespace AssetStudio
|
|||||||
public string[] m_AtlasTags;
|
public string[] m_AtlasTags;
|
||||||
public PPtr<SpriteAtlas> m_SpriteAtlas;
|
public PPtr<SpriteAtlas> m_SpriteAtlas;
|
||||||
public SpriteRenderData m_RD;
|
public SpriteRenderData m_RD;
|
||||||
public Vector2[][] m_PhysicsShape;
|
//public Vector2[][] m_PhysicsShape;
|
||||||
|
|
||||||
public Sprite(ObjectReader reader) : base(reader)
|
public Sprite(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
@@ -217,7 +216,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
m_PixelsToUnits = reader.ReadSingle();
|
m_PixelsToUnits = reader.ReadSingle();
|
||||||
if (version >= (5, 4, 2)
|
if (version >= (5, 4, 2)
|
||||||
|| version == (5, 4, 1) && buildType.IsPatch && version.Build >= 3) //5.4.1p3 and up
|
|| version == (5, 4, 1) && version.IsPatch && version.Build >= 3) //5.4.1p3 and up
|
||||||
{
|
{
|
||||||
m_Pivot = reader.ReadVector2();
|
m_Pivot = reader.ReadVector2();
|
||||||
}
|
}
|
||||||
@@ -241,17 +240,18 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_RD = new SpriteRenderData(reader);
|
m_RD = new SpriteRenderData(reader);
|
||||||
|
/*
|
||||||
if (version >= 2017) //2017 and up
|
if (version >= 2017) //2017 and up
|
||||||
{
|
{
|
||||||
var m_PhysicsShapeSize = reader.ReadInt32();
|
var m_PhysicsShapeSize = reader.ReadInt32();
|
||||||
m_PhysicsShape = new Vector2[m_PhysicsShapeSize][];
|
var physicsShapeList = new List<Vector2[]>();
|
||||||
for (int i = 0; i < m_PhysicsShapeSize; i++)
|
for (var i = 0; i < m_PhysicsShapeSize; i++)
|
||||||
{
|
{
|
||||||
m_PhysicsShape[i] = reader.ReadVector2Array();
|
physicsShapeList.Add(reader.ReadVector2Array());
|
||||||
}
|
}
|
||||||
|
m_PhysicsShape = physicsShapeList.ToArray();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
//vector m_Bones 2018 and up
|
//vector m_Bones 2018 and up
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -13,7 +14,7 @@ namespace AssetStudio
|
|||||||
public Vector4 uvTransform;
|
public Vector4 uvTransform;
|
||||||
public float downscaleMultiplier;
|
public float downscaleMultiplier;
|
||||||
public SpriteSettings settingsRaw;
|
public SpriteSettings settingsRaw;
|
||||||
public SecondarySpriteTexture[] secondaryTextures;
|
public List<SecondarySpriteTexture> secondaryTextures;
|
||||||
|
|
||||||
public SpriteAtlasData(ObjectReader reader)
|
public SpriteAtlasData(ObjectReader reader)
|
||||||
{
|
{
|
||||||
@@ -32,10 +33,10 @@ namespace AssetStudio
|
|||||||
if (version >= (2020, 2)) //2020.2 and up
|
if (version >= (2020, 2)) //2020.2 and up
|
||||||
{
|
{
|
||||||
var secondaryTexturesSize = reader.ReadInt32();
|
var secondaryTexturesSize = reader.ReadInt32();
|
||||||
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
|
secondaryTextures = new List<SecondarySpriteTexture>();
|
||||||
for (int i = 0; i < secondaryTexturesSize; i++)
|
for (var i = 0; i < secondaryTexturesSize; i++)
|
||||||
{
|
{
|
||||||
secondaryTextures[i] = new SecondarySpriteTexture(reader);
|
secondaryTextures.Add(new SecondarySpriteTexture(reader));
|
||||||
}
|
}
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
@@ -44,24 +45,25 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public sealed class SpriteAtlas : NamedObject
|
public sealed class SpriteAtlas : NamedObject
|
||||||
{
|
{
|
||||||
public PPtr<Sprite>[] m_PackedSprites;
|
public List<PPtr<Sprite>> m_PackedSprites;
|
||||||
|
[JsonConverter(typeof(JsonConverterHelper.RenderDataMapConverter))]
|
||||||
public Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> m_RenderDataMap;
|
public Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> m_RenderDataMap;
|
||||||
public bool m_IsVariant;
|
public bool m_IsVariant;
|
||||||
|
|
||||||
public SpriteAtlas(ObjectReader reader) : base(reader)
|
public SpriteAtlas(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
var m_PackedSpritesSize = reader.ReadInt32();
|
var m_PackedSpritesSize = reader.ReadInt32();
|
||||||
m_PackedSprites = new PPtr<Sprite>[m_PackedSpritesSize];
|
m_PackedSprites = new List<PPtr<Sprite>>();
|
||||||
for (int i = 0; i < m_PackedSpritesSize; i++)
|
for (var i = 0; i < m_PackedSpritesSize; i++)
|
||||||
{
|
{
|
||||||
m_PackedSprites[i] = new PPtr<Sprite>(reader);
|
m_PackedSprites.Add(new PPtr<Sprite>(reader));
|
||||||
}
|
}
|
||||||
|
|
||||||
var m_PackedSpriteNamesToIndex = reader.ReadStringArray();
|
var m_PackedSpriteNamesToIndex = reader.ReadStringArray();
|
||||||
|
|
||||||
var m_RenderDataMapSize = reader.ReadInt32();
|
var m_RenderDataMapSize = reader.ReadInt32();
|
||||||
m_RenderDataMap = new Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>(m_RenderDataMapSize);
|
m_RenderDataMap = new Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>();
|
||||||
for (int i = 0; i < m_RenderDataMapSize; i++)
|
for (var i = 0; i < m_RenderDataMapSize; i++)
|
||||||
{
|
{
|
||||||
var first = new Guid(reader.ReadBytes(16));
|
var first = new Guid(reader.ReadBytes(16));
|
||||||
var second = reader.ReadInt64();
|
var second = reader.ReadInt64();
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public sealed class TextAsset : NamedObject
|
public sealed class TextAsset : NamedObject
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Text.Json;
|
||||||
using Newtonsoft.Json;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -8,15 +8,17 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public int m_Width;
|
public int m_Width;
|
||||||
public int m_Height;
|
public int m_Height;
|
||||||
public int m_CompleteImageSize;
|
public uint m_CompleteImageSize;
|
||||||
public TextureFormat m_TextureFormat;
|
public TextureFormat m_TextureFormat;
|
||||||
public bool m_MipMap;
|
public bool m_MipMap;
|
||||||
public int m_MipCount;
|
public int m_MipCount;
|
||||||
public GLTextureSettings m_TextureSettings;
|
public GLTextureSettings m_TextureSettings;
|
||||||
public int m_ImageCount;
|
public int m_ImageCount;
|
||||||
public byte[] m_PlatformBlob;
|
public byte[] m_PlatformBlob;
|
||||||
|
[JsonPropertyName("image data")]
|
||||||
public ResourceReader image_data;
|
public ResourceReader image_data;
|
||||||
public StreamingInfo m_StreamData;
|
public StreamingInfo m_StreamData;
|
||||||
|
public StreamingInfo m_DataStreamData; //Tuanjie
|
||||||
|
|
||||||
public Texture2D() { }
|
public Texture2D() { }
|
||||||
|
|
||||||
@@ -43,7 +45,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
//var imgActualDataSize = GetImageDataSize(m_TextureFormat);
|
//var imgActualDataSize = GetImageDataSize(m_TextureFormat);
|
||||||
//var mipmapSize = (int)(m_Texture2DArray.m_DataSize / m_Texture2DArray.m_Depth - imgActualDataSize);
|
//var mipmapSize = (int)(m_Texture2DArray.m_DataSize / m_Texture2DArray.m_Depth - imgActualDataSize);
|
||||||
m_CompleteImageSize = (int)m_Texture2DArray.m_DataSize / m_Texture2DArray.m_Depth;
|
m_CompleteImageSize = (uint)(m_Texture2DArray.m_DataSize / m_Texture2DArray.m_Depth);
|
||||||
var offset = layer * m_CompleteImageSize + m_Texture2DArray.image_data.Offset;
|
var offset = layer * m_CompleteImageSize + m_Texture2DArray.image_data.Offset;
|
||||||
|
|
||||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
||||||
@@ -53,9 +55,9 @@ namespace AssetStudio
|
|||||||
byteSize = (uint)(m_Width * m_Height) * 4;
|
byteSize = (uint)(m_Width * m_Height) * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Texture2D(ObjectReader reader, IDictionary typeDict) : base(reader)
|
public Texture2D(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
|
||||||
{
|
{
|
||||||
var parsedTex2d = JsonConvert.DeserializeObject<Texture2D>(JsonConvert.SerializeObject(typeDict));
|
var parsedTex2d = JsonSerializer.Deserialize<Texture2D>(type, jsonOptions);
|
||||||
m_Width = parsedTex2d.m_Width;
|
m_Width = parsedTex2d.m_Width;
|
||||||
m_Height = parsedTex2d.m_Height;
|
m_Height = parsedTex2d.m_Height;
|
||||||
m_CompleteImageSize = parsedTex2d.m_CompleteImageSize;
|
m_CompleteImageSize = parsedTex2d.m_CompleteImageSize;
|
||||||
@@ -70,19 +72,37 @@ namespace AssetStudio
|
|||||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
||||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
||||||
: new ResourceReader(reader, parsedTex2d.image_data.Offset, parsedTex2d.image_data.Size);
|
: new ResourceReader(reader, parsedTex2d.image_data.Offset, parsedTex2d.image_data.Size);
|
||||||
typeDict.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Texture2D(ObjectReader reader) : base(reader)
|
public Texture2D(ObjectReader reader) : base(reader)
|
||||||
{
|
{
|
||||||
m_Width = reader.ReadInt32();
|
m_Width = reader.ReadInt32();
|
||||||
m_Height = reader.ReadInt32();
|
m_Height = reader.ReadInt32();
|
||||||
m_CompleteImageSize = reader.ReadInt32();
|
m_CompleteImageSize = reader.ReadUInt32();
|
||||||
if (version >= 2020) //2020.1 and up
|
if (version >= 2020) //2020.1 and up
|
||||||
{
|
{
|
||||||
var m_MipsStripped = reader.ReadInt32();
|
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();
|
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 < (5, 2)) //5.2 down
|
||||||
{
|
{
|
||||||
m_MipMap = reader.ReadBoolean();
|
m_MipMap = reader.ReadBoolean();
|
||||||
@@ -167,19 +187,19 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
case TextureFormat.ASTC_RGBA_5x5:
|
case TextureFormat.ASTC_RGBA_5x5:
|
||||||
// https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/
|
// https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/
|
||||||
imgDataSize = (int)(Math.Floor((m_Width + 4) / 5f) * Math.Floor((m_Height + 4) / 5f) * 16);
|
imgDataSize = (int)(MathF.Floor((m_Width + 4) / 5f) * MathF.Floor((m_Height + 4) / 5f) * 16);
|
||||||
break;
|
break;
|
||||||
case TextureFormat.ASTC_RGBA_6x6:
|
case TextureFormat.ASTC_RGBA_6x6:
|
||||||
imgDataSize = (int)(Math.Floor((m_Width + 5) / 6f) * Math.Floor((m_Height + 5) / 6f) * 16);
|
imgDataSize = (int)(MathF.Floor((m_Width + 5) / 6f) * MathF.Floor((m_Height + 5) / 6f) * 16);
|
||||||
break;
|
break;
|
||||||
case TextureFormat.ASTC_RGBA_8x8:
|
case TextureFormat.ASTC_RGBA_8x8:
|
||||||
imgDataSize = (int)(Math.Floor((m_Width + 7) / 8f) * Math.Floor((m_Height + 7) / 8f) * 16);
|
imgDataSize = (int)(MathF.Floor((m_Width + 7) / 8f) * MathF.Floor((m_Height + 7) / 8f) * 16);
|
||||||
break;
|
break;
|
||||||
case TextureFormat.ASTC_RGBA_10x10:
|
case TextureFormat.ASTC_RGBA_10x10:
|
||||||
imgDataSize = (int)(Math.Floor((m_Width + 9) / 10f) * Math.Floor((m_Height + 9) / 10f) * 16);
|
imgDataSize = (int)(MathF.Floor((m_Width + 9) / 10f) * MathF.Floor((m_Height + 9) / 10f) * 16);
|
||||||
break;
|
break;
|
||||||
case TextureFormat.ASTC_RGBA_12x12:
|
case TextureFormat.ASTC_RGBA_12x12:
|
||||||
imgDataSize = (int)(Math.Floor((m_Width + 11) / 12f) * Math.Floor((m_Height + 11) / 12f) * 16);
|
imgDataSize = (int)(MathF.Floor((m_Width + 11) / 12f) * MathF.Floor((m_Height + 11) / 12f) * 16);
|
||||||
break;
|
break;
|
||||||
case TextureFormat.DXT1:
|
case TextureFormat.DXT1:
|
||||||
case TextureFormat.EAC_R:
|
case TextureFormat.EAC_R:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Newtonsoft.Json;
|
using System.Collections.Generic;
|
||||||
using System.Collections;
|
using System.Text.Json;
|
||||||
using System.Collections.Generic;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -14,6 +14,7 @@ namespace AssetStudio
|
|||||||
public uint m_DataSize;
|
public uint m_DataSize;
|
||||||
public GLTextureSettings m_TextureSettings;
|
public GLTextureSettings m_TextureSettings;
|
||||||
public int m_ColorSpace;
|
public int m_ColorSpace;
|
||||||
|
[JsonPropertyName("image data")]
|
||||||
public ResourceReader image_data;
|
public ResourceReader image_data;
|
||||||
public StreamingInfo m_StreamData;
|
public StreamingInfo m_StreamData;
|
||||||
public List<Texture2D> TextureList;
|
public List<Texture2D> TextureList;
|
||||||
@@ -21,24 +22,47 @@ namespace AssetStudio
|
|||||||
public Texture2DArray() { }
|
public Texture2DArray() { }
|
||||||
|
|
||||||
public Texture2DArray(ObjectReader reader) : base(reader)
|
public Texture2DArray(ObjectReader reader) : base(reader)
|
||||||
|
{
|
||||||
|
if (version >= 2019) //2019 and up
|
||||||
{
|
{
|
||||||
m_ColorSpace = reader.ReadInt32();
|
m_ColorSpace = reader.ReadInt32();
|
||||||
m_Format = (GraphicsFormat)reader.ReadInt32();
|
m_Format = (GraphicsFormat)reader.ReadInt32();
|
||||||
|
}
|
||||||
m_Width = reader.ReadInt32();
|
m_Width = reader.ReadInt32();
|
||||||
m_Height = reader.ReadInt32();
|
m_Height = reader.ReadInt32();
|
||||||
m_Depth = reader.ReadInt32();
|
m_Depth = reader.ReadInt32();
|
||||||
|
if (version < 2019) //2019 down
|
||||||
|
{
|
||||||
|
m_Format = (GraphicsFormat)reader.ReadInt32();
|
||||||
|
}
|
||||||
m_MipCount = reader.ReadInt32();
|
m_MipCount = reader.ReadInt32();
|
||||||
|
if (version >= (2023, 2)) //2023.2 and up
|
||||||
|
{
|
||||||
|
var m_MipsStripped = reader.ReadInt32();
|
||||||
|
}
|
||||||
m_DataSize = reader.ReadUInt32();
|
m_DataSize = reader.ReadUInt32();
|
||||||
m_TextureSettings = new GLTextureSettings(reader);
|
m_TextureSettings = new GLTextureSettings(reader);
|
||||||
|
if (version < 2019) //2019 down
|
||||||
|
{
|
||||||
|
m_ColorSpace = reader.ReadInt32();
|
||||||
|
}
|
||||||
if (version >= (2020, 2)) //2020.2 and up
|
if (version >= (2020, 2)) //2020.2 and up
|
||||||
{
|
{
|
||||||
var m_UsageMode = reader.ReadInt32();
|
var m_UsageMode = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
var m_IsReadable = reader.ReadBoolean();
|
var m_IsReadable = reader.ReadBoolean();
|
||||||
|
if (version > (2023, 2)) //2023.2 and up
|
||||||
|
{
|
||||||
|
var m_IgnoreMipmapLimit = reader.ReadBoolean();
|
||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
|
var m_MipmapLimitGroupName = reader.ReadAlignedString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reader.AlignStream();
|
||||||
|
}
|
||||||
var image_data_size = reader.ReadInt32();
|
var image_data_size = reader.ReadInt32();
|
||||||
if (image_data_size == 0)
|
if (image_data_size == 0 && version >= (5, 6)) //5.6 and up
|
||||||
{
|
{
|
||||||
m_StreamData = new StreamingInfo(reader);
|
m_StreamData = new StreamingInfo(reader);
|
||||||
}
|
}
|
||||||
@@ -50,9 +74,9 @@ namespace AssetStudio
|
|||||||
TextureList = new List<Texture2D>();
|
TextureList = new List<Texture2D>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Texture2DArray(ObjectReader reader, IDictionary typeDict) : base(reader)
|
public Texture2DArray(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
|
||||||
{
|
{
|
||||||
var parsedTex2dArray = JsonConvert.DeserializeObject<Texture2DArray>(JsonConvert.SerializeObject(typeDict));
|
var parsedTex2dArray = JsonSerializer.Deserialize<Texture2DArray>(type, jsonOptions);
|
||||||
m_Width = parsedTex2dArray.m_Width;
|
m_Width = parsedTex2dArray.m_Width;
|
||||||
m_Height = parsedTex2dArray.m_Height;
|
m_Height = parsedTex2dArray.m_Height;
|
||||||
m_Depth = parsedTex2dArray.m_Depth;
|
m_Depth = parsedTex2dArray.m_Depth;
|
||||||
@@ -65,7 +89,6 @@ namespace AssetStudio
|
|||||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
||||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
||||||
: new ResourceReader(reader, parsedTex2dArray.image_data.Offset, parsedTex2dArray.image_data.Size);
|
: new ResourceReader(reader, parsedTex2dArray.image_data.Offset, parsedTex2dArray.image_data.Size);
|
||||||
typeDict.Clear();
|
|
||||||
|
|
||||||
TextureList = new List<Texture2D>();
|
TextureList = new List<Texture2D>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -10,7 +7,7 @@ namespace AssetStudio
|
|||||||
public Quaternion m_LocalRotation;
|
public Quaternion m_LocalRotation;
|
||||||
public Vector3 m_LocalPosition;
|
public Vector3 m_LocalPosition;
|
||||||
public Vector3 m_LocalScale;
|
public Vector3 m_LocalScale;
|
||||||
public PPtr<Transform>[] m_Children;
|
public List<PPtr<Transform>> m_Children;
|
||||||
public PPtr<Transform> m_Father;
|
public PPtr<Transform> m_Father;
|
||||||
|
|
||||||
public Transform(ObjectReader reader) : base(reader)
|
public Transform(ObjectReader reader) : base(reader)
|
||||||
@@ -20,10 +17,10 @@ namespace AssetStudio
|
|||||||
m_LocalScale = reader.ReadVector3();
|
m_LocalScale = reader.ReadVector3();
|
||||||
|
|
||||||
int m_ChildrenCount = reader.ReadInt32();
|
int m_ChildrenCount = reader.ReadInt32();
|
||||||
m_Children = new PPtr<Transform>[m_ChildrenCount];
|
m_Children = new List<PPtr<Transform>>();
|
||||||
for (int i = 0; i < m_ChildrenCount; i++)
|
for (var i = 0; i < m_ChildrenCount; i++)
|
||||||
{
|
{
|
||||||
m_Children[i] = new PPtr<Transform>(reader);
|
m_Children.Add(new PPtr<Transform>(reader));
|
||||||
}
|
}
|
||||||
m_Father = new PPtr<Transform>(reader);
|
m_Father = new PPtr<Transform>(reader);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,9 @@ namespace AssetStudio
|
|||||||
if (version >= 2020) //2020.1 and up
|
if (version >= 2020) //2020.1 and up
|
||||||
{
|
{
|
||||||
var m_VideoShadersSize = reader.ReadInt32();
|
var m_VideoShadersSize = reader.ReadInt32();
|
||||||
var m_VideoShaders = new PPtr<Shader>[m_VideoShadersSize];
|
for (var i = 0; i < m_VideoShadersSize; i++)
|
||||||
for (int i = 0; i < m_VideoShadersSize; i++)
|
|
||||||
{
|
{
|
||||||
m_VideoShaders[i] = new PPtr<Shader>(reader);
|
var m_VideoShaders = new PPtr<Shader>(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_ExternalResources = new StreamedResource(reader);
|
m_ExternalResources = new StreamedResource(reader);
|
||||||
|
|||||||
@@ -28,13 +28,22 @@ namespace AssetStudio
|
|||||||
public static string Color(this string str, string ansiColor)
|
public static string Color(this string str, string ansiColor)
|
||||||
{
|
{
|
||||||
if (!ColorConsoleHelper.isAnsiCodesSupported)
|
if (!ColorConsoleHelper.isAnsiCodesSupported)
|
||||||
{
|
|
||||||
return str;
|
return str;
|
||||||
}
|
|
||||||
|
|
||||||
return $"{ansiColor}{str}{Reset}";
|
return $"{ansiColor}{str}{Reset}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string ColorIf(this string str, bool isTrue, string ansiColor, string defaultAnsiColor = null)
|
||||||
|
{
|
||||||
|
if (isTrue)
|
||||||
|
return str.Color(ansiColor);
|
||||||
|
|
||||||
|
if (defaultAnsiColor != null)
|
||||||
|
return str.Color(defaultAnsiColor);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
public static void AnsiCodesTest()
|
public static void AnsiCodesTest()
|
||||||
{
|
{
|
||||||
Console.WriteLine("ANSI escape codes test");
|
Console.WriteLine("ANSI escape codes test");
|
||||||
@@ -45,5 +54,4 @@ namespace AssetStudio
|
|||||||
Console.WriteLine("\u001b[34;1m E \u001b[35;1m F \u001b[36;1m G \u001b[37;1m H \u001b[0m");
|
Console.WriteLine("\u001b[34;1m E \u001b[35;1m F \u001b[36;1m G \u001b[37;1m H \u001b[0m");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,10 @@ namespace AssetStudio
|
|||||||
{1121, "m_PrefabInstance"},
|
{1121, "m_PrefabInstance"},
|
||||||
{1138, "m_PrefabAsset"},
|
{1138, "m_PrefabAsset"},
|
||||||
{1152, "FileSize"},
|
{1152, "FileSize"},
|
||||||
{1161, "Hash128"}
|
{1161, "Hash128"},
|
||||||
|
{1169, "RenderingLayerMask"},
|
||||||
|
{1188, "fixed_array"},
|
||||||
|
{1200, "EntityId"},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
133
AssetStudio/CubismMoc.cs
Normal file
133
AssetStudio/CubismMoc.cs
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,149 +1,31 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using static AssetStudio.EndianSpanReader;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public enum CubismSDKVersion : byte
|
public class CubismModel
|
||||||
{
|
{
|
||||||
V30 = 1,
|
public string Name { get; set; }
|
||||||
V33,
|
public string Container { get; set; }
|
||||||
V40,
|
public MonoBehaviour CubismModelMono { get; set; }
|
||||||
V42,
|
public MonoBehaviour PhysicsController { get; set; }
|
||||||
V50
|
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 sealed class CubismModel : IDisposable
|
public CubismModel(GameObject m_GameObject)
|
||||||
{
|
{
|
||||||
public CubismSDKVersion Version { get; }
|
Name = m_GameObject.m_Name;
|
||||||
public string VersionDescription { get; }
|
ModelGameObject = m_GameObject;
|
||||||
public float CanvasWidth { get; }
|
RenderTextureList = new List<MonoBehaviour>();
|
||||||
public float CanvasHeight { get; }
|
ParamDisplayInfoList = new List<MonoBehaviour>();
|
||||||
public float CentralPosX { get; }
|
PartDisplayInfoList = new List<MonoBehaviour>();
|
||||||
public float CentralPosY { get; }
|
PosePartList = new List<MonoBehaviour>();
|
||||||
public float PixelPerUnit { get; }
|
ClipMotionList = new List<AnimationClip>();
|
||||||
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 CubismModel(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);
|
|
||||||
|
|
||||||
//offsets
|
|
||||||
var countInfoTableOffset = (int)SpanToUint32(modelData, 64, isBigEndian);
|
|
||||||
var canvasInfoOffset = (int)SpanToUint32(modelData, 68, isBigEndian);
|
|
||||||
var partIdsOffset = SpanToUint32(modelData, 76, isBigEndian);
|
|
||||||
var parameterIdsOffset = SpanToUint32(modelData, 264, isBigEndian);
|
|
||||||
|
|
||||||
//canvas
|
|
||||||
PixelPerUnit = ToSingle(modelData, canvasInfoOffset, isBigEndian);
|
|
||||||
CentralPosX = ToSingle(modelData, canvasInfoOffset + 4, isBigEndian);
|
|
||||||
CentralPosY = ToSingle(modelData, canvasInfoOffset + 8, isBigEndian);
|
|
||||||
CanvasWidth = ToSingle(modelData, canvasInfoOffset + 12, isBigEndian);
|
|
||||||
CanvasHeight = ToSingle(modelData, canvasInfoOffset + 16, isBigEndian);
|
|
||||||
|
|
||||||
//model
|
|
||||||
PartCount = SpanToUint32(modelData, countInfoTableOffset, isBigEndian);
|
|
||||||
ParamCount = SpanToUint32(modelData, countInfoTableOffset + 20, isBigEndian);
|
|
||||||
PartNames = ReadMocStringHashSet(modelData, (int)partIdsOffset, (int)PartCount);
|
|
||||||
ParamNames = ReadMocStringHashSet(modelData, (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 float ToSingle(ReadOnlySpan<byte> data, int index, bool isBigEndian) //net framework ver
|
|
||||||
{
|
|
||||||
var bytes = data.Slice(index, index + 4).ToArray();
|
|
||||||
if ((isBigEndian && BitConverter.IsLittleEndian) || (!isBigEndian && !BitConverter.IsLittleEndian))
|
|
||||||
(bytes[0], bytes[1], bytes[2], bytes[3]) = (bytes[3], bytes[2], bytes[1], bytes[0]);
|
|
||||||
|
|
||||||
return BitConverter.ToSingle(bytes, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HashSet<string> ReadMocStringHashSet(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 buff = data.Slice(index + i * strLen, strLen);
|
|
||||||
strHashSet.Add(Encoding.UTF8.GetString(buff.ToArray()).TrimEnd('\0'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strHashSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
BigArrayPool<byte>.Shared.Return(modelData, clearArray: true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
56
AssetStudio/CustomOptions/Asmo/OptionsFile.cs
Normal file
56
AssetStudio/CustomOptions/Asmo/OptionsFile.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
AssetStudio/CustomOptions/CustomBundleOptions.cs
Normal file
40
AssetStudio/CustomOptions/CustomBundleOptions.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
94
AssetStudio/CustomOptions/ImportOptions.cs
Normal file
94
AssetStudio/CustomOptions/ImportOptions.cs
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,12 +82,13 @@ namespace AssetStudio
|
|||||||
return base.ReadUInt64();
|
return base.ReadUInt64();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if NETFRAMEWORK
|
||||||
public override float ReadSingle()
|
public override float ReadSingle()
|
||||||
{
|
{
|
||||||
if (Endian == EndianType.BigEndian)
|
if (Endian == EndianType.BigEndian)
|
||||||
{
|
{
|
||||||
Read(buffer, 0, 4);
|
Read(buffer, 0, 4);
|
||||||
Array.Reverse(buffer, 0, 4);
|
buffer.AsSpan(0, 4).Reverse();
|
||||||
return BitConverter.ToSingle(buffer, 0);
|
return BitConverter.ToSingle(buffer, 0);
|
||||||
}
|
}
|
||||||
return base.ReadSingle();
|
return base.ReadSingle();
|
||||||
@@ -98,10 +99,31 @@ namespace AssetStudio
|
|||||||
if (Endian == EndianType.BigEndian)
|
if (Endian == EndianType.BigEndian)
|
||||||
{
|
{
|
||||||
Read(buffer, 0, 8);
|
Read(buffer, 0, 8);
|
||||||
Array.Reverse(buffer);
|
buffer.AsSpan().Reverse();
|
||||||
return BitConverter.ToDouble(buffer, 0);
|
return BitConverter.ToDouble(buffer, 0);
|
||||||
}
|
}
|
||||||
return base.ReadDouble();
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,95 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public static class EndianSpanReader
|
public static class EndianSpanReader
|
||||||
{
|
{
|
||||||
public static uint SpanToUint32(Span<byte> data, int start, bool isBigEndian)
|
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
|
return isBigEndian
|
||||||
? BinaryPrimitives.ReadUInt32BigEndian(data.Slice(start))
|
? BinaryPrimitives.ReadUInt32BigEndian(data.Slice(start))
|
||||||
: BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(start));
|
: BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(start));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static uint SpanToUint16(Span<byte> data, int start, bool isBigEndian)
|
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
|
return isBigEndian
|
||||||
? BinaryPrimitives.ReadUInt16BigEndian(data.Slice(start))
|
? BinaryPrimitives.ReadUInt16BigEndian(data.Slice(start))
|
||||||
: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(start));
|
: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(start));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long SpanToInt64(Span<byte> data, int start, bool isBigEndian)
|
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
|
return isBigEndian
|
||||||
? BinaryPrimitives.ReadInt64BigEndian(data.Slice(start))
|
? BinaryPrimitives.ReadInt64BigEndian(data.Slice(start))
|
||||||
: BinaryPrimitives.ReadInt64LittleEndian(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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public static class BinaryReaderExtensions
|
public static class BinaryReaderExtensions
|
||||||
{
|
{
|
||||||
public static void AlignStream(this BinaryReader reader)
|
public static void AlignStream(this BinaryReader reader, int alignment = 4)
|
||||||
{
|
|
||||||
reader.AlignStream(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AlignStream(this BinaryReader reader, int alignment)
|
|
||||||
{
|
{
|
||||||
var pos = reader.BaseStream.Position;
|
var pos = reader.BaseStream.Position;
|
||||||
var mod = pos % alignment;
|
var mod = pos % alignment;
|
||||||
@@ -25,11 +21,13 @@ namespace AssetStudio
|
|||||||
public static string ReadAlignedString(this BinaryReader reader)
|
public static string ReadAlignedString(this BinaryReader reader)
|
||||||
{
|
{
|
||||||
var length = reader.ReadInt32();
|
var length = reader.ReadInt32();
|
||||||
if (length > 0 && length <= reader.BaseStream.Length - reader.BaseStream.Position)
|
if (length > reader.BaseStream.Length - reader.BaseStream.Position)
|
||||||
|
throw new EndOfStreamException();
|
||||||
|
if (length > 0)
|
||||||
{
|
{
|
||||||
var stringData = reader.ReadBytes(length);
|
var stringData = reader.ReadBytes(length);
|
||||||
var result = Encoding.UTF8.GetString(stringData);
|
var result = Encoding.UTF8.GetString(stringData);
|
||||||
reader.AlignStream(4);
|
reader.AlignStream();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
@@ -53,7 +51,11 @@ namespace AssetStudio
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
bytes = bytes.Slice(0, count);
|
bytes = bytes.Slice(0, count);
|
||||||
|
#if NETFRAMEWORK
|
||||||
return encoding?.GetString(bytes.ToArray()) ?? Encoding.UTF8.GetString(bytes.ToArray());
|
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)
|
private static string ReadUnicodeStringToNull(this BinaryReader reader, int maxLength)
|
||||||
@@ -98,24 +100,22 @@ namespace AssetStudio
|
|||||||
return new Color(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
return new Color(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Matrix4x4 ReadMatrix(this BinaryReader reader)
|
private static T[] ReadArray<T>(BinaryReader reader, int byteLen) where T : struct
|
||||||
{
|
{
|
||||||
return new Matrix4x4(reader.ReadSingleArray(16));
|
if (byteLen < 0)
|
||||||
}
|
throw new ArgumentOutOfRangeException(nameof(byteLen));
|
||||||
|
if (reader.BaseStream.Position + byteLen > reader.BaseStream.Length)
|
||||||
|
throw new EndOfStreamException();
|
||||||
|
|
||||||
private static T[] ReadArray<T>(Func<T> del, int length)
|
var bytes = reader.ReadBytes(byteLen);
|
||||||
{
|
|
||||||
var array = new T[length];
|
var span = MemoryMarshal.Cast<byte, T>(bytes);
|
||||||
for (int i = 0; i < length; i++)
|
return span.ToArray();
|
||||||
{
|
|
||||||
array[i] = del();
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool[] ReadBooleanArray(this BinaryReader reader)
|
public static bool[] ReadBooleanArray(this BinaryReader reader)
|
||||||
{
|
{
|
||||||
return ReadArray(reader.ReadBoolean, reader.ReadInt32());
|
return ReadArray<bool>(reader, reader.ReadInt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] ReadUInt8Array(this BinaryReader reader)
|
public static byte[] ReadUInt8Array(this BinaryReader reader)
|
||||||
@@ -125,62 +125,65 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public static ushort[] ReadUInt16Array(this BinaryReader reader)
|
public static ushort[] ReadUInt16Array(this BinaryReader reader)
|
||||||
{
|
{
|
||||||
return ReadArray(reader.ReadUInt16, reader.ReadInt32());
|
return ReadArray<ushort>(reader, reader.ReadInt32() * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] ReadInt32Array(this BinaryReader reader)
|
public static int[] ReadInt32Array(this BinaryReader reader, int length = -1)
|
||||||
{
|
{
|
||||||
return ReadArray(reader.ReadInt32, reader.ReadInt32());
|
if (length == -1)
|
||||||
|
length = reader.ReadInt32();
|
||||||
|
return ReadArray<int>(reader, length * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] ReadInt32Array(this BinaryReader reader, int length)
|
public static uint[] ReadUInt32Array(this BinaryReader reader, int length = -1)
|
||||||
{
|
{
|
||||||
return ReadArray(reader.ReadInt32, length);
|
if (length == -1)
|
||||||
}
|
length = reader.ReadInt32();
|
||||||
|
return ReadArray<uint>(reader, length * 4);
|
||||||
public static uint[] ReadUInt32Array(this BinaryReader reader)
|
|
||||||
{
|
|
||||||
return ReadArray(reader.ReadUInt32, reader.ReadInt32());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static uint[][] ReadUInt32ArrayArray(this BinaryReader reader)
|
public static uint[][] ReadUInt32ArrayArray(this BinaryReader reader)
|
||||||
{
|
{
|
||||||
return ReadArray(reader.ReadUInt32Array, reader.ReadInt32());
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static uint[] ReadUInt32Array(this BinaryReader reader, int length)
|
public static float[] ReadSingleArray(this BinaryReader reader, int length = -1)
|
||||||
{
|
{
|
||||||
return ReadArray(reader.ReadUInt32, length);
|
if (length == -1)
|
||||||
}
|
length = reader.ReadInt32();
|
||||||
|
return ReadArray<float>(reader, length * 4);
|
||||||
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)
|
public static string[] ReadStringArray(this BinaryReader reader)
|
||||||
{
|
{
|
||||||
return ReadArray(reader.ReadAlignedString, reader.ReadInt32());
|
var length = reader.ReadInt32();
|
||||||
|
var list = new List<string>();
|
||||||
|
for (var i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
list.Add(reader.ReadAlignedString());
|
||||||
|
}
|
||||||
|
return list.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector2[] ReadVector2Array(this BinaryReader reader)
|
public static Vector2[] ReadVector2Array(this BinaryReader reader)
|
||||||
{
|
{
|
||||||
return ReadArray(reader.ReadVector2, reader.ReadInt32());
|
return ReadArray<Vector2>(reader, reader.ReadInt32() * 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector4[] ReadVector4Array(this BinaryReader reader)
|
public static Vector4[] ReadVector4Array(this BinaryReader reader)
|
||||||
{
|
{
|
||||||
return ReadArray(reader.ReadVector4, reader.ReadInt32());
|
return ReadArray<Vector4>(reader, reader.ReadInt32() * 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Matrix4x4[] ReadMatrixArray(this BinaryReader reader)
|
public static Matrix4x4[] ReadMatrixArray(this BinaryReader reader)
|
||||||
{
|
{
|
||||||
return ReadArray(reader.ReadMatrix, reader.ReadInt32());
|
return ReadArray<Matrix4x4>(reader, reader.ReadInt32() * 64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using static AssetStudio.EndianSpanReader;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -14,6 +13,9 @@ namespace AssetStudio
|
|||||||
private static readonly byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
|
private static readonly byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
|
||||||
private static readonly byte[] zipMagic = { 0x50, 0x4B, 0x03, 0x04 };
|
private static readonly byte[] zipMagic = { 0x50, 0x4B, 0x03, 0x04 };
|
||||||
private static readonly byte[] zipSpannedMagic = { 0x50, 0x4B, 0x07, 0x08 };
|
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)) { }
|
public FileReader(string path) : this(path, File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { }
|
||||||
|
|
||||||
@@ -26,30 +28,34 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private FileType CheckFileType()
|
private FileType CheckFileType()
|
||||||
{
|
{
|
||||||
var signature = this.ReadStringToNull(20);
|
var buff = headerBuff.AsSpan();
|
||||||
|
buff.Clear();
|
||||||
|
var dataLen = Read(headerBuff, 0, headerBuffLen);
|
||||||
Position = 0;
|
Position = 0;
|
||||||
|
|
||||||
|
var signature = buff.ReadStringToNull(20);
|
||||||
switch (signature)
|
switch (signature)
|
||||||
{
|
{
|
||||||
case "UnityWeb":
|
case "UnityWeb":
|
||||||
case "UnityRaw":
|
case "UnityRaw":
|
||||||
case "UnityArchive":
|
case "UnityArchive":
|
||||||
case "UnityFS":
|
case "UnityFS":
|
||||||
|
CheckBundleDataOffset(buff);
|
||||||
return FileType.BundleFile;
|
return FileType.BundleFile;
|
||||||
case "UnityWebData1.0":
|
case "UnityWebData1.0":
|
||||||
|
case "TuanjieWebData1.0":
|
||||||
return FileType.WebFile;
|
return FileType.WebFile;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
var buff = ReadBytes(40).AsSpan();
|
|
||||||
var magic = Span<byte>.Empty;
|
var magic = Span<byte>.Empty;
|
||||||
Position = 0;
|
|
||||||
|
|
||||||
magic = buff.Length > 2 ? buff.Slice(0, 2) : magic;
|
magic = dataLen > 2 ? buff.Slice(0, 2) : magic;
|
||||||
if (magic.SequenceEqual(gzipMagic))
|
if (magic.SequenceEqual(gzipMagic))
|
||||||
{
|
{
|
||||||
return FileType.GZipFile;
|
return FileType.GZipFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
magic = buff.Length > 38 ? buff.Slice(32, 6) : magic;
|
magic = dataLen > 38 ? buff.Slice(32, 6) : magic;
|
||||||
if (magic.SequenceEqual(brotliMagic))
|
if (magic.SequenceEqual(brotliMagic))
|
||||||
{
|
{
|
||||||
return FileType.BrotliFile;
|
return FileType.BrotliFile;
|
||||||
@@ -60,18 +66,23 @@ namespace AssetStudio
|
|||||||
return FileType.AssetsFile;
|
return FileType.AssetsFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
magic = buff.Length > 4 ? buff.Slice(0, 4): magic;
|
magic = dataLen > 4 ? buff.Slice(0, 4): magic;
|
||||||
if (magic.SequenceEqual(zipMagic) || magic.SequenceEqual(zipSpannedMagic))
|
if (magic.SequenceEqual(zipMagic) || magic.SequenceEqual(zipSpannedMagic))
|
||||||
{
|
{
|
||||||
return FileType.ZipFile;
|
return FileType.ZipFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CheckBundleDataOffset(buff))
|
||||||
|
{
|
||||||
|
return FileType.BundleFile;
|
||||||
|
}
|
||||||
|
|
||||||
return FileType.ResourceFile;
|
return FileType.ResourceFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsSerializedFile(Span<byte> buff)
|
private bool IsSerializedFile(ReadOnlySpan<byte> buff)
|
||||||
{
|
{
|
||||||
var fileSize = BaseStream.Length;
|
var fileSize = BaseStream.Length;
|
||||||
if (fileSize < 20)
|
if (fileSize < 20)
|
||||||
@@ -80,10 +91,10 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
var isBigEndian = Endian == EndianType.BigEndian;
|
var isBigEndian = Endian == EndianType.BigEndian;
|
||||||
|
|
||||||
//var m_MetadataSize = SpanToUint32(buff, 0, isBigEndian);
|
//var m_MetadataSize = buff.ReadUInt32(0, isBigEndian);
|
||||||
long m_FileSize = SpanToUint32(buff, 4, isBigEndian);
|
long m_FileSize = buff.ReadUInt32(4, isBigEndian);
|
||||||
var m_Version = SpanToUint32(buff, 8, isBigEndian);
|
var m_Version = buff.ReadUInt32(8, isBigEndian);
|
||||||
long m_DataOffset = SpanToUint32(buff, 12, isBigEndian);
|
long m_DataOffset = buff.ReadUInt32(12, isBigEndian);
|
||||||
//var m_Endianess = buff[16];
|
//var m_Endianess = buff[16];
|
||||||
//var m_Reserved = buff.Slice(17, 3);
|
//var m_Reserved = buff.Slice(17, 3);
|
||||||
if (m_Version >= 22)
|
if (m_Version >= 22)
|
||||||
@@ -92,9 +103,9 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//m_MetadataSize = SpanToUint32(buff, 20, isBigEndian);
|
//m_MetadataSize = buff.ReadUInt32(20, isBigEndian);
|
||||||
m_FileSize = SpanToInt64(buff, 24, isBigEndian);
|
m_FileSize = buff.ReadInt64(24, isBigEndian);
|
||||||
m_DataOffset = SpanToInt64(buff, 32, isBigEndian);
|
m_DataOffset = buff.ReadInt64(32, isBigEndian);
|
||||||
}
|
}
|
||||||
if (m_FileSize != fileSize || m_DataOffset > fileSize)
|
if (m_FileSize != fileSize || m_DataOffset > fileSize)
|
||||||
{
|
{
|
||||||
@@ -103,5 +114,32 @@ namespace AssetStudio
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool CheckBundleDataOffset(ReadOnlySpan<byte> buff)
|
||||||
|
{
|
||||||
|
var lastOffset = buff.LastIndexOf(unityFsMagic);
|
||||||
|
if (lastOffset <= 0)
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace AssetStudio
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
|
||||||
{
|
{
|
||||||
public enum FileType
|
public enum FileType
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,13 +68,15 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
catch (System.Exception e)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
Logger.Warning($"Error while decompressing gzip file {reader.FullPath}\r\n{e}");
|
Logger.Warning($"Error while decompressing Gzip file {reader.FullPath}\n{e}");
|
||||||
reader.Dispose();
|
reader.Dispose();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FileReader DecompressBrotli(FileReader reader)
|
public static FileReader DecompressBrotli(FileReader reader)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using (reader)
|
using (reader)
|
||||||
{
|
{
|
||||||
@@ -87,5 +89,12 @@ namespace AssetStudio
|
|||||||
return new FileReader(reader.FullPath, stream);
|
return new FileReader(reader.FullPath, stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (System.Exception e)
|
||||||
|
{
|
||||||
|
Logger.Warning($"Error while decompressing Brotli file {reader.FullPath}\n{e}");
|
||||||
|
reader.Dispose();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
AssetStudio/JsonConverterHelpers/ByteArrayConverter.cs
Normal file
25
AssetStudio/JsonConverterHelpers/ByteArrayConverter.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
AssetStudio/JsonConverterHelpers/FloatConverter.cs
Normal file
40
AssetStudio/JsonConverterHelpers/FloatConverter.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
AssetStudio/JsonConverterHelpers/KVPConverter.cs
Normal file
53
AssetStudio/JsonConverterHelpers/KVPConverter.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
45
AssetStudio/JsonConverterHelpers/PPtrConverter.cs
Normal file
45
AssetStudio/JsonConverterHelpers/PPtrConverter.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
58
AssetStudio/JsonConverterHelpers/RenderDataMapConverter.cs
Normal file
58
AssetStudio/JsonConverterHelpers/RenderDataMapConverter.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
AssetStudio/Math/Clamp.cs
Normal file
18
AssetStudio/Math/Clamp.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
|
#if NETFRAMEWORK
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -35,27 +36,27 @@ namespace AssetStudio
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the smallest positive System.Half value greater than zero. This field is constant.
|
/// Represents the smallest positive System.Half value greater than zero. This field is constant.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Half Epsilon = Half.ToHalf(0x0001);
|
public static readonly Half Epsilon = HalfHelper.ToHalf(0x0001);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the largest possible value of System.Half. This field is constant.
|
/// Represents the largest possible value of System.Half. This field is constant.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Half MaxValue = Half.ToHalf(0x7bff);
|
public static readonly Half MaxValue = HalfHelper.ToHalf(0x7bff);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the smallest possible value of System.Half. This field is constant.
|
/// Represents the smallest possible value of System.Half. This field is constant.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Half MinValue = Half.ToHalf(0xfbff);
|
public static readonly Half MinValue = HalfHelper.ToHalf(0xfbff);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents not a number (NaN). This field is constant.
|
/// Represents not a number (NaN). This field is constant.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Half NaN = Half.ToHalf(0xfe00);
|
public static readonly Half NaN = HalfHelper.ToHalf(0xfe00);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents negative infinity. This field is constant.
|
/// Represents negative infinity. This field is constant.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Half NegativeInfinity = Half.ToHalf(0xfc00);
|
public static readonly Half NegativeInfinity = HalfHelper.ToHalf(0xfc00);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents positive infinity. This field is constant.
|
/// Represents positive infinity. This field is constant.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly Half PositiveInfinity = Half.ToHalf(0x7c00);
|
public static readonly Half PositiveInfinity = HalfHelper.ToHalf(0x7c00);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
@@ -63,7 +64,7 @@ namespace AssetStudio
|
|||||||
/// Initializes a new instance of System.Half to the value of the specified single-precision floating-point number.
|
/// Initializes a new instance of System.Half to the value of the specified single-precision floating-point number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The value to represent as a System.Half.</param>
|
/// <param name="value">The value to represent as a System.Half.</param>
|
||||||
public Half(float value) { this = HalfHelper.SingleToHalf(value); }
|
public Half(float value) { this = HalfHelper.ToHalf(value); }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of System.Half to the value of the specified 32-bit signed integer.
|
/// Initializes a new instance of System.Half to the value of the specified 32-bit signed integer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -314,7 +315,7 @@ namespace AssetStudio
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">A System.Half to convert.</param>
|
/// <param name="value">A System.Half to convert.</param>
|
||||||
/// <returns>A single-precision floating-point number that represents the converted System.Half.</returns>
|
/// <returns>A single-precision floating-point number that represents the converted System.Half.</returns>
|
||||||
public static implicit operator float(Half value) { return (float)HalfHelper.HalfToSingle(value); }
|
public static implicit operator float(Half value) { return value.ToSingle(); }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a System.Half to a double-precision floating-point number.
|
/// Converts a System.Half to a double-precision floating-point number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -508,32 +509,6 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
return value.value;
|
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>
|
/// <summary>
|
||||||
/// Returns a value indicating the sign of a half-precision floating-point number.
|
/// Returns a value indicating the sign of a half-precision floating-point number.
|
||||||
@@ -886,3 +861,4 @@ namespace AssetStudio
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,18 +1,32 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Buffers.Binary;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace AssetStudio
|
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>
|
/// <summary>
|
||||||
/// Helper class for Half conversions and some low level operations.
|
/// Helper class for Half conversions and some low level operations.
|
||||||
/// This class is internally used in the Half class.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// References:
|
/// References:
|
||||||
/// - Fast Half Float Conversions, Jeroen van der Zijp, link: http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
|
/// - Fast Half Float Conversions, Jeroen van der Zijp, link: http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[ComVisible(false)]
|
[ComVisible(false)]
|
||||||
internal static class HalfHelper
|
public static class HalfHelper
|
||||||
{
|
{
|
||||||
private static uint[] mantissaTable = GenerateMantissaTable();
|
private static uint[] mantissaTable = GenerateMantissaTable();
|
||||||
private static uint[] exponentTable = GenerateExponentTable();
|
private static uint[] exponentTable = GenerateExponentTable();
|
||||||
@@ -169,27 +183,54 @@ namespace AssetStudio
|
|||||||
ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23]));
|
ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23]));
|
||||||
return Half.ToHalf(result);
|
return Half.ToHalf(result);
|
||||||
}*/
|
}*/
|
||||||
public static float HalfToSingle(Half half)
|
|
||||||
|
/// <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)
|
||||||
{
|
{
|
||||||
uint result = mantissaTable[offsetTable[half.value >> 10] + (half.value & 0x3ff)] + exponentTable[half.value >> 10];
|
uint result = mantissaTable[offsetTable[half.value >> 10] + (half.value & 0x3ff)] + exponentTable[half.value >> 10];
|
||||||
byte[] uintBytes = BitConverter.GetBytes(result);
|
byte[] uintBytes = BitConverter.GetBytes(result);
|
||||||
return BitConverter.ToSingle(uintBytes, 0);
|
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)
|
public static Half Negate(Half half)
|
||||||
{
|
{
|
||||||
return Half.ToHalf((ushort)(half.value ^ 0x8000));
|
return ToHalf((ushort)(half.value ^ 0x8000));
|
||||||
}
|
}
|
||||||
public static Half Abs(Half half)
|
public static Half Abs(Half half)
|
||||||
{
|
{
|
||||||
return Half.ToHalf((ushort)(half.value & 0x7fff));
|
return ToHalf((ushort)(half.value & 0x7fff));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsNaN(Half half)
|
public static bool IsNaN(Half half)
|
||||||
@@ -209,4 +250,5 @@ namespace AssetStudio
|
|||||||
return (half.value == 0xfc00);
|
return (half.value == 0xfc00);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ namespace AssetStudio
|
|||||||
public float M23;
|
public float M23;
|
||||||
public float M33;
|
public float M33;
|
||||||
|
|
||||||
public Matrix4x4(float[] values)
|
public Matrix4x4(Span<float> values)
|
||||||
{
|
{
|
||||||
if (values == null)
|
if (values.IsEmpty)
|
||||||
throw new ArgumentNullException(nameof(values));
|
throw new ArgumentNullException(nameof(values));
|
||||||
if (values.Length != 16)
|
if (values.Length != 16)
|
||||||
throw new ArgumentOutOfRangeException(nameof(values), "There must be sixteen and only sixteen input values for Matrix.");
|
throw new ArgumentOutOfRangeException(nameof(values), "There must be sixteen and only sixteen input values for Matrix.");
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public override bool Equals(object other)
|
public override bool Equals(object other)
|
||||||
{
|
{
|
||||||
if (!(other is Vector2))
|
if (!(other is Vector2 vector2))
|
||||||
return false;
|
return false;
|
||||||
return Equals((Vector2)other);
|
return Equals(vector2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(Vector2 other)
|
public bool Equals(Vector2 other)
|
||||||
@@ -73,7 +73,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public float Length()
|
public float Length()
|
||||||
{
|
{
|
||||||
return (float)Math.Sqrt(LengthSquared());
|
return MathF.Sqrt(LengthSquared());
|
||||||
}
|
}
|
||||||
|
|
||||||
public float LengthSquared()
|
public float LengthSquared()
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public override bool Equals(object other)
|
public override bool Equals(object other)
|
||||||
{
|
{
|
||||||
if (!(other is Vector3))
|
if (!(other is Vector3 vector3))
|
||||||
return false;
|
return false;
|
||||||
return Equals((Vector3)other);
|
return Equals(vector3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(Vector3 other)
|
public bool Equals(Vector3 other)
|
||||||
@@ -79,7 +79,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public float Length()
|
public float Length()
|
||||||
{
|
{
|
||||||
return (float)Math.Sqrt(LengthSquared());
|
return MathF.Sqrt(LengthSquared());
|
||||||
}
|
}
|
||||||
|
|
||||||
public float LengthSquared()
|
public float LengthSquared()
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public override bool Equals(object other)
|
public override bool Equals(object other)
|
||||||
{
|
{
|
||||||
if (!(other is Vector4))
|
if (!(other is Vector4 vector4))
|
||||||
return false;
|
return false;
|
||||||
return Equals((Vector4)other);
|
return Equals(vector4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(Vector4 other)
|
public bool Equals(Vector4 other)
|
||||||
@@ -93,7 +93,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
public float Length()
|
public float Length()
|
||||||
{
|
{
|
||||||
return (float)Math.Sqrt(LengthSquared());
|
return MathF.Sqrt(LengthSquared());
|
||||||
}
|
}
|
||||||
|
|
||||||
public float LengthSquared()
|
public float LengthSquared()
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -12,13 +9,15 @@ namespace AssetStudio
|
|||||||
public long m_PathID;
|
public long m_PathID;
|
||||||
public long byteStart;
|
public long byteStart;
|
||||||
public uint byteSize;
|
public uint byteSize;
|
||||||
|
public int classID;
|
||||||
public ClassIDType type;
|
public ClassIDType type;
|
||||||
public SerializedType serializedType;
|
public SerializedType serializedType;
|
||||||
public BuildTarget platform;
|
public BuildTarget platform;
|
||||||
public SerializedFileFormatVersion m_Version;
|
public SerializedFileFormatVersion m_Version;
|
||||||
|
|
||||||
public UnityVersion version => assetsFile.version;
|
public UnityVersion version => assetsFile.version;
|
||||||
public BuildType buildType => assetsFile.buildType;
|
|
||||||
|
public long Remaining => byteStart + byteSize - Position;
|
||||||
|
|
||||||
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.Endian)
|
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.Endian)
|
||||||
{
|
{
|
||||||
@@ -26,6 +25,7 @@ namespace AssetStudio
|
|||||||
m_PathID = objectInfo.m_PathID;
|
m_PathID = objectInfo.m_PathID;
|
||||||
byteStart = objectInfo.byteStart;
|
byteStart = objectInfo.byteStart;
|
||||||
byteSize = objectInfo.byteSize;
|
byteSize = objectInfo.byteSize;
|
||||||
|
classID = objectInfo.classID;
|
||||||
if (Enum.IsDefined(typeof(ClassIDType), objectInfo.classID))
|
if (Enum.IsDefined(typeof(ClassIDType), objectInfo.classID))
|
||||||
{
|
{
|
||||||
type = (ClassIDType)objectInfo.classID;
|
type = (ClassIDType)objectInfo.classID;
|
||||||
@@ -39,6 +39,12 @@ namespace AssetStudio
|
|||||||
m_Version = assetsFile.header.m_Version;
|
m_Version = assetsFile.header.m_Version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ThrowIfTooLarge(float val)
|
||||||
|
{
|
||||||
|
if (val < 0 || val > Remaining)
|
||||||
|
throw new EndOfStreamException();
|
||||||
|
}
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
Position = byteStart;
|
Position = byteStart;
|
||||||
|
|||||||
102
AssetStudio/OffsetStream.cs
Normal file
102
AssetStudio/OffsetStream.cs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,28 +4,58 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public static class Progress
|
public static class Progress
|
||||||
{
|
{
|
||||||
public static IProgress<int> Default = new Progress<int>();
|
private static readonly int InstanceCount = 2;
|
||||||
private static int preValue;
|
private static readonly IProgress<int>[] Instances;
|
||||||
|
private static readonly int[] PreValues;
|
||||||
|
|
||||||
public static void Reset()
|
static Progress()
|
||||||
{
|
{
|
||||||
preValue = 0;
|
Instances = new IProgress<int>[InstanceCount];
|
||||||
Default.Report(0);
|
for (var i = 0; i < InstanceCount; i++)
|
||||||
|
{
|
||||||
|
Instances[i] = new Progress<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Report(int current, int total)
|
PreValues = new int[InstanceCount];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int MaxCount => InstanceCount;
|
||||||
|
|
||||||
|
public static IProgress<int> Default //alias
|
||||||
|
{
|
||||||
|
get => Instances[0];
|
||||||
|
set => SetInstance(0, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Reset(int index = 0)
|
||||||
|
{
|
||||||
|
PreValues[index] = 0;
|
||||||
|
Instances[index].Report(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Report(int current, int total, int index = 0)
|
||||||
{
|
{
|
||||||
var value = (int)(current * 100f / total);
|
var value = (int)(current * 100f / total);
|
||||||
Report(value);
|
_Report(value, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Report(int value)
|
private static void _Report(int value, int index)
|
||||||
{
|
{
|
||||||
if (value > preValue)
|
if (value > PreValues[index])
|
||||||
{
|
{
|
||||||
preValue = value;
|
PreValues[index] = value;
|
||||||
Default.Report(value);
|
Instances[index].Report(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SetInstance(int index, IProgress<int> progress)
|
||||||
|
{
|
||||||
|
if (progress == null)
|
||||||
|
throw new ArgumentNullException(nameof(progress));
|
||||||
|
if (index < 0 || index >= MaxCount)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
|
|
||||||
|
Instances[index] = progress;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,18 +80,20 @@ namespace AssetStudio
|
|||||||
lock (binaryReader)
|
lock (binaryReader)
|
||||||
{
|
{
|
||||||
binaryReader.BaseStream.Position = Offset;
|
binaryReader.BaseStream.Position = Offset;
|
||||||
return binaryReader.ReadBytes((int) size);
|
return binaryReader.ReadBytes((int)size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetData(byte[] buff)
|
public int GetData(byte[] buff, int startIndex = 0)
|
||||||
{
|
{
|
||||||
|
int dataLen;
|
||||||
var binaryReader = GetReader();
|
var binaryReader = GetReader();
|
||||||
lock (binaryReader)
|
lock (binaryReader)
|
||||||
{
|
{
|
||||||
binaryReader.BaseStream.Position = Offset;
|
binaryReader.BaseStream.Position = Offset;
|
||||||
binaryReader.Read(buff, 0, (int) size);
|
dataLen = binaryReader.Read(buff, startIndex, (int)size);
|
||||||
}
|
}
|
||||||
|
return dataLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteData(string path)
|
public void WriteData(string path)
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -14,14 +12,13 @@ namespace AssetStudio
|
|||||||
public string originalPath;
|
public string originalPath;
|
||||||
public string fileName;
|
public string fileName;
|
||||||
public UnityVersion version = new UnityVersion();
|
public UnityVersion version = new UnityVersion();
|
||||||
public BuildType buildType;
|
|
||||||
public List<Object> Objects;
|
public List<Object> Objects;
|
||||||
public Dictionary<long, Object> ObjectsDic;
|
public Dictionary<long, Object> ObjectsDic;
|
||||||
|
|
||||||
public SerializedFileHeader header;
|
public SerializedFileHeader header;
|
||||||
private byte m_FileEndianess;
|
private byte m_FileEndianess;
|
||||||
public string unityVersion = "2.5.0f5";
|
|
||||||
public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform;
|
public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform;
|
||||||
|
public string targetPlatformString;
|
||||||
private bool m_EnableTypeTree = true;
|
private bool m_EnableTypeTree = true;
|
||||||
public List<SerializedType> m_Types;
|
public List<SerializedType> m_Types;
|
||||||
public int bigIDEnabled = 0;
|
public int bigIDEnabled = 0;
|
||||||
@@ -72,16 +69,39 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_7)
|
if (header.m_Version >= SerializedFileFormatVersion.Unknown_7)
|
||||||
{
|
{
|
||||||
unityVersion = reader.ReadStringToNull();
|
var versionPos = reader.Position;
|
||||||
SetVersion(new UnityVersion(unityVersion));
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_8)
|
if (header.m_Version >= SerializedFileFormatVersion.Unknown_8)
|
||||||
{
|
{
|
||||||
m_TargetPlatform = (BuildTarget)reader.ReadInt32();
|
var target = reader.ReadInt32();
|
||||||
|
|
||||||
|
m_TargetPlatform = (BuildTarget)target;
|
||||||
if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
|
if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
|
||||||
{
|
{
|
||||||
m_TargetPlatform = BuildTarget.UnknownPlatform;
|
m_TargetPlatform = BuildTarget.UnknownPlatform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
targetPlatformString = version.IsTuanjie && Enum.IsDefined(typeof(TuanjieBuildTarget), target)
|
||||||
|
? ((TuanjieBuildTarget)target).ToString()
|
||||||
|
: m_TargetPlatform.ToString();
|
||||||
}
|
}
|
||||||
if (header.m_Version >= SerializedFileFormatVersion.HasTypeTreeHashes)
|
if (header.m_Version >= SerializedFileFormatVersion.HasTypeTreeHashes)
|
||||||
{
|
{
|
||||||
@@ -90,8 +110,8 @@ namespace AssetStudio
|
|||||||
|
|
||||||
// Read Types
|
// Read Types
|
||||||
int typeCount = reader.ReadInt32();
|
int typeCount = reader.ReadInt32();
|
||||||
m_Types = new List<SerializedType>(typeCount);
|
m_Types = new List<SerializedType>();
|
||||||
for (int i = 0; i < typeCount; i++)
|
for (var i = 0; i < typeCount; i++)
|
||||||
{
|
{
|
||||||
m_Types.Add(ReadSerializedType(false));
|
m_Types.Add(ReadSerializedType(false));
|
||||||
}
|
}
|
||||||
@@ -103,10 +123,10 @@ namespace AssetStudio
|
|||||||
|
|
||||||
// Read Objects
|
// Read Objects
|
||||||
int objectCount = reader.ReadInt32();
|
int objectCount = reader.ReadInt32();
|
||||||
m_Objects = new List<ObjectInfo>(objectCount);
|
m_Objects = new List<ObjectInfo>();
|
||||||
Objects = new List<Object>(objectCount);
|
Objects = new List<Object>();
|
||||||
ObjectsDic = new Dictionary<long, Object>(objectCount);
|
ObjectsDic = new Dictionary<long, Object>();
|
||||||
for (int i = 0; i < objectCount; i++)
|
for (var i = 0; i < objectCount; i++)
|
||||||
{
|
{
|
||||||
var objectInfo = new ObjectInfo();
|
var objectInfo = new ObjectInfo();
|
||||||
if (bigIDEnabled != 0)
|
if (bigIDEnabled != 0)
|
||||||
@@ -162,8 +182,8 @@ namespace AssetStudio
|
|||||||
if (header.m_Version >= SerializedFileFormatVersion.HasScriptTypeIndex)
|
if (header.m_Version >= SerializedFileFormatVersion.HasScriptTypeIndex)
|
||||||
{
|
{
|
||||||
int scriptCount = reader.ReadInt32();
|
int scriptCount = reader.ReadInt32();
|
||||||
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>(scriptCount);
|
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>();
|
||||||
for (int i = 0; i < scriptCount; i++)
|
for (var i = 0; i < scriptCount; i++)
|
||||||
{
|
{
|
||||||
var m_ScriptType = new LocalSerializedObjectIdentifier();
|
var m_ScriptType = new LocalSerializedObjectIdentifier();
|
||||||
m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
|
m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
|
||||||
@@ -181,8 +201,8 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
int externalsCount = reader.ReadInt32();
|
int externalsCount = reader.ReadInt32();
|
||||||
m_Externals = new List<FileIdentifier>(externalsCount);
|
m_Externals = new List<FileIdentifier>();
|
||||||
for (int i = 0; i < externalsCount; i++)
|
for (var i = 0; i < externalsCount; i++)
|
||||||
{
|
{
|
||||||
var m_External = new FileIdentifier();
|
var m_External = new FileIdentifier();
|
||||||
if (header.m_Version >= SerializedFileFormatVersion.Unknown_6)
|
if (header.m_Version >= SerializedFileFormatVersion.Unknown_6)
|
||||||
@@ -202,8 +222,8 @@ namespace AssetStudio
|
|||||||
if (header.m_Version >= SerializedFileFormatVersion.SupportsRefObject)
|
if (header.m_Version >= SerializedFileFormatVersion.SupportsRefObject)
|
||||||
{
|
{
|
||||||
int refTypesCount = reader.ReadInt32();
|
int refTypesCount = reader.ReadInt32();
|
||||||
m_RefTypes = new List<SerializedType>(refTypesCount);
|
m_RefTypes = new List<SerializedType>();
|
||||||
for (int i = 0; i < refTypesCount; i++)
|
for (var i = 0; i < refTypesCount; i++)
|
||||||
{
|
{
|
||||||
m_RefTypes.Add(ReadSerializedType(true));
|
m_RefTypes.Add(ReadSerializedType(true));
|
||||||
}
|
}
|
||||||
@@ -217,16 +237,6 @@ namespace AssetStudio
|
|||||||
//reader.AlignStream(16);
|
//reader.AlignStream(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVersion(UnityVersion unityVer)
|
|
||||||
{
|
|
||||||
if (unityVer != null && !unityVer.IsStripped)
|
|
||||||
{
|
|
||||||
unityVersion = unityVer.FullVersion;
|
|
||||||
buildType = new BuildType(unityVer.BuildType);
|
|
||||||
version = unityVer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private SerializedType ReadSerializedType(bool isRefType)
|
private SerializedType ReadSerializedType(bool isRefType)
|
||||||
{
|
{
|
||||||
var type = new SerializedType();
|
var type = new SerializedType();
|
||||||
@@ -310,7 +320,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
int childrenCount = reader.ReadInt32();
|
int childrenCount = reader.ReadInt32();
|
||||||
for (int i = 0; i < childrenCount; i++)
|
for (var i = 0; i < childrenCount; i++)
|
||||||
{
|
{
|
||||||
ReadTypeTree(m_Type, level + 1);
|
ReadTypeTree(m_Type, level + 1);
|
||||||
}
|
}
|
||||||
@@ -320,7 +330,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
int numberOfNodes = reader.ReadInt32();
|
int numberOfNodes = reader.ReadInt32();
|
||||||
int stringBufferSize = reader.ReadInt32();
|
int stringBufferSize = reader.ReadInt32();
|
||||||
for (int i = 0; i < numberOfNodes; i++)
|
for (var i = 0; i < numberOfNodes; i++)
|
||||||
{
|
{
|
||||||
var typeTreeNode = new TypeTreeNode();
|
var typeTreeNode = new TypeTreeNode();
|
||||||
m_Type.m_Nodes.Add(typeTreeNode);
|
m_Type.m_Nodes.Add(typeTreeNode);
|
||||||
@@ -341,7 +351,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
using (var stringBufferReader = new BinaryReader(new MemoryStream(m_Type.m_StringBuffer)))
|
using (var stringBufferReader = new BinaryReader(new MemoryStream(m_Type.m_StringBuffer)))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numberOfNodes; i++)
|
for (var i = 0; i < numberOfNodes; i++)
|
||||||
{
|
{
|
||||||
var m_Node = m_Type.m_Nodes[i];
|
var m_Node = m_Type.m_Nodes[i];
|
||||||
m_Node.m_Type = ReadString(stringBufferReader, m_Node.m_TypeStrOffset);
|
m_Node.m_Type = ReadString(stringBufferReader, m_Node.m_TypeStrOffset);
|
||||||
|
|||||||
40
AssetStudio/TempFileStream.cs
Normal file
40
AssetStudio/TempFileStream.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public class TempFileStream : FileStream
|
||||||
|
{
|
||||||
|
private readonly string _tempFilePath;
|
||||||
|
private bool _disposed;
|
||||||
|
|
||||||
|
public TempFileStream(string path, FileMode fileMode, FileAccess fileAccess = FileAccess.ReadWrite, FileShare fileShare = FileShare.Read, int bufferSize = 4096)
|
||||||
|
: base(path, fileMode, fileAccess, fileShare, bufferSize, FileOptions.DeleteOnClose)
|
||||||
|
{
|
||||||
|
_tempFilePath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Close()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && File.Exists(_tempFilePath))
|
||||||
|
{
|
||||||
|
File.Delete(_tempFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,25 +3,47 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
public static class TypeTreeHelper
|
public static class TypeTreeHelper
|
||||||
{
|
{
|
||||||
|
private static readonly JsonSerializerOptions JsonOptions;
|
||||||
|
static TypeTreeHelper()
|
||||||
|
{
|
||||||
|
JsonOptions = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
|
||||||
|
ReferenceHandler = ReferenceHandler.IgnoreCycles,
|
||||||
|
IncludeFields = true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static string ReadTypeString(TypeTree m_Type, ObjectReader reader)
|
public static string ReadTypeString(TypeTree m_Type, ObjectReader reader)
|
||||||
{
|
{
|
||||||
reader.Reset();
|
reader.Reset();
|
||||||
|
var readed = 0L;
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
var m_Nodes = m_Type.m_Nodes;
|
var m_Nodes = m_Type.m_Nodes;
|
||||||
for (int i = 0; i < m_Nodes.Count; i++)
|
try
|
||||||
|
{
|
||||||
|
for (var i = 0; i < m_Nodes.Count; i++)
|
||||||
{
|
{
|
||||||
ReadStringValue(sb, m_Nodes, reader, ref i);
|
ReadStringValue(sb, m_Nodes, reader, ref i);
|
||||||
|
readed = reader.Position - reader.byteStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
//Ignore
|
||||||
}
|
}
|
||||||
var readed = reader.Position - reader.byteStart;
|
|
||||||
if (readed != reader.byteSize)
|
if (readed != reader.byteSize)
|
||||||
{
|
{
|
||||||
Logger.Info($"Failed to read type, read {readed} bytes but expected {reader.byteSize} bytes");
|
Logger.Info($"Failed to read type, read {readed} bytes but expected {reader.byteSize} bytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +102,7 @@ namespace AssetStudio
|
|||||||
case "bool":
|
case "bool":
|
||||||
value = reader.ReadBoolean();
|
value = reader.ReadBoolean();
|
||||||
break;
|
break;
|
||||||
case "string":
|
case "string" when m_Nodes[i + 1].m_Type == "Array":
|
||||||
append = false;
|
append = false;
|
||||||
var str = reader.ReadAlignedString();
|
var str = reader.ReadAlignedString();
|
||||||
sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, str);
|
sb.AppendFormat("{0}{1} {2} = \"{3}\"\r\n", (new string('\t', level)), varTypeStr, varNameStr, str);
|
||||||
@@ -145,6 +167,8 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
else //Class
|
else //Class
|
||||||
{
|
{
|
||||||
|
if (m_Node.m_Type == "string")
|
||||||
|
m_Node.m_Type = "CustomType";
|
||||||
append = false;
|
append = false;
|
||||||
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
|
sb.AppendFormat("{0}{1} {2}\r\n", (new string('\t', level)), varTypeStr, varNameStr);
|
||||||
var @class = GetNodes(m_Nodes, i);
|
var @class = GetNodes(m_Nodes, i);
|
||||||
@@ -163,18 +187,34 @@ namespace AssetStudio
|
|||||||
reader.AlignStream();
|
reader.AlignStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] ReadTypeByteArray(TypeTree m_Types, ObjectReader reader)
|
||||||
|
{
|
||||||
|
var type = ReadType(m_Types, reader);
|
||||||
|
var bytes = JsonSerializer.SerializeToUtf8Bytes(type, JsonOptions);
|
||||||
|
type.Clear();
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
public static OrderedDictionary ReadType(TypeTree m_Types, ObjectReader reader)
|
public static OrderedDictionary ReadType(TypeTree m_Types, ObjectReader reader)
|
||||||
{
|
{
|
||||||
reader.Reset();
|
reader.Reset();
|
||||||
var obj = new OrderedDictionary();
|
var obj = new OrderedDictionary();
|
||||||
var m_Nodes = m_Types.m_Nodes;
|
var m_Nodes = m_Types.m_Nodes;
|
||||||
|
var readed = 0L;
|
||||||
|
try
|
||||||
|
{
|
||||||
for (int i = 1; i < m_Nodes.Count; i++)
|
for (int i = 1; i < m_Nodes.Count; i++)
|
||||||
{
|
{
|
||||||
var m_Node = m_Nodes[i];
|
var m_Node = m_Nodes[i];
|
||||||
var varNameStr = m_Node.m_Name.Replace("image data", "image_data");
|
var varNameStr = m_Node.m_Name;
|
||||||
obj[varNameStr] = ReadValue(m_Nodes, reader, ref i);
|
obj[varNameStr] = ReadValue(m_Nodes, reader, ref i);
|
||||||
|
readed = reader.Position - reader.byteStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
//Ignore
|
||||||
}
|
}
|
||||||
var readed = reader.Position - reader.byteStart;
|
|
||||||
if (readed != reader.byteSize)
|
if (readed != reader.byteSize)
|
||||||
{
|
{
|
||||||
Logger.Info($"Failed to read type, read {readed} bytes but expected {reader.byteSize} bytes");
|
Logger.Info($"Failed to read type, read {readed} bytes but expected {reader.byteSize} bytes");
|
||||||
@@ -234,7 +274,7 @@ namespace AssetStudio
|
|||||||
case "bool":
|
case "bool":
|
||||||
value = reader.ReadBoolean();
|
value = reader.ReadBoolean();
|
||||||
break;
|
break;
|
||||||
case "string":
|
case "string" when m_Nodes[i + 1].m_Type == "Array":
|
||||||
value = reader.ReadAlignedString();
|
value = reader.ReadAlignedString();
|
||||||
var toSkip = GetNodes(m_Nodes, i);
|
var toSkip = GetNodes(m_Nodes, i);
|
||||||
i += toSkip.Count - 1;
|
i += toSkip.Count - 1;
|
||||||
@@ -262,10 +302,11 @@ namespace AssetStudio
|
|||||||
case "TypelessData":
|
case "TypelessData":
|
||||||
{
|
{
|
||||||
var size = reader.ReadInt32();
|
var size = reader.ReadInt32();
|
||||||
|
var offset = size > 0 ? reader.BaseStream.Position : 0;
|
||||||
var dic = new OrderedDictionary
|
var dic = new OrderedDictionary
|
||||||
{
|
{
|
||||||
{ "Offset", reader.BaseStream.Position },
|
{"Offset", offset},
|
||||||
{ "Size", size }
|
{"Size", size}
|
||||||
};
|
};
|
||||||
value = dic;
|
value = dic;
|
||||||
reader.BaseStream.Position += size;
|
reader.BaseStream.Position += size;
|
||||||
@@ -274,6 +315,8 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
if (m_Node.m_Type == "string")
|
||||||
|
m_Node.m_Type = "CustomType";
|
||||||
if (i < m_Nodes.Count - 1 && m_Nodes[i + 1].m_Type == "Array") //Array
|
if (i < m_Nodes.Count - 1 && m_Nodes[i + 1].m_Type == "Array") //Array
|
||||||
{
|
{
|
||||||
if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0)
|
if ((m_Nodes[i + 1].m_MetaFlag & 0x4000) != 0)
|
||||||
@@ -281,13 +324,13 @@ namespace AssetStudio
|
|||||||
var vector = GetNodes(m_Nodes, i);
|
var vector = GetNodes(m_Nodes, i);
|
||||||
i += vector.Count - 1;
|
i += vector.Count - 1;
|
||||||
var size = reader.ReadInt32();
|
var size = reader.ReadInt32();
|
||||||
var list = new List<object>(size);
|
var array = new object[size];
|
||||||
for (int j = 0; j < size; j++)
|
for (int j = 0; j < size; j++)
|
||||||
{
|
{
|
||||||
int tmp = 3;
|
int tmp = 3;
|
||||||
list.Add(ReadValue(vector, reader, ref tmp));
|
array[j] = ReadValue(vector, reader, ref tmp);
|
||||||
}
|
}
|
||||||
value = list;
|
value = array;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else //Class
|
else //Class
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
|
public static class BuildTypes
|
||||||
|
{
|
||||||
|
public static readonly string
|
||||||
|
Alpha = "a",
|
||||||
|
Beta = "b",
|
||||||
|
Final = "f",
|
||||||
|
Patch = "p",
|
||||||
|
Tuanjie = "t";
|
||||||
|
}
|
||||||
|
|
||||||
public class UnityVersion : IComparable
|
public class UnityVersion : IComparable
|
||||||
{
|
{
|
||||||
public int Major { get; }
|
public int Major { get; }
|
||||||
@@ -14,6 +25,10 @@ namespace AssetStudio
|
|||||||
public string FullVersion { get; }
|
public string FullVersion { get; }
|
||||||
|
|
||||||
public bool IsStripped => this == (0, 0, 0);
|
public bool IsStripped => this == (0, 0, 0);
|
||||||
|
public bool IsAlpha => BuildType == BuildTypes.Alpha;
|
||||||
|
public bool IsBeta => BuildType == BuildTypes.Beta;
|
||||||
|
public bool IsPatch => BuildType == BuildTypes.Patch;
|
||||||
|
public bool IsTuanjie => BuildType == BuildTypes.Tuanjie && this >= (2022, 3, 2);
|
||||||
|
|
||||||
public UnityVersion(string version)
|
public UnityVersion(string version)
|
||||||
{
|
{
|
||||||
@@ -24,7 +39,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
int[] ver = Regex.Matches(version, @"\d+").Cast<Match>().Select(x => int.Parse(x.Value)).ToArray();
|
int[] ver = Regex.Matches(version, @"\d+").Cast<Match>().Select(x => int.Parse(x.Value)).ToArray();
|
||||||
(Major, Minor, Patch) = (ver[0], ver[1], ver[2]);
|
(Major, Minor, Patch) = (ver[0], ver[1], ver[2]);
|
||||||
if (ver.Length == 4)
|
if (ver.Length >= 4)
|
||||||
Build = ver[3];
|
Build = ver[3];
|
||||||
FullVersion = version;
|
FullVersion = version;
|
||||||
}
|
}
|
||||||
@@ -40,6 +55,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
public UnityVersion(int major = 0, int minor = 0, int patch = 0)
|
public UnityVersion(int major = 0, int minor = 0, int patch = 0)
|
||||||
{
|
{
|
||||||
(Major, Minor, Patch) = (major, minor, patch);
|
(Major, Minor, Patch) = (major, minor, patch);
|
||||||
@@ -47,11 +63,25 @@ namespace AssetStudio
|
|||||||
if (!IsStripped)
|
if (!IsStripped)
|
||||||
{
|
{
|
||||||
Build = 1;
|
Build = 1;
|
||||||
BuildType = "f";
|
BuildType = BuildTypes.Final;
|
||||||
FullVersion += $"{BuildType}{Build}";
|
FullVersion += $"{BuildType}{Build}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool TryParse(string versionStr, out UnityVersion version)
|
||||||
|
{
|
||||||
|
version = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
version = new UnityVersion(versionStr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region UnityVer, UnityVer
|
#region UnityVer, UnityVer
|
||||||
public static bool operator ==(UnityVersion left, UnityVersion right)
|
public static bool operator ==(UnityVersion left, UnityVersion right)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
public class WebFile
|
public class WebFile
|
||||||
{
|
{
|
||||||
public StreamFile[] fileList;
|
public List<StreamFile> fileList;
|
||||||
|
|
||||||
private class WebData
|
private class WebData
|
||||||
{
|
{
|
||||||
@@ -30,16 +30,15 @@ namespace AssetStudio
|
|||||||
data.path = Encoding.UTF8.GetString(reader.ReadBytes(pathLength));
|
data.path = Encoding.UTF8.GetString(reader.ReadBytes(pathLength));
|
||||||
dataList.Add(data);
|
dataList.Add(data);
|
||||||
}
|
}
|
||||||
fileList = new StreamFile[dataList.Count];
|
fileList = new List<StreamFile>(dataList.Count);
|
||||||
for (int i = 0; i < dataList.Count; i++)
|
foreach (var data in dataList)
|
||||||
{
|
{
|
||||||
var data = dataList[i];
|
|
||||||
var file = new StreamFile();
|
var file = new StreamFile();
|
||||||
file.path = data.path;
|
file.path = data.path;
|
||||||
file.fileName = Path.GetFileName(data.path);
|
file.fileName = Path.GetFileName(data.path);
|
||||||
reader.BaseStream.Position = data.dataOffset;
|
reader.BaseStream.Position = data.dataOffset;
|
||||||
file.stream = new MemoryStream(reader.ReadBytes(data.dataLength));
|
file.stream = new MemoryStream(reader.ReadBytes(data.dataLength));
|
||||||
fileList[i] = file;
|
fileList.Add(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user