Compare commits
426 Commits
v0.14.38.5
...
v0.19.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
bb7accd04d | ||
|
|
5120999026 | ||
|
|
1fc504e587 | ||
|
|
4e991d85fb | ||
|
|
29b4bb59a0 | ||
|
|
9750f486d5 | ||
|
|
97bbfe8fbb | ||
|
|
684bf5a874 | ||
|
|
3cc6bed844 | ||
|
|
c9e9bc840c | ||
|
|
cadcf0b492 | ||
|
|
1e8085da2d | ||
|
|
770d7e7532 | ||
|
|
d0d8a35f67 | ||
|
|
3f004f74d1 | ||
|
|
3effd06e64 | ||
|
|
4f0afffeba | ||
|
|
9b69b5607c | ||
|
|
9b16ea8d41 | ||
|
|
ae4548f1c3 | ||
|
|
4cd246592b | ||
|
|
f54cc004bd | ||
|
|
afdc81bca8 | ||
|
|
045f6c0ff4 | ||
|
|
bc9380b8be | ||
|
|
46f8023756 | ||
|
|
0f9afa60d7 | ||
|
|
ec7f2c393d | ||
|
|
3ec8169b08 | ||
|
|
5c24183d18 | ||
|
|
c68eaa5e3c | ||
|
|
8460ecef8d | ||
|
|
f90c0ecc00 | ||
|
|
535153be6b | ||
|
|
d4162161be | ||
|
|
6fe12d274f | ||
|
|
70213e3012 | ||
|
|
2f6d9ec77f | ||
|
|
0d2aebc1f4 | ||
|
|
115074fdc0 | ||
|
|
c2d3b8c5f9 | ||
|
|
67a74fd395 | ||
|
|
a00c857ac3 | ||
|
|
5333757843 | ||
|
|
4747687bec | ||
|
|
5c2ac1a5e8 | ||
|
|
e2eae53ac0 | ||
|
|
87347e8b60 | ||
|
|
0fdbddea55 | ||
|
|
823190abb7 | ||
|
|
60aef1b8ed | ||
|
|
f82a73f018 | ||
|
|
d42a1879ab | ||
|
|
632e5f8d08 | ||
|
|
51d259464b | ||
|
|
efd06648ad | ||
|
|
b27482e22b | ||
|
|
d572bd0e64 | ||
|
|
e415740373 | ||
|
|
45bf9251c9 | ||
|
|
75ebe67713 | ||
|
|
ed7b0a2415 | ||
|
|
22ab5c0633 | ||
|
|
a2bc935850 | ||
|
|
cb84c137e5 | ||
|
|
25c611fb9e | ||
|
|
6d3875cb2c | ||
|
|
be4ced77ea | ||
|
|
2bd762e8f4 | ||
|
|
a926644ff6 | ||
|
|
a4cdff5934 | ||
|
|
2e10e627b0 | ||
|
|
e216abd6be | ||
|
|
93c7e617d8 | ||
|
|
000916913e | ||
|
|
28f9744497 | ||
|
|
c3f99216b6 | ||
|
|
19c4835ea3 | ||
|
|
6b321da695 | ||
|
|
7cca301f7a | ||
|
|
5ac597c935 | ||
|
|
171962e61f | ||
|
|
c8a21838c9 | ||
|
|
cf67815d53 | ||
|
|
94c8b355fe | ||
|
|
4e41caf203 | ||
|
|
74a8555514 | ||
|
|
e1d883adf6 | ||
|
|
9784df0e16 | ||
|
|
4d919a2bfe | ||
|
|
6701f467b7 | ||
|
|
50f5da5554 | ||
|
|
2b6dcca9c8 | ||
|
|
0bdcb89b08 | ||
|
|
dcd7b98229 | ||
|
|
007e5c7e4d | ||
|
|
63564d5fff | ||
|
|
aea6cbc97f | ||
|
|
6d41693b85 | ||
|
|
5695afae7b | ||
|
|
bb9ea7d86b | ||
|
|
547659e151 | ||
|
|
2f8f57c1a6 | ||
|
|
b7d5d73f23 | ||
|
|
f0c237473c | ||
|
|
09947fd14f | ||
|
|
da216dace8 | ||
|
|
c7356875f9 | ||
|
|
02e46eaa0d | ||
|
|
b0bf5e0cfd | ||
|
|
11b9ca37da | ||
|
|
5944dd8c58 | ||
|
|
1c67e39504 | ||
|
|
2d81007556 | ||
|
|
4bae98813b | ||
|
|
90ec395b2a | ||
|
|
af3684bab8 | ||
|
|
1da51ac95b | ||
|
|
9e14f1ef00 | ||
|
|
4edadb19f8 | ||
|
|
44a1240f5f | ||
|
|
01957a9443 | ||
|
|
ad1b3b4911 | ||
|
|
0925751776 | ||
|
|
b59ba3ba94 | ||
|
|
67898c72ca | ||
|
|
0425423ca9 | ||
|
|
16a7107d4e | ||
|
|
10b7e84ffb | ||
|
|
679e7041a6 | ||
|
|
629c6248a4 | ||
|
|
7674081df7 | ||
|
|
fb574064c9 | ||
|
|
c52940abc4 | ||
|
|
5c662d64e4 | ||
|
|
b9cf95616b | ||
|
|
39490d4e03 | ||
|
|
a96d1a5d5d | ||
|
|
568daafc7f | ||
|
|
2a2216e2bf | ||
|
|
dfbe46e1e5 | ||
|
|
6a9aad510c | ||
|
|
fd21cafd29 | ||
|
|
ea09a8de64 | ||
|
|
7fa5b4f355 | ||
|
|
c22d92009a | ||
|
|
53f3e8232a | ||
|
|
2fe57a1c5d | ||
|
|
ded2dcd54e | ||
|
|
8ae3df6197 | ||
|
|
64d9718c34 | ||
|
|
220004c976 | ||
|
|
a324366be9 | ||
|
|
06b4ae9ffe | ||
|
|
77b056de5e | ||
|
|
344edb722f | ||
|
|
98c4d0c3ab | ||
|
|
23ac590648 | ||
|
|
54445475a3 | ||
|
|
7299bcba6d | ||
|
|
5487ff4e60 | ||
|
|
b3621a75b0 | ||
|
|
8b048b9e1e | ||
|
|
41a79f485f | ||
|
|
a060a392e7 | ||
|
|
0798af7c5c | ||
|
|
8ebfa16e19 | ||
|
|
d158e864b5 | ||
|
|
b70b5196e3 | ||
|
|
4f88841026 | ||
|
|
dc9429feac | ||
|
|
a3c16ed3d6 | ||
|
|
5b83eebdda | ||
|
|
1fcf7a4364 | ||
|
|
973d50ce8b | ||
|
|
50485a9bd3 | ||
|
|
dbb3d3fef7 | ||
|
|
e1cfff63c3 | ||
|
|
44514a4e10 | ||
|
|
b1205808e2 | ||
|
|
7d3a4a10fc | ||
|
|
b909857820 | ||
|
|
b674e66407 | ||
|
|
d7dcd3f405 | ||
|
|
44145e0b9c | ||
|
|
d4e21f824c | ||
|
|
e7a4604a65 | ||
|
|
74f2c3190b | ||
|
|
8d193a63cd | ||
|
|
e61a317185 | ||
|
|
f67965b1dd | ||
|
|
07a81d9bfe | ||
|
|
95fd1823c8 | ||
|
|
d25451d5b9 | ||
|
|
0e1a886e0b | ||
|
|
97b5f51f3a | ||
|
|
7295feda72 | ||
|
|
fe95c91759 | ||
|
|
d220315d9b | ||
|
|
a94caa5e34 | ||
|
|
3660b4ed67 | ||
|
|
3370f93037 | ||
|
|
80653711cd | ||
|
|
f0b23bbfe7 | ||
|
|
88c5804586 | ||
|
|
e501940f03 | ||
|
|
d4060cde6d | ||
|
|
582a779441 | ||
|
|
5fa4934787 | ||
|
|
18277fbea8 | ||
|
|
571ea2da4a | ||
|
|
9cbe91decb | ||
|
|
19c6c5fe73 | ||
|
|
792850dbb2 | ||
|
|
2ce9cae957 | ||
|
|
af5e50cfa9 | ||
|
|
ce1172ca9a | ||
|
|
a7e6d91f5b | ||
|
|
34a0af683a | ||
|
|
91410a33b1 | ||
|
|
d08b78c2cf | ||
|
|
2ef52afe1e | ||
|
|
05a41d2f1e | ||
|
|
34c38e1415 | ||
|
|
c85873b729 | ||
|
|
b146d251a7 | ||
|
|
3129d67fc1 | ||
|
|
850ba63a10 | ||
|
|
17b91984d6 | ||
|
|
7ab2cda120 | ||
|
|
4345885cc9 | ||
|
|
53720e37ab | ||
|
|
7c3cb36630 | ||
|
|
c1cddce031 | ||
|
|
973a1076e4 | ||
|
|
089e164756 | ||
|
|
c2b6691fd9 | ||
|
|
8dec094304 | ||
|
|
bedee240be | ||
|
|
d963d71b12 | ||
|
|
77a0c9c40a | ||
|
|
f3e406983b | ||
|
|
08b7bfcf9a | ||
|
|
57e4f7cefd | ||
|
|
c9cf2d188e | ||
|
|
ab98585b6a | ||
|
|
075d53a455 | ||
|
|
432116d834 | ||
|
|
caa45216ef | ||
|
|
c9394cd957 | ||
|
|
46c0e8ffe1 | ||
|
|
d14c232015 | ||
|
|
4002bdecb8 | ||
|
|
17259e00c7 | ||
|
|
44b02b92d8 | ||
|
|
251854cc41 | ||
|
|
6f7b77245d | ||
|
|
6d99f5ebf6 | ||
|
|
f1f2430f97 | ||
|
|
b52696c965 | ||
|
|
5fba52dc83 | ||
|
|
dfb74baf79 | ||
|
|
978e90a403 | ||
|
|
c17d7d6331 | ||
|
|
9fef18d6ea | ||
|
|
ee0cd4ab52 | ||
|
|
f904bc138b | ||
|
|
7ed5345b1b | ||
|
|
d7f652d572 | ||
|
|
32ce032655 | ||
|
|
e1cf36aa3c | ||
|
|
f644396a15 | ||
|
|
3e77c34bd5 | ||
|
|
052c60f629 | ||
|
|
a1f2e3e7fe | ||
|
|
32ee8b326f | ||
|
|
06ce479eb6 | ||
|
|
03f74bac64 | ||
|
|
344b675745 | ||
|
|
86590d95a5 | ||
|
|
bbea1341b2 | ||
|
|
ca60dd9834 | ||
|
|
7aa35b5b8c | ||
|
|
bd2decdb8f | ||
|
|
9b2c85bcae | ||
|
|
efbab7c43a | ||
|
|
729a8a8263 | ||
|
|
0ec29f62ca | ||
|
|
796317f9d9 | ||
|
|
7596dcc7cd | ||
|
|
422851cdab | ||
|
|
ec0a2a47f1 | ||
|
|
8ce5b947f6 | ||
|
|
419ca63f9d | ||
|
|
6fdb0c7b0e | ||
|
|
4e97b4b898 | ||
|
|
1766dcbdeb | ||
|
|
ef38471ff1 | ||
|
|
217a7993e9 | ||
|
|
0a41615763 | ||
|
|
9d34f668d5 | ||
|
|
9269a36725 | ||
|
|
813e8b10a6 | ||
|
|
84c75fadf5 | ||
|
|
c76e41b1ab | ||
|
|
fefeea5f35 |
57
.github/workflows/build.yml
vendored
Normal file
57
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: AssetStudioBuild
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: microsoft/setup-msbuild@v1.1
|
||||
|
||||
- name: Download FBX SDK
|
||||
run: |
|
||||
md fbx
|
||||
cd fbx
|
||||
Invoke-WebRequest "https://damassets.autodesk.net/content/dam/autodesk/www/adn/fbx/2020-2-1/fbx202021_fbxsdk_vs2019_win.exe" -OutFile "fbxsdk.exe"
|
||||
Start-Process -FilePath "fbxsdk.exe" /S -Wait
|
||||
Invoke-WebRequest "https://damassets.autodesk.net/content/dam/autodesk/www/adn/fbx/2020-2-1/fbx202021_fbxsdk_vs2019_pdbs.exe" -OutFile "fbxpdb.exe"
|
||||
Start-Process -FilePath "fbxpdb.exe" /S -Wait
|
||||
cd ..
|
||||
|
||||
- name: Nuget Restore
|
||||
run: nuget restore
|
||||
|
||||
- name: Build .Net472
|
||||
run: msbuild /p:Configuration=Release /p:TargetFramework=net472 /verbosity:minimal
|
||||
|
||||
- name: Build .Net5
|
||||
run: msbuild /t:AssetStudioGUI:publish /p:Configuration=Release /p:TargetFramework=net5.0-windows /p:SelfContained=false /verbosity:minimal
|
||||
|
||||
- name: Build .Net6
|
||||
run: msbuild /t:AssetStudioGUI:publish /p:Configuration=Release /p:TargetFramework=net6.0-windows /p:SelfContained=false /verbosity:minimal
|
||||
|
||||
- name: Upload .Net472 Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: AssetStudio.net472
|
||||
path: AssetStudioGUI/bin/Release/net472
|
||||
|
||||
- name: Upload .Net5 Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: AssetStudio.net5
|
||||
path: AssetStudioGUI/bin/Release/net5.0-windows/publish
|
||||
|
||||
- name: Upload .Net6 Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: AssetStudio.net6
|
||||
path: AssetStudioGUI/bin/Release/net6.0-windows/publish
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -35,6 +35,9 @@ bld/
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# Launch Settings
|
||||
*launchSettings.json
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
11
AssetStudio.PInvoke/AssetStudio.PInvoke.csproj
Normal file
11
AssetStudio.PInvoke/AssetStudio.PInvoke.csproj
Normal file
@@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net472;net8.0;net8.0-windows;net9.0;net9.0-windows</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Version>0.19.0.0</Version>
|
||||
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
65
AssetStudio.PInvoke/DllLoader.cs
Normal file
65
AssetStudio.PInvoke/DllLoader.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#if NETFRAMEWORK
|
||||
namespace AssetStudio.PInvoke
|
||||
{
|
||||
public static class DllLoader
|
||||
{
|
||||
public static void PreloadDll(string dllName)
|
||||
{
|
||||
var localPath = Process.GetCurrentProcess().MainModule?.FileName;
|
||||
var localDir = Path.GetDirectoryName(localPath);
|
||||
|
||||
// Not using OperatingSystem.Platform.
|
||||
// See: https://www.mono-project.com/docs/faq/technical/#how-to-detect-the-execution-platform
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
Win32.LoadDll(GetDirectedDllDirectory(localDir), dllName);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetDirectedDllDirectory(string localDir)
|
||||
{
|
||||
var win32Path = Path.Combine("runtimes", "win-x86", "native");
|
||||
var win64Path = Path.Combine("runtimes", "win-x64", "native");
|
||||
var subDir = Environment.Is64BitProcess ? win64Path : win32Path;
|
||||
|
||||
var directedDllDir = Path.Combine(localDir, subDir);
|
||||
|
||||
return directedDllDir;
|
||||
}
|
||||
|
||||
private static class Win32
|
||||
{
|
||||
internal static void LoadDll(string dllDir, string dllName)
|
||||
{
|
||||
var dllFileName = $"{dllName}.dll";
|
||||
var directedDllPath = Path.Combine(dllDir, dllFileName);
|
||||
|
||||
// Specify SEARCH_DLL_LOAD_DIR to load dependent libraries located in the same platform-specific directory.
|
||||
var hLibrary = LoadLibraryEx(directedDllPath, IntPtr.Zero, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
|
||||
|
||||
if (hLibrary == IntPtr.Zero)
|
||||
{
|
||||
var errorCode = Marshal.GetLastWin32Error();
|
||||
var exception = new Win32Exception(errorCode);
|
||||
|
||||
throw new DllNotFoundException(exception.Message, exception);
|
||||
}
|
||||
}
|
||||
|
||||
// HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
|
||||
// HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr LoadLibraryEx(string lpLibFileName, IntPtr hFile, uint dwFlags);
|
||||
|
||||
private const uint LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x1000;
|
||||
private const uint LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x100;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
100
AssetStudio.PInvoke/Utf8StringHandle.cs
Normal file
100
AssetStudio.PInvoke/Utf8StringHandle.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace AssetStudio.PInvoke
|
||||
{
|
||||
// Generally the technique from Steamworks.NET
|
||||
public class Utf8StringHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
|
||||
static Utf8StringHandle()
|
||||
{
|
||||
Utf8 = new UTF8Encoding(false);
|
||||
}
|
||||
|
||||
public Utf8StringHandle(string str)
|
||||
: base(true)
|
||||
{
|
||||
IntPtr buffer;
|
||||
|
||||
if (str == null)
|
||||
{
|
||||
buffer = IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (str.Length == 0)
|
||||
{
|
||||
buffer = Marshal.AllocHGlobal(1);
|
||||
|
||||
unsafe
|
||||
{
|
||||
*(byte*)buffer = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var strlen = Utf8.GetByteCount(str);
|
||||
var strBuffer = new byte[strlen + 1];
|
||||
|
||||
Utf8.GetBytes(str, 0, str.Length, strBuffer, 0);
|
||||
|
||||
buffer = Marshal.AllocHGlobal(strBuffer.Length);
|
||||
|
||||
Marshal.Copy(strBuffer, 0, buffer, strBuffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
SetHandle(buffer);
|
||||
}
|
||||
|
||||
public static string ReadUtf8StringFromPointer(IntPtr lpstr)
|
||||
{
|
||||
if (lpstr == IntPtr.Zero || lpstr == new IntPtr(-1))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var byteCount = 0;
|
||||
|
||||
unsafe
|
||||
{
|
||||
var p = (byte*)lpstr.ToPointer();
|
||||
|
||||
while (*p != 0)
|
||||
{
|
||||
byteCount += 1;
|
||||
p += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (byteCount == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var strBuffer = new byte[byteCount];
|
||||
|
||||
Marshal.Copy(lpstr, strBuffer, 0, byteCount);
|
||||
|
||||
var str = Utf8.GetString(strBuffer);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
if (!IsInvalid)
|
||||
{
|
||||
Marshal.FreeHGlobal(handle);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static readonly UTF8Encoding Utf8;
|
||||
|
||||
}
|
||||
}
|
||||
184
AssetStudio.sln
184
AssetStudio.sln
@@ -1,71 +1,159 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29920.165
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.33414.496
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{422FEC21-EF60-4F29-AA56-95DFDA23C913}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBX", "AssetStudioFBX\AssetStudioFBX.vcxproj", "{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudio.PInvoke", "AssetStudio.PInvoke\AssetStudio.PInvoke.csproj", "{0B2BE613-3049-4021-85D1-21C325F729F4}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Texture2DDecoder", "Texture2DDecoder\Texture2DDecoder.vcxproj", "{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioFBXWrapper", "AssetStudioFBXWrapper\AssetStudioFBXWrapper.csproj", "{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027} = {11EA25A3-ED68-40EE-A9D0-7FDE3B583027}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioUtility", "AssetStudioUtility\AssetStudioUtility.csproj", "{80AEC261-21EE-4E4F-A93B-7A744DC84888}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{29EAD018-1C67-497A-AB8E-727D595AD756}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioUtility", "AssetStudioUtility\AssetStudioUtility.csproj", "{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Texture2DDecoderWrapper", "Texture2DDecoderWrapper\Texture2DDecoderWrapper.csproj", "{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD} = {29356642-C46E-4144-83D8-22DC09D0D7FD}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBXNative", "AssetStudioFBXNative\AssetStudioFBXNative.vcxproj", "{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Texture2DDecoderNative", "Texture2DDecoderNative\Texture2DDecoderNative.vcxproj", "{29356642-C46E-4144-83D8-22DC09D0D7FD}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetStudioCLI", "AssetStudioCLI\AssetStudioCLI.csproj", "{34B6329B-0E73-45AC-B8CC-015F119F63DC}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913} = {422FEC21-EF60-4F29-AA56-95DFDA23C913}
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF} = {65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x64.Build.0 = Debug|x64
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x64.ActiveCfg = Release|x64
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x64.Build.0 = Release|x64
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B82DD1BA-4EEC-4F29-A686-03D7F0DF39B8}.Release|x86.Build.0 = Release|Win32
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x64.Build.0 = Debug|x64
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Debug|x86.Build.0 = Debug|Win32
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x64.ActiveCfg = Release|x64
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x64.Build.0 = Release|x64
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x86.ActiveCfg = Release|Win32
|
||||
{BEC7B5E6-0A7B-4824-97A7-EEA04D9EBA29}.Release|x86.Build.0 = Release|Win32
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x64.Build.0 = Debug|x64
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Debug|x86.Build.0 = Debug|x86
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x64.ActiveCfg = Release|x64
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x64.Build.0 = Release|x64
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x86.ActiveCfg = Release|x86
|
||||
{80AEC261-21EE-4E4F-A93B-7A744DC84888}.Release|x86.Build.0 = Release|x86
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x64.Build.0 = Debug|x64
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Debug|x86.Build.0 = Debug|x86
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x64.ActiveCfg = Release|x64
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x64.Build.0 = Release|x64
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x86.ActiveCfg = Release|x86
|
||||
{52B196FB-4C8A-499B-B877-1A0EB4F33EC0}.Release|x86.Build.0 = Release|x86
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x64.Build.0 = Release|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{422FEC21-EF60-4F29-AA56-95DFDA23C913}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0B2BE613-3049-4021-85D1-21C325F729F4}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E301AFEA-84E7-4BCE-8D65-A2576D8D105B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x64.Build.0 = Release|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{29EAD018-1C67-497A-AB8E-727D595AD756}.Release|x86.Build.0 = Release|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x64.Build.0 = Release|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{65EAFFA3-01D3-4EF5-B092-8B4647E9A1FF}.Release|x86.Build.0 = Release|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{6438FEC1-56B0-488C-A5E2-FBDB23E9574B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|Any CPU.Build.0 = Debug|Win32
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|x64.Build.0 = Debug|x64
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Debug|x86.Build.0 = Debug|Win32
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|Any CPU.Build.0 = Release|Win32
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x64.ActiveCfg = Release|x64
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x64.Build.0 = Release|x64
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x86.ActiveCfg = Release|Win32
|
||||
{11EA25A3-ED68-40EE-A9D0-7FDE3B583027}.Release|x86.Build.0 = Release|Win32
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|Any CPU.ActiveCfg = Debug|Win32
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|Any CPU.Build.0 = Debug|Win32
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|x64.Build.0 = Debug|x64
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Debug|x86.Build.0 = Debug|Win32
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|Any CPU.ActiveCfg = Release|Win32
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|Any CPU.Build.0 = Release|Win32
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x64.ActiveCfg = Release|x64
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x64.Build.0 = Release|x64
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x86.ActiveCfg = Release|Win32
|
||||
{29356642-C46E-4144-83D8-22DC09D0D7FD}.Release|x86.Build.0 = Release|Win32
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|x64.Build.0 = Release|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{34B6329B-0E73-45AC-B8CC-015F119F63DC}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F8734F96-97B6-40CA-B791-6D5467F2F713}
|
||||
SolutionGuid = {3C074481-9CDD-4780-B9F6-57BBC5092EA2}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -1,154 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{7662F8C2-7BFD-442E-A948-A43B4F7EB06E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>AssetStudio</RootNamespace>
|
||||
<AssemblyName>AssetStudio</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TargetFrameworks>net472;net8.0;net8.0-windows;net9.0;net9.0-windows</TargetFrameworks>
|
||||
<Version>0.19.0.0</Version>
|
||||
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2021-2025</Copyright>
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<PackageReference Include="ZstdSharp.Port" Version="0.8.6" />
|
||||
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.8" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="7zip\Common\CommandLineParser.cs" />
|
||||
<Compile Include="7zip\Common\CRC.cs" />
|
||||
<Compile Include="7zip\Common\InBuffer.cs" />
|
||||
<Compile Include="7zip\Common\OutBuffer.cs" />
|
||||
<Compile Include="7zip\Compress\LZMA\LzmaBase.cs" />
|
||||
<Compile Include="7zip\Compress\LZMA\LzmaDecoder.cs" />
|
||||
<Compile Include="7zip\Compress\LZMA\LzmaEncoder.cs" />
|
||||
<Compile Include="7zip\Compress\LZ\IMatchFinder.cs" />
|
||||
<Compile Include="7zip\Compress\LZ\LzBinTree.cs" />
|
||||
<Compile Include="7zip\Compress\LZ\LzInWindow.cs" />
|
||||
<Compile Include="7zip\Compress\LZ\LzOutWindow.cs" />
|
||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoder.cs" />
|
||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBit.cs" />
|
||||
<Compile Include="7zip\Compress\RangeCoder\RangeCoderBitTree.cs" />
|
||||
<Compile Include="7zip\ICoder.cs" />
|
||||
<Compile Include="AssetsManager.cs" />
|
||||
<Compile Include="Brotli\BitReader.cs" />
|
||||
<Compile Include="Brotli\BrotliInputStream.cs" />
|
||||
<Compile Include="Brotli\BrotliRuntimeException.cs" />
|
||||
<Compile Include="Brotli\Context.cs" />
|
||||
<Compile Include="Brotli\Decode.cs" />
|
||||
<Compile Include="Brotli\Dictionary.cs" />
|
||||
<Compile Include="Brotli\Huffman.cs" />
|
||||
<Compile Include="Brotli\HuffmanTreeGroup.cs" />
|
||||
<Compile Include="Brotli\IntReader.cs" />
|
||||
<Compile Include="Brotli\Prefix.cs" />
|
||||
<Compile Include="Brotli\RunningState.cs" />
|
||||
<Compile Include="Brotli\State.cs" />
|
||||
<Compile Include="Brotli\Transform.cs" />
|
||||
<Compile Include="Brotli\Utils.cs" />
|
||||
<Compile Include="Brotli\WordTransformType.cs" />
|
||||
<Compile Include="BuildTarget.cs" />
|
||||
<Compile Include="BuildType.cs" />
|
||||
<Compile Include="BundleFile.cs" />
|
||||
<Compile Include="Classes\Animation.cs" />
|
||||
<Compile Include="Classes\AnimationClip.cs" />
|
||||
<Compile Include="Classes\Animator.cs" />
|
||||
<Compile Include="Classes\AnimatorController.cs" />
|
||||
<Compile Include="Classes\AnimatorOverrideController.cs" />
|
||||
<Compile Include="Classes\AssetBundle.cs" />
|
||||
<Compile Include="Classes\AudioClip.cs" />
|
||||
<Compile Include="Classes\Avatar.cs" />
|
||||
<Compile Include="Classes\Behaviour.cs" />
|
||||
<Compile Include="Classes\BuildSettings.cs" />
|
||||
<Compile Include="Classes\Component.cs" />
|
||||
<Compile Include="Classes\EditorExtension.cs" />
|
||||
<Compile Include="Classes\Font.cs" />
|
||||
<Compile Include="Classes\GameObject.cs" />
|
||||
<Compile Include="Classes\Material.cs" />
|
||||
<Compile Include="Classes\Mesh.cs" />
|
||||
<Compile Include="Classes\MeshFilter.cs" />
|
||||
<Compile Include="Classes\MeshRenderer.cs" />
|
||||
<Compile Include="Classes\MonoBehaviour.cs" />
|
||||
<Compile Include="Classes\MonoScript.cs" />
|
||||
<Compile Include="Classes\MovieTexture.cs" />
|
||||
<Compile Include="Classes\NamedObject.cs" />
|
||||
<Compile Include="Classes\Object.cs" />
|
||||
<Compile Include="Classes\PlayerSettings.cs" />
|
||||
<Compile Include="Classes\PPtr.cs" />
|
||||
<Compile Include="Classes\RectTransform.cs" />
|
||||
<Compile Include="Classes\Renderer.cs" />
|
||||
<Compile Include="Classes\RuntimeAnimatorController.cs" />
|
||||
<Compile Include="Classes\Shader.cs" />
|
||||
<Compile Include="Classes\SkinnedMeshRenderer.cs" />
|
||||
<Compile Include="Classes\Sprite.cs" />
|
||||
<Compile Include="Classes\SpriteAtlas.cs" />
|
||||
<Compile Include="Classes\TextAsset.cs" />
|
||||
<Compile Include="Classes\Texture.cs" />
|
||||
<Compile Include="Classes\Texture2D.cs" />
|
||||
<Compile Include="Classes\Transform.cs" />
|
||||
<Compile Include="Classes\VideoClip.cs" />
|
||||
<Compile Include="ClassIDType.cs" />
|
||||
<Compile Include="CommonString.cs" />
|
||||
<Compile Include="EndianBinaryReader.cs" />
|
||||
<Compile Include="Extensions\BinaryReaderExtensions.cs" />
|
||||
<Compile Include="Extensions\BinaryWriterExtensions.cs" />
|
||||
<Compile Include="Extensions\StreamExtensions.cs" />
|
||||
<Compile Include="FileIdentifier.cs" />
|
||||
<Compile Include="IImported.cs" />
|
||||
<Compile Include="ILogger.cs" />
|
||||
<Compile Include="ImportHelper.cs" />
|
||||
<Compile Include="IProgress.cs" />
|
||||
<Compile Include="LocalSerializedObjectIdentifier.cs" />
|
||||
<Compile Include="Logger.cs" />
|
||||
<Compile Include="Lz4DecoderStream.cs" />
|
||||
<Compile Include="Math\Color.cs" />
|
||||
<Compile Include="Math\Half.cs" />
|
||||
<Compile Include="Math\HalfHelper.cs" />
|
||||
<Compile Include="Math\Matrix4x4.cs" />
|
||||
<Compile Include="Math\Quaternion.cs" />
|
||||
<Compile Include="Math\Vector2.cs" />
|
||||
<Compile Include="Math\Vector3.cs" />
|
||||
<Compile Include="Math\Vector4.cs" />
|
||||
<Compile Include="ObjectInfo.cs" />
|
||||
<Compile Include="ObjectReader.cs" />
|
||||
<Compile Include="Progress.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ResourceReader.cs" />
|
||||
<Compile Include="SerializedFile.cs" />
|
||||
<Compile Include="SerializedFileHeader.cs" />
|
||||
<Compile Include="SerializedType.cs" />
|
||||
<Compile Include="SevenZipHelper.cs" />
|
||||
<Compile Include="StreamFile.cs" />
|
||||
<Compile Include="TypeTreeHelper.cs" />
|
||||
<Compile Include="TypeTreeNode.cs" />
|
||||
<Compile Include="UType.cs" />
|
||||
<Compile Include="WebFile.cs" />
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
|
||||
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Bcl.Numerics" Version="9.0.8" />
|
||||
|
||||
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,34 +1,131 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.Json;
|
||||
using AssetStudio.CustomOptions;
|
||||
using AssetStudio.CustomOptions.Asmo;
|
||||
using static AssetStudio.ImportHelper;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class AssetsManager
|
||||
{
|
||||
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
|
||||
public bool LoadViaTypeTree = true;
|
||||
public bool MeshLazyLoad = true;
|
||||
public ImportOptions Options = new ImportOptions();
|
||||
public readonly List<Action<OptionsFile>> OptionLoaders = new List<Action<OptionsFile>>();
|
||||
public readonly List<SerializedFile> AssetsFileList = new List<SerializedFile>();
|
||||
|
||||
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
||||
internal Dictionary<string, BinaryReader> resourceFileReaders = new Dictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
|
||||
internal ConcurrentDictionary<string, BinaryReader> resourceFileReaders = new ConcurrentDictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private List<string> importFiles = new List<string>();
|
||||
private HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
private HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly List<string> importFiles = new List<string>();
|
||||
private readonly HashSet<ClassIDType> filteredAssetTypesList = new HashSet<ClassIDType>();
|
||||
private readonly HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public void LoadFiles(params string[] files)
|
||||
public AssetsManager()
|
||||
{
|
||||
var path = Path.GetDirectoryName(files[0]);
|
||||
MergeSplitAssets(path);
|
||||
var toReadFile = ProcessingSplitFiles(files.ToList());
|
||||
Load(toReadFile);
|
||||
OptionLoaders.Add(LoadImportOptions);
|
||||
}
|
||||
|
||||
public void LoadFolder(string path)
|
||||
public void SetAssetFilter(params ClassIDType[] classIDTypes)
|
||||
{
|
||||
MergeSplitAssets(path, true);
|
||||
var files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).ToList();
|
||||
var toReadFile = ProcessingSplitFiles(files);
|
||||
filteredAssetTypesList.UnionWith(new[]
|
||||
{
|
||||
ClassIDType.AssetBundle,
|
||||
ClassIDType.ResourceManager,
|
||||
ClassIDType.GameObject,
|
||||
ClassIDType.Transform,
|
||||
ClassIDType.RectTransform,
|
||||
});
|
||||
|
||||
if (classIDTypes.Contains(ClassIDType.MonoBehaviour))
|
||||
{
|
||||
filteredAssetTypesList.Add(ClassIDType.MonoScript);
|
||||
}
|
||||
if (classIDTypes.Contains(ClassIDType.Sprite))
|
||||
{
|
||||
filteredAssetTypesList.Add(ClassIDType.Texture2D);
|
||||
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);
|
||||
}
|
||||
|
||||
public void SetAssetFilter(List<ClassIDType> classIDTypeList)
|
||||
{
|
||||
SetAssetFilter(classIDTypeList.ToArray());
|
||||
}
|
||||
|
||||
public void LoadFilesAndFolders(params string[] paths)
|
||||
{
|
||||
LoadFilesAndFolders(out _, paths.ToList());
|
||||
}
|
||||
|
||||
public void LoadFilesAndFolders(out string parentPath, params string[] paths)
|
||||
{
|
||||
LoadFilesAndFolders(out parentPath, paths.ToList());
|
||||
}
|
||||
|
||||
public void LoadFilesAndFolders(out string parentPath, List<string> pathList)
|
||||
{
|
||||
var fileList = new List<string>();
|
||||
var filesInPath = false;
|
||||
parentPath = "";
|
||||
foreach (var path in pathList)
|
||||
{
|
||||
var fullPath = Path.GetFullPath(path);
|
||||
if (Directory.Exists(fullPath))
|
||||
{
|
||||
var parent = Directory.GetParent(fullPath)?.FullName;
|
||||
if (!filesInPath && (parentPath == "" || parentPath?.Length > parent?.Length))
|
||||
{
|
||||
parentPath = parent;
|
||||
}
|
||||
MergeSplitAssets(fullPath, true);
|
||||
fileList.AddRange(Directory.GetFiles(fullPath, "*.*", SearchOption.AllDirectories));
|
||||
}
|
||||
else if (File.Exists(fullPath))
|
||||
{
|
||||
parentPath = Path.GetDirectoryName(fullPath);
|
||||
fileList.Add(fullPath);
|
||||
filesInPath = true;
|
||||
}
|
||||
}
|
||||
if (filesInPath)
|
||||
{
|
||||
MergeSplitAssets(parentPath);
|
||||
}
|
||||
LoadOptionFiles(fileList);
|
||||
|
||||
var toReadFile = ProcessingSplitFiles(fileList);
|
||||
fileList.Clear();
|
||||
pathList.Clear();
|
||||
|
||||
Load(toReadFile);
|
||||
}
|
||||
|
||||
@@ -44,172 +141,275 @@ namespace AssetStudio
|
||||
//use a for loop because list size can change
|
||||
for (var i = 0; i < importFiles.Count; i++)
|
||||
{
|
||||
LoadFile(importFiles[i]);
|
||||
Progress.Report(i + 1, importFiles.Count);
|
||||
if (LoadFile(importFiles[i]))
|
||||
{
|
||||
Progress.Report(i + 1, importFiles.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
importFiles.Clear();
|
||||
importFilesHash.Clear();
|
||||
noexistFiles.Clear();
|
||||
assetsFileListHash.Clear();
|
||||
if (AssetsFileList.Count == 0)
|
||||
return;
|
||||
|
||||
ReadAssets();
|
||||
ProcessAssets();
|
||||
}
|
||||
|
||||
private void LoadFile(string fullName)
|
||||
private bool LoadFile(string fullName)
|
||||
{
|
||||
switch (CheckFileType(fullName, out var reader))
|
||||
{
|
||||
case FileType.AssetsFile:
|
||||
LoadAssetsFile(fullName, reader);
|
||||
break;
|
||||
case FileType.BundleFile:
|
||||
LoadBundleFile(fullName, reader);
|
||||
break;
|
||||
case FileType.WebFile:
|
||||
LoadWebFile(fullName, reader);
|
||||
break;
|
||||
}
|
||||
var reader = new FileReader(fullName);
|
||||
return LoadFile(reader);
|
||||
}
|
||||
|
||||
private void LoadAssetsFile(string fullName, EndianBinaryReader reader)
|
||||
private bool LoadFile(FileReader reader, bool fromZip = false)
|
||||
{
|
||||
var fileName = Path.GetFileName(fullName);
|
||||
if (!assetsFileListHash.Contains(fileName))
|
||||
if (reader == null)
|
||||
return false;
|
||||
|
||||
switch (reader.FileType)
|
||||
{
|
||||
Logger.Info($"Loading {fileName}");
|
||||
case FileType.AssetsFile:
|
||||
return LoadAssetsFile(reader, fromZip);
|
||||
case FileType.BundleFile:
|
||||
return LoadBundleFile(reader);
|
||||
case FileType.WebFile:
|
||||
LoadWebFile(reader);
|
||||
break;
|
||||
case FileType.GZipFile:
|
||||
LoadFile(DecompressGZip(reader));
|
||||
break;
|
||||
case FileType.BrotliFile:
|
||||
LoadFile(DecompressBrotli(reader));
|
||||
break;
|
||||
case FileType.ZipFile:
|
||||
LoadZipFile(reader);
|
||||
break;
|
||||
case FileType.ResourceFile when !fromZip:
|
||||
reader.Dispose();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool LoadAssetsFile(FileReader reader, bool fromZip)
|
||||
{
|
||||
if (!assetsFileListHash.Contains(reader.FileName))
|
||||
{
|
||||
Logger.Info($"Loading \"{reader.FullPath}\"");
|
||||
try
|
||||
{
|
||||
var assetsFile = new SerializedFile(this, fullName, reader);
|
||||
assetsFileList.Add(assetsFile);
|
||||
var assetsFile = new SerializedFile(reader, this);
|
||||
var dirName = Path.GetDirectoryName(reader.FullPath);
|
||||
CheckStrippedVersion(assetsFile);
|
||||
AssetsFileList.Add(assetsFile);
|
||||
assetsFileListHash.Add(assetsFile.fileName);
|
||||
if (fromZip)
|
||||
return true;
|
||||
|
||||
foreach (var sharedFile in assetsFile.m_Externals)
|
||||
{
|
||||
var sharedFilePath = Path.GetDirectoryName(fullName) + "\\" + sharedFile.fileName;
|
||||
var sharedFileName = sharedFile.fileName;
|
||||
|
||||
if (!importFilesHash.Contains(sharedFileName))
|
||||
{
|
||||
if (!File.Exists(sharedFilePath))
|
||||
var sharedFilePath = Path.Combine(dirName, sharedFileName);
|
||||
if (!noexistFiles.Contains(sharedFilePath))
|
||||
{
|
||||
var findFiles = Directory.GetFiles(Path.GetDirectoryName(fullName), sharedFileName, SearchOption.AllDirectories);
|
||||
if (findFiles.Length > 0)
|
||||
if (!File.Exists(sharedFilePath))
|
||||
{
|
||||
sharedFilePath = findFiles[0];
|
||||
var findFiles = Directory.GetFiles(dirName, sharedFileName, SearchOption.AllDirectories);
|
||||
if (findFiles.Length > 0)
|
||||
{
|
||||
sharedFilePath = findFiles[0];
|
||||
}
|
||||
}
|
||||
if (File.Exists(sharedFilePath))
|
||||
{
|
||||
importFiles.Add(sharedFilePath);
|
||||
importFilesHash.Add(sharedFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
noexistFiles.Add(sharedFilePath);
|
||||
Logger.Warning($"Dependency wasn't found: {sharedFilePath}");
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(sharedFilePath))
|
||||
{
|
||||
importFiles.Add(sharedFilePath);
|
||||
importFilesHash.Add(sharedFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch (NotSupportedException e)
|
||||
{
|
||||
Logger.Error(e.Message);
|
||||
reader.Dispose();
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warning($"Failed to read assets file \"{reader.FullPath}\"\n{e}");
|
||||
reader.Dispose();
|
||||
//Logger.Warning($"Unable to load assets file {fileName}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info($"Skipping \"{reader.FullPath}\"");
|
||||
reader.Dispose();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void LoadAssetsFromMemory(string fullName, EndianBinaryReader reader, string originalPath, string unityVersion = null)
|
||||
private bool LoadAssetsFromMemory(FileReader reader, string originalPath, UnityVersion assetBundleUnityVer = null)
|
||||
{
|
||||
var fileName = Path.GetFileName(fullName);
|
||||
if (!assetsFileListHash.Contains(fileName))
|
||||
if (!assetsFileListHash.Contains(reader.FileName))
|
||||
{
|
||||
try
|
||||
{
|
||||
var assetsFile = new SerializedFile(this, fullName, reader);
|
||||
var assetsFile = new SerializedFile(reader, this);
|
||||
assetsFile.originalPath = originalPath;
|
||||
if (assetsFile.header.m_Version < 7)
|
||||
if (assetBundleUnityVer != null && assetsFile.header.m_Version < SerializedFileFormatVersion.Unknown_7)
|
||||
{
|
||||
assetsFile.SetVersion(unityVersion);
|
||||
assetsFile.version = assetBundleUnityVer;
|
||||
}
|
||||
assetsFileList.Add(assetsFile);
|
||||
CheckStrippedVersion(assetsFile, assetBundleUnityVer);
|
||||
AssetsFileList.Add(assetsFile);
|
||||
assetsFileListHash.Add(assetsFile.fileName);
|
||||
}
|
||||
catch
|
||||
catch (NotSupportedException e)
|
||||
{
|
||||
//Logger.Error($"Unable to load assets file {fileName} from {Path.GetFileName(originalPath)}");
|
||||
resourceFileReaders.Add(fileName, reader);
|
||||
Logger.Error(e.Message);
|
||||
reader.Dispose();
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warning($"Failed to read assets file \"{reader.FullPath}\" from {Path.GetFileName(originalPath)}\n{e}");
|
||||
resourceFileReaders.TryAdd(reader.FileName, reader);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info($"Skipping \"{originalPath}\" ({reader.FileName})");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void LoadBundleFile(string fullName, EndianBinaryReader reader, string parentPath = null)
|
||||
private bool LoadBundleFile(FileReader reader, string originalPath = null)
|
||||
{
|
||||
var fileName = Path.GetFileName(fullName);
|
||||
Logger.Info("Loading " + fileName);
|
||||
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
|
||||
{
|
||||
var bundleFile = new BundleFile(reader, fullName);
|
||||
foreach (var file in bundleFile.fileList)
|
||||
var bundleFile = new BundleFile(bundleReader, Options.BundleOptions);
|
||||
isLoaded = LoadBundleFiles(bundleReader, bundleFile, originalPath);
|
||||
if (!isLoaded)
|
||||
return false;
|
||||
|
||||
while (bundleFile.IsDataAfterBundle && isLoaded)
|
||||
{
|
||||
var subReader = new EndianBinaryReader(file.stream);
|
||||
if (SerializedFile.IsSerializedFile(subReader))
|
||||
isLoaded = false;
|
||||
bundleStream.Offset = reader.Position;
|
||||
bundleReader = new FileReader($"{reader.FullPath}_0x{bundleStream.Offset:X}", bundleStream);
|
||||
if (bundleReader.FileType != FileType.BundleFile)
|
||||
{
|
||||
var dummyPath = Path.GetDirectoryName(fullName) + Path.DirectorySeparatorChar + file.fileName;
|
||||
LoadAssetsFromMemory(dummyPath, subReader, parentPath ?? fullName, bundleFile.m_Header.unityRevision);
|
||||
Logger.Debug("Unknown data was detected after the end of the bundle.");
|
||||
break;
|
||||
}
|
||||
else
|
||||
if (bundleReader.Position > 0)
|
||||
{
|
||||
resourceFileReaders.Add(file.fileName, subReader);
|
||||
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
|
||||
catch (NotSupportedException e)
|
||||
{
|
||||
/*var str = $"Unable to load bundle file {fileName}";
|
||||
if (parentPath != null)
|
||||
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(parentPath)}";
|
||||
str += $" from {Path.GetFileName(originalPath)}";
|
||||
}
|
||||
Logger.Error(str);*/
|
||||
Logger.Warning($"{str}\n{e}");
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader.Dispose();
|
||||
if (!isLoaded)
|
||||
bundleReader.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadWebFile(string fullName, EndianBinaryReader reader)
|
||||
private bool LoadBundleFiles(FileReader reader, BundleFile bundleFile, string originalPath = null)
|
||||
{
|
||||
var fileName = Path.GetFileName(fullName);
|
||||
Logger.Info("Loading " + fileName);
|
||||
foreach (var file in bundleFile.fileList)
|
||||
{
|
||||
if (file.stream == null)
|
||||
continue;
|
||||
file.stream.Position = 0; //go to file offset
|
||||
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
|
||||
var subReader = new FileReader(dummyPath, file.stream);
|
||||
if (subReader.FileType == FileType.AssetsFile)
|
||||
{
|
||||
if (!LoadAssetsFromMemory(subReader, originalPath ?? reader.FullPath, bundleFile.m_Header.unityRevision))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
resourceFileReaders.TryAdd(file.fileName, subReader);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void LoadWebFile(FileReader reader)
|
||||
{
|
||||
Logger.Info($"Loading \"{reader.FullPath}\"");
|
||||
try
|
||||
{
|
||||
var webFile = new WebFile(reader);
|
||||
foreach (var file in webFile.fileList)
|
||||
{
|
||||
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
|
||||
switch (CheckFileType(file.stream, out var fileReader))
|
||||
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
|
||||
var subReader = new FileReader(dummyPath, file.stream);
|
||||
switch (subReader.FileType)
|
||||
{
|
||||
case FileType.AssetsFile:
|
||||
LoadAssetsFromMemory(dummyPath, fileReader, fullName);
|
||||
LoadAssetsFromMemory(subReader, reader.FullPath);
|
||||
break;
|
||||
case FileType.BundleFile:
|
||||
LoadBundleFile(dummyPath, fileReader, fullName);
|
||||
LoadBundleFile(subReader, reader.FullPath);
|
||||
break;
|
||||
case FileType.WebFile:
|
||||
LoadWebFile(dummyPath, fileReader);
|
||||
LoadWebFile(subReader);
|
||||
break;
|
||||
case FileType.ResourceFile:
|
||||
resourceFileReaders.Add(file.fileName, fileReader);
|
||||
resourceFileReaders.TryAdd(file.fileName, subReader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
//Logger.Error($"Unable to load web file {fileName}");
|
||||
Logger.Error($"Error while reading web file \"{reader.FullPath}\"", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -217,14 +417,199 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadZipFile(FileReader reader)
|
||||
{
|
||||
Logger.Info("Reading " + reader.FileName);
|
||||
try
|
||||
{
|
||||
using (ZipArchive archive = new ZipArchive(reader.BaseStream, ZipArchiveMode.Read))
|
||||
{
|
||||
List<string> splitFiles = new List<string>();
|
||||
// register all files before parsing the assets so that the external references can be found
|
||||
// and find split files
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
{
|
||||
if (entry.Name.Contains(".split"))
|
||||
{
|
||||
string baseName = Path.GetFileNameWithoutExtension(entry.Name);
|
||||
string basePath = Path.Combine(Path.GetDirectoryName(entry.FullName), baseName);
|
||||
if (!splitFiles.Contains(basePath))
|
||||
{
|
||||
splitFiles.Add(basePath);
|
||||
importFilesHash.Add(baseName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
importFilesHash.Add(entry.Name);
|
||||
}
|
||||
}
|
||||
|
||||
// merge split files and load the result
|
||||
for (var i = 0; i < splitFiles.Count; i++)
|
||||
{
|
||||
var basePath = splitFiles[i].Replace("\\", "/");
|
||||
try
|
||||
{
|
||||
Stream splitStream = new MemoryStream();
|
||||
var j = 0;
|
||||
while (true)
|
||||
{
|
||||
string path = $"{basePath}.split{j++}";
|
||||
ZipArchiveEntry entry = archive.GetEntry(path);
|
||||
if (entry == null)
|
||||
break;
|
||||
using (Stream entryStream = entry.Open())
|
||||
{
|
||||
entryStream.CopyTo(splitStream);
|
||||
}
|
||||
}
|
||||
splitStream.Seek(0, SeekOrigin.Begin);
|
||||
FileReader entryReader = new FileReader(basePath, splitStream);
|
||||
if (!LoadFile(entryReader, fromZip: true))
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warning($"Error while reading zip split file \"{basePath}\"\n{e}");
|
||||
}
|
||||
}
|
||||
|
||||
// load all entries
|
||||
var progressCount = archive.Entries.Count;
|
||||
int k = 0;
|
||||
Progress.Reset();
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
{
|
||||
if (entry.Length == 0)
|
||||
continue;
|
||||
try
|
||||
{
|
||||
string dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), reader.FileName, entry.FullName);
|
||||
// create a new stream
|
||||
// - to store the deflated stream in
|
||||
// - to keep the data for later extraction
|
||||
Stream streamReader = new MemoryStream();
|
||||
using (Stream entryStream = entry.Open())
|
||||
{
|
||||
entryStream.CopyTo(streamReader);
|
||||
}
|
||||
streamReader.Position = 0;
|
||||
|
||||
FileReader entryReader = new FileReader(dummyPath, streamReader);
|
||||
if (!LoadFile(entryReader, fromZip: true))
|
||||
break;
|
||||
|
||||
if (entryReader.FileType == FileType.ResourceFile)
|
||||
{
|
||||
entryReader.Position = 0;
|
||||
resourceFileReaders.TryAdd(entry.Name, entryReader);
|
||||
}
|
||||
Progress.Report(++k, progressCount);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warning($"Error while reading zip entry \"{entry.FullName}\"\n{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Error while reading zip file {reader.FileName}", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (assetsFile.version.IsStripped && Options.CustomUnityVersion == null)
|
||||
{
|
||||
var msg = "The asset's Unity version has been stripped, please set the version in the options.";
|
||||
if (bundleUnityVer != null && !bundleUnityVer.IsStripped)
|
||||
msg += $"\n\nAssumed Unity version based on asset bundle: {bundleUnityVer}";
|
||||
throw new NotSupportedException(msg);
|
||||
}
|
||||
if (Options.CustomUnityVersion != null)
|
||||
{
|
||||
assetsFile.version = Options.CustomUnityVersion;
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var assetsFile in assetsFileList)
|
||||
foreach (var assetsFile in AssetsFileList)
|
||||
{
|
||||
assetsFile.Objects.Clear();
|
||||
assetsFile.reader.Close();
|
||||
}
|
||||
assetsFileList.Clear();
|
||||
AssetsFileList.Clear();
|
||||
|
||||
foreach (var resourceFileReader in resourceFileReaders)
|
||||
{
|
||||
@@ -239,24 +624,39 @@ namespace AssetStudio
|
||||
{
|
||||
Logger.Info("Read assets...");
|
||||
|
||||
var progressCount = assetsFileList.Sum(x => x.m_Objects.Count);
|
||||
int i = 0;
|
||||
Progress.Reset();
|
||||
foreach (var assetsFile in assetsFileList)
|
||||
var jsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
Converters = { new JsonConverterHelper.ByteArrayConverter(), new JsonConverterHelper.PPtrConverter(), new JsonConverterHelper.KVPConverter() },
|
||||
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
|
||||
PropertyNameCaseInsensitive = true,
|
||||
IncludeFields = true,
|
||||
};
|
||||
|
||||
var progressCount = AssetsFileList.Sum(x => x.m_Objects.Count);
|
||||
var i = 0;
|
||||
Progress.Reset();
|
||||
foreach (var assetsFile in AssetsFileList)
|
||||
{
|
||||
JsonConverterHelper.AssetsFile = assetsFile;
|
||||
foreach (var objectInfo in assetsFile.m_Objects)
|
||||
{
|
||||
var objectReader = new ObjectReader(assetsFile.reader, assetsFile, objectInfo);
|
||||
if (filteredAssetTypesList.Count > 0 && !filteredAssetTypesList.Contains(objectReader.type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
Object obj;
|
||||
Object obj = null;
|
||||
switch (objectReader.type)
|
||||
{
|
||||
case ClassIDType.Animation:
|
||||
obj = new Animation(objectReader);
|
||||
break;
|
||||
case ClassIDType.AnimationClip:
|
||||
obj = new AnimationClip(objectReader);
|
||||
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
|
||||
? new AnimationClip(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions, objectInfo)
|
||||
: new AnimationClip(objectReader);
|
||||
break;
|
||||
case ClassIDType.Animator:
|
||||
obj = new Animator(objectReader);
|
||||
@@ -276,6 +676,9 @@ namespace AssetStudio
|
||||
case ClassIDType.Avatar:
|
||||
obj = new Avatar(objectReader);
|
||||
break;
|
||||
case ClassIDType.BuildSettings:
|
||||
obj = new BuildSettings(objectReader);
|
||||
break;
|
||||
case ClassIDType.Font:
|
||||
obj = new Font(objectReader);
|
||||
break;
|
||||
@@ -283,7 +686,9 @@ namespace AssetStudio
|
||||
obj = new GameObject(objectReader);
|
||||
break;
|
||||
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;
|
||||
case ClassIDType.Mesh:
|
||||
obj = new Mesh(objectReader);
|
||||
@@ -306,11 +711,15 @@ namespace AssetStudio
|
||||
case ClassIDType.PlayerSettings:
|
||||
obj = new PlayerSettings(objectReader);
|
||||
break;
|
||||
case ClassIDType.PreloadData:
|
||||
obj = new PreloadData(objectReader);
|
||||
break;
|
||||
case ClassIDType.RectTransform:
|
||||
obj = new RectTransform(objectReader);
|
||||
break;
|
||||
case ClassIDType.Shader:
|
||||
obj = new Shader(objectReader);
|
||||
if (objectReader.version < 2021)
|
||||
obj = new Shader(objectReader);
|
||||
break;
|
||||
case ClassIDType.SkinnedMeshRenderer:
|
||||
obj = new SkinnedMeshRenderer(objectReader);
|
||||
@@ -325,7 +734,14 @@ namespace AssetStudio
|
||||
obj = new TextAsset(objectReader);
|
||||
break;
|
||||
case ClassIDType.Texture2D:
|
||||
obj = new Texture2D(objectReader);
|
||||
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
|
||||
? new Texture2D(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions)
|
||||
: new Texture2D(objectReader);
|
||||
break;
|
||||
case ClassIDType.Texture2DArray:
|
||||
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
|
||||
? new Texture2DArray(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions)
|
||||
: new Texture2DArray(objectReader);
|
||||
break;
|
||||
case ClassIDType.Transform:
|
||||
obj = new Transform(objectReader);
|
||||
@@ -333,21 +749,28 @@ namespace AssetStudio
|
||||
case ClassIDType.VideoClip:
|
||||
obj = new VideoClip(objectReader);
|
||||
break;
|
||||
case ClassIDType.ResourceManager:
|
||||
obj = new ResourceManager(objectReader);
|
||||
break;
|
||||
default:
|
||||
obj = new Object(objectReader);
|
||||
break;
|
||||
}
|
||||
assetsFile.AddObject(obj);
|
||||
if (obj != null)
|
||||
{
|
||||
assetsFile.AddObject(obj);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
/*var sb = new StringBuilder();
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Unable to load object")
|
||||
.AppendLine($"Assets {assetsFile.fileName}")
|
||||
.AppendLine($"Path {assetsFile.originalPath}")
|
||||
.AppendLine($"Type {objectReader.type}")
|
||||
.AppendLine($"PathID {objectInfo.m_PathID}")
|
||||
.Append(e);
|
||||
Logger.Error(sb.ToString());*/
|
||||
Logger.Warning(sb.ToString());
|
||||
}
|
||||
|
||||
Progress.Report(++i, progressCount);
|
||||
@@ -357,9 +780,9 @@ namespace AssetStudio
|
||||
|
||||
private void ProcessAssets()
|
||||
{
|
||||
Logger.Info("Process Assets...");
|
||||
Logger.Info("Process assets...");
|
||||
|
||||
foreach (var assetsFile in assetsFileList)
|
||||
foreach (var assetsFile in AssetsFileList)
|
||||
{
|
||||
foreach (var obj in assetsFile.Objects)
|
||||
{
|
||||
@@ -389,6 +812,34 @@ namespace AssetStudio
|
||||
case Animation m_Animation:
|
||||
m_GameObject.m_Animation = m_Animation;
|
||||
break;
|
||||
case MonoBehaviour m_MonoBehaviour:
|
||||
if (m_MonoBehaviour.m_Script.TryGet(out var m_Script))
|
||||
{
|
||||
switch (m_Script.m_ClassName)
|
||||
{
|
||||
case "CubismModel":
|
||||
if (m_GameObject.m_Transform == null)
|
||||
break;
|
||||
m_GameObject.CubismModel = new CubismModel(m_GameObject)
|
||||
{
|
||||
CubismModelMono = m_MonoBehaviour
|
||||
};
|
||||
break;
|
||||
case "CubismPhysicsController":
|
||||
if (m_GameObject.CubismModel != null)
|
||||
m_GameObject.CubismModel.PhysicsController = m_MonoBehaviour;
|
||||
break;
|
||||
case "CubismFadeController":
|
||||
if (m_GameObject.CubismModel != null)
|
||||
m_GameObject.CubismModel.FadeController = m_MonoBehaviour;
|
||||
break;
|
||||
case "CubismExpressionController":
|
||||
if (m_GameObject.CubismModel != null)
|
||||
m_GameObject.CubismModel.ExpressionController = m_MonoBehaviour;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -403,6 +854,18 @@ namespace AssetStudio
|
||||
{
|
||||
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
||||
}
|
||||
else if (m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlasOld))
|
||||
{
|
||||
if (m_SpriteAtlasOld.m_IsVariant)
|
||||
{
|
||||
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Debug($"\"{m_Sprite.m_Name}\": The actual SpriteAtlas PathID \"{m_SpriteAtlas.m_PathID}\" does not match the specified one \"{m_Sprite.m_SpriteAtlas.m_PathID}\".");
|
||||
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -410,4 +873,4 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
AssetStudio/BigArrayPool.cs
Normal file
14
AssetStudio/BigArrayPool.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Buffers;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static class BigArrayPool<T>
|
||||
{
|
||||
public static ArrayPool<T> Shared { get; }
|
||||
|
||||
static BigArrayPool()
|
||||
{
|
||||
Shared = ArrayPool<T>.Create(256 * 1024 * 1024, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public enum BuildTarget
|
||||
{
|
||||
UnknownPlatform = 3716,
|
||||
DashboardWidget = 1,
|
||||
NoTarget = -2,
|
||||
AnyPlayer = -1,
|
||||
ValidPlayer = 1,
|
||||
StandaloneOSX = 2,
|
||||
StandaloneOSXPPC = 3,
|
||||
StandaloneOSXIntel = 4,
|
||||
@@ -19,8 +15,10 @@ namespace AssetStudio
|
||||
iOS = 9,
|
||||
PS3,
|
||||
XBOX360,
|
||||
Broadcom = 12,
|
||||
Android = 13,
|
||||
StandaloneGLESEmu = 14,
|
||||
StandaloneGLES20Emu = 15,
|
||||
NaCl = 16,
|
||||
StandaloneLinux = 17,
|
||||
FlashPlayer = 18,
|
||||
@@ -42,6 +40,26 @@ namespace AssetStudio
|
||||
WiiU,
|
||||
tvOS,
|
||||
Switch,
|
||||
NoTarget = -2
|
||||
Lumin,
|
||||
Stadia,
|
||||
CloudRendering,
|
||||
GameCoreXboxSeries,
|
||||
GameCoreXboxOne,
|
||||
PS5,
|
||||
EmbeddedLinux,
|
||||
QNX,
|
||||
VisionOS,
|
||||
Switch2,
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,26 +22,26 @@ namespace SevenZip
|
||||
}
|
||||
}
|
||||
|
||||
uint _value = 0xFFFFFFFF;
|
||||
private uint _value = 0xFFFFFFFF;
|
||||
|
||||
public void Init() { _value = 0xFFFFFFFF; }
|
||||
|
||||
public void UpdateByte(byte b)
|
||||
{
|
||||
_value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8);
|
||||
_value = Table[(byte)_value ^ b] ^ (_value >> 8);
|
||||
}
|
||||
|
||||
public void Update(byte[] data, uint offset, uint size)
|
||||
{
|
||||
for (uint i = 0; i < size; i++)
|
||||
_value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8);
|
||||
_value = Table[(byte)_value ^ data[offset + i]] ^ (_value >> 8);
|
||||
}
|
||||
|
||||
public uint GetDigest() { return _value ^ 0xFFFFFFFF; }
|
||||
|
||||
static uint CalculateDigest(byte[] data, uint offset, uint size)
|
||||
public static uint CalculateDigest(byte[] data, uint offset, uint size)
|
||||
{
|
||||
CRC crc = new CRC();
|
||||
var crc = new CRC();
|
||||
// crc.Init();
|
||||
crc.Update(data, offset, size);
|
||||
return crc.GetDigest();
|
||||
@@ -49,7 +49,7 @@ namespace SevenZip
|
||||
|
||||
static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size)
|
||||
{
|
||||
return (CalculateDigest(data, offset, size) == digest);
|
||||
return CalculateDigest(data, offset, size) == digest;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
// LzmaDecoder.cs
|
||||
|
||||
using System;
|
||||
using AssetStudio;
|
||||
|
||||
namespace SevenZip.Compression.LZMA
|
||||
{
|
||||
@@ -247,6 +248,8 @@ namespace SevenZip.Compression.LZMA
|
||||
m_OutWindow.PutByte(b);
|
||||
nowPos64++;
|
||||
}
|
||||
|
||||
Progress.Reset();
|
||||
while (nowPos64 < outSize64)
|
||||
{
|
||||
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
|
||||
@@ -338,6 +341,8 @@ namespace SevenZip.Compression.LZMA
|
||||
}
|
||||
m_OutWindow.CopyBlock(rep0, len);
|
||||
nowPos64 += len;
|
||||
|
||||
Progress.Report((int)(nowPos64 * 100f / outSize64), 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,11 @@ using System;
|
||||
using System.IO;
|
||||
using SevenZip.Compression.LZMA;
|
||||
|
||||
|
||||
namespace AssetStudio
|
||||
namespace BundleCompression.Lzma
|
||||
{
|
||||
public static class SevenZipHelper
|
||||
public static class SevenZipLzma
|
||||
{
|
||||
public static MemoryStream StreamDecompress(MemoryStream inStream)
|
||||
public static MemoryStream DecompressStream(MemoryStream inStream)
|
||||
{
|
||||
var decoder = new Decoder();
|
||||
|
||||
@@ -34,15 +33,17 @@ namespace AssetStudio
|
||||
return newOutStream;
|
||||
}
|
||||
|
||||
public static void StreamDecompress(Stream inStream, Stream outStream, long inSize, long outSize)
|
||||
public static long DecompressStream(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize)
|
||||
{
|
||||
var basePosition = compressedStream.Position;
|
||||
var decoder = new Decoder();
|
||||
var properties = new byte[5];
|
||||
if (inStream.Read(properties, 0, 5) != 5)
|
||||
if (compressedStream.Read(properties, 0, 5) != 5)
|
||||
throw new Exception("input .lzma is too short");
|
||||
decoder.SetDecoderProperties(properties);
|
||||
inSize -= 5L;
|
||||
decoder.Code(inStream, outStream, inSize, outSize, null);
|
||||
decoder.Code(compressedStream, decompressedStream, compressedSize - 5, decompressedSize, null);
|
||||
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,30 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Lz4;
|
||||
using System.Collections.Generic;
|
||||
using AssetStudio.CustomOptions;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
[Flags]
|
||||
public enum ArchiveFlags
|
||||
{
|
||||
CompressionTypeMask = 0x3f,
|
||||
BlocksAndDirectoryInfoCombined = 0x40,
|
||||
BlocksInfoAtTheEnd = 0x80,
|
||||
OldWebPluginCompatibility = 0x100,
|
||||
BlockInfoNeedPaddingAtStart = 0x200
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum CnEncryptionFlags
|
||||
{
|
||||
V1 = 0x200,
|
||||
V2_V3 = 0x1400,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum StorageBlockFlags
|
||||
{
|
||||
CompressionTypeMask = 0x3f,
|
||||
Streamed = 0x40
|
||||
}
|
||||
|
||||
public enum CompressionType
|
||||
{
|
||||
Auto = -1,
|
||||
None,
|
||||
Lzma,
|
||||
Lz4,
|
||||
Lz4HC,
|
||||
Lzham,
|
||||
Zstd, //custom
|
||||
Oodle, //custom
|
||||
}
|
||||
|
||||
public class BundleFile
|
||||
{
|
||||
public readonly bool IsDataAfterBundle;
|
||||
private readonly CustomBundleOptions _bundleOptions;
|
||||
|
||||
public class Header
|
||||
{
|
||||
public string signature;
|
||||
public uint version;
|
||||
public string unityVersion;
|
||||
public string unityRevision;
|
||||
public UnityVersion unityRevision;
|
||||
public long size;
|
||||
public uint compressedBlocksInfoSize;
|
||||
public uint uncompressedBlocksInfoSize;
|
||||
public uint flags;
|
||||
public ArchiveFlags flags;
|
||||
}
|
||||
|
||||
public class StorageBlock
|
||||
{
|
||||
public uint compressedSize;
|
||||
public uint uncompressedSize;
|
||||
public ushort flags;
|
||||
public StorageBlockFlags flags;
|
||||
}
|
||||
|
||||
public class Node
|
||||
@@ -39,60 +78,93 @@ namespace AssetStudio
|
||||
private StorageBlock[] m_BlocksInfo;
|
||||
private Node[] m_DirectoryInfo;
|
||||
|
||||
public StreamFile[] fileList;
|
||||
public List<StreamFile> fileList;
|
||||
|
||||
public BundleFile(EndianBinaryReader reader, string path)
|
||||
public BundleFile(FileReader reader, CustomBundleOptions bundleOptions, bool isMultiBundle = false)
|
||||
{
|
||||
_bundleOptions = bundleOptions;
|
||||
m_Header = new Header();
|
||||
m_Header.signature = reader.ReadStringToNull();
|
||||
m_Header.version = reader.ReadUInt32();
|
||||
m_Header.unityVersion = reader.ReadStringToNull();
|
||||
var revStr = reader.ReadStringToNull();
|
||||
if (!UnityVersion.TryParse(revStr, out m_Header.unityRevision))
|
||||
m_Header.unityRevision = new UnityVersion();
|
||||
|
||||
switch (m_Header.signature)
|
||||
{
|
||||
case "UnityArchive":
|
||||
break; //TODO
|
||||
case "UnityWeb":
|
||||
case "UnityRaw":
|
||||
ReadHeaderAndBlocksInfo(reader);
|
||||
using (var blocksStream = CreateBlocksStream(path))
|
||||
if (m_Header.version == 6)
|
||||
{
|
||||
ReadBlocksAndDirectory(reader, blocksStream);
|
||||
ReadFiles(blocksStream, path);
|
||||
goto case "UnityFS";
|
||||
}
|
||||
ReadHeaderAndBlocksInfo(reader);
|
||||
using (reader)
|
||||
{
|
||||
ReadFiles(ReadBlocksAndDirectory(reader));
|
||||
}
|
||||
break;
|
||||
case "UnityFS":
|
||||
ReadHeader(reader);
|
||||
ReadBlocksInfoAndDirectory(reader);
|
||||
using (var blocksStream = CreateBlocksStream(path))
|
||||
|
||||
var bundleSize = m_Header.size;
|
||||
var streamSize = reader.BaseStream.Length;
|
||||
if (bundleSize > streamSize)
|
||||
Logger.Warning("Bundle size is incorrect.");
|
||||
IsDataAfterBundle = streamSize - bundleSize > 200;
|
||||
|
||||
var unityVer = m_Header.unityRevision;
|
||||
var customUnityVer = _bundleOptions.Options.CustomUnityVersion;
|
||||
if (customUnityVer != null)
|
||||
{
|
||||
ReadBlocks(reader, blocksStream);
|
||||
ReadFiles(blocksStream, path);
|
||||
if (!unityVer.IsStripped && customUnityVer != unityVer)
|
||||
{
|
||||
Logger.Warning($"Detected Unity version is different from the specified one ({customUnityVer.FullVersion.Color(ColorConsole.BrightCyan)}).\n" +
|
||||
$"Assets may load with errors.\n" +
|
||||
$"It is recommended to specify the detected Unity version: {unityVer.FullVersion.Color(ColorConsole.BrightCyan)}");
|
||||
}
|
||||
unityVer = customUnityVer;
|
||||
}
|
||||
UnityCnCheck(reader, unityVer);
|
||||
|
||||
ReadBlocksInfoAndDirectory(reader, unityVer);
|
||||
|
||||
if (IsUncompressedBundle && !IsDataAfterBundle && !isMultiBundle)
|
||||
{
|
||||
Logger.Debug($"[Uncompressed bundle] BlockData count: {m_BlocksInfo.Length}");
|
||||
ReadFiles(reader.BaseStream, reader.Position);
|
||||
break;
|
||||
}
|
||||
|
||||
ReadFiles(ReadBlocks(reader));
|
||||
if (!IsDataAfterBundle)
|
||||
reader.Close();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadHeaderAndBlocksInfo(EndianBinaryReader reader)
|
||||
private void ReadHeaderAndBlocksInfo(FileReader reader)
|
||||
{
|
||||
var isCompressed = m_Header.signature == "UnityWeb";
|
||||
m_Header.version = reader.ReadUInt32();
|
||||
m_Header.unityVersion = reader.ReadStringToNull();
|
||||
m_Header.unityRevision = reader.ReadStringToNull();
|
||||
if (m_Header.version >= 4)
|
||||
{
|
||||
var hash = reader.ReadBytes(16);
|
||||
var crc = reader.ReadUInt32();
|
||||
}
|
||||
var minimumStreamedBytes = reader.ReadUInt32();
|
||||
var headerSize = reader.ReadUInt32();
|
||||
m_Header.size = reader.ReadUInt32();
|
||||
var numberOfLevelsToDownloadBeforeStreaming = reader.ReadUInt32();
|
||||
var levelCount = reader.ReadInt32();
|
||||
m_BlocksInfo = new StorageBlock[1];
|
||||
for (int i = 0; i < levelCount; i++)
|
||||
{
|
||||
var storageBlock = new StorageBlock()
|
||||
var storageBlock = new StorageBlock
|
||||
{
|
||||
compressedSize = reader.ReadUInt32(),
|
||||
uncompressedSize = reader.ReadUInt32(),
|
||||
flags = (ushort)(isCompressed ? 1 : 0)
|
||||
};
|
||||
if (i == levelCount - 1)
|
||||
{
|
||||
@@ -107,36 +179,38 @@ namespace AssetStudio
|
||||
{
|
||||
var fileInfoHeaderSize = reader.ReadUInt32();
|
||||
}
|
||||
reader.Position = headerSize;
|
||||
reader.Position = m_Header.size;
|
||||
}
|
||||
|
||||
private Stream CreateBlocksStream(string path)
|
||||
{
|
||||
Stream blocksStream;
|
||||
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(Path.GetFileName(path), uncompressedSizeSum);
|
||||
assetsDataStream = memoryMappedFile.CreateViewStream();*/
|
||||
blocksStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
|
||||
var tempDir = Path.Combine(Directory.GetCurrentDirectory(), "Studio_temp");
|
||||
Directory.CreateDirectory(tempDir);
|
||||
var filename = Path.GetFileName(path);
|
||||
var hash = path.GetHashCode();
|
||||
path = Path.Combine(tempDir, $"{filename}_{hash:X}");
|
||||
}
|
||||
else
|
||||
{
|
||||
blocksStream = new MemoryStream((int)uncompressedSizeSum);
|
||||
}
|
||||
return blocksStream;
|
||||
return new TempFileStream(path + ".temp", FileMode.Create);
|
||||
}
|
||||
|
||||
private void ReadBlocksAndDirectory(EndianBinaryReader reader, Stream blocksStream)
|
||||
private Stream ReadBlocksAndDirectory(FileReader reader)
|
||||
{
|
||||
var blocksStream = CreateBlocksStream(reader.FullPath);
|
||||
var isCompressed = m_Header.signature == "UnityWeb";
|
||||
foreach (var blockInfo in m_BlocksInfo)
|
||||
{
|
||||
var uncompressedBytes = reader.ReadBytes((int)blockInfo.compressedSize);
|
||||
if (blockInfo.flags == 1)
|
||||
if (isCompressed)
|
||||
{
|
||||
using (var memoryStream = new MemoryStream(uncompressedBytes))
|
||||
{
|
||||
using (var decompressStream = SevenZipHelper.StreamDecompress(memoryStream))
|
||||
using (var decompressStream = BundleDecompressionHelper.DecompressLzmaStream(memoryStream))
|
||||
{
|
||||
uncompressedBytes = decompressStream.ToArray();
|
||||
}
|
||||
@@ -145,10 +219,11 @@ namespace AssetStudio
|
||||
blocksStream.Write(uncompressedBytes, 0, uncompressedBytes.Length);
|
||||
}
|
||||
blocksStream.Position = 0;
|
||||
|
||||
var blocksReader = new EndianBinaryReader(blocksStream);
|
||||
var nodesCount = blocksReader.ReadInt32();
|
||||
m_DirectoryInfo = new Node[nodesCount];
|
||||
for (int i = 0; i < nodesCount; i++)
|
||||
for (var i = 0; i < nodesCount; i++)
|
||||
{
|
||||
m_DirectoryInfo[i] = new Node
|
||||
{
|
||||
@@ -157,109 +232,165 @@ namespace AssetStudio
|
||||
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];
|
||||
for (int i = 0; i < m_DirectoryInfo.Length; i++)
|
||||
fileList = new List<StreamFile>(m_DirectoryInfo.Length);
|
||||
foreach (var node in m_DirectoryInfo)
|
||||
{
|
||||
var node = m_DirectoryInfo[i];
|
||||
var file = new StreamFile();
|
||||
fileList[i] = file;
|
||||
fileList.Add(file);
|
||||
file.path = node.path;
|
||||
file.fileName = Path.GetFileName(node.path);
|
||||
if (node.size >= int.MaxValue)
|
||||
try
|
||||
{
|
||||
/*var memoryMappedFile = MemoryMappedFile.CreateNew(file.fileName, entryinfo_size);
|
||||
file.stream = memoryMappedFile.CreateViewStream();*/
|
||||
var extractPath = path + "_unpacked" + Path.DirectorySeparatorChar;
|
||||
Directory.CreateDirectory(extractPath);
|
||||
file.stream = File.Create(extractPath + file.fileName);
|
||||
file.stream = new OffsetStream(inputStream, node.offset + blocksOffset, node.size);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadHeader(EndianBinaryReader reader)
|
||||
private void ReadHeader(FileReader reader)
|
||||
{
|
||||
m_Header.version = reader.ReadUInt32();
|
||||
m_Header.unityVersion = reader.ReadStringToNull();
|
||||
m_Header.unityRevision = reader.ReadStringToNull();
|
||||
m_Header.size = reader.ReadInt64();
|
||||
m_Header.compressedBlocksInfoSize = reader.ReadUInt32();
|
||||
m_Header.uncompressedBlocksInfoSize = reader.ReadUInt32();
|
||||
m_Header.flags = reader.ReadUInt32();
|
||||
m_Header.flags = (ArchiveFlags)reader.ReadUInt32();
|
||||
if (m_Header.signature != "UnityFS")
|
||||
{
|
||||
reader.ReadByte();
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader)
|
||||
private void ReadBlocksInfoAndDirectory(FileReader reader, UnityVersion unityVer, bool silent = false)
|
||||
{
|
||||
byte[] blocksInfoBytes;
|
||||
if ((m_Header.flags & 0x80) != 0) //kArchiveBlocksInfoAtTheEnd
|
||||
|
||||
if (m_Header.version >= 7)
|
||||
{
|
||||
reader.AlignStream(16);
|
||||
}
|
||||
else if (unityVer >= (2019, 4) && m_Header.flags != ArchiveFlags.BlocksAndDirectoryInfoCombined)
|
||||
{
|
||||
//check if we need to align the reader
|
||||
//- align to 16 bytes and check if all are 0
|
||||
//- if not, reset the reader to the previous position
|
||||
var preAlign = reader.Position;
|
||||
var alignData = reader.ReadBytes((16 - (int)(preAlign % 16)) % 16);
|
||||
if (alignData.Any(x => x != 0))
|
||||
{
|
||||
reader.Position = preAlign;
|
||||
}
|
||||
}
|
||||
|
||||
var compressedSize = (int)m_Header.compressedBlocksInfoSize;
|
||||
var uncompressedSize = (int)m_Header.uncompressedBlocksInfoSize;
|
||||
if (uncompressedSize < 0 || compressedSize < 0 || compressedSize > reader.BaseStream.Length)
|
||||
{
|
||||
throw new IOException("Incorrect blockInfo length.\nBlockInfo sizes might be encrypted.\n");
|
||||
}
|
||||
|
||||
if ((m_Header.flags & ArchiveFlags.BlocksInfoAtTheEnd) != 0)
|
||||
{
|
||||
var position = reader.Position;
|
||||
reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
|
||||
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
|
||||
reader.Position = m_Header.size - compressedSize;
|
||||
blocksInfoBytes = reader.ReadBytes(compressedSize);
|
||||
reader.Position = position;
|
||||
}
|
||||
else //0x40 kArchiveBlocksAndDirectoryInfoCombined
|
||||
else //0x40 BlocksAndDirectoryInfoCombined
|
||||
{
|
||||
if (m_Header.version >= 7)
|
||||
blocksInfoBytes = reader.ReadBytes(compressedSize);
|
||||
}
|
||||
|
||||
var customBlockInfoCompression = _bundleOptions.CustomBlockInfoCompression;
|
||||
var compressionType = (CompressionType)(m_Header.flags & ArchiveFlags.CompressionTypeMask);
|
||||
if (customBlockInfoCompression == CompressionType.Auto)
|
||||
{
|
||||
if (!silent && compressionType > CompressionType.Lzham && Enum.IsDefined(typeof(CompressionType), compressionType))
|
||||
{
|
||||
reader.AlignStream(16);
|
||||
Logger.Warning($"Non-standard blockInfo compression type: {(int)compressionType}. Trying to decompress as {compressionType} archive..");
|
||||
}
|
||||
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
|
||||
}
|
||||
var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
|
||||
MemoryStream blocksInfoUncompresseddStream;
|
||||
switch (m_Header.flags & 0x3F) //kArchiveCompressionTypeMask
|
||||
else if (compressionType != CompressionType.None)
|
||||
{
|
||||
default: //None
|
||||
{
|
||||
blocksInfoUncompresseddStream = blocksInfoCompressedStream;
|
||||
break;
|
||||
}
|
||||
case 1: //LZMA
|
||||
{
|
||||
blocksInfoUncompresseddStream = SevenZipHelper.StreamDecompress(blocksInfoCompressedStream);
|
||||
blocksInfoCompressedStream.Close();
|
||||
break;
|
||||
}
|
||||
case 2: //LZ4
|
||||
case 3: //LZ4HC
|
||||
{
|
||||
var uncompressedBytes = new byte[m_Header.uncompressedBlocksInfoSize];
|
||||
using (var decoder = new Lz4DecoderStream(blocksInfoCompressedStream))
|
||||
{
|
||||
decoder.Read(uncompressedBytes, 0, uncompressedBytes.Length);
|
||||
}
|
||||
blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
|
||||
break;
|
||||
}
|
||||
compressionType = customBlockInfoCompression;
|
||||
if (!silent)
|
||||
{
|
||||
Logger.Info($"Custom blockInfo compression type: {customBlockInfoCompression}");
|
||||
}
|
||||
}
|
||||
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
|
||||
Logger.Debug($"BlockInfo compression: {compressionType}");
|
||||
|
||||
int numWrite;
|
||||
var errorMsg = string.Empty;
|
||||
MemoryStream blocksInfoUncompressedStream;
|
||||
switch (compressionType)
|
||||
{
|
||||
case CompressionType.None:
|
||||
{
|
||||
blocksInfoUncompressedStream = new MemoryStream(blocksInfoBytes);
|
||||
numWrite = compressedSize;
|
||||
break;
|
||||
}
|
||||
case CompressionType.Lzma:
|
||||
{
|
||||
blocksInfoUncompressedStream = new MemoryStream(uncompressedSize);
|
||||
using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
|
||||
{
|
||||
numWrite = (int)BundleDecompressionHelper.DecompressLzmaStream(blocksInfoCompressedStream, blocksInfoUncompressedStream, compressedSize, uncompressedSize, ref errorMsg);
|
||||
}
|
||||
blocksInfoUncompressedStream.Position = 0;
|
||||
break;
|
||||
}
|
||||
case CompressionType.Lz4:
|
||||
case CompressionType.Lz4HC:
|
||||
case CompressionType.Zstd:
|
||||
case CompressionType.Oodle:
|
||||
{
|
||||
var uncompressedBytes = new byte[uncompressedSize];
|
||||
numWrite = BundleDecompressionHelper.DecompressBlock(compressionType, blocksInfoBytes, uncompressedBytes, ref errorMsg);
|
||||
blocksInfoUncompressedStream = new MemoryStream(uncompressedBytes);
|
||||
break;
|
||||
}
|
||||
case CompressionType.Lzham:
|
||||
throw new IOException($"Unsupported blockInfo compression type: {compressionType}.\n");
|
||||
default:
|
||||
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))
|
||||
{
|
||||
var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
|
||||
var blocksInfoCount = blocksInfoReader.ReadInt32();
|
||||
m_BlocksInfo = new StorageBlock[blocksInfoCount];
|
||||
for (int i = 0; i < blocksInfoCount; i++)
|
||||
for (var i = 0; i < blocksInfoCount; i++)
|
||||
{
|
||||
m_BlocksInfo[i] = new StorageBlock
|
||||
{
|
||||
uncompressedSize = blocksInfoReader.ReadUInt32(),
|
||||
compressedSize = blocksInfoReader.ReadUInt32(),
|
||||
flags = blocksInfoReader.ReadUInt16()
|
||||
flags = (StorageBlockFlags)blocksInfoReader.ReadUInt16()
|
||||
};
|
||||
}
|
||||
|
||||
var nodesCount = blocksInfoReader.ReadInt32();
|
||||
m_DirectoryInfo = new Node[nodesCount];
|
||||
for (int i = 0; i < nodesCount; i++)
|
||||
for (var i = 0; i < nodesCount; i++)
|
||||
{
|
||||
m_DirectoryInfo[i] = new Node
|
||||
{
|
||||
@@ -270,37 +401,153 @@ namespace AssetStudio
|
||||
};
|
||||
}
|
||||
}
|
||||
if ((m_Header.flags & ArchiveFlags.BlockInfoNeedPaddingAtStart) != 0)
|
||||
{
|
||||
reader.AlignStream(16);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
|
||||
private Stream ReadBlocks(FileReader reader)
|
||||
{
|
||||
foreach (var blockInfo in m_BlocksInfo)
|
||||
var customBlockCompression = _bundleOptions.CustomBlockCompression;
|
||||
var blocksStream = CreateBlocksStream(reader.FullPath);
|
||||
var blocksCompression = m_BlocksInfo.Max(x => (CompressionType)(x.flags & StorageBlockFlags.CompressionTypeMask));
|
||||
var blockSize = (int)m_BlocksInfo.Max(x => x.uncompressedSize);
|
||||
Logger.Debug($"BlockData compression: {blocksCompression}\n" +
|
||||
$"BlockData count: {m_BlocksInfo.Length}\n" +
|
||||
$"BlockSize: {blockSize}");
|
||||
|
||||
if (customBlockCompression == CompressionType.Auto)
|
||||
{
|
||||
switch (blockInfo.flags & 0x3F) //kStorageBlockCompressionTypeMask
|
||||
if (blocksCompression > CompressionType.Lzham && Enum.IsDefined(typeof(CompressionType), blocksCompression))
|
||||
{
|
||||
default: //None
|
||||
{
|
||||
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
|
||||
break;
|
||||
}
|
||||
case 1: //LZMA
|
||||
{
|
||||
SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
|
||||
break;
|
||||
}
|
||||
case 2: //LZ4
|
||||
case 3: //LZ4HC
|
||||
{
|
||||
var compressedStream = new MemoryStream(reader.ReadBytes((int)blockInfo.compressedSize));
|
||||
using (var lz4Stream = new Lz4DecoderStream(compressedStream))
|
||||
{
|
||||
lz4Stream.CopyTo(blocksStream, blockInfo.uncompressedSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
Logger.Warning($"Non-standard block compression type: {(int)blocksCompression}. Trying to decompress as {blocksCompression} archive..");
|
||||
}
|
||||
}
|
||||
blocksStream.Position = 0;
|
||||
else
|
||||
{
|
||||
Logger.Info($"Custom block compression type: {customBlockCompression}");
|
||||
blocksCompression = customBlockCompression;
|
||||
}
|
||||
|
||||
byte[] sharedCompressedBuff = null;
|
||||
byte[] sharedUncompressedBuff = null;
|
||||
if (blocksCompression != CompressionType.Lzma && blocksCompression != CompressionType.Lzham)
|
||||
{
|
||||
sharedCompressedBuff = BigArrayPool<byte>.Shared.Rent(blockSize);
|
||||
sharedUncompressedBuff = BigArrayPool<byte>.Shared.Rent(blockSize);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var blockInfo in m_BlocksInfo)
|
||||
{
|
||||
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
|
||||
|
||||
if (customBlockCompression != CompressionType.Auto && compressionType > 0)
|
||||
{
|
||||
compressionType = customBlockCompression;
|
||||
}
|
||||
|
||||
long numWrite;
|
||||
var errorMsg = string.Empty;
|
||||
switch (compressionType)
|
||||
{
|
||||
case CompressionType.None:
|
||||
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
|
||||
numWrite = blockInfo.compressedSize;
|
||||
break;
|
||||
case CompressionType.Lzma:
|
||||
Logger.Info("Decompressing LZMA stream...");
|
||||
numWrite = BundleDecompressionHelper.DecompressLzmaStream(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize, ref errorMsg);
|
||||
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();
|
||||
|
||||
_ = reader.Read(sharedCompressedBuff, 0, compressedSize);
|
||||
var compressedSpan = new ReadOnlySpan<byte>(sharedCompressedBuff, 0, compressedSize);
|
||||
var uncompressedSpan = new Span<byte>(sharedUncompressedBuff, 0, uncompressedSize);
|
||||
|
||||
numWrite = BundleDecompressionHelper.DecompressBlock(compressionType, compressedSpan, uncompressedSpan, ref errorMsg);
|
||||
if (numWrite == uncompressedSize)
|
||||
{
|
||||
blocksStream.Write(sharedUncompressedBuff, 0, uncompressedSize);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case CompressionType.Lzham:
|
||||
throw new IOException($"Unsupported block compression type: {compressionType}.\n");
|
||||
default:
|
||||
throw new IOException($"Unknown block compression type: {compressionType}.\nYou may try to specify the compression type manually.\n");
|
||||
}
|
||||
|
||||
if (numWrite != blockInfo.uncompressedSize)
|
||||
{
|
||||
var msg = $"{compressionType} block decompression error. {errorMsg}\nWrite {numWrite} bytes but expected {blockInfo.uncompressedSize} bytes.";
|
||||
var exMsg = compressionType > CompressionType.Lz4HC || customBlockCompression != CompressionType.Auto
|
||||
? "Wrong compression type or block data might be encrypted."
|
||||
: "Block data might be encrypted.";
|
||||
throw new IOException($"{msg}\n{exMsg}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (sharedCompressedBuff != null)
|
||||
BigArrayPool<byte>.Shared.Return(sharedCompressedBuff, clearArray: true);
|
||||
|
||||
if (sharedUncompressedBuff != null)
|
||||
BigArrayPool<byte>.Shared.Return(sharedUncompressedBuff, clearArray: true);
|
||||
}
|
||||
|
||||
return blocksStream;
|
||||
}
|
||||
|
||||
private void UnityCnCheck(FileReader reader, UnityVersion unityVer)
|
||||
{
|
||||
if ((m_Header.flags & ArchiveFlags.BlocksInfoAtTheEnd) != 0)
|
||||
return;
|
||||
|
||||
var hasUnityCnFlag = false;
|
||||
if (!unityVer.IsStripped)
|
||||
{
|
||||
// https://issuetracker.unity3d.com/issues/files-within-assetbundles-do-not-start-on-aligned-boundaries-breaking-patching-on-nintendo-switch
|
||||
if (unityVer < 2020
|
||||
|| unityVer.IsInRange(2020, (2020, 3, 34))
|
||||
|| unityVer.IsInRange(2021, (2021, 3, 2))
|
||||
|| unityVer.IsInRange(2022, (2022, 1, 1)))
|
||||
{
|
||||
hasUnityCnFlag = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.V1) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasUnityCnFlag = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.V2_V3) != 0;
|
||||
}
|
||||
}
|
||||
if (!hasUnityCnFlag)
|
||||
return;
|
||||
|
||||
var pos = reader.Position;
|
||||
reader.Position += 70;
|
||||
try
|
||||
{
|
||||
ReadBlocksInfoAndDirectory(reader, unityVer, silent: true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
reader.Position = pos;
|
||||
return;
|
||||
}
|
||||
throw new NotSupportedException("Unsupported bundle file. UnityCN encryption was detected.");
|
||||
}
|
||||
|
||||
private bool IsUncompressedBundle => m_BlocksInfo.All(x => (CompressionType)(x.flags & StorageBlockFlags.CompressionTypeMask) == CompressionType.None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
namespace AssetStudio
|
||||
// official Class ID Reference: https://docs.unity3d.com/Manual/ClassIDReference.html
|
||||
namespace AssetStudio
|
||||
{
|
||||
public enum ClassIDType
|
||||
{
|
||||
@@ -26,7 +27,7 @@
|
||||
ParticleRenderer = 26,
|
||||
Texture = 27,
|
||||
Texture2D = 28,
|
||||
SceneSettings = 29,
|
||||
OcclusionCullingSettings = 29,
|
||||
GraphicsSettings = 30,
|
||||
MeshFilter = 33,
|
||||
OcclusionPortal = 41,
|
||||
@@ -49,7 +50,7 @@
|
||||
PhysicsMaterial2D = 62,
|
||||
MeshCollider = 64,
|
||||
BoxCollider = 65,
|
||||
SpriteCollider2D = 66,
|
||||
CompositeCollider2D = 66,
|
||||
EdgeCollider2D = 68,
|
||||
CapsuleCollider2D = 70,
|
||||
ComputeShader = 72,
|
||||
@@ -92,6 +93,7 @@
|
||||
FlareLayer = 124,
|
||||
HaloLayer = 125,
|
||||
NavMeshAreas = 126,
|
||||
NavMeshProjectSettings = 126,
|
||||
HaloManager = 127,
|
||||
Font = 128,
|
||||
PlayerSettings = 129,
|
||||
@@ -143,6 +145,7 @@
|
||||
ProceduralMaterial = 185,
|
||||
ProceduralTexture = 186,
|
||||
Texture2DArray = 187,
|
||||
Texture2DArrayImage = -187, //fake type
|
||||
CubemapArray = 188,
|
||||
OffMeshLink = 191,
|
||||
OcclusionArea = 192,
|
||||
@@ -158,7 +161,7 @@
|
||||
BlendTree = 206,
|
||||
Motion = 207,
|
||||
NavMeshObstacle = 208,
|
||||
TerrainInstance = 210,
|
||||
SortingGroup = 210,
|
||||
SpriteRenderer = 212,
|
||||
Sprite = 213,
|
||||
CachedSpriteAtlas = 214,
|
||||
@@ -216,15 +219,19 @@
|
||||
PerformanceReportingManager = 305,
|
||||
UnityConnectSettings = 310,
|
||||
AvatarMask = 319,
|
||||
PlayableDirector = 320,
|
||||
VideoPlayer = 328,
|
||||
VideoClip = 329,
|
||||
ParticleSystemForceField = 330,
|
||||
SpriteMask = 331,
|
||||
WorldAnchor = 362,
|
||||
OcclusionCullingData = 363,
|
||||
//kLargestRuntimeClassID = 364
|
||||
SmallestEditorClassID = 1000,
|
||||
Prefab = 1001,
|
||||
PrefabInstance = 1001,
|
||||
EditorExtensionImpl = 1002,
|
||||
AssetImporter = 1003,
|
||||
AssetDatabase = 1004,
|
||||
AssetDatabaseV1 = 1004,
|
||||
Mesh3DSImporter = 1005,
|
||||
TextureImporter = 1006,
|
||||
ShaderImporter = 1007,
|
||||
@@ -259,13 +266,13 @@
|
||||
AnimatorState = 1102,
|
||||
HumanTemplate = 1105,
|
||||
AnimatorStateMachine = 1107,
|
||||
PreviewAssetType = 1108,
|
||||
PreviewAnimationClip = 1108,
|
||||
AnimatorTransition = 1109,
|
||||
SpeedTreeImporter = 1110,
|
||||
AnimatorTransitionBase = 1111,
|
||||
SubstanceImporter = 1112,
|
||||
LightmapParameters = 1113,
|
||||
LightmapSnapshot = 1120,
|
||||
LightingDataAsset = 1120,
|
||||
GISRaster = 1121,
|
||||
GISRasterImporter = 1122,
|
||||
CadImporter = 1123,
|
||||
@@ -276,11 +283,125 @@
|
||||
ActivationLogComponent = 2000,
|
||||
//kLargestEditorClassID = 2001
|
||||
//kClassIdOutOfHierarchy = 100000
|
||||
SubDerived = 367388927,
|
||||
//int = 100000,
|
||||
//bool = 100001,
|
||||
//float = 100002,
|
||||
MonoObject = 100003,
|
||||
Collision = 100004,
|
||||
Vector3f = 100005,
|
||||
RootMotionData = 100006,
|
||||
Collision2D = 100007,
|
||||
AudioMixerLiveUpdateFloat = 100008,
|
||||
AudioMixerLiveUpdateBool = 100009,
|
||||
Polygon2D = 100010,
|
||||
//void = 100011,
|
||||
TilemapCollider2D = 19719996,
|
||||
AssetImporterLog = 41386430,
|
||||
GraphicsStateCollection = 55640938,
|
||||
VFXRenderer = 73398921,
|
||||
SerializableManagedRefTestClass = 76251197,
|
||||
Grid = 156049354,
|
||||
ScenesUsingAssets = 156483287,
|
||||
ArticulationBody = 171741748,
|
||||
Preset = 181963792,
|
||||
EmptyObject = 277625683,
|
||||
IConstraint = 285090594,
|
||||
TestObjectWithSpecialLayoutOne = 293259124,
|
||||
AssemblyDefinitionReferenceImporter = 294290339,
|
||||
SiblingDerived = 334799969,
|
||||
TestObjectWithSerializedMapStringNonAlignedStruct = 342846651,
|
||||
AudioResource = 355983997,
|
||||
SubDerived = 367388927,
|
||||
AssetImportInProgressProxy = 369655926,
|
||||
PluginBuildInfo = 382020655,
|
||||
MemorySettings = 387306366,
|
||||
BuildMetaDataImporter = 403037116,
|
||||
BuildInstructionImporter = 403037117,
|
||||
EditorProjectAccess = 426301858,
|
||||
PrefabImporter = 468431735,
|
||||
TestObjectWithSerializedArray = 478637458,
|
||||
TestObjectWithSerializedAnimationCurve = 478637459,
|
||||
TilemapRenderer = 483693784,
|
||||
ScriptableCamera = 488575907,
|
||||
SpriteAtlasAsset = 612988286,
|
||||
SpriteAtlasDatabase = 638013454,
|
||||
AudioBuildInfo = 641289076,
|
||||
CachedSpriteAtlasRuntimeData = 644342135,
|
||||
RendererFake = 646504946,
|
||||
MultiplayerManager = 655991488,
|
||||
AssemblyDefinitionReferenceAsset = 662584278,
|
||||
BuiltAssetBundleInfoSet = 668709126,
|
||||
SpriteAtlas = 687078895,
|
||||
RayTracingShaderImporter = 747330370,
|
||||
BuildArchiveImporter = 780535461,
|
||||
PreviewImporter = 815301076,
|
||||
RayTracingShader = 825902497,
|
||||
LightingSettings = 850595691,
|
||||
PlatformModuleSetup = 877146078,
|
||||
VersionControlSettings = 890905787,
|
||||
CustomCollider2D = 893571522,
|
||||
AimConstraint = 895512359,
|
||||
VFXManager = 937362698,
|
||||
RoslynAnalyzerConfigAsset = 947337230,
|
||||
RuleSetFileAsset = 954905827,
|
||||
VisualEffectSubgraph = 994735392,
|
||||
VisualEffectSubgraphOperator = 994735403,
|
||||
VisualEffectSubgraphBlock = 994735404,
|
||||
LocalizationImporter = 1027052791,
|
||||
Derived = 1091556383,
|
||||
PropertyModificationsTargetTestObject = 1111377672,
|
||||
ReferencesArtifactGenerator = 1114811875,
|
||||
AssemblyDefinitionAsset = 1152215463,
|
||||
SceneVisibilityState = 1154873562,
|
||||
LookAtConstraint = 1183024399,
|
||||
SpriteAtlasImporter = 1210832254,
|
||||
MultiArtifactTestImporter = 1223240404,
|
||||
AudioContainerElement = 1233149941,
|
||||
GameObjectRecorder = 1268269756,
|
||||
AudioRandomContainer = 1307931743,
|
||||
LightingDataAssetParent = 1325145578,
|
||||
PresetManager = 1386491679,
|
||||
TestObjectWithSpecialLayoutTwo = 1392443030,
|
||||
StreamingManager = 1403656975,
|
||||
LowerResBlitTexture = 1480428607,
|
||||
RenderPassAttachment = 1571458007
|
||||
VideoBuildInfo = 1521398425,
|
||||
C4DImporter = 1541671625,
|
||||
StreamingController = 1542919678,
|
||||
RenderPassAttachment = 1571458007,
|
||||
TestObjectVectorPairStringBool = 1628831178,
|
||||
ShaderContainer = 1557264870,
|
||||
RoslynAdditionalFileAsset = 1597193336,
|
||||
RoslynAdditionalFileImporter = 1642787288,
|
||||
MultiplayerRolesData = 1652712579,
|
||||
SceneRoots = 1660057539,
|
||||
BrokenPrefabAsset = 1731078267,
|
||||
AndroidAssetPackImporter = 1736697216,
|
||||
VulkanDeviceFilterLists = 1740304944,
|
||||
GridLayout = 1742807556,
|
||||
AssemblyDefinitionImporter = 1766753193,
|
||||
ParentConstraint = 1773428102,
|
||||
FakeComponent = 1803986026,
|
||||
RuleSetFileImporter = 1777034230,
|
||||
PositionConstraint = 1818360608,
|
||||
RotationConstraint = 1818360609,
|
||||
ScaleConstraint = 1818360610,
|
||||
Tilemap = 1839735485,
|
||||
PackageManifest = 1896753125,
|
||||
PackageManifestImporter = 1896753126,
|
||||
RoslynAnalyzerConfigImporter = 1903396204,
|
||||
UIRenderer = 1931382933,
|
||||
TerrainLayer = 1953259897,
|
||||
SpriteShapeRenderer = 1971053207,
|
||||
NativeObjectType = 1977754360,
|
||||
TestObjectWithSerializedMapStringBool = 1981279845,
|
||||
SerializableManagedHost = 1995898324,
|
||||
VisualEffectAsset = 2058629509,
|
||||
VisualEffectImporter = 2058629510,
|
||||
VisualEffectResource = 2058629511,
|
||||
VisualEffectObject = 2059678085,
|
||||
VisualEffect = 2083052967,
|
||||
LocalizationAsset = 2083778819,
|
||||
ScriptedImporter = 2089858483,
|
||||
ShaderIncludeImporter = 2103361453,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class Animation : Behaviour
|
||||
{
|
||||
public PPtr<AnimationClip>[] m_Animations;
|
||||
public List<PPtr<AnimationClip>> m_Animations;
|
||||
|
||||
public Animation(ObjectReader reader) : base(reader)
|
||||
{
|
||||
var m_Animation = new PPtr<AnimationClip>(reader);
|
||||
int numAnimations = reader.ReadInt32();
|
||||
m_Animations = new PPtr<AnimationClip>[numAnimations];
|
||||
for (int i = 0; i < numAnimations; i++)
|
||||
m_Animations = new List<PPtr<AnimationClip>>();
|
||||
for (var i = 0; i < numAnimations; i++)
|
||||
{
|
||||
m_Animations[i] = new PPtr<AnimationClip>(reader);
|
||||
m_Animations.Add(new PPtr<AnimationClip>(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class Animator : Behaviour
|
||||
{
|
||||
@@ -17,43 +12,57 @@ namespace AssetStudio
|
||||
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
|
||||
var m_CullingMode = reader.ReadInt32();
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
|
||||
if (version >= (4, 5)) //4.5 and up
|
||||
{
|
||||
var m_UpdateMode = reader.ReadInt32();
|
||||
}
|
||||
|
||||
if (version.IsTuanjie && (version > (2022, 3, 48) || version == (2022, 3, 48) && version.Build >= 7)) //2022.3.48t7(1.4.4) and up
|
||||
{
|
||||
var m_UpdateFrequencyMode = reader.ReadInt32();
|
||||
var m_UpdateFrequency = reader.ReadSingle();
|
||||
}
|
||||
|
||||
var m_ApplyRootMotion = reader.ReadBoolean();
|
||||
if (version[0] == 4 && version[1] >= 5) //4.5 and up - 5.0 down
|
||||
if (version == 4 && version.Minor >= 5) //4.5 and up - 5.0 down
|
||||
{
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
var m_LinearVelocityBlending = reader.ReadBoolean();
|
||||
if (version >= (2021, 2)) //2021.2 and up
|
||||
{
|
||||
var m_StabilizeFeet = reader.ReadBoolean();
|
||||
}
|
||||
if (version >= (2023, 1)) //2023.1 and up
|
||||
{
|
||||
var m_AnimatePhysics = reader.ReadBoolean();
|
||||
}
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] < 4 || (version[0] == 4 && version[1] < 5)) //4.5 down
|
||||
if (version < (4, 5)) //4.5 down
|
||||
{
|
||||
var m_AnimatePhysics = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
if (version >= (4, 3)) //4.3 and up
|
||||
{
|
||||
m_HasTransformHierarchy = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
|
||||
if (version >= (4, 5)) //4.5 and up
|
||||
{
|
||||
var m_AllowConstantClipSamplingOptimization = reader.ReadBoolean();
|
||||
}
|
||||
if (version[0] >= 5 && version[0] < 2018) //5.0 and up - 2018 down
|
||||
if (version.IsInRange(5, 2018)) //5.0 and up - 2018 down
|
||||
{
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] >= 2018) //2018 and up
|
||||
if (version >= 2018) //2018 and up
|
||||
{
|
||||
var m_KeepAnimatorControllerStateOnDisable = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -17,7 +14,7 @@ namespace AssetStudio
|
||||
|
||||
word0 = reader.ReadUInt32();
|
||||
word1 = reader.ReadUInt32();
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
|
||||
if (version >= (5, 2)) //5.2 and up
|
||||
{
|
||||
word2 = reader.ReadUInt32();
|
||||
}
|
||||
@@ -38,15 +35,15 @@ namespace AssetStudio
|
||||
|
||||
public class SkeletonMask
|
||||
{
|
||||
public SkeletonMaskElement[] m_Data;
|
||||
public List<SkeletonMaskElement> m_Data;
|
||||
|
||||
public SkeletonMask(ObjectReader reader)
|
||||
{
|
||||
int numElements = reader.ReadInt32();
|
||||
m_Data = new SkeletonMaskElement[numElements];
|
||||
for (int i = 0; i < numElements; i++)
|
||||
m_Data = new List<SkeletonMaskElement>();
|
||||
for (var i = 0; i < numElements; i++)
|
||||
{
|
||||
m_Data[i] = new SkeletonMaskElement(reader);
|
||||
m_Data.Add(new SkeletonMaskElement(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,12 +70,12 @@ namespace AssetStudio
|
||||
m_SkeletonMask = new SkeletonMask(reader);
|
||||
m_Binding = reader.ReadUInt32();
|
||||
m_LayerBlendingMode = reader.ReadInt32();
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
|
||||
if (version >= (4, 2)) //4.2 and up
|
||||
{
|
||||
m_DefaultWeight = reader.ReadSingle();
|
||||
}
|
||||
m_IKPass = reader.ReadBoolean();
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
|
||||
if (version >= (4, 2)) //4.2 and up
|
||||
{
|
||||
m_SyncedLayerAffectsTiming = reader.ReadBoolean();
|
||||
}
|
||||
@@ -124,14 +121,15 @@ namespace AssetStudio
|
||||
var version = reader.version;
|
||||
|
||||
int numConditions = reader.ReadInt32();
|
||||
m_ConditionConstantArray = new ConditionConstant[numConditions];
|
||||
for (int i = 0; i < numConditions; i++)
|
||||
var conditionConstantList = new List<ConditionConstant>();
|
||||
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();
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
m_FullPathID = reader.ReadUInt32();
|
||||
}
|
||||
@@ -140,7 +138,7 @@ namespace AssetStudio
|
||||
m_UserID = reader.ReadUInt32();
|
||||
m_TransitionDuration = reader.ReadSingle();
|
||||
m_TransitionOffset = reader.ReadSingle();
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
m_ExitTime = reader.ReadSingle();
|
||||
m_HasExitTime = reader.ReadBoolean();
|
||||
@@ -154,7 +152,7 @@ namespace AssetStudio
|
||||
m_Atomic = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
|
||||
if (version >= (4, 5)) //4.5 and up
|
||||
{
|
||||
m_CanTransitionToSelf = reader.ReadBoolean();
|
||||
}
|
||||
@@ -201,11 +199,12 @@ namespace AssetStudio
|
||||
m_ChildPairAvgMagInvArray = reader.ReadSingleArray();
|
||||
|
||||
int numNeighbours = reader.ReadInt32();
|
||||
m_ChildNeighborListArray = new MotionNeighborList[numNeighbours];
|
||||
for (int i = 0; i < numNeighbours; i++)
|
||||
var childNeighborLists = new List<MotionNeighborList>();
|
||||
for (var i = 0; i < numNeighbours; i++)
|
||||
{
|
||||
m_ChildNeighborListArray[i] = new MotionNeighborList(reader);
|
||||
childNeighborLists.Add(new MotionNeighborList(reader));
|
||||
}
|
||||
m_ChildNeighborListArray = childNeighborLists.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,43 +251,41 @@ namespace AssetStudio
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||
if (version >= (4, 1)) //4.1 and up
|
||||
{
|
||||
m_BlendType = reader.ReadUInt32();
|
||||
}
|
||||
m_BlendEventID = reader.ReadUInt32();
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||
if (version >= (4, 1)) //4.1 and up
|
||||
{
|
||||
m_BlendEventYID = reader.ReadUInt32();
|
||||
}
|
||||
m_ChildIndices = reader.ReadUInt32Array();
|
||||
if (version[0] < 4 || (version[0] == 4 && version[1] < 1)) //4.1 down
|
||||
if (version < (4, 1)) //4.1 down
|
||||
{
|
||||
m_ChildThresholdArray = reader.ReadSingleArray();
|
||||
}
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||
if (version >= (4, 1)) //4.1 and up
|
||||
{
|
||||
m_Blend1dData = new Blend1dDataConstant(reader);
|
||||
m_Blend2dData = new Blend2dDataConstant(reader);
|
||||
}
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
m_BlendDirectData = new BlendDirectDataConstant(reader);
|
||||
}
|
||||
|
||||
m_ClipID = reader.ReadUInt32();
|
||||
if (version[0] == 4 && version[1] >= 5) //4.5 - 5.0
|
||||
if (version == 4 && version.Minor >= 5) //4.5 - 5.0
|
||||
{
|
||||
m_ClipIndex = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
m_Duration = reader.ReadSingle();
|
||||
|
||||
if (version[0] > 4
|
||||
|| (version[0] == 4 && version[1] > 1)
|
||||
|| (version[0] == 4 && version[1] == 1 && version[2] >= 3)) //4.1.3 and up
|
||||
if (version >= (4, 1, 3)) //4.1.3 and up
|
||||
{
|
||||
m_CycleOffset = reader.ReadSingle();
|
||||
m_Mirror = reader.ReadBoolean();
|
||||
@@ -307,13 +304,14 @@ namespace AssetStudio
|
||||
var version = reader.version;
|
||||
|
||||
int numNodes = reader.ReadInt32();
|
||||
m_NodeArray = new BlendTreeNodeConstant[numNodes];
|
||||
for (int i = 0; i < numNodes; i++)
|
||||
var nodeList = new List<BlendTreeNodeConstant>();
|
||||
for (var i = 0; i < numNodes; i++)
|
||||
{
|
||||
m_NodeArray[i] = new BlendTreeNodeConstant(reader);
|
||||
nodeList.Add(new BlendTreeNodeConstant(reader));
|
||||
}
|
||||
m_NodeArray = nodeList.ToArray();
|
||||
|
||||
if (version[0] < 4 || (version[0] == 4 && version[1] < 5)) //4.5 down
|
||||
if (version < (4, 5)) //4.5 down
|
||||
{
|
||||
m_BlendEventArrayConstant = new ValueArrayConstant(reader);
|
||||
}
|
||||
@@ -345,68 +343,71 @@ namespace AssetStudio
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
int numTransistions = reader.ReadInt32();
|
||||
m_TransitionConstantArray = new TransitionConstant[numTransistions];
|
||||
for (int i = 0; i < numTransistions; i++)
|
||||
int numTransitions = reader.ReadInt32();
|
||||
var transitionConstantList = new List<TransitionConstant>();
|
||||
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();
|
||||
|
||||
if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) //5.2 down
|
||||
if (version < (5, 2)) //5.2 down
|
||||
{
|
||||
int numInfos = reader.ReadInt32();
|
||||
m_LeafInfoArray = new LeafInfoConstant[numInfos];
|
||||
for (int i = 0; i < numInfos; i++)
|
||||
var leafInfoList = new List<LeafInfoConstant>();
|
||||
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();
|
||||
m_BlendTreeConstantArray = new BlendTreeConstant[numBlends];
|
||||
for (int i = 0; i < numBlends; i++)
|
||||
var blendTreeConstantList = new List<BlendTreeConstant>();
|
||||
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();
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
if (version >= (4, 3)) //4.3 and up
|
||||
{
|
||||
m_PathID = reader.ReadUInt32();
|
||||
}
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
m_FullPathID = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
m_TagID = reader.ReadUInt32();
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 1)) //5.1 and up
|
||||
if (version >= (5, 1)) //5.1 and up
|
||||
{
|
||||
m_SpeedParamID = reader.ReadUInt32();
|
||||
m_MirrorParamID = reader.ReadUInt32();
|
||||
m_CycleOffsetParamID = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||
if (version >= (2017, 2)) //2017.2 and up
|
||||
{
|
||||
var m_TimeParamID = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
m_Speed = reader.ReadSingle();
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||
if (version >= (4, 1)) //4.1 and up
|
||||
{
|
||||
m_CycleOffset = reader.ReadSingle();
|
||||
}
|
||||
m_IKOnFeet = reader.ReadBoolean();
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
m_WriteDefaultValues = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
m_Loop = reader.ReadBoolean();
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
|
||||
if (version >= (4, 1)) //4.1 and up
|
||||
{
|
||||
m_Mirror = reader.ReadBoolean();
|
||||
}
|
||||
@@ -425,11 +426,12 @@ namespace AssetStudio
|
||||
m_Destination = reader.ReadUInt32();
|
||||
|
||||
int numConditions = reader.ReadInt32();
|
||||
m_ConditionConstantArray = new ConditionConstant[numConditions];
|
||||
for (int i = 0; i < numConditions; i++)
|
||||
var conditionConstantList = new List<ConditionConstant>();
|
||||
for (var i = 0; i < numConditions; i++)
|
||||
{
|
||||
m_ConditionConstantArray[i] = new ConditionConstant(reader);
|
||||
conditionConstantList.Add(new ConditionConstant(reader));
|
||||
}
|
||||
m_ConditionConstantArray = conditionConstantList.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,11 +444,12 @@ namespace AssetStudio
|
||||
public SelectorStateConstant(ObjectReader reader)
|
||||
{
|
||||
int numTransitions = reader.ReadInt32();
|
||||
m_TransitionConstantArray = new SelectorTransitionConstant[numTransitions];
|
||||
for (int i = 0; i < numTransitions; i++)
|
||||
var transitionConstantList = new List<SelectorTransitionConstant>();
|
||||
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_isEntry = reader.ReadBoolean();
|
||||
@@ -467,27 +470,30 @@ namespace AssetStudio
|
||||
var version = reader.version;
|
||||
|
||||
int numStates = reader.ReadInt32();
|
||||
m_StateConstantArray = new StateConstant[numStates];
|
||||
for (int i = 0; i < numStates; i++)
|
||||
var stateConstantList = new List<StateConstant>();
|
||||
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();
|
||||
m_AnyStateTransitionConstantArray = new TransitionConstant[numAnyStates];
|
||||
for (int i = 0; i < numAnyStates; i++)
|
||||
var anyStateTransitionConstantList = new List<TransitionConstant>();
|
||||
for (var i = 0; i < numAnyStates; i++)
|
||||
{
|
||||
m_AnyStateTransitionConstantArray[i] = new TransitionConstant(reader);
|
||||
anyStateTransitionConstantList.Add(new TransitionConstant(reader));
|
||||
}
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
m_AnyStateTransitionConstantArray = anyStateTransitionConstantList.ToArray();
|
||||
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
int numSelectors = reader.ReadInt32();
|
||||
m_SelectorStateConstantArray = new SelectorStateConstant[numSelectors];
|
||||
for (int i = 0; i < numSelectors; i++)
|
||||
var selectorStateConstantList = new List<SelectorStateConstant>();
|
||||
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();
|
||||
@@ -509,7 +515,7 @@ namespace AssetStudio
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
if (version[0] < 5 || (version[0] == 5 && version[1] < 5)) //5.5 down
|
||||
if (version < (5, 5)) //5.5 down
|
||||
{
|
||||
m_BoolValues = reader.ReadBooleanArray();
|
||||
reader.AlignStream();
|
||||
@@ -517,29 +523,35 @@ namespace AssetStudio
|
||||
m_FloatValues = reader.ReadSingleArray();
|
||||
}
|
||||
|
||||
if (version[0] < 4 || (version[0] == 4 && version[1] < 3)) //4.3 down
|
||||
if (version < (4, 3)) //4.3 down
|
||||
{
|
||||
m_VectorValues = reader.ReadVector4Array();
|
||||
}
|
||||
else
|
||||
{
|
||||
int numPosValues = reader.ReadInt32();
|
||||
m_PositionValues = new Vector3[numPosValues];
|
||||
for (int i = 0; i < numPosValues; i++)
|
||||
var positionValuesList = new List<Vector3>();
|
||||
for (var i = 0; i < numPosValues; i++)
|
||||
{
|
||||
m_PositionValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 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();
|
||||
|
||||
int numScaleValues = reader.ReadInt32();
|
||||
m_ScaleValues = new Vector3[numScaleValues];
|
||||
for (int i = 0; i < numScaleValues; i++)
|
||||
var scaleValuesList = new List<Vector3>();
|
||||
for (var i = 0; i < numScaleValues; i++)
|
||||
{
|
||||
m_ScaleValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 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[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
|
||||
if (version >= (5, 5)) //5.5 and up
|
||||
{
|
||||
m_FloatValues = reader.ReadSingleArray();
|
||||
m_IntValues = reader.ReadInt32Array();
|
||||
@@ -560,18 +572,20 @@ namespace AssetStudio
|
||||
public ControllerConstant(ObjectReader reader)
|
||||
{
|
||||
int numLayers = reader.ReadInt32();
|
||||
m_LayerArray = new LayerConstant[numLayers];
|
||||
for (int i = 0; i < numLayers; i++)
|
||||
var layerList = new List<LayerConstant>();
|
||||
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();
|
||||
m_StateMachineArray = new StateMachineConstant[numStates];
|
||||
for (int i = 0; i < numStates; i++)
|
||||
var stateMachineList = new List<StateMachineConstant>();
|
||||
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_DefaultValues = new ValueArray(reader);
|
||||
@@ -580,7 +594,8 @@ namespace AssetStudio
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -588,17 +603,17 @@ namespace AssetStudio
|
||||
var m_Controller = new ControllerConstant(reader);
|
||||
|
||||
int tosSize = reader.ReadInt32();
|
||||
var m_TOS = new KeyValuePair<uint, string>[tosSize];
|
||||
for (int i = 0; i < tosSize; i++)
|
||||
m_TOS = new List<KeyValuePair<uint, string>>();
|
||||
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();
|
||||
m_AnimationClips = new PPtr<AnimationClip>[numClips];
|
||||
for (int i = 0; i < numClips; i++)
|
||||
m_AnimationClips = new List<PPtr<AnimationClip>>();
|
||||
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.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -20,17 +17,17 @@ namespace AssetStudio
|
||||
public sealed class AnimatorOverrideController : RuntimeAnimatorController
|
||||
{
|
||||
public PPtr<RuntimeAnimatorController> m_Controller;
|
||||
public AnimationClipOverride[] m_Clips;
|
||||
public List<AnimationClipOverride> m_Clips;
|
||||
|
||||
public AnimatorOverrideController(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
|
||||
|
||||
int numOverrides = reader.ReadInt32();
|
||||
m_Clips = new AnimationClipOverride[numOverrides];
|
||||
for (int i = 0; i < numOverrides; i++)
|
||||
m_Clips = new List<AnimationClipOverride>();
|
||||
for (var i = 0; i < numOverrides; i++)
|
||||
{
|
||||
m_Clips[i] = new AnimationClipOverride(reader);
|
||||
m_Clips.Add(new AnimationClipOverride(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -21,23 +18,52 @@ namespace AssetStudio
|
||||
|
||||
public sealed class AssetBundle : NamedObject
|
||||
{
|
||||
public PPtr<Object>[] m_PreloadTable;
|
||||
public KeyValuePair<string, AssetInfo>[] m_Container;
|
||||
public List<PPtr<Object>> m_PreloadTable;
|
||||
public List<KeyValuePair<string, AssetInfo>> m_Container;
|
||||
public string m_AssetBundleName;
|
||||
public string[] m_Dependencies;
|
||||
public bool m_IsStreamedSceneAssetBundle;
|
||||
|
||||
public AssetBundle(ObjectReader reader) : base(reader)
|
||||
{
|
||||
var m_PreloadTableSize = reader.ReadInt32();
|
||||
m_PreloadTable = new PPtr<Object>[m_PreloadTableSize];
|
||||
for (int i = 0; i < m_PreloadTableSize; i++)
|
||||
m_PreloadTable = new List<PPtr<Object>>();
|
||||
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();
|
||||
m_Container = new KeyValuePair<string, AssetInfo>[m_ContainerSize];
|
||||
for (int i = 0; i < m_ContainerSize; i++)
|
||||
m_Container = new List<KeyValuePair<string, AssetInfo>>();
|
||||
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);
|
||||
|
||||
if (version == (5, 4)) //5.4.x
|
||||
{
|
||||
var m_ClassVersionMapSize = reader.ReadInt32();
|
||||
for (var i = 0; i < m_ClassVersionMapSize; i++)
|
||||
{
|
||||
var first = reader.ReadInt32();
|
||||
var second = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
|
||||
if (version >= (4, 2)) //4.2 and up
|
||||
{
|
||||
var m_RuntimeCompatibility = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
m_AssetBundleName = reader.ReadAlignedString();
|
||||
|
||||
m_Dependencies = reader.ReadStringArray();
|
||||
|
||||
m_IsStreamedSceneAssetBundle = reader.ReadBoolean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class AudioClip : NamedObject
|
||||
{
|
||||
public int m_Format;
|
||||
public AudioType m_Type;
|
||||
public FMODSoundType m_Type;
|
||||
public bool m_3D;
|
||||
public bool m_UseHardware;
|
||||
|
||||
@@ -27,28 +21,36 @@ namespace AssetStudio
|
||||
public AudioCompressionFormat m_CompressionFormat;
|
||||
|
||||
public string m_Source;
|
||||
public long m_Offset;
|
||||
public long m_Size;
|
||||
public long m_Offset; //ulong
|
||||
public long m_Size; //ulong
|
||||
public ResourceReader m_AudioData;
|
||||
|
||||
public AudioClip(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if (version[0] < 5)
|
||||
if (version < 5)
|
||||
{
|
||||
m_Format = reader.ReadInt32();
|
||||
m_Type = (AudioType)reader.ReadInt32();
|
||||
m_3D = reader.ReadBoolean();
|
||||
m_UseHardware = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
|
||||
if (version[0] >= 4 || (version[0] == 3 && version[1] >= 2)) //3.2.0 to 5
|
||||
if (version >= (2, 6)) //2.6 to 5
|
||||
{
|
||||
m_Type = (FMODSoundType)reader.ReadInt32();
|
||||
m_3D = reader.ReadBoolean();
|
||||
m_UseHardware = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Length = reader.ReadSingle();
|
||||
m_Frequency = reader.ReadInt32();
|
||||
m_Channels = m_Format != 0x05 ? m_Format >> 1 : 0;
|
||||
}
|
||||
if (version >= (3, 2)) //3.2.0 to 5
|
||||
{
|
||||
int m_Stream = reader.ReadInt32();
|
||||
m_Size = reader.ReadInt32();
|
||||
var tsize = m_Size % 4 != 0 ? m_Size + 4 - m_Size % 4 : m_Size;
|
||||
if (reader.byteSize + reader.byteStart - reader.Position != tsize)
|
||||
{
|
||||
m_Offset = reader.ReadInt32();
|
||||
m_Offset = reader.ReadUInt32();
|
||||
m_Source = assetsFile.fullName + ".resS";
|
||||
}
|
||||
}
|
||||
@@ -72,6 +74,7 @@ namespace AssetStudio
|
||||
m_Legacy3D = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
|
||||
//StreamedResource m_Resource
|
||||
m_Source = reader.ReadAlignedString();
|
||||
m_Offset = reader.ReadInt64();
|
||||
m_Size = reader.ReadInt64();
|
||||
@@ -81,44 +84,61 @@ namespace AssetStudio
|
||||
ResourceReader resourceReader;
|
||||
if (!string.IsNullOrEmpty(m_Source))
|
||||
{
|
||||
resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, (int)m_Size);
|
||||
resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, m_Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size);
|
||||
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_Size);
|
||||
}
|
||||
m_AudioData = resourceReader;
|
||||
}
|
||||
}
|
||||
|
||||
public enum AudioType
|
||||
public enum FMODSoundType
|
||||
{
|
||||
UNKNOWN,
|
||||
ACC,
|
||||
AIFF,
|
||||
UNKNOWN = 0,
|
||||
AAC = 1,
|
||||
AIFF = 2,
|
||||
ASF = 3,
|
||||
AT3 = 4,
|
||||
CDDA = 5,
|
||||
DLS = 6,
|
||||
FLAC = 7,
|
||||
FSB = 8,
|
||||
GCADPCM = 9,
|
||||
IT = 10,
|
||||
MIDI = 11,
|
||||
MOD = 12,
|
||||
MPEG,
|
||||
OGGVORBIS,
|
||||
MPEG = 13,
|
||||
OGGVORBIS = 14,
|
||||
PLAYLIST = 15,
|
||||
RAW = 16,
|
||||
S3M = 17,
|
||||
SF2 = 18,
|
||||
USER = 19,
|
||||
WAV = 20,
|
||||
XM,
|
||||
XMA,
|
||||
VAG,
|
||||
AUDIOQUEUE
|
||||
XM = 21,
|
||||
XMA = 22,
|
||||
VAG = 23,
|
||||
AUDIOQUEUE = 24,
|
||||
XWMA = 25,
|
||||
BCWAV = 26,
|
||||
AT9 = 27,
|
||||
VORBIS = 28,
|
||||
MEDIA_FOUNDATION = 29
|
||||
}
|
||||
|
||||
public enum AudioCompressionFormat
|
||||
{
|
||||
PCM,
|
||||
Vorbis,
|
||||
ADPCM,
|
||||
MP3,
|
||||
VAG,
|
||||
HEVAG,
|
||||
XMA,
|
||||
AAC,
|
||||
GCADPCM,
|
||||
ATRAC9
|
||||
PCM = 0,
|
||||
Vorbis = 1,
|
||||
ADPCM = 2,
|
||||
MP3 = 3,
|
||||
PSMVAG = 4,
|
||||
HEVAG = 5,
|
||||
XMA = 6,
|
||||
AAC = 7,
|
||||
GCADPCM = 8,
|
||||
ATRAC9 = 9
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace AssetStudio
|
||||
public Limit(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up
|
||||
if (version >= (5, 4))//5.4 and up
|
||||
{
|
||||
m_Min = reader.ReadVector3();
|
||||
m_Max = reader.ReadVector3();
|
||||
@@ -50,7 +50,7 @@ namespace AssetStudio
|
||||
var version = reader.version;
|
||||
m_PreQ = reader.ReadVector4();
|
||||
m_PostQ = reader.ReadVector4();
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
|
||||
if (version >= (5, 4)) //5.4 and up
|
||||
{
|
||||
m_Sgn = reader.ReadVector3();
|
||||
}
|
||||
@@ -66,7 +66,7 @@ namespace AssetStudio
|
||||
|
||||
public class Skeleton
|
||||
{
|
||||
public Node[] m_Node;
|
||||
public List<Node> m_Node;
|
||||
public uint[] m_ID;
|
||||
public Axes[] m_AxesArray;
|
||||
|
||||
@@ -74,34 +74,35 @@ namespace AssetStudio
|
||||
public Skeleton(ObjectReader reader)
|
||||
{
|
||||
int numNodes = reader.ReadInt32();
|
||||
m_Node = new Node[numNodes];
|
||||
for (int i = 0; i < numNodes; i++)
|
||||
m_Node = new List<Node>();
|
||||
for (var i = 0; i < numNodes; i++)
|
||||
{
|
||||
m_Node[i] = new Node(reader);
|
||||
m_Node.Add(new Node(reader));
|
||||
}
|
||||
|
||||
m_ID = reader.ReadUInt32Array();
|
||||
|
||||
int numAxes = reader.ReadInt32();
|
||||
m_AxesArray = new Axes[numAxes];
|
||||
for (int i = 0; i < numAxes; i++)
|
||||
var axesList = new List<Axes>();
|
||||
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 xform[] m_X;
|
||||
public List<xform> m_X;
|
||||
|
||||
public SkeletonPose(ObjectReader reader)
|
||||
{
|
||||
int numXforms = reader.ReadInt32();
|
||||
m_X = new xform[numXforms];
|
||||
for (int i = 0; i < numXforms; i++)
|
||||
m_X = new List<xform>();
|
||||
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 Hand m_LeftHand;
|
||||
public Hand m_RightHand;
|
||||
public Handle[] m_Handles;
|
||||
public List<Handle> m_Handles;
|
||||
public Collider[] m_ColliderArray;
|
||||
public int[] m_HumanBoneIndex;
|
||||
public float[] m_HumanBoneMass;
|
||||
@@ -189,28 +190,29 @@ namespace AssetStudio
|
||||
m_LeftHand = new Hand(reader);
|
||||
m_RightHand = new Hand(reader);
|
||||
|
||||
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
|
||||
if (version < (2018, 2)) //2018.2 down
|
||||
{
|
||||
int numHandles = reader.ReadInt32();
|
||||
m_Handles = new Handle[numHandles];
|
||||
for (int i = 0; i < numHandles; i++)
|
||||
m_Handles = new List<Handle>();
|
||||
for (var i = 0; i < numHandles; i++)
|
||||
{
|
||||
m_Handles[i] = new Handle(reader);
|
||||
m_Handles.Add(new Handle(reader));
|
||||
}
|
||||
|
||||
int numColliders = reader.ReadInt32();
|
||||
m_ColliderArray = new Collider[numColliders];
|
||||
for (int i = 0; i < numColliders; i++)
|
||||
var colliderList = new List<Collider>();
|
||||
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_HumanBoneMass = reader.ReadSingleArray();
|
||||
|
||||
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
|
||||
if (version < (2018, 2)) //2018.2 down
|
||||
{
|
||||
m_ColliderIndex = reader.ReadInt32Array();
|
||||
}
|
||||
@@ -225,7 +227,7 @@ namespace AssetStudio
|
||||
m_FeetSpacing = reader.ReadSingle();
|
||||
m_HasLeftHand = reader.ReadBoolean();
|
||||
m_HasRightHand = reader.ReadBoolean();
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
|
||||
if (version >= (5, 2)) //5.2 and up
|
||||
{
|
||||
m_HasTDoF = reader.ReadBoolean();
|
||||
}
|
||||
@@ -254,7 +256,7 @@ namespace AssetStudio
|
||||
m_AvatarSkeleton = new Skeleton(reader);
|
||||
m_AvatarSkeletonPose = new SkeletonPose(reader);
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
if (version >= (4, 3)) //4.3 and up
|
||||
{
|
||||
m_DefaultPose = new SkeletonPose(reader);
|
||||
|
||||
@@ -265,7 +267,7 @@ namespace AssetStudio
|
||||
|
||||
m_HumanSkeletonIndexArray = reader.ReadInt32Array();
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
if (version >= (4, 3)) //4.3 and up
|
||||
{
|
||||
m_HumanSkeletonReverseIndexArray = reader.ReadInt32Array();
|
||||
}
|
||||
@@ -273,7 +275,7 @@ namespace AssetStudio
|
||||
m_RootMotionBoneIndex = reader.ReadInt32();
|
||||
m_RootMotionBoneX = new xform(reader);
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
if (version >= (4, 3)) //4.3 and up
|
||||
{
|
||||
m_RootMotionSkeleton = new Skeleton(reader);
|
||||
m_RootMotionSkeletonPose = new SkeletonPose(reader);
|
||||
@@ -287,7 +289,7 @@ namespace AssetStudio
|
||||
{
|
||||
public uint m_AvatarSize;
|
||||
public AvatarConstant m_Avatar;
|
||||
public KeyValuePair<uint, string>[] m_TOS;
|
||||
public List<KeyValuePair<uint, string>> m_TOS;
|
||||
|
||||
public Avatar(ObjectReader reader) : base(reader)
|
||||
{
|
||||
@@ -295,10 +297,10 @@ namespace AssetStudio
|
||||
m_Avatar = new AvatarConstant(reader);
|
||||
|
||||
int numTOS = reader.ReadInt32();
|
||||
m_TOS = new KeyValuePair<uint, string>[numTOS];
|
||||
for (int i = 0; i < numTOS; i++)
|
||||
m_TOS = new List<KeyValuePair<uint, string>>();
|
||||
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
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public abstract class Behaviour : Component
|
||||
{
|
||||
public byte m_Enabled;
|
||||
|
||||
public Behaviour() { }
|
||||
|
||||
protected Behaviour(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_Enabled = reader.ReadByte();
|
||||
|
||||
@@ -1,24 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class BuildSettings : Object
|
||||
{
|
||||
public string m_Version;
|
||||
public string[] levels;
|
||||
public string[] scenes;
|
||||
|
||||
public BuildSettings(ObjectReader reader) : base(reader)
|
||||
{
|
||||
var levels = reader.ReadStringArray();
|
||||
|
||||
var hasRenderTexture = reader.ReadBoolean();
|
||||
var hasPROVersion = reader.ReadBoolean();
|
||||
var hasPublishingRights = reader.ReadBoolean();
|
||||
var hasShadows = reader.ReadBoolean();
|
||||
|
||||
m_Version = reader.ReadAlignedString();
|
||||
if (reader.version < (5, 1)) //5.1 down
|
||||
{
|
||||
levels = reader.ReadStringArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
scenes = reader.ReadStringArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public abstract class Component : EditorExtension
|
||||
{
|
||||
public PPtr<GameObject> m_GameObject;
|
||||
|
||||
public Component() { }
|
||||
|
||||
protected Component(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_GameObject = new PPtr<GameObject>(reader);
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public abstract class EditorExtension : Object
|
||||
{
|
||||
protected EditorExtension() { }
|
||||
|
||||
protected EditorExtension(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if (platform == BuildTarget.NoTarget)
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class Font : NamedObject
|
||||
{
|
||||
@@ -11,7 +6,7 @@ namespace AssetStudio
|
||||
|
||||
public Font(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5 and up
|
||||
if (version >= (5, 5))//5.5 and up
|
||||
{
|
||||
var m_LineSpacing = reader.ReadSingle();
|
||||
var m_DefaultMaterial = new PPtr<Material>(reader);
|
||||
@@ -23,12 +18,12 @@ namespace AssetStudio
|
||||
var m_CharacterPadding = reader.ReadInt32();
|
||||
var m_ConvertCase = 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
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -43,7 +38,7 @@ namespace AssetStudio
|
||||
{
|
||||
int m_AsciiStartOffset = reader.ReadInt32();
|
||||
|
||||
if (version[0] <= 3)
|
||||
if (version <= 3)
|
||||
{
|
||||
int m_FontCountX = reader.ReadInt32();
|
||||
int m_FontCountY = reader.ReadInt32();
|
||||
@@ -52,10 +47,10 @@ namespace AssetStudio
|
||||
float m_Kerning = reader.ReadSingle();
|
||||
float m_LineSpacing = reader.ReadSingle();
|
||||
|
||||
if (version[0] <= 3)
|
||||
if (version <= 3)
|
||||
{
|
||||
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();
|
||||
float second = reader.ReadSingle();
|
||||
@@ -71,7 +66,7 @@ namespace AssetStudio
|
||||
var m_DefaultMaterial = new PPtr<Material>(reader);
|
||||
|
||||
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();
|
||||
//Rectf uv
|
||||
@@ -86,7 +81,7 @@ namespace AssetStudio
|
||||
float vertheight = reader.ReadSingle();
|
||||
float width = reader.ReadSingle();
|
||||
|
||||
if (version[0] >= 4)
|
||||
if (version >= 4)
|
||||
{
|
||||
var flipped = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
@@ -96,14 +91,14 @@ namespace AssetStudio
|
||||
var m_Texture = new PPtr<Texture>(reader);
|
||||
|
||||
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 pairsecond = reader.ReadInt16();
|
||||
float second = reader.ReadSingle();
|
||||
}
|
||||
|
||||
if (version[0] <= 3)
|
||||
if (version <= 3)
|
||||
{
|
||||
var m_GridFont = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
|
||||
35
AssetStudio/Classes/GLTextureSettings.cs
Normal file
35
AssetStudio/Classes/GLTextureSettings.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class GLTextureSettings
|
||||
{
|
||||
public int m_FilterMode;
|
||||
public int m_Aniso;
|
||||
public float m_MipBias;
|
||||
public int m_WrapMode;
|
||||
[JsonInclude]
|
||||
private int m_WrapU { set => m_WrapMode = value; }
|
||||
|
||||
public GLTextureSettings() { }
|
||||
|
||||
public GLTextureSettings(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
m_FilterMode = reader.ReadInt32();
|
||||
m_Aniso = reader.ReadInt32();
|
||||
m_MipBias = reader.ReadSingle();
|
||||
if (version >= 2017)//2017.x and up
|
||||
{
|
||||
m_WrapMode = reader.ReadInt32(); //m_WrapU
|
||||
var m_WrapV = reader.ReadInt32();
|
||||
var m_WrapW = reader.ReadInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_WrapMode = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class GameObject : EditorExtension
|
||||
{
|
||||
public PPtr<Component>[] m_Components;
|
||||
public List<PPtr<Component>> m_Components;
|
||||
public string m_Name;
|
||||
|
||||
public Transform m_Transform;
|
||||
@@ -16,21 +14,28 @@ namespace AssetStudio
|
||||
public SkinnedMeshRenderer m_SkinnedMeshRenderer;
|
||||
public Animator m_Animator;
|
||||
public Animation m_Animation;
|
||||
[JsonIgnore]
|
||||
public CubismModel CubismModel;
|
||||
|
||||
public GameObject(ObjectReader reader) : base(reader)
|
||||
{
|
||||
int m_Component_size = reader.ReadInt32();
|
||||
m_Components = new PPtr<Component>[m_Component_size];
|
||||
for (int i = 0; i < m_Component_size; i++)
|
||||
var m_ComponentSize = reader.ReadInt32();
|
||||
m_Components = new List<PPtr<Component>>();
|
||||
for (var i = 0; i < m_ComponentSize; i++)
|
||||
{
|
||||
if ((version[0] == 5 && version[1] < 5) || version[0] < 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();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
711
AssetStudio/Classes/GraphicsFormat.cs
Normal file
711
AssetStudio/Classes/GraphicsFormat.cs
Normal file
@@ -0,0 +1,711 @@
|
||||
namespace AssetStudio
|
||||
{
|
||||
public enum GraphicsFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// The format is not specified.
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// A one-component, 8-bit unsigned normalized format that has a single 8-bit R component stored with sRGB nonlinear encoding.
|
||||
/// </summary>
|
||||
R8_SRGB,
|
||||
/// <summary>
|
||||
/// A two-component, 16-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, and an 8-bit G component stored with sRGB nonlinear encoding in byte 1.
|
||||
/// </summary>
|
||||
R8G8_SRGB,
|
||||
/// <summary>
|
||||
/// A three-component, 24-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, and an 8-bit B component stored with sRGB nonlinear encoding in byte 2.
|
||||
/// </summary>
|
||||
R8G8B8_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, an 8-bit B component stored with sRGB nonlinear encoding in byte 2, and an 8-bit A component in byte 3.
|
||||
/// </summary>
|
||||
R8G8B8A8_SRGB,
|
||||
/// <summary>
|
||||
/// A one-component, 8-bit unsigned normalized format that has a single 8-bit R component.
|
||||
/// </summary>
|
||||
R8_UNorm,
|
||||
/// <summary>
|
||||
/// A two-component, 16-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, and an 8-bit G component stored with sRGB nonlinear encoding in byte 1.
|
||||
/// </summary>
|
||||
R8G8_UNorm,
|
||||
/// <summary>
|
||||
/// A three-component, 24-bit unsigned normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
|
||||
/// </summary>
|
||||
R8G8B8_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit unsigned normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
|
||||
/// </summary>
|
||||
R8G8B8A8_UNorm,
|
||||
/// <summary>
|
||||
/// A one-component, 8-bit signed normalized format that has a single 8-bit R component.
|
||||
/// </summary>
|
||||
R8_SNorm,
|
||||
/// <summary>
|
||||
/// A two-component, 16-bit signed normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, and an 8-bit G component stored with sRGB nonlinear encoding in byte 1.
|
||||
/// </summary>
|
||||
R8G8_SNorm,
|
||||
/// <summary>
|
||||
/// A three-component, 24-bit signed normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
|
||||
/// </summary>
|
||||
R8G8B8_SNorm,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit signed normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
|
||||
/// </summary>
|
||||
R8G8B8A8_SNorm,
|
||||
/// <summary>
|
||||
/// A one-component, 8-bit unsigned integer format that has a single 8-bit R component.
|
||||
/// </summary>
|
||||
R8_UInt,
|
||||
/// <summary>
|
||||
/// A two-component, 16-bit unsigned integer format that has an 8-bit R component in byte 0, and an 8-bit G component in byte 1.
|
||||
/// </summary>
|
||||
R8G8_UInt,
|
||||
/// <summary>
|
||||
/// A three-component, 24-bit unsigned integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
|
||||
/// </summary>
|
||||
R8G8B8_UInt,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit unsigned integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
|
||||
/// </summary>
|
||||
R8G8B8A8_UInt,
|
||||
/// <summary>
|
||||
/// A one-component, 8-bit signed integer format that has a single 8-bit R component.
|
||||
/// </summary>
|
||||
R8_SInt,
|
||||
/// <summary>
|
||||
/// A two-component, 16-bit signed integer format that has an 8-bit R component in byte 0, and an 8-bit G component in byte 1.
|
||||
/// </summary>
|
||||
R8G8_SInt,
|
||||
/// <summary>
|
||||
/// A three-component, 24-bit signed integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
|
||||
/// </summary>
|
||||
R8G8B8_SInt,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit signed integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
|
||||
/// </summary>
|
||||
R8G8B8A8_SInt,
|
||||
/// <summary>
|
||||
/// A one-component, 16-bit unsigned normalized format that has a single 16-bit R component.
|
||||
/// </summary>
|
||||
R16_UNorm,
|
||||
/// <summary>
|
||||
/// A two-component, 32-bit unsigned normalized format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
|
||||
/// </summary>
|
||||
R16G16_UNorm,
|
||||
/// <summary>
|
||||
/// A three-component, 48-bit unsigned normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
|
||||
/// </summary>
|
||||
R16G16B16_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, 64-bit unsigned normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
|
||||
/// </summary>
|
||||
R16G16B16A16_UNorm,
|
||||
/// <summary>
|
||||
/// A one-component, 16-bit signed normalized format that has a single 16-bit R component.
|
||||
/// </summary>
|
||||
R16_SNorm,
|
||||
/// <summary>
|
||||
/// A two-component, 32-bit signed normalized format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
|
||||
/// </summary>
|
||||
R16G16_SNorm,
|
||||
/// <summary>
|
||||
/// A three-component, 48-bit signed normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
|
||||
/// </summary>
|
||||
R16G16B16_SNorm,
|
||||
/// <summary>
|
||||
/// A four-component, 64-bit signed normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
|
||||
/// </summary>
|
||||
R16G16B16A16_SNorm,
|
||||
/// <summary>
|
||||
/// A one-component, 16-bit unsigned integer format that has a single 16-bit R component.
|
||||
/// </summary>
|
||||
R16_UInt,
|
||||
/// <summary>
|
||||
/// A two-component, 32-bit unsigned integer format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
|
||||
/// </summary>
|
||||
R16G16_UInt,
|
||||
/// <summary>
|
||||
/// A three-component, 48-bit unsigned integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
|
||||
/// </summary>
|
||||
R16G16B16_UInt,
|
||||
/// <summary>
|
||||
/// A four-component, 64-bit unsigned integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
|
||||
/// </summary>
|
||||
R16G16B16A16_UInt,
|
||||
/// <summary>
|
||||
/// A one-component, 16-bit signed integer format that has a single 16-bit R component.
|
||||
/// </summary>
|
||||
R16_SInt,
|
||||
/// <summary>
|
||||
/// A two-component, 32-bit signed integer format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
|
||||
/// </summary>
|
||||
R16G16_SInt,
|
||||
/// <summary>
|
||||
/// A three-component, 48-bit signed integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
|
||||
/// </summary>
|
||||
R16G16B16_SInt,
|
||||
/// <summary>
|
||||
/// A four-component, 64-bit signed integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
|
||||
/// </summary>
|
||||
R16G16B16A16_SInt,
|
||||
/// <summary>
|
||||
/// A one-component, 32-bit unsigned integer format that has a single 32-bit R component.
|
||||
/// </summary>
|
||||
R32_UInt,
|
||||
/// <summary>
|
||||
/// A two-component, 64-bit unsigned integer format that has a 32-bit R component in bytes 0..3, and a 32-bit G component in bytes 4..7.
|
||||
/// </summary>
|
||||
R32G32_UInt,
|
||||
/// <summary>
|
||||
/// A three-component, 96-bit unsigned integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, and a 32-bit B component in bytes 8..11.
|
||||
/// </summary>
|
||||
R32G32B32_UInt,
|
||||
/// <summary>
|
||||
/// A four-component, 128-bit unsigned integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, a 32-bit B component in bytes 8..11, and a 32-bit A component in bytes 12..15.
|
||||
/// </summary>
|
||||
R32G32B32A32_UInt,
|
||||
/// <summary>
|
||||
/// A one-component, 32-bit signed integer format that has a single 32-bit R component.
|
||||
/// </summary>
|
||||
R32_SInt,
|
||||
/// <summary>
|
||||
/// A two-component, 64-bit signed integer format that has a 32-bit R component in bytes 0..3, and a 32-bit G component in bytes 4..7.
|
||||
/// </summary>
|
||||
R32G32_SInt,
|
||||
/// <summary>
|
||||
/// A three-component, 96-bit signed integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, and a 32-bit B component in bytes 8..11.
|
||||
/// </summary>
|
||||
R32G32B32_SInt,
|
||||
/// <summary>
|
||||
/// A four-component, 128-bit signed integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, a 32-bit B component in bytes 8..11, and a 32-bit A component in bytes 12..15.
|
||||
/// </summary>
|
||||
R32G32B32A32_SInt,
|
||||
/// <summary>
|
||||
/// A one-component, 16-bit signed floating-point format that has a single 16-bit R component.
|
||||
/// </summary>
|
||||
R16_SFloat,
|
||||
/// <summary>
|
||||
/// A two-component, 32-bit signed floating-point format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
|
||||
/// </summary>
|
||||
R16G16_SFloat,
|
||||
/// <summary>
|
||||
/// A three-component, 48-bit signed floating-point format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
|
||||
/// </summary>
|
||||
R16G16B16_SFloat,
|
||||
/// <summary>
|
||||
/// A four-component, 64-bit signed floating-point format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
|
||||
/// </summary>
|
||||
R16G16B16A16_SFloat,
|
||||
/// <summary>
|
||||
/// A one-component, 32-bit signed floating-point format that has a single 32-bit R component.
|
||||
/// </summary>
|
||||
R32_SFloat,
|
||||
/// <summary>
|
||||
/// A two-component, 64-bit signed floating-point format that has a 32-bit R component in bytes 0..3, and a 32-bit G component in bytes 4..7.
|
||||
/// </summary>
|
||||
R32G32_SFloat,
|
||||
/// <summary>
|
||||
/// A three-component, 96-bit signed floating-point format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, and a 32-bit B component in bytes 8..11.
|
||||
/// </summary>
|
||||
R32G32B32_SFloat,
|
||||
/// <summary>
|
||||
/// A four-component, 128-bit signed floating-point format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, a 32-bit B component in bytes 8..11, and a 32-bit A component in bytes 12..15.
|
||||
/// </summary>
|
||||
R32G32B32A32_SFloat,
|
||||
/// <summary>
|
||||
/// A three-component, 24-bit unsigned normalized format that has an 8-bit B component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, and an 8-bit R component stored with sRGB nonlinear encoding in byte 2.
|
||||
/// </summary>
|
||||
B8G8R8_SRGB = 56,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit unsigned normalized format that has an 8-bit B component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, an 8-bit R component stored with sRGB nonlinear encoding in byte 2, and an 8-bit A component in byte 3.
|
||||
/// </summary>
|
||||
B8G8R8A8_SRGB,
|
||||
/// <summary>
|
||||
/// A three-component, 24-bit unsigned normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2.
|
||||
/// </summary>
|
||||
B8G8R8_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit unsigned normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
|
||||
/// </summary>
|
||||
B8G8R8A8_UNorm,
|
||||
/// <summary>
|
||||
/// A three-component, 24-bit signed normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2.
|
||||
/// </summary>
|
||||
B8G8R8_SNorm,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit signed normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
|
||||
/// </summary>
|
||||
B8G8R8A8_SNorm,
|
||||
/// <summary>
|
||||
/// A three-component, 24-bit unsigned integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2
|
||||
/// </summary>
|
||||
B8G8R8_UInt,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit unsigned integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
|
||||
/// </summary>
|
||||
B8G8R8A8_UInt,
|
||||
/// <summary>
|
||||
/// A three-component, 24-bit signed integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2.
|
||||
/// </summary>
|
||||
B8G8R8_SInt,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit signed integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
|
||||
/// </summary>
|
||||
B8G8R8A8_SInt,
|
||||
/// <summary>
|
||||
/// A four-component, 16-bit packed unsigned normalized format that has a 4-bit R component in bits 12..15, a 4-bit G component in bits 8..11, a 4-bit B component in bits 4..7, and a 4-bit A component in bits 0..3.
|
||||
/// </summary>
|
||||
R4G4B4A4_UNormPack16,
|
||||
/// <summary>
|
||||
/// A four-component, 16-bit packed unsigned normalized format that has a 4-bit B component in bits 12..15, a 4-bit G component in bits 8..11, a 4-bit R component in bits 4..7, and a 4-bit A component in bits 0..3.
|
||||
/// </summary>
|
||||
B4G4R4A4_UNormPack16,
|
||||
/// <summary>
|
||||
/// A three-component, 16-bit packed unsigned normalized format that has a 5-bit R component in bits 11..15, a 6-bit G component in bits 5..10, and a 5-bit B component in bits 0..4.
|
||||
/// </summary>
|
||||
R5G6B5_UNormPack16,
|
||||
/// <summary>
|
||||
/// A three-component, 16-bit packed unsigned normalized format that has a 5-bit B component in bits 11..15, a 6-bit G component in bits 5..10, and a 5-bit R component in bits 0..4.
|
||||
/// </summary>
|
||||
B5G6R5_UNormPack16,
|
||||
/// <summary>
|
||||
/// A four-component, 16-bit packed unsigned normalized format that has a 5-bit R component in bits 11..15, a 5-bit G component in bits 6..10, a 5-bit B component in bits 1..5, and a 1-bit A component in bit 0.
|
||||
/// </summary>
|
||||
R5G5B5A1_UNormPack16,
|
||||
/// <summary>
|
||||
/// A four-component, 16-bit packed unsigned normalized format that has a 5-bit B component in bits 11..15, a 5-bit G component in bits 6..10, a 5-bit R component in bits 1..5, and a 1-bit A component in bit 0.
|
||||
/// </summary>
|
||||
B5G5R5A1_UNormPack16,
|
||||
/// <summary>
|
||||
/// A four-component, 16-bit packed unsigned normalized format that has a 1-bit A component in bit 15, a 5-bit R component in bits 10..14, a 5-bit G component in bits 5..9, and a 5-bit B component in bits 0..4.
|
||||
/// </summary>
|
||||
A1R5G5B5_UNormPack16,
|
||||
/// <summary>
|
||||
/// A three-component, 32-bit packed unsigned floating-point format that has a 5-bit shared exponent in bits 27..31, a 9-bit B component mantissa in bits 18..26, a 9-bit G component mantissa in bits 9..17, and a 9-bit R component mantissa in bits 0..8.
|
||||
/// </summary>
|
||||
E5B9G9R9_UFloatPack32,
|
||||
/// <summary>
|
||||
/// A three-component, 32-bit packed unsigned floating-point format that has a 10-bit B component in bits 22..31, an 11-bit G component in bits 11..21, an 11-bit R component in bits 0..10.
|
||||
/// </summary>
|
||||
B10G11R11_UFloatPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit B component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit R component in bits 0..9.
|
||||
/// </summary>
|
||||
A2B10G10R10_UNormPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit packed unsigned integer format that has a 2-bit A component in bits 30..31, a 10-bit B component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit R component in bits 0..9.
|
||||
/// </summary>
|
||||
A2B10G10R10_UIntPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit packed signed integer format that has a 2-bit A component in bits 30..31, a 10-bit B component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit R component in bits 0..9.
|
||||
/// </summary>
|
||||
A2B10G10R10_SIntPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9.
|
||||
/// </summary>
|
||||
A2R10G10B10_UNormPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit packed unsigned integer format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9.
|
||||
/// </summary>
|
||||
A2R10G10B10_UIntPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit packed signed integer format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9.
|
||||
/// </summary>
|
||||
A2R10G10B10_SIntPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are gamma encoded and their values range from -0.5271 to 1.66894. The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
|
||||
/// </summary>
|
||||
A2R10G10B10_XRSRGBPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are linearly encoded and their values range from -0.752941 to 1.25098 (pre-expansion). The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
|
||||
/// </summary>
|
||||
A2R10G10B10_XRUNormPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit packed unsigned normalized format that has a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are gamma encoded and their values range from -0.5271 to 1.66894. The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
|
||||
/// </summary>
|
||||
R10G10B10_XRSRGBPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 32-bit packed unsigned normalized format that has a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are linearly encoded and their values range from -0.752941 to 1.25098 (pre-expansion).
|
||||
/// </summary>
|
||||
R10G10B10_XRUNormPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 64-bit packed unsigned normalized format that has a 10-bit A component in bits 30..39, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are gamma encoded and their values range from -0.5271 to 1.66894. The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
|
||||
/// </summary>
|
||||
A10R10G10B10_XRSRGBPack32,
|
||||
/// <summary>
|
||||
/// A four-component, 64-bit packed unsigned normalized format that has a 10-bit A component in bits 30..39, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are linearly encoded and their values range from -0.752941 to 1.25098 (pre-expansion). The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
|
||||
/// </summary>
|
||||
A10R10G10B10_XRUNormPack32,
|
||||
/// <summary>
|
||||
/// A one-component, 16-bit unsigned normalized format that has a single 16-bit depth component.
|
||||
/// </summary>
|
||||
D16_UNorm = 90,
|
||||
/// <summary>
|
||||
/// A two-component, 32-bit format that has 24 unsigned normalized bits in the depth component and, optionally: 8 bits that are unused.
|
||||
/// </summary>
|
||||
D24_UNorm,
|
||||
/// <summary>
|
||||
/// A two-component, 32-bit packed format that has 8 unsigned integer bits in the stencil component, and 24 unsigned normalized bits in the depth component.
|
||||
/// </summary>
|
||||
D24_UNorm_S8_UInt,
|
||||
/// <summary>
|
||||
/// A one-component, 32-bit signed floating-point format that has 32-bits in the depth component.
|
||||
/// </summary>
|
||||
D32_SFloat,
|
||||
/// <summary>
|
||||
/// A two-component format that has 32 signed float bits in the depth component and 8 unsigned integer bits in the stencil component. There are optionally: 24-bits that are unused.
|
||||
/// </summary>
|
||||
D32_SFloat_S8_UInt,
|
||||
/// <summary>
|
||||
/// A one-component, 8-bit unsigned integer format that has 8-bits in the stencil component.
|
||||
/// </summary>
|
||||
S8_UInt,
|
||||
/// <summary>
|
||||
/// A three-component, block-compressed format (also known as BC1). Each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has a 1 bit alpha channel.
|
||||
/// </summary>
|
||||
RGBA_DXT1_SRGB,
|
||||
/// <summary>
|
||||
/// A three-component, block-compressed format (also known as BC1). Each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has a 1 bit alpha channel.
|
||||
/// </summary>
|
||||
RGBA_DXT1_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, block-compressed format (also known as BC2) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values with sRGB nonlinear encoding.
|
||||
/// </summary>
|
||||
RGBA_DXT3_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, block-compressed format (also known as BC2) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values.
|
||||
/// </summary>
|
||||
RGBA_DXT3_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, block-compressed format (also known as BC3) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values with sRGB nonlinear encoding.
|
||||
/// </summary>
|
||||
RGBA_DXT5_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, block-compressed format (also known as BC3) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values.
|
||||
/// </summary>
|
||||
RGBA_DXT5_UNorm,
|
||||
/// <summary>
|
||||
/// A one-component, block-compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized red texel data.
|
||||
/// </summary>
|
||||
R_BC4_UNorm,
|
||||
/// <summary>
|
||||
/// A one-component, block-compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of signed normalized red texel data.
|
||||
/// </summary>
|
||||
R_BC4_SNorm,
|
||||
/// <summary>
|
||||
/// A two-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
|
||||
/// </summary>
|
||||
RG_BC5_UNorm,
|
||||
/// <summary>
|
||||
/// A two-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of signed normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
|
||||
/// </summary>
|
||||
RG_BC5_SNorm,
|
||||
/// <summary>
|
||||
/// A three-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned floating-point RGB texel data.
|
||||
/// </summary>
|
||||
RGB_BC6H_UFloat,
|
||||
/// <summary>
|
||||
/// A three-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of signed floating-point RGB texel data.
|
||||
/// </summary>
|
||||
RGB_BC6H_SFloat,
|
||||
/// <summary>
|
||||
/// A four-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
||||
/// </summary>
|
||||
RGBA_BC7_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_BC7_UNorm,
|
||||
/// <summary>
|
||||
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has no alpha and is considered opaque.
|
||||
/// </summary>
|
||||
RGB_PVRTC_2Bpp_SRGB,
|
||||
/// <summary>
|
||||
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
|
||||
/// </summary>
|
||||
RGB_PVRTC_2Bpp_UNorm,
|
||||
/// <summary>
|
||||
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has no alpha and is considered opaque.
|
||||
/// </summary>
|
||||
RGB_PVRTC_4Bpp_SRGB,
|
||||
/// <summary>
|
||||
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
|
||||
/// </summary>
|
||||
RGB_PVRTC_4Bpp_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values with sRGB nonlinear encoding applied.
|
||||
/// </summary>
|
||||
RGBA_PVRTC_2Bpp_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values.
|
||||
/// </summary>
|
||||
RGBA_PVRTC_2Bpp_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values with sRGB nonlinear encoding applied.
|
||||
/// </summary>
|
||||
RGBA_PVRTC_4Bpp_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values.
|
||||
/// </summary>
|
||||
RGBA_PVRTC_4Bpp_UNorm,
|
||||
/// <summary>
|
||||
/// A three-component, ETC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
|
||||
/// </summary>
|
||||
RGB_ETC_UNorm,
|
||||
/// <summary>
|
||||
/// A three-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has no alpha and is considered opaque.
|
||||
/// </summary>
|
||||
RGB_ETC2_SRGB,
|
||||
/// <summary>
|
||||
/// A three-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
|
||||
/// </summary>
|
||||
RGB_ETC2_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding, and provides 1 bit of alpha.
|
||||
/// </summary>
|
||||
RGB_A1_ETC2_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data, and provides 1 bit of alpha.
|
||||
/// </summary>
|
||||
RGB_A1_ETC2_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values with sRGB nonlinear encoding applied.
|
||||
/// </summary>
|
||||
RGBA_ETC2_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values.
|
||||
/// </summary>
|
||||
RGBA_ETC2_UNorm,
|
||||
/// <summary>
|
||||
/// A one-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized red texel data.
|
||||
/// </summary>
|
||||
R_EAC_UNorm,
|
||||
/// <summary>
|
||||
/// A one-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of signed normalized red texel data.
|
||||
/// </summary>
|
||||
R_EAC_SNorm,
|
||||
/// <summary>
|
||||
/// A two-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
|
||||
/// </summary>
|
||||
RG_EAC_UNorm,
|
||||
/// <summary>
|
||||
/// A two-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of signed normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
|
||||
/// </summary>
|
||||
RG_EAC_SNorm,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
||||
/// </summary>
|
||||
RGBA_ASTC4X4_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC4X4_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 5×5 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
||||
/// </summary>
|
||||
RGBA_ASTC5X5_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 5×5 rectangle of unsigned normalized RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC5X5_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 6×6 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
||||
/// </summary>
|
||||
RGBA_ASTC6X6_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 6×6 rectangle of unsigned normalized RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC6X6_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes an 8×8 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
||||
/// </summary>
|
||||
RGBA_ASTC8X8_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes an 8×8 rectangle of unsigned normalized RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC8X8_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 10×10 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
||||
/// </summary>
|
||||
RGBA_ASTC10X10_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 10×10 rectangle of unsigned normalized RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC10X10_UNorm,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 12×12 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
|
||||
/// </summary>
|
||||
RGBA_ASTC12X12_SRGB,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 12×12 rectangle of unsigned normalized RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC12X12_UNorm,
|
||||
/// <summary>
|
||||
/// YUV 4:2:2 Video resource format.
|
||||
/// </summary>
|
||||
YUV2,
|
||||
/// <summary>
|
||||
/// GraphicsFormat.YUV2.
|
||||
/// </summary>
|
||||
VideoAuto = 144,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of float RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC4X4_UFloat,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 5×5 rectangle of float RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC5X5_UFloat,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 6×6 rectangle of float RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC6X6_UFloat,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes an 8×8 rectangle of float RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC8X8_UFloat,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 10×10 rectangle of float RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC10X10_UFloat,
|
||||
/// <summary>
|
||||
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 12×12 rectangle of float RGBA texel data.
|
||||
/// </summary>
|
||||
RGBA_ASTC12X12_UFloat,
|
||||
/// <summary>
|
||||
/// A two-component, 24-bit format that has 16 unsigned normalized bits in the depth component and 8 unsigned integer bits in the stencil component. Most platforms do not support this format.
|
||||
/// </summary>
|
||||
D16_UNorm_S8_UInt,
|
||||
}
|
||||
|
||||
public static class GraphicsFormatExtension
|
||||
{
|
||||
public static TextureFormat ToTextureFormat(this GraphicsFormat graphicsFormat)
|
||||
{
|
||||
switch (graphicsFormat)
|
||||
{
|
||||
case GraphicsFormat.R8_SRGB:
|
||||
case GraphicsFormat.R8_UInt:
|
||||
case GraphicsFormat.R8_UNorm:
|
||||
return TextureFormat.R8;
|
||||
case GraphicsFormat.R8G8_SRGB:
|
||||
case GraphicsFormat.R8G8_UInt:
|
||||
case GraphicsFormat.R8G8_UNorm:
|
||||
return TextureFormat.RG16;
|
||||
case GraphicsFormat.R8G8B8_SRGB:
|
||||
case GraphicsFormat.R8G8B8_UInt:
|
||||
case GraphicsFormat.R8G8B8_UNorm:
|
||||
return TextureFormat.RGB24;
|
||||
case GraphicsFormat.R8G8B8A8_SRGB:
|
||||
case GraphicsFormat.R8G8B8A8_UInt:
|
||||
case GraphicsFormat.R8G8B8A8_UNorm:
|
||||
return TextureFormat.RGBA32;
|
||||
case GraphicsFormat.R16_UInt:
|
||||
case GraphicsFormat.R16_UNorm:
|
||||
return TextureFormat.R16;
|
||||
case GraphicsFormat.R16G16_UInt:
|
||||
case GraphicsFormat.R16G16_UNorm:
|
||||
return TextureFormat.RG32;
|
||||
case GraphicsFormat.R16G16B16_UInt:
|
||||
case GraphicsFormat.R16G16B16_UNorm:
|
||||
return TextureFormat.RGB48;
|
||||
case GraphicsFormat.R16G16B16A16_UInt:
|
||||
case GraphicsFormat.R16G16B16A16_UNorm:
|
||||
return TextureFormat.RGBA64;
|
||||
case GraphicsFormat.R16_SFloat:
|
||||
return TextureFormat.RHalf;
|
||||
case GraphicsFormat.R16G16_SFloat:
|
||||
return TextureFormat.RGHalf;
|
||||
case GraphicsFormat.R16G16B16_SFloat: //?
|
||||
case GraphicsFormat.R16G16B16A16_SFloat:
|
||||
return TextureFormat.RGBAHalf;
|
||||
case GraphicsFormat.R32_SFloat:
|
||||
return TextureFormat.RFloat;
|
||||
case GraphicsFormat.R32G32_SFloat:
|
||||
return TextureFormat.RGFloat;
|
||||
case GraphicsFormat.R32G32B32_SFloat: //?
|
||||
case GraphicsFormat.R32G32B32A32_SFloat:
|
||||
return TextureFormat.RGBAFloat;
|
||||
case GraphicsFormat.B8G8R8A8_SRGB:
|
||||
case GraphicsFormat.B8G8R8A8_UInt:
|
||||
case GraphicsFormat.B8G8R8A8_UNorm:
|
||||
return TextureFormat.BGRA32;
|
||||
case GraphicsFormat.E5B9G9R9_UFloatPack32:
|
||||
return TextureFormat.RGB9e5Float;
|
||||
case GraphicsFormat.RGBA_DXT1_SRGB:
|
||||
case GraphicsFormat.RGBA_DXT1_UNorm:
|
||||
return TextureFormat.DXT1;
|
||||
case GraphicsFormat.RGBA_DXT3_SRGB:
|
||||
case GraphicsFormat.RGBA_DXT3_UNorm:
|
||||
return TextureFormat.DXT3;
|
||||
case GraphicsFormat.RGBA_DXT5_SRGB:
|
||||
case GraphicsFormat.RGBA_DXT5_UNorm:
|
||||
return TextureFormat.DXT5;
|
||||
case GraphicsFormat.R_BC4_UNorm:
|
||||
return TextureFormat.BC4;
|
||||
case GraphicsFormat.RG_BC5_UNorm:
|
||||
return TextureFormat.BC5;
|
||||
case GraphicsFormat.RGB_BC6H_SFloat:
|
||||
case GraphicsFormat.RGB_BC6H_UFloat:
|
||||
return TextureFormat.BC6H;
|
||||
case GraphicsFormat.RGBA_BC7_SRGB:
|
||||
case GraphicsFormat.RGBA_BC7_UNorm:
|
||||
return TextureFormat.BC7;
|
||||
case GraphicsFormat.RGB_PVRTC_2Bpp_SRGB:
|
||||
case GraphicsFormat.RGB_PVRTC_2Bpp_UNorm:
|
||||
case GraphicsFormat.RGBA_PVRTC_2Bpp_SRGB:
|
||||
case GraphicsFormat.RGBA_PVRTC_2Bpp_UNorm:
|
||||
return TextureFormat.PVRTC_RGBA2;
|
||||
case GraphicsFormat.RGB_PVRTC_4Bpp_SRGB:
|
||||
case GraphicsFormat.RGB_PVRTC_4Bpp_UNorm:
|
||||
case GraphicsFormat.RGBA_PVRTC_4Bpp_SRGB:
|
||||
case GraphicsFormat.RGBA_PVRTC_4Bpp_UNorm:
|
||||
return TextureFormat.PVRTC_RGBA4;
|
||||
case GraphicsFormat.RGB_ETC_UNorm:
|
||||
return TextureFormat.ETC_RGB4;
|
||||
case GraphicsFormat.RGB_ETC2_SRGB:
|
||||
case GraphicsFormat.RGB_ETC2_UNorm:
|
||||
return TextureFormat.ETC2_RGB;
|
||||
case GraphicsFormat.RGB_A1_ETC2_SRGB:
|
||||
case GraphicsFormat.RGB_A1_ETC2_UNorm:
|
||||
return TextureFormat.ETC2_RGBA1;
|
||||
case GraphicsFormat.RGBA_ETC2_SRGB:
|
||||
case GraphicsFormat.RGBA_ETC2_UNorm:
|
||||
return TextureFormat.ETC2_RGBA8;
|
||||
case GraphicsFormat.R_EAC_UNorm:
|
||||
return TextureFormat.EAC_R;
|
||||
case GraphicsFormat.R_EAC_SNorm:
|
||||
return TextureFormat.EAC_R_SIGNED;
|
||||
case GraphicsFormat.RG_EAC_UNorm:
|
||||
return TextureFormat.EAC_RG;
|
||||
case GraphicsFormat.RG_EAC_SNorm:
|
||||
return TextureFormat.EAC_RG_SIGNED;
|
||||
case GraphicsFormat.RGBA_ASTC4X4_SRGB:
|
||||
case GraphicsFormat.RGBA_ASTC4X4_UNorm:
|
||||
return TextureFormat.ASTC_RGBA_4x4;
|
||||
case GraphicsFormat.RGBA_ASTC5X5_SRGB:
|
||||
case GraphicsFormat.RGBA_ASTC5X5_UNorm:
|
||||
return TextureFormat.ASTC_RGBA_5x5;
|
||||
case GraphicsFormat.RGBA_ASTC6X6_SRGB:
|
||||
case GraphicsFormat.RGBA_ASTC6X6_UNorm:
|
||||
return TextureFormat.ASTC_RGBA_6x6;
|
||||
case GraphicsFormat.RGBA_ASTC8X8_SRGB:
|
||||
case GraphicsFormat.RGBA_ASTC8X8_UNorm:
|
||||
return TextureFormat.ASTC_RGBA_8x8;
|
||||
case GraphicsFormat.RGBA_ASTC10X10_SRGB:
|
||||
case GraphicsFormat.RGBA_ASTC10X10_UNorm:
|
||||
return TextureFormat.ASTC_RGBA_10x10;
|
||||
case GraphicsFormat.RGBA_ASTC12X12_SRGB:
|
||||
case GraphicsFormat.RGBA_ASTC12X12_UNorm:
|
||||
return TextureFormat.ASTC_RGBA_12x12;
|
||||
case GraphicsFormat.YUV2:
|
||||
case GraphicsFormat.VideoAuto:
|
||||
return TextureFormat.YUY2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -8,6 +9,8 @@ namespace AssetStudio
|
||||
public Vector2 m_Scale;
|
||||
public Vector2 m_Offset;
|
||||
|
||||
public UnityTexEnv() { }
|
||||
|
||||
public UnityTexEnv(ObjectReader reader)
|
||||
{
|
||||
m_Texture = new PPtr<Texture>(reader);
|
||||
@@ -18,31 +21,46 @@ namespace AssetStudio
|
||||
|
||||
public class UnityPropertySheet
|
||||
{
|
||||
public KeyValuePair<string, UnityTexEnv>[] m_TexEnvs;
|
||||
public KeyValuePair<string, float>[] m_Floats;
|
||||
public KeyValuePair<string, Color>[] m_Colors;
|
||||
public List<KeyValuePair<string, UnityTexEnv>> m_TexEnvs;
|
||||
public List<KeyValuePair<string, int>> m_Ints;
|
||||
public List<KeyValuePair<string, float>> m_Floats;
|
||||
public List<KeyValuePair<string, Color>> m_Colors;
|
||||
|
||||
public UnityPropertySheet() { }
|
||||
|
||||
public UnityPropertySheet(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
int m_TexEnvsSize = reader.ReadInt32();
|
||||
m_TexEnvs = new KeyValuePair<string, UnityTexEnv>[m_TexEnvsSize];
|
||||
for (int i = 0; i < m_TexEnvsSize; i++)
|
||||
m_TexEnvs = new List<KeyValuePair<string, UnityTexEnv>>();
|
||||
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
|
||||
{
|
||||
int m_IntsSize = reader.ReadInt32();
|
||||
m_Ints = new List<KeyValuePair<string, int>>();
|
||||
for (var i = 0; i < m_IntsSize; i++)
|
||||
{
|
||||
m_Ints.Add(new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32()));
|
||||
}
|
||||
}
|
||||
|
||||
int m_FloatsSize = reader.ReadInt32();
|
||||
m_Floats = new KeyValuePair<string, float>[m_FloatsSize];
|
||||
for (int i = 0; i < m_FloatsSize; i++)
|
||||
m_Floats = new List<KeyValuePair<string, float>>();
|
||||
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();
|
||||
m_Colors = new KeyValuePair<string, Color>[m_ColorsSize];
|
||||
for (int i = 0; i < m_ColorsSize; i++)
|
||||
m_Colors = new List<KeyValuePair<string, Color>>();
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,49 +70,69 @@ namespace AssetStudio
|
||||
public PPtr<Shader> m_Shader;
|
||||
public UnityPropertySheet m_SavedProperties;
|
||||
|
||||
public Material() { }
|
||||
|
||||
public Material(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
|
||||
{
|
||||
var parsedMaterial = JsonSerializer.Deserialize<Material>(type, jsonOptions);
|
||||
m_Shader = parsedMaterial.m_Shader;
|
||||
m_SavedProperties = parsedMaterial.m_SavedProperties;
|
||||
}
|
||||
|
||||
public Material(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_Shader = new PPtr<Shader>(reader);
|
||||
|
||||
if (version[0] == 4 && version[1] >= 1) //4.x
|
||||
if (version == 4 && version.Minor >= 1) //4.1 - 4.7.2
|
||||
{
|
||||
var m_ShaderKeywords = reader.ReadStringArray();
|
||||
}
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
if (version >= (2021, 2, 18)) //2021.2.18 and up
|
||||
{
|
||||
var m_ValidKeywords = reader.ReadStringArray();
|
||||
var m_InvalidKeywords = reader.ReadStringArray();
|
||||
}
|
||||
else if (version >= 5) //5.0 - 2021.2.17
|
||||
{
|
||||
var m_ShaderKeywords = reader.ReadAlignedString();
|
||||
}
|
||||
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
var m_LightmapFlags = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||
if (version >= (5, 6)) //5.6 and up
|
||||
{
|
||||
var m_EnableInstancingVariants = reader.ReadBoolean();
|
||||
//var m_DoubleSidedGI = a_Stream.ReadBoolean(); //2017 and up
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
if (version >= (4, 3)) //4.3 and up
|
||||
{
|
||||
var m_CustomRenderQueue = reader.ReadInt32();
|
||||
}
|
||||
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 1)) //5.1 and up
|
||||
if (version >= (5, 1)) //5.1 and up
|
||||
{
|
||||
var stringTagMapSize = reader.ReadInt32();
|
||||
for (int i = 0; i < stringTagMapSize; i++)
|
||||
for (var i = 0; i < stringTagMapSize; i++)
|
||||
{
|
||||
var first = reader.ReadAlignedString();
|
||||
var second = reader.ReadAlignedString();
|
||||
}
|
||||
}
|
||||
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||
if (version >= (5, 6)) //5.6 and up
|
||||
{
|
||||
var disabledShaderPasses = reader.ReadStringArray();
|
||||
}
|
||||
|
||||
m_SavedProperties = new UnityPropertySheet(reader);
|
||||
|
||||
//vector m_BuildTextureStacks 2020 and up
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class MeshFilter : Component
|
||||
{
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class MeshRenderer : Renderer
|
||||
{
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class MonoBehaviour : Behaviour
|
||||
public class MonoBehaviour : Behaviour
|
||||
{
|
||||
public PPtr<MonoScript> m_Script;
|
||||
public string m_Name;
|
||||
|
||||
public MonoBehaviour() { }
|
||||
|
||||
public MonoBehaviour(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_Script = new PPtr<MonoScript>(reader);
|
||||
|
||||
@@ -1,41 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class MonoScript : NamedObject
|
||||
{
|
||||
public string m_ClassName;
|
||||
public string m_Namespace = string.Empty;
|
||||
public string m_Namespace;
|
||||
public string m_AssemblyName;
|
||||
|
||||
public MonoScript(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if (version[0] > 3 || (version[0] == 3 && version[1] >= 4)) //3.4 and up
|
||||
if (version >= (3, 4)) //3.4 and up
|
||||
{
|
||||
var m_ExecutionOrder = reader.ReadInt32();
|
||||
|
||||
if (version < 5) //5.0 down
|
||||
{
|
||||
var m_PropertiesHash = reader.ReadUInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
var m_PropertiesHash = reader.ReadBytes(16);
|
||||
}
|
||||
}
|
||||
if (version[0] < 5) //5.0 down
|
||||
{
|
||||
var m_PropertiesHash = reader.ReadUInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
var m_PropertiesHash = reader.ReadBytes(16);
|
||||
}
|
||||
if (version[0] < 3) //3.0 down
|
||||
|
||||
if (version < 3) //3.0 down
|
||||
{
|
||||
var m_PathName = reader.ReadAlignedString();
|
||||
}
|
||||
m_ClassName = reader.ReadAlignedString();
|
||||
if (version[0] >= 3) //3.0 and up
|
||||
if (version >= 3) //3.0 and up
|
||||
{
|
||||
m_Namespace = reader.ReadAlignedString();
|
||||
}
|
||||
m_AssemblyName = reader.ReadAlignedString();
|
||||
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
|
||||
if (version < (2018, 2)) //2018.2 down
|
||||
{
|
||||
var m_IsEditorScript = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class MovieTexture : Texture
|
||||
{
|
||||
@@ -12,10 +7,13 @@ namespace AssetStudio
|
||||
|
||||
public MovieTexture(ObjectReader reader) : base(reader)
|
||||
{
|
||||
var m_Loop = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
m_AudioClip = new PPtr<AudioClip>(reader);
|
||||
m_MovieData = reader.ReadBytes(reader.ReadInt32());
|
||||
if (reader.version < (2019, 3)) //2019.3 down
|
||||
{
|
||||
var m_Loop = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
m_AudioClip = new PPtr<AudioClip>(reader);
|
||||
m_MovieData = reader.ReadUInt8Array();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class NamedObject : EditorExtension
|
||||
{
|
||||
public string m_Name;
|
||||
|
||||
protected NamedObject() { }
|
||||
|
||||
protected NamedObject(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_Name = reader.ReadAlignedString();
|
||||
|
||||
@@ -1,21 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Specialized;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class Object
|
||||
{
|
||||
[JsonIgnore]
|
||||
public SerializedFile assetsFile;
|
||||
[JsonIgnore]
|
||||
public ObjectReader reader;
|
||||
public long m_PathID;
|
||||
public int[] version;
|
||||
protected BuildType buildType;
|
||||
[JsonIgnore]
|
||||
public UnityVersion version;
|
||||
[JsonIgnore]
|
||||
public BuildTarget platform;
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public ClassIDType type;
|
||||
[JsonIgnore]
|
||||
public SerializedType serializedType;
|
||||
public int classID;
|
||||
public uint byteSize;
|
||||
[JsonIgnore]
|
||||
public string Name;
|
||||
private static readonly JsonSerializerOptions jsonOptions;
|
||||
|
||||
static Object()
|
||||
{
|
||||
jsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
Converters = { new JsonConverterHelper.FloatConverter() },
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
|
||||
ReferenceHandler = ReferenceHandler.IgnoreCycles,
|
||||
PropertyNameCaseInsensitive = true,
|
||||
IncludeFields = true,
|
||||
WriteIndented = true,
|
||||
};
|
||||
}
|
||||
|
||||
public Object() { }
|
||||
|
||||
public Object(ObjectReader reader)
|
||||
{
|
||||
@@ -25,9 +51,9 @@ namespace AssetStudio
|
||||
type = reader.type;
|
||||
m_PathID = reader.m_PathID;
|
||||
version = reader.version;
|
||||
buildType = reader.buildType;
|
||||
platform = reader.platform;
|
||||
serializedType = reader.serializedType;
|
||||
classID = reader.classID;
|
||||
byteSize = reader.byteSize;
|
||||
|
||||
if (platform == BuildTarget.NoTarget)
|
||||
@@ -36,20 +62,67 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
protected bool HasStructMember(string name)
|
||||
public string DumpObject()
|
||||
{
|
||||
return serializedType?.m_Nodes != null && serializedType.m_Nodes.Any(x => x.m_Name == name);
|
||||
string str = null;
|
||||
try
|
||||
{
|
||||
if (this is Mesh m_Mesh)
|
||||
{
|
||||
m_Mesh.ProcessData();
|
||||
}
|
||||
|
||||
str = JsonSerializer.Deserialize<JsonObject>(JsonSerializer.SerializeToUtf8Bytes(this, GetType(), jsonOptions))
|
||||
.ToJsonString(jsonOptions).Replace(" ", " ");
|
||||
}
|
||||
catch
|
||||
{
|
||||
//ignore
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
public string Dump()
|
||||
public string Dump(TypeTree m_Type = null)
|
||||
{
|
||||
reader.Reset();
|
||||
if (serializedType?.m_Nodes != null)
|
||||
m_Type = m_Type ?? serializedType?.m_Type;
|
||||
if (m_Type == null)
|
||||
return null;
|
||||
|
||||
return TypeTreeHelper.ReadTypeString(m_Type, reader);
|
||||
}
|
||||
|
||||
public OrderedDictionary ToType(TypeTree m_Type = null)
|
||||
{
|
||||
m_Type = m_Type ?? serializedType?.m_Type;
|
||||
if (m_Type == null)
|
||||
return null;
|
||||
|
||||
return TypeTreeHelper.ReadType(m_Type, reader);
|
||||
}
|
||||
|
||||
public JsonDocument ToJsonDoc(TypeTree m_Type = null)
|
||||
{
|
||||
var typeDict = ToType(m_Type);
|
||||
try
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
TypeTreeHelper.ReadTypeString(sb, serializedType.m_Nodes, reader);
|
||||
return sb.ToString();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -6,46 +7,55 @@ namespace AssetStudio
|
||||
{
|
||||
public int m_FileID;
|
||||
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)
|
||||
{
|
||||
m_FileID = reader.ReadInt32();
|
||||
m_PathID = reader.m_Version < 14 ? reader.ReadInt32() : reader.ReadInt64();
|
||||
assetsFile = reader.assetsFile;
|
||||
m_PathID = reader.m_Version < SerializedFileFormatVersion.Unknown_14 ? reader.ReadInt32() : reader.ReadInt64();
|
||||
_assetsFile = reader.assetsFile;
|
||||
}
|
||||
|
||||
public PPtr() { }
|
||||
|
||||
private bool TryGetAssetsFile(out SerializedFile result)
|
||||
{
|
||||
result = null;
|
||||
if (m_FileID == 0)
|
||||
{
|
||||
result = assetsFile;
|
||||
result = _assetsFile;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_FileID > 0 && m_FileID - 1 < assetsFile.m_Externals.Count)
|
||||
if (m_FileID > 0 && m_FileID - 1 < _assetsFile.m_Externals.Count)
|
||||
{
|
||||
var assetsManager = assetsFile.assetsManager;
|
||||
var assetsFileList = assetsManager.assetsFileList;
|
||||
var assetsManager = _assetsFile.assetsManager;
|
||||
var assetsFileList = assetsManager.AssetsFileList;
|
||||
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
||||
|
||||
if (index == -2)
|
||||
if (_index == -2)
|
||||
{
|
||||
var m_External = assetsFile.m_Externals[m_FileID - 1];
|
||||
var m_External = _assetsFile.m_Externals[m_FileID - 1];
|
||||
var name = m_External.fileName;
|
||||
if (!assetsFileIndexCache.TryGetValue(name, out index))
|
||||
if (!assetsFileIndexCache.TryGetValue(name, out _index))
|
||||
{
|
||||
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
assetsFileIndexCache.Add(name, index);
|
||||
_index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
assetsFileIndexCache.Add(name, _index);
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= 0)
|
||||
if (_index >= 0)
|
||||
{
|
||||
result = assetsFileList[index];
|
||||
result = assetsFileList[_index];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -53,9 +63,10 @@ namespace AssetStudio
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryGet(out T result)
|
||||
public bool TryGet(out T result, SerializedFile assetsFile = null)
|
||||
{
|
||||
if (TryGetAssetsFile(out var sourceFile))
|
||||
_assetsFile = _assetsFile ?? assetsFile;
|
||||
if (!IsNull && TryGetAssetsFile(out var sourceFile))
|
||||
{
|
||||
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
||||
{
|
||||
@@ -71,9 +82,10 @@ namespace AssetStudio
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryGet<T2>(out T2 result) where T2 : Object
|
||||
public bool TryGet<T2>(out T2 result, SerializedFile assetsFile = null) where T2 : Object
|
||||
{
|
||||
if (TryGetAssetsFile(out var sourceFile))
|
||||
_assetsFile = _assetsFile ?? assetsFile;
|
||||
if (!IsNull && TryGetAssetsFile(out var sourceFile))
|
||||
{
|
||||
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
|
||||
{
|
||||
@@ -92,20 +104,20 @@ namespace AssetStudio
|
||||
public void Set(T m_Object)
|
||||
{
|
||||
var name = m_Object.assetsFile.fileName;
|
||||
if (string.Equals(assetsFile.fileName, name, StringComparison.OrdinalIgnoreCase))
|
||||
if (string.Equals(_assetsFile.fileName, name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
m_FileID = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FileID = assetsFile.m_Externals.FindIndex(x => string.Equals(x.fileName, name, StringComparison.OrdinalIgnoreCase));
|
||||
m_FileID = _assetsFile.m_Externals.FindIndex(x => string.Equals(x.fileName, name, StringComparison.OrdinalIgnoreCase));
|
||||
if (m_FileID == -1)
|
||||
{
|
||||
assetsFile.m_Externals.Add(new FileIdentifier
|
||||
_assetsFile.m_Externals.Add(new FileIdentifier
|
||||
{
|
||||
fileName = m_Object.assetsFile.fileName
|
||||
});
|
||||
m_FileID = assetsFile.m_Externals.Count;
|
||||
m_FileID = _assetsFile.m_Externals.Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -113,14 +125,14 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
var assetsManager = assetsFile.assetsManager;
|
||||
var assetsFileList = assetsManager.assetsFileList;
|
||||
var assetsManager = _assetsFile.assetsManager;
|
||||
var assetsFileList = assetsManager.AssetsFileList;
|
||||
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
|
||||
|
||||
if (!assetsFileIndexCache.TryGetValue(name, out index))
|
||||
if (!assetsFileIndexCache.TryGetValue(name, out _index))
|
||||
{
|
||||
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
assetsFileIndexCache.Add(name, index);
|
||||
_index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
assetsFileIndexCache.Add(name, _index);
|
||||
}
|
||||
|
||||
m_PathID = m_Object.m_PathID;
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class PlayerSettings : Object
|
||||
{
|
||||
@@ -12,37 +7,40 @@ namespace AssetStudio
|
||||
|
||||
public PlayerSettings(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4.0 nad up
|
||||
if (version >= (3, 0))
|
||||
{
|
||||
var productGUID = reader.ReadBytes(16);
|
||||
}
|
||||
|
||||
var AndroidProfiler = reader.ReadBoolean();
|
||||
//bool AndroidFilterTouchesWhenObscured 2017.2 and up
|
||||
//bool AndroidEnableSustainedPerformanceMode 2018 and up
|
||||
reader.AlignStream();
|
||||
int defaultScreenOrientation = reader.ReadInt32();
|
||||
int targetDevice = reader.ReadInt32();
|
||||
if (version[0] < 5 || (version[0] == 5 && version[1] < 3)) //5.3 down
|
||||
{
|
||||
if (version[0] < 5) //5.0 down
|
||||
if (version >= (5, 4)) //5.4.0 and up
|
||||
{
|
||||
int targetPlatform = reader.ReadInt32(); //4.0 and up targetGlesGraphics
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 6)) //4.6 and up
|
||||
{
|
||||
var targetIOSGraphics = reader.ReadInt32();
|
||||
}
|
||||
var productGUID = reader.ReadBytes(16);
|
||||
}
|
||||
int targetResolution = reader.ReadInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
var useOnDemandResources = reader.ReadBoolean();
|
||||
|
||||
var AndroidProfiler = reader.ReadBoolean();
|
||||
//bool AndroidFilterTouchesWhenObscured 2017.2 and up
|
||||
//bool AndroidEnableSustainedPerformanceMode 2018 and up
|
||||
reader.AlignStream();
|
||||
}
|
||||
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 and up
|
||||
{
|
||||
var accelerometerFrequency = reader.ReadInt32();
|
||||
int defaultScreenOrientation = reader.ReadInt32();
|
||||
int targetDevice = reader.ReadInt32();
|
||||
if (version < (5, 3)) //5.3 down
|
||||
{
|
||||
if (version < 5) //5.0 down
|
||||
{
|
||||
int targetPlatform = reader.ReadInt32(); //4.0 and up targetGlesGraphics
|
||||
if (version >= (4, 6)) //4.6 and up
|
||||
{
|
||||
var targetIOSGraphics = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
int targetResolution = reader.ReadInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
var useOnDemandResources = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
}
|
||||
if (version >= (3, 5)) //3.5 and up
|
||||
{
|
||||
var accelerometerFrequency = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
companyName = reader.ReadAlignedString();
|
||||
productName = reader.ReadAlignedString();
|
||||
|
||||
37
AssetStudio/Classes/PreloadData.cs
Normal file
37
AssetStudio/Classes/PreloadData.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class PreloadData : NamedObject
|
||||
{
|
||||
public List<PPtr<Object>> m_Assets;
|
||||
|
||||
public PreloadData(ObjectReader reader) : base(reader)
|
||||
{
|
||||
var m_PreloadTableSize = reader.ReadInt32();
|
||||
m_Assets = new List<PPtr<Object>>();
|
||||
for (var i = 0; i < m_PreloadTableSize; i++)
|
||||
{
|
||||
m_Assets.Add(new PPtr<Object>(reader));
|
||||
}
|
||||
|
||||
/*
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
{
|
||||
var m_DependenciesSize = reader.ReadInt32();
|
||||
var m_Dependencies = new string[m_DependenciesSize];
|
||||
|
||||
for (var i = 0; i < m_DependenciesSize; i++)
|
||||
{
|
||||
m_Dependencies[i] = reader.ReadAlignedString();
|
||||
}
|
||||
}
|
||||
|
||||
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
|
||||
{
|
||||
var m_ExplicitDataLayout = reader.ReadBoolean();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class RectTransform : Transform
|
||||
{
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -19,13 +16,13 @@ namespace AssetStudio
|
||||
|
||||
public abstract class Renderer : Component
|
||||
{
|
||||
public PPtr<Material>[] m_Materials;
|
||||
public List<PPtr<Material>> m_Materials;
|
||||
public StaticBatchInfo m_StaticBatchInfo;
|
||||
public uint[] m_SubsetIndices;
|
||||
|
||||
protected Renderer(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if (version[0] < 5) //5.0 down
|
||||
if (version < 5) //5.0 down
|
||||
{
|
||||
var m_Enabled = reader.ReadBoolean();
|
||||
var m_CastShadows = reader.ReadBoolean();
|
||||
@@ -34,22 +31,53 @@ namespace AssetStudio
|
||||
}
|
||||
else //5.0 and up
|
||||
{
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
|
||||
if (version >= (5, 4)) //5.4 and up
|
||||
{
|
||||
var m_Enabled = reader.ReadBoolean();
|
||||
var m_CastShadows = reader.ReadByte();
|
||||
var m_ReceiveShadows = reader.ReadByte();
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||
if (version >= (2017, 2)) //2017.2 and up
|
||||
{
|
||||
var m_DynamicOccludee = reader.ReadByte();
|
||||
}
|
||||
if (version >= 2021) //2021.1 and up
|
||||
{
|
||||
var m_StaticShadowCaster = reader.ReadByte();
|
||||
}
|
||||
var m_MotionVectors = reader.ReadByte();
|
||||
var m_LightProbeUsage = reader.ReadByte();
|
||||
var m_ReflectionProbeUsage = reader.ReadByte();
|
||||
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||
if (version >= (2019, 3)) //2019.3 and up
|
||||
{
|
||||
var m_RayTracingMode = reader.ReadByte();
|
||||
}
|
||||
if (version >= 2020) //2020.1 and up
|
||||
{
|
||||
var m_RayTraceProcedural = reader.ReadByte();
|
||||
}
|
||||
if (version.IsTuanjie) //2022.3.2t3(1.0.0) and up
|
||||
{
|
||||
var m_virtualGeometry = reader.ReadByte();
|
||||
var m_virtualGeometryShadow = reader.ReadByte();
|
||||
if (version > (2022, 3, 48) || (version == (2022, 3, 48) && version.Build >= 3)) //2022.3.48t3(1.4.0) and up
|
||||
{
|
||||
reader.AlignStream();
|
||||
var m_ShadingRate = reader.ReadByte();
|
||||
if (version >= (2022, 3, 61)) //2022.3.61t1(1.6.0) and up
|
||||
{
|
||||
var m_ForceDisableGRD = reader.ReadByte();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (version >= (2023, 2)) //2023.2 and up
|
||||
{
|
||||
var m_RayTracingAccelStructBuildFlagsOverride = reader.ReadByte();
|
||||
var m_RayTracingAccelStructBuildFlags = reader.ReadByte();
|
||||
}
|
||||
if (version >= (2023, 3)) //2023.3 and up
|
||||
{
|
||||
var m_SmallMeshCulling = reader.ReadByte();
|
||||
}
|
||||
reader.AlignStream();
|
||||
}
|
||||
else
|
||||
@@ -61,12 +89,12 @@ namespace AssetStudio
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] >= 2018) //2018 and up
|
||||
if (version >= 2018) //2018 and up
|
||||
{
|
||||
var m_RenderingLayerMask = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 3)) //2018.3 and up
|
||||
if (version >= (2018, 3)) //2018.3 and up
|
||||
{
|
||||
var m_RendererPriority = reader.ReadInt32();
|
||||
}
|
||||
@@ -75,30 +103,30 @@ namespace AssetStudio
|
||||
var m_LightmapIndexDynamic = reader.ReadUInt16();
|
||||
}
|
||||
|
||||
if (version[0] >= 3) //3.0 and up
|
||||
if (version >= 3) //3.0 and up
|
||||
{
|
||||
var m_LightmapTilingOffset = reader.ReadVector4();
|
||||
}
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
var m_LightmapTilingOffsetDynamic = reader.ReadVector4();
|
||||
}
|
||||
|
||||
var m_MaterialsSize = reader.ReadInt32();
|
||||
m_Materials = new PPtr<Material>[m_MaterialsSize];
|
||||
for (int i = 0; i < m_MaterialsSize; i++)
|
||||
m_Materials = new List<PPtr<Material>>();
|
||||
for (var i = 0; i < m_MaterialsSize; i++)
|
||||
{
|
||||
m_Materials[i] = new PPtr<Material>(reader);
|
||||
m_Materials.Add(new PPtr<Material>(reader));
|
||||
}
|
||||
|
||||
if (version[0] < 3) //3.0 down
|
||||
if (version < 3) //3.0 down
|
||||
{
|
||||
var m_LightmapTilingOffset = reader.ReadVector4();
|
||||
}
|
||||
else //3.0 and up
|
||||
{
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
|
||||
if (version >= (5, 5)) //5.5 and up
|
||||
{
|
||||
m_StaticBatchInfo = new StaticBatchInfo(reader);
|
||||
}
|
||||
@@ -110,17 +138,17 @@ namespace AssetStudio
|
||||
var m_StaticBatchRoot = new PPtr<Transform>(reader);
|
||||
}
|
||||
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
|
||||
if (version >= (5, 4)) //5.4 and up
|
||||
{
|
||||
var m_ProbeAnchor = new PPtr<Transform>(reader);
|
||||
var m_LightProbeVolumeOverride = new PPtr<GameObject>(reader);
|
||||
}
|
||||
else if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 - 5.3
|
||||
else if (version >= (3, 5)) //3.5 - 5.3
|
||||
{
|
||||
var m_UseLightProbes = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
|
||||
if (version[0] >= 5)//5.0 and up
|
||||
if (version >= 5) //5.0 and up
|
||||
{
|
||||
var m_ReflectionProbeUsage = reader.ReadInt32();
|
||||
}
|
||||
@@ -128,18 +156,22 @@ namespace AssetStudio
|
||||
var m_LightProbeAnchor = new PPtr<Transform>(reader); //5.0 and up m_ProbeAnchor
|
||||
}
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
if (version >= (4, 3)) //4.3 and up
|
||||
{
|
||||
if (version[0] == 4 && version[1] == 3) //4.3
|
||||
if (version == (4, 3)) //4.3
|
||||
{
|
||||
var m_SortingLayer = reader.ReadInt16();
|
||||
}
|
||||
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();
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
19
AssetStudio/Classes/ResourceManager.cs
Normal file
19
AssetStudio/Classes/ResourceManager.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class ResourceManager : Object
|
||||
{
|
||||
public List<KeyValuePair<string, PPtr<Object>>> m_Container;
|
||||
|
||||
public ResourceManager(ObjectReader reader) : base(reader)
|
||||
{
|
||||
var m_ContainerSize = reader.ReadInt32();
|
||||
m_Container = new List<KeyValuePair<string, PPtr<Object>>>();
|
||||
for (var i = 0; i < m_ContainerSize; i++)
|
||||
{
|
||||
m_Container.Add(new KeyValuePair<string, PPtr<Object>>(reader.ReadAlignedString(), new PPtr<Object>(reader)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public abstract class RuntimeAnimatorController : NamedObject
|
||||
{
|
||||
|
||||
@@ -5,10 +5,20 @@ using System.Linq;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class Hash128
|
||||
{
|
||||
public byte[] bytes;
|
||||
|
||||
public Hash128(BinaryReader reader)
|
||||
{
|
||||
bytes = reader.ReadBytes(16);
|
||||
}
|
||||
}
|
||||
|
||||
public class StructParameter
|
||||
{
|
||||
public MatrixParameter[] m_MatrixParams;
|
||||
public VectorParameter[] m_VectorParams;
|
||||
public List<MatrixParameter> m_MatrixParams;
|
||||
public List<VectorParameter> m_VectorParams;
|
||||
|
||||
public StructParameter(BinaryReader reader)
|
||||
{
|
||||
@@ -18,17 +28,17 @@ namespace AssetStudio
|
||||
var m_StructSize = reader.ReadInt32();
|
||||
|
||||
int numVectorParams = reader.ReadInt32();
|
||||
m_VectorParams = new VectorParameter[numVectorParams];
|
||||
for (int i = 0; i < numVectorParams; i++)
|
||||
m_VectorParams = new List<VectorParameter>();
|
||||
for (var i = 0; i < numVectorParams; i++)
|
||||
{
|
||||
m_VectorParams[i] = new VectorParameter(reader);
|
||||
m_VectorParams.Add(new VectorParameter(reader));
|
||||
}
|
||||
|
||||
int numMatrixParams = reader.ReadInt32();
|
||||
m_MatrixParams = new MatrixParameter[numMatrixParams];
|
||||
for (int i = 0; i < numMatrixParams; i++)
|
||||
m_MatrixParams = new List<MatrixParameter>();
|
||||
for (var i = 0; i < numMatrixParams; i++)
|
||||
{
|
||||
m_MatrixParams[i] = new MatrixParameter(reader);
|
||||
m_MatrixParams.Add(new MatrixParameter(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,15 +56,14 @@ namespace AssetStudio
|
||||
}
|
||||
public enum TextureDimension
|
||||
{
|
||||
kTexDimUnknown = -1,
|
||||
kTexDimNone = 0,
|
||||
kTexDimAny = 1,
|
||||
kTexDim2D = 2,
|
||||
kTexDim3D = 3,
|
||||
kTexDimCUBE = 4,
|
||||
kTexDim2DArray = 5,
|
||||
kTexDimCubeArray = 6,
|
||||
kTexDimForce32Bit = 2147483647
|
||||
Unknown = -1,
|
||||
None = 0,
|
||||
Any = 1,
|
||||
Tex2D = 2,
|
||||
Tex3D = 3,
|
||||
Cube = 4,
|
||||
Tex2DArray = 5,
|
||||
CubeArray = 6
|
||||
};
|
||||
|
||||
public class SerializedTextureProperty
|
||||
@@ -71,11 +80,12 @@ namespace AssetStudio
|
||||
|
||||
public enum SerializedPropertyType
|
||||
{
|
||||
kColor = 0,
|
||||
kVector = 1,
|
||||
kFloat = 2,
|
||||
kRange = 3,
|
||||
kTexture = 4
|
||||
Color = 0,
|
||||
Vector = 1,
|
||||
Float = 2,
|
||||
Range = 3,
|
||||
Texture = 4,
|
||||
Int = 5
|
||||
};
|
||||
|
||||
public class SerializedProperty
|
||||
@@ -102,15 +112,15 @@ namespace AssetStudio
|
||||
|
||||
public class SerializedProperties
|
||||
{
|
||||
public SerializedProperty[] m_Props;
|
||||
public List<SerializedProperty> m_Props;
|
||||
|
||||
public SerializedProperties(BinaryReader reader)
|
||||
{
|
||||
int numProps = reader.ReadInt32();
|
||||
m_Props = new SerializedProperty[numProps];
|
||||
for (int i = 0; i < numProps; i++)
|
||||
m_Props = new List<SerializedProperty>();
|
||||
for (var i = 0; i < numProps; i++)
|
||||
{
|
||||
m_Props[i] = new SerializedProperty(reader);
|
||||
m_Props.Add(new SerializedProperty(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,11 +195,11 @@ namespace AssetStudio
|
||||
|
||||
public enum FogMode
|
||||
{
|
||||
kFogUnknown = -1,
|
||||
kFogDisabled = 0,
|
||||
kFogLinear = 1,
|
||||
kFogExp = 2,
|
||||
kFogExp2 = 3
|
||||
Unknown = -1,
|
||||
Disabled = 0,
|
||||
Linear = 1,
|
||||
Exp = 2,
|
||||
Exp2 = 3
|
||||
};
|
||||
|
||||
public class SerializedShaderState
|
||||
@@ -201,6 +211,7 @@ namespace AssetStudio
|
||||
public SerializedShaderFloatValue zTest;
|
||||
public SerializedShaderFloatValue zWrite;
|
||||
public SerializedShaderFloatValue culling;
|
||||
public SerializedShaderFloatValue conservative;
|
||||
public SerializedShaderFloatValue offsetFactor;
|
||||
public SerializedShaderFloatValue offsetUnits;
|
||||
public SerializedShaderFloatValue alphaToMask;
|
||||
@@ -226,19 +237,23 @@ namespace AssetStudio
|
||||
|
||||
m_Name = reader.ReadAlignedString();
|
||||
rtBlend = new SerializedShaderRTBlendState[8];
|
||||
for (int i = 0; i < 8; i++)
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
rtBlend[i] = new SerializedShaderRTBlendState(reader);
|
||||
}
|
||||
rtSeparateBlend = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||
if (version >= (2017, 2)) //2017.2 and up
|
||||
{
|
||||
zClip = new SerializedShaderFloatValue(reader);
|
||||
}
|
||||
zTest = new SerializedShaderFloatValue(reader);
|
||||
zWrite = new SerializedShaderFloatValue(reader);
|
||||
culling = new SerializedShaderFloatValue(reader);
|
||||
if (version >= 2020) //2020.1 and up
|
||||
{
|
||||
conservative = new SerializedShaderFloatValue(reader);
|
||||
}
|
||||
offsetFactor = new SerializedShaderFloatValue(reader);
|
||||
offsetUnits = new SerializedShaderFloatValue(reader);
|
||||
alphaToMask = new SerializedShaderFloatValue(reader);
|
||||
@@ -275,16 +290,16 @@ namespace AssetStudio
|
||||
|
||||
public class ParserBindChannels
|
||||
{
|
||||
public ShaderBindChannel[] m_Channels;
|
||||
public List<ShaderBindChannel> m_Channels;
|
||||
public uint m_SourceMap;
|
||||
|
||||
public ParserBindChannels(BinaryReader reader)
|
||||
{
|
||||
int numChannels = reader.ReadInt32();
|
||||
m_Channels = new ShaderBindChannel[numChannels];
|
||||
for (int i = 0; i < numChannels; i++)
|
||||
m_Channels = new List<ShaderBindChannel>();
|
||||
for (var i = 0; i < numChannels; i++)
|
||||
{
|
||||
m_Channels[i] = new ShaderBindChannel(reader);
|
||||
m_Channels.Add(new ShaderBindChannel(reader));
|
||||
}
|
||||
reader.AlignStream();
|
||||
|
||||
@@ -344,7 +359,7 @@ namespace AssetStudio
|
||||
m_NameIndex = reader.ReadInt32();
|
||||
m_Index = reader.ReadInt32();
|
||||
m_SamplerIndex = reader.ReadInt32();
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
|
||||
if (version >= (2017, 3)) //2017.3 and up
|
||||
{
|
||||
var m_MultiSampled = reader.ReadBoolean();
|
||||
}
|
||||
@@ -357,21 +372,29 @@ namespace AssetStudio
|
||||
{
|
||||
public int m_NameIndex;
|
||||
public int m_Index;
|
||||
public int m_ArraySize;
|
||||
|
||||
public BufferBinding(BinaryReader reader)
|
||||
public BufferBinding(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
m_NameIndex = reader.ReadInt32();
|
||||
m_Index = reader.ReadInt32();
|
||||
if (version >= 2020) //2020.1 and up
|
||||
{
|
||||
m_ArraySize = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ConstantBuffer
|
||||
{
|
||||
public int m_NameIndex;
|
||||
public MatrixParameter[] m_MatrixParams;
|
||||
public VectorParameter[] m_VectorParams;
|
||||
public StructParameter[] m_StructParams;
|
||||
public List<MatrixParameter> m_MatrixParams;
|
||||
public List<VectorParameter> m_VectorParams;
|
||||
public List<StructParameter> m_StructParams;
|
||||
public int m_Size;
|
||||
public bool m_IsPartialCB;
|
||||
|
||||
public ConstantBuffer(ObjectReader reader)
|
||||
{
|
||||
@@ -380,28 +403,35 @@ namespace AssetStudio
|
||||
m_NameIndex = reader.ReadInt32();
|
||||
|
||||
int numMatrixParams = reader.ReadInt32();
|
||||
m_MatrixParams = new MatrixParameter[numMatrixParams];
|
||||
for (int i = 0; i < numMatrixParams; i++)
|
||||
m_MatrixParams = new List<MatrixParameter>();
|
||||
for (var i = 0; i < numMatrixParams; i++)
|
||||
{
|
||||
m_MatrixParams[i] = new MatrixParameter(reader);
|
||||
m_MatrixParams.Add(new MatrixParameter(reader));
|
||||
}
|
||||
|
||||
int numVectorParams = reader.ReadInt32();
|
||||
m_VectorParams = new VectorParameter[numVectorParams];
|
||||
for (int i = 0; i < numVectorParams; i++)
|
||||
m_VectorParams = new List<VectorParameter>();
|
||||
for (var i = 0; i < numVectorParams; i++)
|
||||
{
|
||||
m_VectorParams[i] = new VectorParameter(reader);
|
||||
m_VectorParams.Add(new VectorParameter(reader));
|
||||
}
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
|
||||
if (version >= (2017, 3)) //2017.3 and up
|
||||
{
|
||||
int numStructParams = reader.ReadInt32();
|
||||
m_StructParams = new StructParameter[numStructParams];
|
||||
for (int i = 0; i < numStructParams; i++)
|
||||
m_StructParams = new List<StructParameter>();
|
||||
for (var i = 0; i < numStructParams; i++)
|
||||
{
|
||||
m_StructParams[i] = new StructParameter(reader);
|
||||
m_StructParams.Add(new StructParameter(reader));
|
||||
}
|
||||
}
|
||||
m_Size = reader.ReadInt32();
|
||||
|
||||
if (version.IsInRange((2020, 3, 2), 2021) //2020.3.2f1 and up
|
||||
|| version >= (2021, 1, 4)) //2021.1.4f1 and up
|
||||
{
|
||||
m_IsPartialCB = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,35 +451,115 @@ namespace AssetStudio
|
||||
|
||||
public enum ShaderGpuProgramType
|
||||
{
|
||||
kShaderGpuProgramUnknown = 0,
|
||||
kShaderGpuProgramGLLegacy = 1,
|
||||
kShaderGpuProgramGLES31AEP = 2,
|
||||
kShaderGpuProgramGLES31 = 3,
|
||||
kShaderGpuProgramGLES3 = 4,
|
||||
kShaderGpuProgramGLES = 5,
|
||||
kShaderGpuProgramGLCore32 = 6,
|
||||
kShaderGpuProgramGLCore41 = 7,
|
||||
kShaderGpuProgramGLCore43 = 8,
|
||||
kShaderGpuProgramDX9VertexSM20 = 9,
|
||||
kShaderGpuProgramDX9VertexSM30 = 10,
|
||||
kShaderGpuProgramDX9PixelSM20 = 11,
|
||||
kShaderGpuProgramDX9PixelSM30 = 12,
|
||||
kShaderGpuProgramDX10Level9Vertex = 13,
|
||||
kShaderGpuProgramDX10Level9Pixel = 14,
|
||||
kShaderGpuProgramDX11VertexSM40 = 15,
|
||||
kShaderGpuProgramDX11VertexSM50 = 16,
|
||||
kShaderGpuProgramDX11PixelSM40 = 17,
|
||||
kShaderGpuProgramDX11PixelSM50 = 18,
|
||||
kShaderGpuProgramDX11GeometrySM40 = 19,
|
||||
kShaderGpuProgramDX11GeometrySM50 = 20,
|
||||
kShaderGpuProgramDX11HullSM50 = 21,
|
||||
kShaderGpuProgramDX11DomainSM50 = 22,
|
||||
kShaderGpuProgramMetalVS = 23,
|
||||
kShaderGpuProgramMetalFS = 24,
|
||||
kShaderGpuProgramSPIRV = 25,
|
||||
kShaderGpuProgramConsole = 26
|
||||
Unknown = 0,
|
||||
GLLegacy = 1,
|
||||
GLES31AEP = 2,
|
||||
GLES31 = 3,
|
||||
GLES3 = 4,
|
||||
GLES = 5,
|
||||
GLCore32 = 6,
|
||||
GLCore41 = 7,
|
||||
GLCore43 = 8,
|
||||
DX9VertexSM20 = 9,
|
||||
DX9VertexSM30 = 10,
|
||||
DX9PixelSM20 = 11,
|
||||
DX9PixelSM30 = 12,
|
||||
DX10Level9Vertex = 13,
|
||||
DX10Level9Pixel = 14,
|
||||
DX11VertexSM40 = 15,
|
||||
DX11VertexSM50 = 16,
|
||||
DX11PixelSM40 = 17,
|
||||
DX11PixelSM50 = 18,
|
||||
DX11GeometrySM40 = 19,
|
||||
DX11GeometrySM50 = 20,
|
||||
DX11HullSM50 = 21,
|
||||
DX11DomainSM50 = 22,
|
||||
MetalVS = 23,
|
||||
MetalFS = 24,
|
||||
SPIRV = 25,
|
||||
ConsoleVS = 26,
|
||||
ConsoleFS = 27,
|
||||
ConsoleHS = 28,
|
||||
ConsoleDS = 29,
|
||||
ConsoleGS = 30,
|
||||
RayTracing = 31,
|
||||
PS5NGGC = 32
|
||||
};
|
||||
|
||||
public class SerializedProgramParameters
|
||||
{
|
||||
public List<VectorParameter> m_VectorParams;
|
||||
public List<MatrixParameter> m_MatrixParams;
|
||||
public List<TextureParameter> m_TextureParams;
|
||||
public List<BufferBinding> m_BufferParams;
|
||||
public List<ConstantBuffer> m_ConstantBuffers;
|
||||
public List<BufferBinding> m_ConstantBufferBindings;
|
||||
public List<UAVParameter> m_UAVParams;
|
||||
public List<SamplerParameter> m_Samplers;
|
||||
|
||||
public SerializedProgramParameters(ObjectReader reader)
|
||||
{
|
||||
int numVectorParams = reader.ReadInt32();
|
||||
m_VectorParams = new List<VectorParameter>();
|
||||
for (var i = 0; i < numVectorParams; i++)
|
||||
{
|
||||
m_VectorParams.Add(new VectorParameter(reader));
|
||||
}
|
||||
|
||||
int numMatrixParams = reader.ReadInt32();
|
||||
m_MatrixParams = new List<MatrixParameter>();
|
||||
for (var i = 0; i < numMatrixParams; i++)
|
||||
{
|
||||
m_MatrixParams.Add(new MatrixParameter(reader));
|
||||
}
|
||||
|
||||
int numTextureParams = reader.ReadInt32();
|
||||
m_TextureParams = new List<TextureParameter>();
|
||||
for (var i = 0; i < numTextureParams; i++)
|
||||
{
|
||||
m_TextureParams.Add(new TextureParameter(reader));
|
||||
}
|
||||
|
||||
int numBufferParams = reader.ReadInt32();
|
||||
m_BufferParams = new List<BufferBinding>();
|
||||
for (var i = 0; i < numBufferParams; i++)
|
||||
{
|
||||
m_BufferParams.Add(new BufferBinding(reader));
|
||||
}
|
||||
|
||||
int numConstantBuffers = reader.ReadInt32();
|
||||
m_ConstantBuffers = new List<ConstantBuffer>();
|
||||
for (var i = 0; i < numConstantBuffers; i++)
|
||||
{
|
||||
m_ConstantBuffers.Add(new ConstantBuffer(reader));
|
||||
}
|
||||
|
||||
int numConstantBufferBindings = reader.ReadInt32();
|
||||
m_ConstantBufferBindings = new List<BufferBinding>();
|
||||
for (var i = 0; i < numConstantBufferBindings; i++)
|
||||
{
|
||||
m_ConstantBufferBindings.Add(new BufferBinding(reader));
|
||||
}
|
||||
|
||||
int numUAVParams = reader.ReadInt32();
|
||||
m_UAVParams = new List<UAVParameter>();
|
||||
for (var i = 0; i < numUAVParams; i++)
|
||||
{
|
||||
m_UAVParams.Add(new UAVParameter(reader));
|
||||
}
|
||||
|
||||
if (reader.version >= 2017) //2017 and up
|
||||
{
|
||||
int numSamplers = reader.ReadInt32();
|
||||
m_Samplers = new List<SamplerParameter>();
|
||||
for (var i = 0; i < numSamplers; i++)
|
||||
{
|
||||
m_Samplers.Add(new SamplerParameter(reader));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SerializedSubProgram
|
||||
{
|
||||
public uint m_BlobIndex;
|
||||
@@ -457,14 +567,7 @@ namespace AssetStudio
|
||||
public ushort[] m_KeywordIndices;
|
||||
public sbyte m_ShaderHardwareTier;
|
||||
public ShaderGpuProgramType m_GpuProgramType;
|
||||
public VectorParameter[] m_VectorParams;
|
||||
public MatrixParameter[] m_MatrixParams;
|
||||
public TextureParameter[] m_TextureParams;
|
||||
public BufferBinding[] m_BufferParams;
|
||||
public ConstantBuffer[] m_ConstantBuffers;
|
||||
public BufferBinding[] m_ConstantBufferBindings;
|
||||
public UAVParameter[] m_UAVParams;
|
||||
public SamplerParameter[] m_Samplers;
|
||||
public SerializedProgramParameters m_Parameters; // nested since 2020.3.2f1 and up; 2021.1.1f1 and up
|
||||
|
||||
public SerializedSubProgram(ObjectReader reader)
|
||||
{
|
||||
@@ -473,7 +576,7 @@ namespace AssetStudio
|
||||
m_BlobIndex = reader.ReadUInt32();
|
||||
m_Channels = new ParserBindChannels(reader);
|
||||
|
||||
if (version[0] >= 2019) //2019 and up
|
||||
if (version.IsInRange(2019, (2021, 2))) //2019 ~2021.1
|
||||
{
|
||||
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
@@ -483,7 +586,7 @@ namespace AssetStudio
|
||||
else
|
||||
{
|
||||
m_KeywordIndices = reader.ReadUInt16Array();
|
||||
if (version[0] >= 2017) //2017 and up
|
||||
if (version >= 2017) //2017 and up
|
||||
{
|
||||
reader.AlignStream();
|
||||
}
|
||||
@@ -493,96 +596,67 @@ namespace AssetStudio
|
||||
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
|
||||
reader.AlignStream();
|
||||
|
||||
int numVectorParams = reader.ReadInt32();
|
||||
m_VectorParams = new VectorParameter[numVectorParams];
|
||||
for (int i = 0; i < numVectorParams; i++)
|
||||
{
|
||||
m_VectorParams[i] = new VectorParameter(reader);
|
||||
}
|
||||
m_Parameters = new SerializedProgramParameters(reader);
|
||||
|
||||
int numMatrixParams = reader.ReadInt32();
|
||||
m_MatrixParams = new MatrixParameter[numMatrixParams];
|
||||
for (int i = 0; i < numMatrixParams; i++)
|
||||
if (version >= (2017, 2)) //2017.2 and up
|
||||
{
|
||||
m_MatrixParams[i] = new MatrixParameter(reader);
|
||||
}
|
||||
|
||||
int numTextureParams = reader.ReadInt32();
|
||||
m_TextureParams = new TextureParameter[numTextureParams];
|
||||
for (int i = 0; i < numTextureParams; i++)
|
||||
{
|
||||
m_TextureParams[i] = new TextureParameter(reader);
|
||||
}
|
||||
|
||||
int numBufferParams = reader.ReadInt32();
|
||||
m_BufferParams = new BufferBinding[numBufferParams];
|
||||
for (int i = 0; i < numBufferParams; i++)
|
||||
{
|
||||
m_BufferParams[i] = new BufferBinding(reader);
|
||||
}
|
||||
|
||||
int numConstantBuffers = reader.ReadInt32();
|
||||
m_ConstantBuffers = new ConstantBuffer[numConstantBuffers];
|
||||
for (int i = 0; i < numConstantBuffers; i++)
|
||||
{
|
||||
m_ConstantBuffers[i] = new ConstantBuffer(reader);
|
||||
}
|
||||
|
||||
int numConstantBufferBindings = reader.ReadInt32();
|
||||
m_ConstantBufferBindings = new BufferBinding[numConstantBufferBindings];
|
||||
for (int i = 0; i < numConstantBufferBindings; i++)
|
||||
{
|
||||
m_ConstantBufferBindings[i] = new BufferBinding(reader);
|
||||
}
|
||||
|
||||
int numUAVParams = reader.ReadInt32();
|
||||
m_UAVParams = new UAVParameter[numUAVParams];
|
||||
for (int i = 0; i < numUAVParams; i++)
|
||||
{
|
||||
m_UAVParams[i] = new UAVParameter(reader);
|
||||
}
|
||||
|
||||
if (version[0] >= 2017) //2017 and up
|
||||
{
|
||||
int numSamplers = reader.ReadInt32();
|
||||
m_Samplers = new SamplerParameter[numSamplers];
|
||||
for (int i = 0; i < numSamplers; i++)
|
||||
if (version >= 2021) //2021.1 and up
|
||||
{
|
||||
m_Samplers[i] = new SamplerParameter(reader);
|
||||
var m_ShaderRequirements = reader.ReadInt64();
|
||||
}
|
||||
else
|
||||
{
|
||||
var m_ShaderRequirements = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||
{
|
||||
var m_ShaderRequirements = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SerializedProgram
|
||||
{
|
||||
public SerializedSubProgram[] m_SubPrograms;
|
||||
public List<SerializedSubProgram> m_SubPrograms;
|
||||
public SerializedProgramParameters m_CommonParameters;
|
||||
public ushort[] m_SerializedKeywordStateMask;
|
||||
|
||||
public SerializedProgram(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
int numSubPrograms = reader.ReadInt32();
|
||||
m_SubPrograms = new SerializedSubProgram[numSubPrograms];
|
||||
for (int i = 0; i < numSubPrograms; i++)
|
||||
m_SubPrograms = new List<SerializedSubProgram>();
|
||||
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
|
||||
|| version >= (2021, 1, 1)) //2021.1.1f1 and up
|
||||
{
|
||||
m_CommonParameters = new SerializedProgramParameters(reader);
|
||||
}
|
||||
|
||||
if (version >= (2022, 1)) //2022.1 and up
|
||||
{
|
||||
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum PassType
|
||||
{
|
||||
kPassTypeNormal = 0,
|
||||
kPassTypeUse = 1,
|
||||
kPassTypeGrab = 2
|
||||
Normal = 0,
|
||||
Use = 1,
|
||||
Grab = 2
|
||||
};
|
||||
|
||||
public class SerializedPass
|
||||
{
|
||||
public KeyValuePair<string, int>[] m_NameIndices;
|
||||
public List<Hash128> m_EditorDataHash;
|
||||
public byte[] m_Platforms;
|
||||
public ushort[] m_LocalKeywordMask;
|
||||
public ushort[] m_GlobalKeywordMask;
|
||||
public List<KeyValuePair<string, int>> m_NameIndices;
|
||||
public PassType m_Type;
|
||||
public SerializedShaderState m_State;
|
||||
public uint m_ProgramMask;
|
||||
@@ -597,16 +671,37 @@ namespace AssetStudio
|
||||
public string m_Name;
|
||||
public string m_TextureName;
|
||||
public SerializedTagMap m_Tags;
|
||||
public ushort[] m_SerializedKeywordStateMask;
|
||||
|
||||
public SerializedPass(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
int numIndices = reader.ReadInt32();
|
||||
m_NameIndices = new KeyValuePair<string, int>[numIndices];
|
||||
for (int i = 0; i < numIndices; i++)
|
||||
if (version >= (2020, 2)) //2020.2 and up
|
||||
{
|
||||
m_NameIndices[i] = new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32());
|
||||
int numEditorDataHash = reader.ReadInt32();
|
||||
m_EditorDataHash = new List<Hash128>();
|
||||
for (var i = 0; i < numEditorDataHash; i++)
|
||||
{
|
||||
m_EditorDataHash.Add(new Hash128(reader));
|
||||
}
|
||||
reader.AlignStream();
|
||||
m_Platforms = reader.ReadUInt8Array();
|
||||
reader.AlignStream();
|
||||
if (version <= (2021, 1)) //2021.1 and down
|
||||
{
|
||||
m_LocalKeywordMask = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
m_GlobalKeywordMask = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
int numIndices = reader.ReadInt32();
|
||||
m_NameIndices = new List<KeyValuePair<string, int>>();
|
||||
for (var i = 0; i < numIndices; i++)
|
||||
{
|
||||
m_NameIndices.Add(new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32()));
|
||||
}
|
||||
|
||||
m_Type = (PassType)reader.ReadInt32();
|
||||
@@ -617,12 +712,12 @@ namespace AssetStudio
|
||||
progGeometry = new SerializedProgram(reader);
|
||||
progHull = new SerializedProgram(reader);
|
||||
progDomain = new SerializedProgram(reader);
|
||||
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||
if (version >= (2019, 3)) //2019.3 and up
|
||||
{
|
||||
progRayTracing = new SerializedProgram(reader);
|
||||
}
|
||||
m_HasInstancingVariant = reader.ReadBoolean();
|
||||
if (version[0] >= 2018) //2018 and up
|
||||
if (version >= 2018) //2018 and up
|
||||
{
|
||||
var m_HasProceduralInstancingVariant = reader.ReadBoolean();
|
||||
}
|
||||
@@ -631,37 +726,42 @@ namespace AssetStudio
|
||||
m_Name = reader.ReadAlignedString();
|
||||
m_TextureName = reader.ReadAlignedString();
|
||||
m_Tags = new SerializedTagMap(reader);
|
||||
if (version == 2021 && version.Minor >= 2) //2021.2 ~2021.x
|
||||
{
|
||||
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SerializedTagMap
|
||||
{
|
||||
public KeyValuePair<string, string>[] tags;
|
||||
public List<KeyValuePair<string, string>> tags;
|
||||
|
||||
public SerializedTagMap(BinaryReader reader)
|
||||
{
|
||||
int numTags = reader.ReadInt32();
|
||||
tags = new KeyValuePair<string, string>[numTags];
|
||||
for (int i = 0; i < numTags; i++)
|
||||
tags = new List<KeyValuePair<string, string>>();
|
||||
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 SerializedPass[] m_Passes;
|
||||
public List<SerializedPass> m_Passes;
|
||||
public SerializedTagMap m_Tags;
|
||||
public int m_LOD;
|
||||
|
||||
public SerializedSubShader(ObjectReader reader)
|
||||
{
|
||||
int numPasses = reader.ReadInt32();
|
||||
m_Passes = new SerializedPass[numPasses];
|
||||
for (int i = 0; i < numPasses; i++)
|
||||
m_Passes = new List<SerializedPass>();
|
||||
for (var i = 0; i < numPasses; i++)
|
||||
{
|
||||
m_Passes[i] = new SerializedPass(reader);
|
||||
m_Passes.Add(new SerializedPass(reader));
|
||||
}
|
||||
|
||||
m_Tags = new SerializedTagMap(reader);
|
||||
@@ -681,25 +781,49 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
|
||||
public class SerializedCustomEditorForRenderPipeline
|
||||
{
|
||||
public string customEditorName;
|
||||
public string renderPipelineType;
|
||||
|
||||
public SerializedCustomEditorForRenderPipeline(BinaryReader reader)
|
||||
{
|
||||
customEditorName = reader.ReadAlignedString();
|
||||
renderPipelineType = reader.ReadAlignedString();
|
||||
}
|
||||
}
|
||||
|
||||
public class SerializedShader
|
||||
{
|
||||
public SerializedProperties m_PropInfo;
|
||||
public SerializedSubShader[] m_SubShaders;
|
||||
public List<SerializedSubShader> m_SubShaders;
|
||||
public string[] m_KeywordNames;
|
||||
public byte[] m_KeywordFlags;
|
||||
public string m_Name;
|
||||
public string m_CustomEditorName;
|
||||
public string m_FallbackName;
|
||||
public SerializedShaderDependency[] m_Dependencies;
|
||||
public List<SerializedShaderDependency> m_Dependencies;
|
||||
public List<SerializedCustomEditorForRenderPipeline> m_CustomEditorForRenderPipelines;
|
||||
public bool m_DisableNoSubshadersMessage;
|
||||
|
||||
public SerializedShader(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
m_PropInfo = new SerializedProperties(reader);
|
||||
|
||||
int numSubShaders = reader.ReadInt32();
|
||||
m_SubShaders = new SerializedSubShader[numSubShaders];
|
||||
for (int i = 0; i < numSubShaders; i++)
|
||||
m_SubShaders = new List<SerializedSubShader>();
|
||||
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
|
||||
{
|
||||
m_KeywordNames = reader.ReadStringArray();
|
||||
m_KeywordFlags = reader.ReadUInt8Array();
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
m_Name = reader.ReadAlignedString();
|
||||
@@ -707,10 +831,20 @@ namespace AssetStudio
|
||||
m_FallbackName = reader.ReadAlignedString();
|
||||
|
||||
int numDependencies = reader.ReadInt32();
|
||||
m_Dependencies = new SerializedShaderDependency[numDependencies];
|
||||
for (int i = 0; i < numDependencies; i++)
|
||||
m_Dependencies = new List<SerializedShaderDependency>();
|
||||
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
|
||||
{
|
||||
int m_CustomEditorForRenderPipelinesSize = reader.ReadInt32();
|
||||
m_CustomEditorForRenderPipelines = new List<SerializedCustomEditorForRenderPipeline>();
|
||||
for (var i = 0; i < m_CustomEditorForRenderPipelinesSize; i++)
|
||||
{
|
||||
m_CustomEditorForRenderPipelines.Add(new SerializedCustomEditorForRenderPipeline(reader));
|
||||
}
|
||||
}
|
||||
|
||||
m_DisableNoSubshadersMessage = reader.ReadBoolean();
|
||||
@@ -720,28 +854,32 @@ namespace AssetStudio
|
||||
|
||||
public enum ShaderCompilerPlatform
|
||||
{
|
||||
kShaderCompPlatformNone = -1,
|
||||
kShaderCompPlatformGL = 0,
|
||||
kShaderCompPlatformD3D9 = 1,
|
||||
kShaderCompPlatformXbox360 = 2,
|
||||
kShaderCompPlatformPS3 = 3,
|
||||
kShaderCompPlatformD3D11 = 4,
|
||||
kShaderCompPlatformGLES20 = 5,
|
||||
kShaderCompPlatformNaCl = 6,
|
||||
kShaderCompPlatformFlash = 7,
|
||||
kShaderCompPlatformD3D11_9x = 8,
|
||||
kShaderCompPlatformGLES3Plus = 9,
|
||||
kShaderCompPlatformPSP2 = 10,
|
||||
kShaderCompPlatformPS4 = 11,
|
||||
kShaderCompPlatformXboxOne = 12,
|
||||
kShaderCompPlatformPSM = 13,
|
||||
kShaderCompPlatformMetal = 14,
|
||||
kShaderCompPlatformOpenGLCore = 15,
|
||||
kShaderCompPlatformN3DS = 16,
|
||||
kShaderCompPlatformWiiU = 17,
|
||||
kShaderCompPlatformVulkan = 18,
|
||||
kShaderCompPlatformSwitch = 19,
|
||||
kShaderCompPlatformXboxOneD3D12 = 20
|
||||
None = -1,
|
||||
GL = 0,
|
||||
D3D9 = 1,
|
||||
Xbox360 = 2,
|
||||
PS3 = 3,
|
||||
D3D11 = 4,
|
||||
GLES20 = 5,
|
||||
NaCl = 6,
|
||||
Flash = 7,
|
||||
D3D11_9x = 8,
|
||||
GLES3Plus = 9,
|
||||
PSP2 = 10,
|
||||
PS4 = 11,
|
||||
XboxOne = 12,
|
||||
PSM = 13,
|
||||
Metal = 14,
|
||||
OpenGLCore = 15,
|
||||
N3DS = 16,
|
||||
WiiU = 17,
|
||||
Vulkan = 18,
|
||||
Switch = 19,
|
||||
XboxOneD3D12 = 20,
|
||||
GameCoreXboxOne = 21,
|
||||
GameCoreScarlett = 22,
|
||||
PS5 = 23,
|
||||
PS5NGGC = 24
|
||||
};
|
||||
|
||||
public class Shader : NamedObject
|
||||
@@ -753,40 +891,60 @@ namespace AssetStudio
|
||||
//5.5 and up
|
||||
public SerializedShader m_ParsedForm;
|
||||
public ShaderCompilerPlatform[] platforms;
|
||||
public uint[] offsets;
|
||||
public uint[] compressedLengths;
|
||||
public uint[] decompressedLengths;
|
||||
public uint[][] offsets;
|
||||
public uint[][] compressedLengths;
|
||||
public uint[][] decompressedLengths;
|
||||
public byte[] compressedBlob;
|
||||
|
||||
public Shader(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if (version[0] == 5 && version[1] >= 5 || version[0] > 5) //5.5 and up
|
||||
if (version >= (5, 5)) //5.5 and up
|
||||
{
|
||||
m_ParsedForm = new SerializedShader(reader);
|
||||
platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray();
|
||||
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
|
||||
if (version >= (2019, 3)) //2019.3 and up
|
||||
{
|
||||
offsets = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
|
||||
compressedLengths = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
|
||||
decompressedLengths = reader.ReadUInt32ArrayArray().Select(x => x[0]).ToArray();
|
||||
offsets = reader.ReadUInt32ArrayArray();
|
||||
compressedLengths = reader.ReadUInt32ArrayArray();
|
||||
decompressedLengths = reader.ReadUInt32ArrayArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
offsets = reader.ReadUInt32Array();
|
||||
compressedLengths = reader.ReadUInt32Array();
|
||||
decompressedLengths = reader.ReadUInt32Array();
|
||||
offsets = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
|
||||
compressedLengths = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
|
||||
decompressedLengths = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
|
||||
}
|
||||
compressedBlob = reader.ReadBytes(reader.ReadInt32());
|
||||
compressedBlob = reader.ReadUInt8Array();
|
||||
reader.AlignStream();
|
||||
|
||||
var m_DependenciesCount = reader.ReadInt32();
|
||||
for (var i = 0; i < m_DependenciesCount; i++)
|
||||
{
|
||||
var m_Dependencies = new PPtr<Shader>(reader);
|
||||
}
|
||||
|
||||
if (version >= 2018)
|
||||
{
|
||||
var m_NonModifiableTexturesCount = reader.ReadInt32();
|
||||
for (var i = 0; i < m_NonModifiableTexturesCount; i++)
|
||||
{
|
||||
var first = reader.ReadAlignedString();
|
||||
var second = new PPtr<Texture>(reader);
|
||||
}
|
||||
}
|
||||
|
||||
var m_ShaderIsBaked = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Script = reader.ReadBytes(reader.ReadInt32());
|
||||
m_Script = reader.ReadUInt8Array();
|
||||
reader.AlignStream();
|
||||
var m_PathName = reader.ReadAlignedString();
|
||||
if (version[0] == 5 && version[1] >= 3) //5.3 - 5.4
|
||||
if (version == 5 && version.Minor >= 3) //5.3 - 5.4
|
||||
{
|
||||
decompressedSize = reader.ReadUInt32();
|
||||
m_SubProgramBlob = reader.ReadBytes(reader.ReadInt32());
|
||||
m_SubProgramBlob = reader.ReadUInt8Array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class SkinnedMeshRenderer : Renderer
|
||||
{
|
||||
public PPtr<Mesh> m_Mesh;
|
||||
public PPtr<Transform>[] m_Bones;
|
||||
public List<PPtr<Transform>> m_Bones;
|
||||
public float[] m_BlendShapeWeights;
|
||||
|
||||
public SkinnedMeshRenderer(ObjectReader reader) : base(reader)
|
||||
@@ -18,20 +15,21 @@ namespace AssetStudio
|
||||
var m_SkinNormals = reader.ReadBoolean(); //3.1.0 and below
|
||||
reader.AlignStream();
|
||||
|
||||
if (version[0] == 2 && version[1] < 6) //2.6 down
|
||||
if (version < (2, 6)) //2.6 down
|
||||
{
|
||||
var m_DisableAnimationWhenOffscreen = new PPtr<Animation>(reader);
|
||||
}
|
||||
|
||||
m_Mesh = new PPtr<Mesh>(reader);
|
||||
|
||||
m_Bones = new PPtr<Transform>[reader.ReadInt32()];
|
||||
for (int b = 0; b < m_Bones.Length; b++)
|
||||
var numBones = reader.ReadInt32();
|
||||
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[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
if (version >= (4, 3)) //4.3 and up
|
||||
{
|
||||
m_BlendShapeWeights = reader.ReadSingleArray();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
|
||||
namespace AssetStudio
|
||||
@@ -13,29 +12,29 @@ namespace AssetStudio
|
||||
public SecondarySpriteTexture(ObjectReader reader)
|
||||
{
|
||||
texture = new PPtr<Texture2D>(reader);
|
||||
name = reader.ReadStringToNull();
|
||||
name = reader.ReadAlignedString();
|
||||
}
|
||||
}
|
||||
|
||||
public enum SpritePackingRotation
|
||||
{
|
||||
kSPRNone = 0,
|
||||
kSPRFlipHorizontal = 1,
|
||||
kSPRFlipVertical = 2,
|
||||
kSPRRotate180 = 3,
|
||||
kSPRRotate90 = 4
|
||||
None = 0,
|
||||
FlipHorizontal = 1,
|
||||
FlipVertical = 2,
|
||||
Rotate180 = 3,
|
||||
Rotate90 = 4
|
||||
};
|
||||
|
||||
public enum SpritePackingMode
|
||||
{
|
||||
kSPMTight = 0,
|
||||
kSPMRectangle
|
||||
Tight = 0,
|
||||
Rectangle
|
||||
};
|
||||
|
||||
public enum SpriteMeshType
|
||||
{
|
||||
kSpriteMeshTypeFullRect,
|
||||
kSpriteMeshTypeTight
|
||||
FullRect,
|
||||
Tight
|
||||
};
|
||||
|
||||
public class SpriteSettings
|
||||
@@ -69,7 +68,7 @@ namespace AssetStudio
|
||||
var version = reader.version;
|
||||
|
||||
pos = reader.ReadVector3();
|
||||
if (version[0] < 4 || (version[0] == 4 && version[1] <= 3)) //4.3 and down
|
||||
if (version <= (4, 3)) //4.3 and down
|
||||
{
|
||||
uv = reader.ReadVector2();
|
||||
}
|
||||
@@ -80,15 +79,15 @@ namespace AssetStudio
|
||||
{
|
||||
public PPtr<Texture2D> texture;
|
||||
public PPtr<Texture2D> alphaTexture;
|
||||
public SecondarySpriteTexture[] secondaryTextures;
|
||||
public SubMesh[] m_SubMeshes;
|
||||
public List<SecondarySpriteTexture> secondaryTextures;
|
||||
public List<SubMesh> m_SubMeshes;
|
||||
public byte[] m_IndexBuffer;
|
||||
public VertexData m_VertexData;
|
||||
public SpriteVertex[] vertices;
|
||||
public List<SpriteVertex> vertices;
|
||||
public ushort[] indices;
|
||||
public Matrix4x4[] m_Bindpose;
|
||||
public BoneWeights4[] m_SourceSkin;
|
||||
public RectangleF textureRect;
|
||||
public Rectf textureRect;
|
||||
public Vector2 textureRectOffset;
|
||||
public Vector2 atlasRectOffset;
|
||||
public SpriteSettings settingsRaw;
|
||||
@@ -100,31 +99,28 @@ namespace AssetStudio
|
||||
var version = reader.version;
|
||||
|
||||
texture = new PPtr<Texture2D>(reader);
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
|
||||
{
|
||||
alphaTexture = new PPtr<Texture2D>(reader);
|
||||
}
|
||||
alphaTexture = version >= (5, 2) ? new PPtr<Texture2D>(reader) : new PPtr<Texture2D>(); //5.2 and up
|
||||
|
||||
if (version[0] >= 2019) //2019 and up
|
||||
if (version >= 2019) //2019 and up
|
||||
{
|
||||
var secondaryTexturesSize = reader.ReadInt32();
|
||||
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
|
||||
for (int i = 0; i < secondaryTexturesSize; i++)
|
||||
secondaryTextures = new List<SecondarySpriteTexture>();
|
||||
for (var i = 0; i < secondaryTexturesSize; i++)
|
||||
{
|
||||
secondaryTextures[i] = new SecondarySpriteTexture(reader);
|
||||
secondaryTextures.Add(new SecondarySpriteTexture(reader));
|
||||
}
|
||||
}
|
||||
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||
if (version >= (5, 6)) //5.6 and up
|
||||
{
|
||||
var m_SubMeshesSize = reader.ReadInt32();
|
||||
m_SubMeshes = new SubMesh[m_SubMeshesSize];
|
||||
for (int i = 0; i < m_SubMeshesSize; i++)
|
||||
m_SubMeshes = new List<SubMesh>();
|
||||
for (var i = 0; i < m_SubMeshesSize; i++)
|
||||
{
|
||||
m_SubMeshes[i] = new SubMesh(reader);
|
||||
m_SubMeshes.Add(new SubMesh(reader));
|
||||
}
|
||||
|
||||
m_IndexBuffer = reader.ReadBytes(reader.ReadInt32());
|
||||
m_IndexBuffer = reader.ReadUInt8Array();
|
||||
reader.AlignStream();
|
||||
|
||||
m_VertexData = new VertexData(reader);
|
||||
@@ -132,91 +128,107 @@ namespace AssetStudio
|
||||
else
|
||||
{
|
||||
var verticesSize = reader.ReadInt32();
|
||||
vertices = new SpriteVertex[verticesSize];
|
||||
for (int i = 0; i < verticesSize; i++)
|
||||
vertices = new List<SpriteVertex>();
|
||||
for (var i = 0; i < verticesSize; i++)
|
||||
{
|
||||
vertices[i] = new SpriteVertex(reader);
|
||||
vertices.Add(new SpriteVertex(reader));
|
||||
}
|
||||
|
||||
indices = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] >= 2018) //2018 and up
|
||||
if (version >= 2018) //2018 and up
|
||||
{
|
||||
m_Bindpose = reader.ReadMatrixArray();
|
||||
|
||||
if (version[0] == 2018 && version[1] < 2) //2018.2 down
|
||||
if (version < (2018, 2)) //2018.2 down
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
textureRect = reader.ReadRectangleF();
|
||||
textureRect = new Rectf(reader);
|
||||
textureRectOffset = reader.ReadVector2();
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||
if (version >= (5, 6)) //5.6 and up
|
||||
{
|
||||
atlasRectOffset = reader.ReadVector2();
|
||||
}
|
||||
|
||||
settingsRaw = new SpriteSettings(reader);
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
|
||||
if (version >= (4, 5)) //4.5 and up
|
||||
{
|
||||
uvTransform = reader.ReadVector4();
|
||||
}
|
||||
|
||||
if (version[0] >= 2017) //2017 and up
|
||||
if (version >= 2017) //2017 and up
|
||||
{
|
||||
downscaleMultiplier = reader.ReadSingle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Rectf
|
||||
{
|
||||
public float x;
|
||||
public float y;
|
||||
public float width;
|
||||
public float height;
|
||||
|
||||
public Rectf(BinaryReader reader)
|
||||
{
|
||||
x = reader.ReadSingle();
|
||||
y = reader.ReadSingle();
|
||||
width = reader.ReadSingle();
|
||||
height = reader.ReadSingle();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Sprite : NamedObject
|
||||
{
|
||||
public RectangleF m_Rect;
|
||||
public Rectf m_Rect;
|
||||
public Vector2 m_Offset;
|
||||
public Vector4 m_Border;
|
||||
public float m_PixelsToUnits;
|
||||
public Vector2 m_Pivot;
|
||||
public Vector2 m_Pivot = new Vector2(0.5f, 0.5f);
|
||||
public uint m_Extrude;
|
||||
public bool m_IsPolygon;
|
||||
public KeyValuePair<Guid, long> m_RenderDataKey;
|
||||
public string[] m_AtlasTags;
|
||||
public PPtr<SpriteAtlas> m_SpriteAtlas;
|
||||
public SpriteRenderData m_RD;
|
||||
public Vector2[][] m_PhysicsShape;
|
||||
//public Vector2[][] m_PhysicsShape;
|
||||
|
||||
public Sprite(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_Rect = reader.ReadRectangleF();
|
||||
m_Rect = new Rectf(reader);
|
||||
m_Offset = reader.ReadVector2();
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
|
||||
if (version >= (4, 5)) //4.5 and up
|
||||
{
|
||||
m_Border = reader.ReadVector4();
|
||||
}
|
||||
|
||||
m_PixelsToUnits = reader.ReadSingle();
|
||||
if (version[0] > 5
|
||||
|| (version[0] == 5 && version[1] > 4)
|
||||
|| (version[0] == 5 && version[1] == 4 && version[2] >= 2)
|
||||
|| (version[0] == 5 && version[1] == 4 && version[2] == 1 && buildType.IsPatch && version[3] >= 3)) //5.4.1p3 and up
|
||||
if (version >= (5, 4, 2)
|
||||
|| version == (5, 4, 1) && version.IsPatch && version.Build >= 3) //5.4.1p3 and up
|
||||
{
|
||||
m_Pivot = reader.ReadVector2();
|
||||
}
|
||||
|
||||
m_Extrude = reader.ReadUInt32();
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up
|
||||
if (version >= (5, 3)) //5.3 and up
|
||||
{
|
||||
m_IsPolygon = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] >= 2017) //2017 and up
|
||||
if (version >= 2017) //2017 and up
|
||||
{
|
||||
var first = new Guid(reader.ReadBytes(16));
|
||||
var second = reader.ReadInt64();
|
||||
@@ -228,17 +240,18 @@ namespace AssetStudio
|
||||
}
|
||||
|
||||
m_RD = new SpriteRenderData(reader);
|
||||
|
||||
if (version[0] >= 2017) //2017 and up
|
||||
/*
|
||||
if (version >= 2017) //2017 and up
|
||||
{
|
||||
var m_PhysicsShapeSize = reader.ReadInt32();
|
||||
m_PhysicsShape = new Vector2[m_PhysicsShapeSize][];
|
||||
for (int i = 0; i < m_PhysicsShapeSize; i++)
|
||||
var physicsShapeList = new List<Vector2[]>();
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -7,57 +8,71 @@ namespace AssetStudio
|
||||
{
|
||||
public PPtr<Texture2D> texture;
|
||||
public PPtr<Texture2D> alphaTexture;
|
||||
public System.Drawing.RectangleF textureRect;
|
||||
public Rectf textureRect;
|
||||
public Vector2 textureRectOffset;
|
||||
public Vector2 atlasRectOffset;
|
||||
public Vector4 uvTransform;
|
||||
public float downscaleMultiplier;
|
||||
public SpriteSettings settingsRaw;
|
||||
public List<SecondarySpriteTexture> secondaryTextures;
|
||||
|
||||
public SpriteAtlasData(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
texture = new PPtr<Texture2D>(reader);
|
||||
alphaTexture = new PPtr<Texture2D>(reader);
|
||||
textureRect = reader.ReadRectangleF();
|
||||
textureRect = new Rectf(reader);
|
||||
textureRectOffset = reader.ReadVector2();
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||
if (version >= (2017, 2)) //2017.2 and up
|
||||
{
|
||||
atlasRectOffset = reader.ReadVector2();
|
||||
}
|
||||
uvTransform = reader.ReadVector4();
|
||||
downscaleMultiplier = reader.ReadSingle();
|
||||
settingsRaw = new SpriteSettings(reader);
|
||||
if (version >= (2020, 2)) //2020.2 and up
|
||||
{
|
||||
var secondaryTexturesSize = reader.ReadInt32();
|
||||
secondaryTextures = new List<SecondarySpriteTexture>();
|
||||
for (var i = 0; i < secondaryTexturesSize; i++)
|
||||
{
|
||||
secondaryTextures.Add(new SecondarySpriteTexture(reader));
|
||||
}
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 bool m_IsVariant;
|
||||
|
||||
public SpriteAtlas(ObjectReader reader) : base(reader)
|
||||
{
|
||||
var m_PackedSpritesSize = reader.ReadInt32();
|
||||
m_PackedSprites = new PPtr<Sprite>[m_PackedSpritesSize];
|
||||
for (int i = 0; i < m_PackedSpritesSize; i++)
|
||||
m_PackedSprites = new List<PPtr<Sprite>>();
|
||||
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_RenderDataMapSize = reader.ReadInt32();
|
||||
m_RenderDataMap = new Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>(m_RenderDataMapSize);
|
||||
for (int i = 0; i < m_RenderDataMapSize; i++)
|
||||
m_RenderDataMap = new Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>();
|
||||
for (var i = 0; i < m_RenderDataMapSize; i++)
|
||||
{
|
||||
var first = new Guid(reader.ReadBytes(16));
|
||||
var second = reader.ReadInt64();
|
||||
var value = new SpriteAtlasData(reader);
|
||||
m_RenderDataMap.Add(new KeyValuePair<Guid, long>(first, second), value);
|
||||
}
|
||||
//string m_Tag
|
||||
//bool m_IsVariant
|
||||
var m_Tag = reader.ReadAlignedString();
|
||||
m_IsVariant = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
AssetStudio/Classes/StreamingInfo.cs
Normal file
27
AssetStudio/Classes/StreamingInfo.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class StreamingInfo
|
||||
{
|
||||
public long offset; //ulong
|
||||
public uint size;
|
||||
public string path;
|
||||
|
||||
public StreamingInfo() { }
|
||||
|
||||
public StreamingInfo(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
if (version >= 2020) //2020.1 and up
|
||||
{
|
||||
offset = reader.ReadInt64();
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = reader.ReadUInt32();
|
||||
}
|
||||
size = reader.ReadUInt32();
|
||||
path = reader.ReadAlignedString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class TextAsset : NamedObject
|
||||
{
|
||||
@@ -12,7 +6,7 @@ namespace AssetStudio
|
||||
|
||||
public TextAsset(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_Script = reader.ReadBytes(reader.ReadInt32());
|
||||
m_Script = reader.ReadUInt8Array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
namespace AssetStudio
|
||||
{
|
||||
public abstract class Texture : NamedObject
|
||||
{
|
||||
protected Texture() { }
|
||||
|
||||
protected Texture(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
|
||||
if (version >= (2017, 3)) //2017.3 and up
|
||||
{
|
||||
var m_ForcedFallbackFormat = reader.ReadInt32();
|
||||
var m_DownscaleFallback = reader.ReadBoolean();
|
||||
if (version < (2023, 2)) //2023.2 down
|
||||
{
|
||||
var m_ForcedFallbackFormat = reader.ReadInt32();
|
||||
var m_DownscaleFallback = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
if (version >= (2020, 2)) //2020.2 and up
|
||||
{
|
||||
var m_IsAlphaChannelOptional = reader.ReadBoolean();
|
||||
}
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +1,109 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class StreamingInfo
|
||||
{
|
||||
public uint offset;
|
||||
public uint size;
|
||||
public string path;
|
||||
|
||||
public StreamingInfo(ObjectReader reader)
|
||||
{
|
||||
offset = reader.ReadUInt32();
|
||||
size = reader.ReadUInt32();
|
||||
path = reader.ReadAlignedString();
|
||||
}
|
||||
}
|
||||
|
||||
public class GLTextureSettings
|
||||
{
|
||||
public int m_FilterMode;
|
||||
public int m_Aniso;
|
||||
public float m_MipBias;
|
||||
public int m_WrapMode;
|
||||
|
||||
public GLTextureSettings(ObjectReader reader)
|
||||
{
|
||||
var version = reader.version;
|
||||
|
||||
m_FilterMode = reader.ReadInt32();
|
||||
m_Aniso = reader.ReadInt32();
|
||||
m_MipBias = reader.ReadSingle();
|
||||
if (version[0] >= 2017)//2017.x and up
|
||||
{
|
||||
m_WrapMode = reader.ReadInt32(); //m_WrapU
|
||||
int m_WrapV = reader.ReadInt32();
|
||||
int m_WrapW = reader.ReadInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_WrapMode = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Texture2D : Texture
|
||||
{
|
||||
public int m_Width;
|
||||
public int m_Height;
|
||||
public uint m_CompleteImageSize;
|
||||
public TextureFormat m_TextureFormat;
|
||||
public bool m_MipMap;
|
||||
public int m_MipCount;
|
||||
public GLTextureSettings m_TextureSettings;
|
||||
public int m_ImageCount;
|
||||
public byte[] m_PlatformBlob;
|
||||
[JsonPropertyName("image data")]
|
||||
public ResourceReader image_data;
|
||||
public StreamingInfo m_StreamData;
|
||||
public StreamingInfo m_DataStreamData; //Tuanjie
|
||||
|
||||
public Texture2D() { }
|
||||
|
||||
public Texture2D(Texture2DArray m_Texture2DArray, int layer) // Texture2DArrayImage
|
||||
{
|
||||
reader = m_Texture2DArray.reader;
|
||||
assetsFile = m_Texture2DArray.assetsFile;
|
||||
version = m_Texture2DArray.version;
|
||||
platform = m_Texture2DArray.platform;
|
||||
|
||||
m_Name = $"{m_Texture2DArray.m_Name}_{layer + 1}";
|
||||
type = ClassIDType.Texture2DArrayImage;
|
||||
m_PathID = m_Texture2DArray.m_PathID;
|
||||
|
||||
m_Width = m_Texture2DArray.m_Width;
|
||||
m_Height = m_Texture2DArray.m_Height;
|
||||
m_TextureFormat = m_Texture2DArray.m_Format.ToTextureFormat();
|
||||
m_MipCount = m_Texture2DArray.m_MipCount;
|
||||
m_TextureSettings = m_Texture2DArray.m_TextureSettings;
|
||||
m_StreamData = m_Texture2DArray.m_StreamData;
|
||||
m_PlatformBlob = Array.Empty<byte>();
|
||||
m_MipMap = m_MipCount > 1;
|
||||
m_ImageCount = 1;
|
||||
|
||||
//var imgActualDataSize = GetImageDataSize(m_TextureFormat);
|
||||
//var mipmapSize = (int)(m_Texture2DArray.m_DataSize / m_Texture2DArray.m_Depth - imgActualDataSize);
|
||||
m_CompleteImageSize = (uint)(m_Texture2DArray.m_DataSize / m_Texture2DArray.m_Depth);
|
||||
var offset = layer * m_CompleteImageSize + m_Texture2DArray.image_data.Offset;
|
||||
|
||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
||||
? new ResourceReader(m_StreamData.path, assetsFile, offset, m_CompleteImageSize)
|
||||
: new ResourceReader(reader, offset, m_CompleteImageSize);
|
||||
|
||||
byteSize = (uint)(m_Width * m_Height) * 4;
|
||||
}
|
||||
|
||||
public Texture2D(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
|
||||
{
|
||||
var parsedTex2d = JsonSerializer.Deserialize<Texture2D>(type, jsonOptions);
|
||||
m_Width = parsedTex2d.m_Width;
|
||||
m_Height = parsedTex2d.m_Height;
|
||||
m_CompleteImageSize = parsedTex2d.m_CompleteImageSize;
|
||||
m_TextureFormat = parsedTex2d.m_TextureFormat;
|
||||
m_MipMap = parsedTex2d.m_MipMap;
|
||||
m_MipCount = parsedTex2d.m_MipCount;
|
||||
m_ImageCount = parsedTex2d.m_ImageCount;
|
||||
m_TextureSettings = parsedTex2d.m_TextureSettings;
|
||||
m_StreamData = parsedTex2d.m_StreamData;
|
||||
m_PlatformBlob = parsedTex2d.m_PlatformBlob ?? Array.Empty<byte>();
|
||||
|
||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
||||
: new ResourceReader(reader, parsedTex2d.image_data.Offset, parsedTex2d.image_data.Size);
|
||||
}
|
||||
|
||||
public Texture2D(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_Width = reader.ReadInt32();
|
||||
m_Height = reader.ReadInt32();
|
||||
var m_CompleteImageSize = reader.ReadInt32();
|
||||
m_CompleteImageSize = reader.ReadUInt32();
|
||||
if (version >= 2020) //2020.1 and up
|
||||
{
|
||||
var m_MipsStripped = reader.ReadInt32();
|
||||
}
|
||||
if (version.IsTuanjie && (version > (2022, 3, 2) || version.Build >= 8)) //2022.3.2t8(1.1.0) and up
|
||||
{
|
||||
var m_WebStreaming = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
var m_PriorityLevel = reader.ReadInt32();
|
||||
var m_UploadedMode = reader.ReadInt32();
|
||||
m_DataStreamData = new StreamingInfo //sample is needed
|
||||
{
|
||||
offset = 0,
|
||||
size = reader.ReadUInt32(),
|
||||
path = reader.ReadAlignedString()
|
||||
};
|
||||
}
|
||||
m_TextureFormat = (TextureFormat)reader.ReadInt32();
|
||||
if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) //5.2 down
|
||||
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
|
||||
{
|
||||
m_MipMap = reader.ReadBoolean();
|
||||
}
|
||||
@@ -68,108 +111,132 @@ namespace AssetStudio
|
||||
{
|
||||
m_MipCount = reader.ReadInt32();
|
||||
}
|
||||
var m_IsReadable = reader.ReadBoolean(); //2.6.0 and up
|
||||
var m_ReadAllowed = reader.ReadBoolean(); //3.0.0 - 5.4
|
||||
//bool m_StreamingMipmaps 2018.2 and up
|
||||
if (version >= (2, 6)) //2.6.0 and up
|
||||
{
|
||||
var m_IsReadable = reader.ReadBoolean();
|
||||
}
|
||||
if (version >= 2020) //2020.1 and up
|
||||
{
|
||||
var m_IsPreProcessed = reader.ReadBoolean();
|
||||
}
|
||||
if (version >= (2019, 3)) //2019.3 and up
|
||||
{
|
||||
if (version >= (2022, 2)) //2022.2 and up
|
||||
{
|
||||
var m_IgnoreMipmapLimit = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
var m_IgnoreMasterTextureLimit = reader.ReadBoolean();
|
||||
}
|
||||
}
|
||||
if (version.IsInRange(3, (5, 5))) //3.0.0 - 5.4
|
||||
{
|
||||
var m_ReadAllowed = reader.ReadBoolean();
|
||||
}
|
||||
if (version >= (2022, 2)) //2022.2 and up
|
||||
{
|
||||
var m_MipmapLimitGroupName = reader.ReadAlignedString();
|
||||
}
|
||||
if (version >= (2018, 2)) //2018.2 and up
|
||||
{
|
||||
var m_StreamingMipmaps = reader.ReadBoolean();
|
||||
}
|
||||
reader.AlignStream();
|
||||
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
|
||||
if (version >= (2018, 2)) //2018.2 and up
|
||||
{
|
||||
var m_StreamingMipmapsPriority = reader.ReadInt32();
|
||||
}
|
||||
var m_ImageCount = reader.ReadInt32();
|
||||
m_ImageCount = reader.ReadInt32();
|
||||
var m_TextureDimension = reader.ReadInt32();
|
||||
m_TextureSettings = new GLTextureSettings(reader);
|
||||
if (version[0] >= 3) //3.0 and up
|
||||
if (version >= 3) //3.0 and up
|
||||
{
|
||||
var m_LightmapFormat = reader.ReadInt32();
|
||||
}
|
||||
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5.0 and up
|
||||
if (version >= (3, 5)) //3.5.0 and up
|
||||
{
|
||||
var m_ColorSpace = reader.ReadInt32();
|
||||
}
|
||||
if (version >= (2020, 2)) //2020.2 and up
|
||||
{
|
||||
m_PlatformBlob = reader.ReadUInt8Array();
|
||||
reader.AlignStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PlatformBlob = Array.Empty<byte>();
|
||||
}
|
||||
var image_data_size = reader.ReadInt32();
|
||||
if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up
|
||||
if (image_data_size == 0 && version >= (5, 3))//5.3.0 and up
|
||||
{
|
||||
m_StreamData = new StreamingInfo(reader);
|
||||
}
|
||||
|
||||
ResourceReader resourceReader;
|
||||
if (!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(reader, reader.BaseStream.Position, image_data_size);
|
||||
}
|
||||
|
||||
// https://docs.unity3d.com/2023.3/Documentation/Manual/class-TextureImporterOverride.html
|
||||
private int GetImageDataSize(TextureFormat textureFormat)
|
||||
{
|
||||
var imgDataSize = m_Width * m_Height;
|
||||
switch (textureFormat)
|
||||
{
|
||||
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size);
|
||||
case TextureFormat.ASTC_RGBA_5x5:
|
||||
// https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/
|
||||
imgDataSize = (int)(MathF.Floor((m_Width + 4) / 5f) * MathF.Floor((m_Height + 4) / 5f) * 16);
|
||||
break;
|
||||
case TextureFormat.ASTC_RGBA_6x6:
|
||||
imgDataSize = (int)(MathF.Floor((m_Width + 5) / 6f) * MathF.Floor((m_Height + 5) / 6f) * 16);
|
||||
break;
|
||||
case TextureFormat.ASTC_RGBA_8x8:
|
||||
imgDataSize = (int)(MathF.Floor((m_Width + 7) / 8f) * MathF.Floor((m_Height + 7) / 8f) * 16);
|
||||
break;
|
||||
case TextureFormat.ASTC_RGBA_10x10:
|
||||
imgDataSize = (int)(MathF.Floor((m_Width + 9) / 10f) * MathF.Floor((m_Height + 9) / 10f) * 16);
|
||||
break;
|
||||
case TextureFormat.ASTC_RGBA_12x12:
|
||||
imgDataSize = (int)(MathF.Floor((m_Width + 11) / 12f) * MathF.Floor((m_Height + 11) / 12f) * 16);
|
||||
break;
|
||||
case TextureFormat.DXT1:
|
||||
case TextureFormat.EAC_R:
|
||||
case TextureFormat.EAC_R_SIGNED:
|
||||
case TextureFormat.ATC_RGB4:
|
||||
case TextureFormat.ETC_RGB4:
|
||||
case TextureFormat.ETC2_RGB:
|
||||
case TextureFormat.ETC2_RGBA1:
|
||||
case TextureFormat.PVRTC_RGBA4:
|
||||
imgDataSize /= 2;
|
||||
break;
|
||||
case TextureFormat.PVRTC_RGBA2:
|
||||
imgDataSize /= 4;
|
||||
break;
|
||||
case TextureFormat.R16:
|
||||
case TextureFormat.RGB565:
|
||||
imgDataSize *= 2;
|
||||
break;
|
||||
case TextureFormat.RGB24:
|
||||
imgDataSize *= 3;
|
||||
break;
|
||||
case TextureFormat.RG32:
|
||||
case TextureFormat.RGBA32:
|
||||
case TextureFormat.ARGB32:
|
||||
case TextureFormat.BGRA32:
|
||||
case TextureFormat.RGB9e5Float:
|
||||
imgDataSize *= 4;
|
||||
break;
|
||||
case TextureFormat.RGB48:
|
||||
imgDataSize *= 6;
|
||||
break;
|
||||
case TextureFormat.RGBAHalf:
|
||||
case TextureFormat.RGBA64:
|
||||
imgDataSize *= 8;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
|
||||
}
|
||||
image_data = resourceReader;
|
||||
return imgDataSize;
|
||||
}
|
||||
}
|
||||
|
||||
public enum TextureFormat
|
||||
{
|
||||
Alpha8 = 1,
|
||||
ARGB4444,
|
||||
RGB24,
|
||||
RGBA32,
|
||||
ARGB32,
|
||||
RGB565 = 7,
|
||||
R16 = 9,
|
||||
DXT1,
|
||||
DXT5 = 12,
|
||||
RGBA4444,
|
||||
BGRA32,
|
||||
RHalf,
|
||||
RGHalf,
|
||||
RGBAHalf,
|
||||
RFloat,
|
||||
RGFloat,
|
||||
RGBAFloat,
|
||||
YUY2,
|
||||
RGB9e5Float,
|
||||
BC4 = 26,
|
||||
BC5,
|
||||
BC6H = 24,
|
||||
BC7,
|
||||
DXT1Crunched = 28,
|
||||
DXT5Crunched,
|
||||
PVRTC_RGB2,
|
||||
PVRTC_RGBA2,
|
||||
PVRTC_RGB4,
|
||||
PVRTC_RGBA4,
|
||||
ETC_RGB4,
|
||||
ATC_RGB4,
|
||||
ATC_RGBA8,
|
||||
EAC_R = 41,
|
||||
EAC_R_SIGNED,
|
||||
EAC_RG,
|
||||
EAC_RG_SIGNED,
|
||||
ETC2_RGB,
|
||||
ETC2_RGBA1,
|
||||
ETC2_RGBA8,
|
||||
ASTC_RGB_4x4,
|
||||
ASTC_RGB_5x5,
|
||||
ASTC_RGB_6x6,
|
||||
ASTC_RGB_8x8,
|
||||
ASTC_RGB_10x10,
|
||||
ASTC_RGB_12x12,
|
||||
ASTC_RGBA_4x4,
|
||||
ASTC_RGBA_5x5,
|
||||
ASTC_RGBA_6x6,
|
||||
ASTC_RGBA_8x8,
|
||||
ASTC_RGBA_10x10,
|
||||
ASTC_RGBA_12x12,
|
||||
ETC_RGB4_3DS,
|
||||
ETC_RGBA8_3DS,
|
||||
RG16,
|
||||
R8,
|
||||
ETC_RGB4Crunched,
|
||||
ETC2_RGBA8Crunched,
|
||||
ASTC_HDR_4x4,
|
||||
ASTC_HDR_5x5,
|
||||
ASTC_HDR_6x6,
|
||||
ASTC_HDR_8x8,
|
||||
ASTC_HDR_10x10,
|
||||
ASTC_HDR_12x12,
|
||||
}
|
||||
}
|
||||
96
AssetStudio/Classes/Texture2DArray.cs
Normal file
96
AssetStudio/Classes/Texture2DArray.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public sealed class Texture2DArray : Texture
|
||||
{
|
||||
public int m_Width;
|
||||
public int m_Height;
|
||||
public int m_Depth;
|
||||
public GraphicsFormat m_Format;
|
||||
public int m_MipCount;
|
||||
public uint m_DataSize;
|
||||
public GLTextureSettings m_TextureSettings;
|
||||
public int m_ColorSpace;
|
||||
[JsonPropertyName("image data")]
|
||||
public ResourceReader image_data;
|
||||
public StreamingInfo m_StreamData;
|
||||
public List<Texture2D> TextureList;
|
||||
|
||||
public Texture2DArray() { }
|
||||
|
||||
public Texture2DArray(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if (version >= 2019) //2019 and up
|
||||
{
|
||||
m_ColorSpace = reader.ReadInt32();
|
||||
m_Format = (GraphicsFormat)reader.ReadInt32();
|
||||
}
|
||||
m_Width = reader.ReadInt32();
|
||||
m_Height = reader.ReadInt32();
|
||||
m_Depth = reader.ReadInt32();
|
||||
if (version < 2019) //2019 down
|
||||
{
|
||||
m_Format = (GraphicsFormat)reader.ReadInt32();
|
||||
}
|
||||
m_MipCount = reader.ReadInt32();
|
||||
if (version >= (2023, 2)) //2023.2 and up
|
||||
{
|
||||
var m_MipsStripped = reader.ReadInt32();
|
||||
}
|
||||
m_DataSize = reader.ReadUInt32();
|
||||
m_TextureSettings = new GLTextureSettings(reader);
|
||||
if (version < 2019) //2019 down
|
||||
{
|
||||
m_ColorSpace = reader.ReadInt32();
|
||||
}
|
||||
if (version >= (2020, 2)) //2020.2 and up
|
||||
{
|
||||
var m_UsageMode = reader.ReadInt32();
|
||||
}
|
||||
var m_IsReadable = reader.ReadBoolean();
|
||||
if (version > (2023, 2)) //2023.2 and up
|
||||
{
|
||||
var m_IgnoreMipmapLimit = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
var m_MipmapLimitGroupName = reader.ReadAlignedString();
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.AlignStream();
|
||||
}
|
||||
var image_data_size = reader.ReadInt32();
|
||||
if (image_data_size == 0 && version >= (5, 6)) //5.6 and up
|
||||
{
|
||||
m_StreamData = new StreamingInfo(reader);
|
||||
}
|
||||
|
||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size)
|
||||
: new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
|
||||
|
||||
TextureList = new List<Texture2D>();
|
||||
}
|
||||
|
||||
public Texture2DArray(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
|
||||
{
|
||||
var parsedTex2dArray = JsonSerializer.Deserialize<Texture2DArray>(type, jsonOptions);
|
||||
m_Width = parsedTex2dArray.m_Width;
|
||||
m_Height = parsedTex2dArray.m_Height;
|
||||
m_Depth = parsedTex2dArray.m_Depth;
|
||||
m_Format = parsedTex2dArray.m_Format;
|
||||
m_MipCount = parsedTex2dArray.m_MipCount;
|
||||
m_DataSize = parsedTex2dArray.m_DataSize;
|
||||
m_TextureSettings = parsedTex2dArray.m_TextureSettings;
|
||||
m_StreamData = parsedTex2dArray.m_StreamData;
|
||||
|
||||
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
|
||||
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
|
||||
: new ResourceReader(reader, parsedTex2dArray.image_data.Offset, parsedTex2dArray.image_data.Size);
|
||||
|
||||
TextureList = new List<Texture2D>();
|
||||
}
|
||||
}
|
||||
}
|
||||
282
AssetStudio/Classes/TextureFormat.cs
Normal file
282
AssetStudio/Classes/TextureFormat.cs
Normal file
@@ -0,0 +1,282 @@
|
||||
namespace AssetStudio
|
||||
{
|
||||
public enum TextureFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// Alpha-only texture format, 8 bit integer.
|
||||
/// </summary>
|
||||
Alpha8 = 1,
|
||||
/// <summary>
|
||||
/// A 16 bits/pixel texture format. Texture stores color with an alpha channel.
|
||||
/// </summary>
|
||||
ARGB4444,
|
||||
/// <summary>
|
||||
/// Three channel (RGB) texture format, 8-bits unsigned integer per channel.
|
||||
/// </summary>
|
||||
RGB24,
|
||||
/// <summary>
|
||||
/// Four channel (RGBA) texture format, 8-bits unsigned integer per channel.
|
||||
/// </summary>
|
||||
RGBA32,
|
||||
/// <summary>
|
||||
/// Color with alpha texture format, 8-bits per channel.
|
||||
/// </summary>
|
||||
ARGB32,
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
ARGBFloat,
|
||||
/// <summary>
|
||||
/// A 16 bit color texture format.
|
||||
/// </summary>
|
||||
RGB565,
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
BGR24,
|
||||
/// <summary>
|
||||
/// Single channel (R) texture format, 16 bit integer.
|
||||
/// </summary>
|
||||
R16,
|
||||
/// <summary>
|
||||
/// Compressed color texture format.
|
||||
/// </summary>
|
||||
DXT1,
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
DXT3,
|
||||
/// <summary>
|
||||
/// Compressed color with alpha channel texture format.
|
||||
/// </summary>
|
||||
DXT5,
|
||||
/// <summary>
|
||||
/// Color and alpha texture format, 4 bit per channel.
|
||||
/// </summary>
|
||||
RGBA4444,
|
||||
/// <summary>
|
||||
/// Color with alpha texture format, 8-bits per channel.
|
||||
/// </summary>
|
||||
BGRA32,
|
||||
/// <summary>
|
||||
/// Scalar (R) texture format, 16 bit floating point.
|
||||
/// </summary>
|
||||
RHalf,
|
||||
/// <summary>
|
||||
/// Two color (RG) texture format, 16 bit floating point per channel.
|
||||
/// </summary>
|
||||
RGHalf,
|
||||
/// <summary>
|
||||
/// RGB color and alpha texture format, 16 bit floating point per channel.
|
||||
/// </summary>
|
||||
RGBAHalf,
|
||||
/// <summary>
|
||||
/// Scalar (R) texture format, 32 bit floating point.
|
||||
/// </summary>
|
||||
RFloat,
|
||||
/// <summary>
|
||||
/// Two color (RG) texture format, 32 bit floating point per channel.
|
||||
/// </summary>
|
||||
RGFloat,
|
||||
/// <summary>
|
||||
/// RGB color and alpha texture format, 32-bit floats per channel.
|
||||
/// </summary>
|
||||
RGBAFloat,
|
||||
/// <summary>
|
||||
/// A format that uses the YUV color space and is often used for video encoding or playback.
|
||||
/// </summary>
|
||||
YUY2,
|
||||
/// <summary>
|
||||
/// RGB HDR format, with 9 bit mantissa per channel and a 5 bit shared exponent.
|
||||
/// </summary>
|
||||
RGB9e5Float,
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
RGBFloat,
|
||||
/// <summary>
|
||||
/// HDR compressed color texture format.
|
||||
/// </summary>
|
||||
BC6H,
|
||||
/// <summary>
|
||||
/// High quality compressed color texture format.
|
||||
/// </summary>
|
||||
BC7,
|
||||
/// <summary>
|
||||
/// Compressed one channel (R) texture format.
|
||||
/// </summary>
|
||||
BC4,
|
||||
/// <summary>
|
||||
/// Compressed two-channel (RG) texture format.
|
||||
/// </summary>
|
||||
BC5,
|
||||
/// <summary>
|
||||
/// Compressed color texture format with Crunch compression for smaller storage sizes.
|
||||
/// </summary>
|
||||
DXT1Crunched,
|
||||
/// <summary>
|
||||
/// Compressed color with alpha channel texture format with Crunch compression for smaller storage sizes.
|
||||
/// </summary>
|
||||
DXT5Crunched,
|
||||
/// <summary>
|
||||
/// PowerVR (iOS) 2 bits/pixel compressed color texture format.
|
||||
/// </summary>
|
||||
PVRTC_RGB2,
|
||||
/// <summary>
|
||||
/// PowerVR (iOS) 2 bits/pixel compressed with alpha channel texture format.
|
||||
/// </summary>
|
||||
PVRTC_RGBA2,
|
||||
/// <summary>
|
||||
/// PowerVR (iOS) 4 bits/pixel compressed color texture format.
|
||||
/// </summary>
|
||||
PVRTC_RGB4,
|
||||
/// <summary>
|
||||
/// PowerVR (iOS) 4 bits/pixel compressed with alpha channel texture format.
|
||||
/// </summary>
|
||||
PVRTC_RGBA4,
|
||||
/// <summary>
|
||||
/// ETC (GLES2.0) 4 bits/pixel compressed RGB texture format.
|
||||
/// </summary>
|
||||
ETC_RGB4,
|
||||
/// <summary>
|
||||
/// ATC (ATITC) 4 bits/pixel compressed RGB texture format.
|
||||
/// </summary>
|
||||
ATC_RGB4,
|
||||
/// <summary>
|
||||
/// ATC (ATITC) 8 bits/pixel compressed RGB texture format.
|
||||
/// </summary>
|
||||
ATC_RGBA8,
|
||||
/// <summary>
|
||||
/// ETC2 / EAC (GL ES 3.0) 4 bits/pixel compressed unsigned single-channel texture format.
|
||||
/// </summary>
|
||||
EAC_R = 41,
|
||||
/// <summary>
|
||||
/// ETC2 / EAC (GL ES 3.0) 4 bits/pixel compressed signed single-channel texture format.
|
||||
/// </summary>
|
||||
EAC_R_SIGNED,
|
||||
/// <summary>
|
||||
/// ETC2 / EAC (GL ES 3.0) 8 bits/pixel compressed unsigned dual-channel (RG) texture format.
|
||||
/// </summary>
|
||||
EAC_RG,
|
||||
/// <summary>
|
||||
/// ETC2 / EAC (GL ES 3.0) 8 bits/pixel compressed signed dual-channel (RG) texture format.
|
||||
/// </summary>
|
||||
EAC_RG_SIGNED,
|
||||
/// <summary>
|
||||
/// ETC2 (GL ES 3.0) 4 bits/pixel compressed RGB texture format.
|
||||
/// </summary>
|
||||
ETC2_RGB,
|
||||
/// <summary>
|
||||
/// ETC2 (GL ES 3.0) 4 bits/pixel RGB+1-bit alpha texture format.
|
||||
/// </summary>
|
||||
ETC2_RGBA1,
|
||||
/// <summary>
|
||||
/// ETC2 (GL ES 3.0) 8 bits/pixel compressed RGBA texture format.
|
||||
/// </summary>
|
||||
ETC2_RGBA8,
|
||||
/// <summary>
|
||||
/// ASTC (4x4 pixel block in 128 bits) compressed RGB texture format.
|
||||
/// </summary>
|
||||
ASTC_RGB_4x4,
|
||||
/// <summary>
|
||||
/// ASTC (5x5 pixel block in 128 bits) compressed RGB texture format.
|
||||
/// </summary>
|
||||
ASTC_RGB_5x5,
|
||||
/// <summary>
|
||||
/// ASTC (6x6 pixel block in 128 bits) compressed RGB texture format.
|
||||
/// </summary>
|
||||
ASTC_RGB_6x6,
|
||||
/// <summary>
|
||||
/// ASTC (8x8 pixel block in 128 bits) compressed RGB texture format.
|
||||
/// </summary>
|
||||
ASTC_RGB_8x8,
|
||||
/// <summary>
|
||||
/// ASTC (10x10 pixel block in 128 bits) compressed RGB texture format.
|
||||
/// </summary>
|
||||
ASTC_RGB_10x10,
|
||||
/// <summary>
|
||||
/// ASTC (12x12 pixel block in 128 bits) compressed RGB texture format.
|
||||
/// </summary>
|
||||
ASTC_RGB_12x12,
|
||||
/// <summary>
|
||||
/// ASTC (4x4 pixel block in 128 bits) compressed RGBA texture format.
|
||||
/// </summary>
|
||||
ASTC_RGBA_4x4,
|
||||
/// <summary>
|
||||
/// ASTC (5x5 pixel block in 128 bits) compressed RGBA texture format.
|
||||
/// </summary>
|
||||
ASTC_RGBA_5x5,
|
||||
/// <summary>
|
||||
/// ASTC (6x6 pixel block in 128 bits) compressed RGBA texture format.
|
||||
/// </summary>
|
||||
ASTC_RGBA_6x6,
|
||||
/// <summary>
|
||||
/// ASTC (8x8 pixel block in 128 bits) compressed RGBA texture format.
|
||||
/// </summary>
|
||||
ASTC_RGBA_8x8,
|
||||
/// <summary>
|
||||
/// ASTC (10x10 pixel block in 128 bits) compressed RGBA texture format.
|
||||
/// </summary>
|
||||
ASTC_RGBA_10x10,
|
||||
/// <summary>
|
||||
/// ASTC (12x12 pixel block in 128 bits) compressed RGBA texture format.
|
||||
/// </summary>
|
||||
ASTC_RGBA_12x12,
|
||||
/// <summary>
|
||||
/// ETC 4 bits/pixel compressed RGB texture format.
|
||||
/// </summary>
|
||||
ETC_RGB4_3DS,
|
||||
/// <summary>
|
||||
/// ETC 4 bits/pixel RGB + 4 bits/pixel Alpha compressed texture format.
|
||||
/// </summary>
|
||||
ETC_RGBA8_3DS,
|
||||
/// <summary>
|
||||
/// Two color (RG) texture format, 8-bits per channel.
|
||||
/// </summary>
|
||||
RG16,
|
||||
/// <summary>
|
||||
/// Single channel (R) texture format, 8 bit integer.
|
||||
/// </summary>
|
||||
R8,
|
||||
/// <summary>
|
||||
/// Compressed color texture format with Crunch compression for smaller storage sizes.
|
||||
/// </summary>
|
||||
ETC_RGB4Crunched,
|
||||
/// <summary>
|
||||
/// Compressed color with alpha channel texture format using Crunch compression for smaller storage sizes.
|
||||
/// </summary>
|
||||
ETC2_RGBA8Crunched,
|
||||
/// <summary>
|
||||
/// ASTC (4x4 pixel block in 128 bits) compressed RGB(A) HDR texture format.
|
||||
/// </summary>
|
||||
ASTC_HDR_4x4,
|
||||
/// <summary>
|
||||
/// ASTC (5x5 pixel block in 128 bits) compressed RGB(A) HDR texture format.
|
||||
/// </summary>
|
||||
ASTC_HDR_5x5,
|
||||
/// <summary>
|
||||
/// ASTC (6x6 pixel block in 128 bits) compressed RGB(A) HDR texture format.
|
||||
/// </summary>
|
||||
ASTC_HDR_6x6,
|
||||
/// <summary>
|
||||
/// ASTC (8x8 pixel block in 128 bits) compressed RGB(A) texture format.
|
||||
/// </summary>
|
||||
ASTC_HDR_8x8,
|
||||
/// <summary>
|
||||
/// ASTC (10x10 pixel block in 128 bits) compressed RGB(A) HDR texture format.
|
||||
/// </summary>
|
||||
ASTC_HDR_10x10,
|
||||
/// <summary>
|
||||
/// ASTC (12x12 pixel block in 128 bits) compressed RGB(A) HDR texture format.
|
||||
/// </summary>
|
||||
ASTC_HDR_12x12,
|
||||
/// <summary>
|
||||
/// Two channel (RG) texture format, 16-bits unsigned integer per channel.
|
||||
/// </summary>
|
||||
RG32,
|
||||
/// <summary>
|
||||
/// Three channel (RGB) texture format, 16-bits unsigned integer per channel.
|
||||
/// </summary>
|
||||
RGB48,
|
||||
/// <summary>
|
||||
/// Four channel (RGBA) texture format, 16-bits unsigned integer per channel.
|
||||
/// </summary>
|
||||
RGBA64,
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -10,7 +7,7 @@ namespace AssetStudio
|
||||
public Quaternion m_LocalRotation;
|
||||
public Vector3 m_LocalPosition;
|
||||
public Vector3 m_LocalScale;
|
||||
public PPtr<Transform>[] m_Children;
|
||||
public List<PPtr<Transform>> m_Children;
|
||||
public PPtr<Transform> m_Father;
|
||||
|
||||
public Transform(ObjectReader reader) : base(reader)
|
||||
@@ -20,10 +17,10 @@ namespace AssetStudio
|
||||
m_LocalScale = reader.ReadVector3();
|
||||
|
||||
int m_ChildrenCount = reader.ReadInt32();
|
||||
m_Children = new PPtr<Transform>[m_ChildrenCount];
|
||||
for (int i = 0; i < m_ChildrenCount; i++)
|
||||
m_Children = new List<PPtr<Transform>>();
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,51 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class StreamedResource
|
||||
{
|
||||
public string m_Source;
|
||||
public long m_Offset; //ulong
|
||||
public long m_Size; //ulong
|
||||
|
||||
public StreamedResource(BinaryReader reader)
|
||||
{
|
||||
m_Source = reader.ReadAlignedString();
|
||||
m_Offset = reader.ReadInt64();
|
||||
m_Size = reader.ReadInt64();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class VideoClip : NamedObject
|
||||
{
|
||||
public ResourceReader m_VideoData;
|
||||
public string m_OriginalPath;
|
||||
public string m_Source;
|
||||
public ulong m_Size;
|
||||
public StreamedResource m_ExternalResources;
|
||||
public uint Width;
|
||||
public uint Height;
|
||||
public double m_FrameRate;
|
||||
public int m_Format;
|
||||
public bool m_HasSplitAlpha;
|
||||
|
||||
public VideoClip(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_OriginalPath = reader.ReadAlignedString();
|
||||
var m_ProxyWidth = reader.ReadUInt32();
|
||||
var m_ProxyHeight = reader.ReadUInt32();
|
||||
var Width = reader.ReadUInt32();
|
||||
var Height = reader.ReadUInt32();
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||
Width = reader.ReadUInt32();
|
||||
Height = reader.ReadUInt32();
|
||||
if (version >= (2017, 2)) //2017.2 and up
|
||||
{
|
||||
var m_PixelAspecRatioNum = reader.ReadUInt32();
|
||||
var m_PixelAspecRatioDen = reader.ReadUInt32();
|
||||
}
|
||||
var m_FrameRate = reader.ReadDouble();
|
||||
m_FrameRate = reader.ReadDouble();
|
||||
var m_FrameCount = reader.ReadUInt64();
|
||||
var m_Format = reader.ReadInt32();
|
||||
m_Format = reader.ReadInt32();
|
||||
var m_AudioChannelCount = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
var m_AudioSampleRate = reader.ReadUInt32Array();
|
||||
var m_AudioLanguage = reader.ReadStringArray();
|
||||
//StreamedResource m_ExternalResources
|
||||
m_Source = reader.ReadAlignedString();
|
||||
var m_Offset = reader.ReadUInt64();
|
||||
m_Size = reader.ReadUInt64();
|
||||
var m_HasSplitAlpha = reader.ReadBoolean();
|
||||
if (version >= 2020) //2020.1 and up
|
||||
{
|
||||
var m_VideoShadersSize = reader.ReadInt32();
|
||||
for (var i = 0; i < m_VideoShadersSize; i++)
|
||||
{
|
||||
var m_VideoShaders = new PPtr<Shader>(reader);
|
||||
}
|
||||
}
|
||||
m_ExternalResources = new StreamedResource(reader);
|
||||
m_HasSplitAlpha = reader.ReadBoolean();
|
||||
if (version >= 2020) //2020.1 and up
|
||||
{
|
||||
var m_sRGB = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
ResourceReader resourceReader;
|
||||
if (!string.IsNullOrEmpty(m_Source))
|
||||
if (!string.IsNullOrEmpty(m_ExternalResources.m_Source))
|
||||
{
|
||||
resourceReader = new ResourceReader(m_Source, assetsFile, (long)m_Offset, (int)m_Size);
|
||||
resourceReader = new ResourceReader(m_ExternalResources.m_Source, assetsFile, m_ExternalResources.m_Offset, m_ExternalResources.m_Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size);
|
||||
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_ExternalResources.m_Size);
|
||||
}
|
||||
m_VideoData = resourceReader;
|
||||
}
|
||||
|
||||
49
AssetStudio/ColorConsole.cs
Normal file
49
AssetStudio/ColorConsole.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
// Represents set with 16 base colors using ANSI escape codes, which should be supported in most terminals
|
||||
// (well, except for windows editions before windows 10)
|
||||
public static class ColorConsole
|
||||
{
|
||||
public static readonly string
|
||||
Black = "\u001b[30m",
|
||||
Red = "\u001b[31m",
|
||||
Green = "\u001b[32m",
|
||||
Yellow = "\u001b[33m", //remapped to ~BrightWhite in Windows PowerShell 6
|
||||
Blue = "\u001b[34m",
|
||||
Magenta = "\u001b[35m", //remapped to ~Blue in Windows PowerShell 6
|
||||
Cyan = "\u001b[36m",
|
||||
White = "\u001b[37m",
|
||||
BrightBlack = "\u001b[30;1m",
|
||||
BrightRed = "\u001b[31;1m",
|
||||
BrightGreen = "\u001b[32;1m",
|
||||
BrightYellow = "\u001b[33;1m",
|
||||
BrightBlue = "\u001b[34;1m",
|
||||
BrightMagenta = "\u001b[35;1m",
|
||||
BrightCyan = "\u001b[36;1m",
|
||||
BrightWhite = "\u001b[37;1m";
|
||||
private static readonly string Reset = "\u001b[0m";
|
||||
|
||||
public static string Color(this string str, string ansiColor)
|
||||
{
|
||||
if (!ColorConsoleHelper.isAnsiCodesSupported)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
return $"{ansiColor}{str}{Reset}";
|
||||
}
|
||||
|
||||
public static void AnsiCodesTest()
|
||||
{
|
||||
Console.WriteLine("ANSI escape codes test");
|
||||
Console.WriteLine($"Supported: {ColorConsoleHelper.isAnsiCodesSupported}");
|
||||
Console.WriteLine("\u001b[30m A \u001b[31m B \u001b[32m C \u001b[33m D \u001b[0m");
|
||||
Console.WriteLine("\u001b[34m E \u001b[35m F \u001b[36m G \u001b[37m H \u001b[0m");
|
||||
Console.WriteLine("\u001b[30;1m A \u001b[31;1m B \u001b[32;1m C \u001b[33;1m D \u001b[0m");
|
||||
Console.WriteLine("\u001b[34;1m E \u001b[35;1m F \u001b[36;1m G \u001b[37;1m H \u001b[0m");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
57
AssetStudio/ColorConsoleHelper.cs
Normal file
57
AssetStudio/ColorConsoleHelper.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
// Based on code by tomzorz (https://gist.github.com/tomzorz/6142d69852f831fb5393654c90a1f22e)
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
internal static class ColorConsoleHelper
|
||||
{
|
||||
public static readonly bool isAnsiCodesSupported;
|
||||
private const int STD_OUTPUT_HANDLE = -11;
|
||||
private const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
private static extern IntPtr GetStdHandle(int nStdHandle);
|
||||
|
||||
static ColorConsoleHelper()
|
||||
{
|
||||
var isWin = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
if (isWin)
|
||||
{
|
||||
isAnsiCodesSupported = TryEnableVTMode();
|
||||
if (!isAnsiCodesSupported)
|
||||
{
|
||||
//Check for bash terminal emulator. E.g., Git Bash, Cmder
|
||||
isAnsiCodesSupported = Environment.GetEnvironmentVariable("TERM") != null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isAnsiCodesSupported = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable support for ANSI escape codes
|
||||
// (but probably only suitable for windows 10+)
|
||||
// https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
|
||||
private static bool TryEnableVTMode()
|
||||
{
|
||||
var iStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
if (!GetConsoleMode(iStdOut, out uint outConsoleMode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
outConsoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||
|
||||
return SetConsoleMode(iStdOut, outConsoleMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +113,9 @@ namespace AssetStudio
|
||||
{1093, "m_CorrespondingSourceObject"},
|
||||
{1121, "m_PrefabInstance"},
|
||||
{1138, "m_PrefabAsset"},
|
||||
{1152, "FileSize"}
|
||||
{1152, "FileSize"},
|
||||
{1161, "Hash128"},
|
||||
{1169, "RenderingLayerMask"},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
AssetStudio/CubismModel.cs
Normal file
31
AssetStudio/CubismModel.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class CubismModel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Container { get; set; }
|
||||
public MonoBehaviour CubismModelMono { get; set; }
|
||||
public MonoBehaviour PhysicsController { get; set; }
|
||||
public MonoBehaviour FadeController { get; set; }
|
||||
public MonoBehaviour ExpressionController { get; set; }
|
||||
public List<MonoBehaviour> RenderTextureList { get; set; }
|
||||
public List<MonoBehaviour> ParamDisplayInfoList { get; set; }
|
||||
public List<MonoBehaviour> PartDisplayInfoList { get; set; }
|
||||
public List<MonoBehaviour> PosePartList { get; set; }
|
||||
public List<AnimationClip> ClipMotionList { get; set; }
|
||||
public GameObject ModelGameObject { get; set; }
|
||||
|
||||
public CubismModel(GameObject m_GameObject)
|
||||
{
|
||||
Name = m_GameObject.m_Name;
|
||||
ModelGameObject = m_GameObject;
|
||||
RenderTextureList = new List<MonoBehaviour>();
|
||||
ParamDisplayInfoList = new List<MonoBehaviour>();
|
||||
PartDisplayInfoList = new List<MonoBehaviour>();
|
||||
PosePartList = new List<MonoBehaviour>();
|
||||
ClipMotionList = new List<AnimationClip>();
|
||||
}
|
||||
}
|
||||
}
|
||||
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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Buffers.Binary;
|
||||
using System.IO;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public enum EndianType
|
||||
{
|
||||
LittleEndian,
|
||||
BigEndian
|
||||
}
|
||||
|
||||
public class EndianBinaryReader : BinaryReader
|
||||
{
|
||||
public EndianType endian;
|
||||
private readonly byte[] buffer;
|
||||
|
||||
public EndianType Endian;
|
||||
|
||||
public EndianBinaryReader(Stream stream, EndianType endian = EndianType.BigEndian) : base(stream)
|
||||
{
|
||||
this.endian = endian;
|
||||
Endian = endian;
|
||||
buffer = new byte[8];
|
||||
}
|
||||
|
||||
public long Position
|
||||
@@ -28,90 +24,106 @@ namespace AssetStudio
|
||||
|
||||
public override short ReadInt16()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(2);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToInt16(buff, 0);
|
||||
Read(buffer, 0, 2);
|
||||
return BinaryPrimitives.ReadInt16BigEndian(buffer);
|
||||
}
|
||||
return base.ReadInt16();
|
||||
}
|
||||
|
||||
public override int ReadInt32()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(4);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToInt32(buff, 0);
|
||||
Read(buffer, 0, 4);
|
||||
return BinaryPrimitives.ReadInt32BigEndian(buffer);
|
||||
}
|
||||
return base.ReadInt32();
|
||||
}
|
||||
|
||||
public override long ReadInt64()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(8);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToInt64(buff, 0);
|
||||
Read(buffer, 0, 8);
|
||||
return BinaryPrimitives.ReadInt64BigEndian(buffer);
|
||||
}
|
||||
return base.ReadInt64();
|
||||
}
|
||||
|
||||
public override ushort ReadUInt16()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(2);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt16(buff, 0);
|
||||
Read(buffer, 0, 2);
|
||||
return BinaryPrimitives.ReadUInt16BigEndian(buffer);
|
||||
}
|
||||
return base.ReadUInt16();
|
||||
}
|
||||
|
||||
public override uint ReadUInt32()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(4);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt32(buff, 0);
|
||||
Read(buffer, 0, 4);
|
||||
return BinaryPrimitives.ReadUInt32BigEndian(buffer);
|
||||
}
|
||||
return base.ReadUInt32();
|
||||
}
|
||||
|
||||
public override ulong ReadUInt64()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(8);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt64(buff, 0);
|
||||
Read(buffer, 0, 8);
|
||||
return BinaryPrimitives.ReadUInt64BigEndian(buffer);
|
||||
}
|
||||
return base.ReadUInt64();
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
public override float ReadSingle()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(4);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToSingle(buff, 0);
|
||||
Read(buffer, 0, 4);
|
||||
buffer.AsSpan(0, 4).Reverse();
|
||||
return BitConverter.ToSingle(buffer, 0);
|
||||
}
|
||||
return base.ReadSingle();
|
||||
}
|
||||
|
||||
public override double ReadDouble()
|
||||
{
|
||||
if (endian == EndianType.BigEndian)
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
var buff = ReadBytes(8);
|
||||
Array.Reverse(buff);
|
||||
return BitConverter.ToUInt64(buff, 0);
|
||||
Read(buffer, 0, 8);
|
||||
buffer.AsSpan().Reverse();
|
||||
return BitConverter.ToDouble(buffer, 0);
|
||||
}
|
||||
return base.ReadDouble();
|
||||
}
|
||||
#else
|
||||
public override float ReadSingle()
|
||||
{
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
Read(buffer, 0, 4);
|
||||
return BinaryPrimitives.ReadSingleBigEndian(buffer);
|
||||
}
|
||||
return base.ReadSingle();
|
||||
}
|
||||
|
||||
public override double ReadDouble()
|
||||
{
|
||||
if (Endian == EndianType.BigEndian)
|
||||
{
|
||||
Read(buffer, 0, 8);
|
||||
return BinaryPrimitives.ReadDoubleBigEndian(buffer);
|
||||
}
|
||||
return base.ReadDouble();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
95
AssetStudio/EndianSpanReader.cs
Normal file
95
AssetStudio/EndianSpanReader.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static class EndianSpanReader
|
||||
{
|
||||
public static uint ReadUInt32(this Span<byte> data, int start, bool isBigEndian)
|
||||
{
|
||||
return ReadUInt32((ReadOnlySpan<byte>)data, start, isBigEndian);
|
||||
}
|
||||
|
||||
public static uint ReadUInt32(this ReadOnlySpan<byte> data, int start, bool isBigEndian)
|
||||
{
|
||||
return isBigEndian
|
||||
? BinaryPrimitives.ReadUInt32BigEndian(data.Slice(start))
|
||||
: BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(start));
|
||||
}
|
||||
|
||||
public static long ReadUInt16(this Span<byte> data, int start, bool isBigEndian)
|
||||
{
|
||||
return ReadUInt16((ReadOnlySpan<byte>)data, start, isBigEndian);
|
||||
}
|
||||
|
||||
public static uint ReadUInt16(this ReadOnlySpan<byte> data, int start, bool isBigEndian)
|
||||
{
|
||||
return isBigEndian
|
||||
? BinaryPrimitives.ReadUInt16BigEndian(data.Slice(start))
|
||||
: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(start));
|
||||
}
|
||||
|
||||
public static long ReadInt64(this Span<byte> data, int start, bool isBigEndian)
|
||||
{
|
||||
return ReadInt64((ReadOnlySpan<byte>)data, start, isBigEndian);
|
||||
}
|
||||
|
||||
public static long ReadInt64(this ReadOnlySpan<byte> data, int start, bool isBigEndian)
|
||||
{
|
||||
return isBigEndian
|
||||
? BinaryPrimitives.ReadInt64BigEndian(data.Slice(start))
|
||||
: BinaryPrimitives.ReadInt64LittleEndian(data.Slice(start));
|
||||
}
|
||||
|
||||
public static float ReadSingle(this Span<byte> data, int start, bool isBigEndian)
|
||||
{
|
||||
return ReadSingle((ReadOnlySpan<byte>)data, start, isBigEndian);
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
public static float ReadSingle(this ReadOnlySpan<byte> data, int start, bool isBigEndian)
|
||||
{
|
||||
var bytes = data.Slice(start, 4).ToArray();
|
||||
if ((isBigEndian && BitConverter.IsLittleEndian) || (!isBigEndian && !BitConverter.IsLittleEndian))
|
||||
bytes.AsSpan().Reverse();
|
||||
|
||||
return BitConverter.ToSingle(bytes, 0);
|
||||
}
|
||||
#else
|
||||
public static float ReadSingle(this ReadOnlySpan<byte> data, int start, bool isBigEndian)
|
||||
{
|
||||
return isBigEndian
|
||||
? BinaryPrimitives.ReadSingleBigEndian(data[start..])
|
||||
: BinaryPrimitives.ReadSingleLittleEndian(data[start..]);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static string ReadStringToNull(this Span<byte> data, int maxLength = 32767)
|
||||
{
|
||||
return ReadStringToNull((ReadOnlySpan<byte>)data, maxLength);
|
||||
}
|
||||
|
||||
public static string ReadStringToNull(this ReadOnlySpan<byte> data, int maxLength = 32767)
|
||||
{
|
||||
Span<byte> bytes = stackalloc byte[maxLength];
|
||||
var count = 0;
|
||||
while (count != data.Length && count < maxLength)
|
||||
{
|
||||
var b = data[count];
|
||||
if (b == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
bytes[count] = b;
|
||||
count++;
|
||||
}
|
||||
bytes = bytes.Slice(0, count);
|
||||
#if NETFRAMEWORK
|
||||
return Encoding.UTF8.GetString(bytes.ToArray());
|
||||
#else
|
||||
return Encoding.UTF8.GetString(bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
14
AssetStudio/EndianType.cs
Normal file
14
AssetStudio/EndianType.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public enum EndianType
|
||||
{
|
||||
LittleEndian,
|
||||
BigEndian
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public static class BinaryReaderExtensions
|
||||
{
|
||||
public static void AlignStream(this BinaryReader reader)
|
||||
{
|
||||
reader.AlignStream(4);
|
||||
}
|
||||
|
||||
public static void AlignStream(this BinaryReader reader, int alignment)
|
||||
public static void AlignStream(this BinaryReader reader, int alignment = 4)
|
||||
{
|
||||
var pos = reader.BaseStream.Position;
|
||||
var mod = pos % alignment;
|
||||
@@ -25,20 +21,25 @@ namespace AssetStudio
|
||||
public static string ReadAlignedString(this BinaryReader reader)
|
||||
{
|
||||
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 result = Encoding.UTF8.GetString(stringData);
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
return result;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string ReadStringToNull(this BinaryReader reader, int maxLength = 32767)
|
||||
public static string ReadStringToNull(this BinaryReader reader, int maxLength = 32767, Encoding encoding = null)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
int count = 0;
|
||||
if (encoding?.CodePage == 1200) //Unicode (UTF-16LE)
|
||||
return reader.ReadUnicodeStringToNull(maxLength * 2);
|
||||
|
||||
Span<byte> bytes = stackalloc byte[maxLength];
|
||||
var count = 0;
|
||||
while (reader.BaseStream.Position != reader.BaseStream.Length && count < maxLength)
|
||||
{
|
||||
var b = reader.ReadByte();
|
||||
@@ -46,10 +47,32 @@ namespace AssetStudio
|
||||
{
|
||||
break;
|
||||
}
|
||||
bytes.Add(b);
|
||||
bytes[count] = b;
|
||||
count++;
|
||||
}
|
||||
return Encoding.UTF8.GetString(bytes.ToArray());
|
||||
bytes = bytes.Slice(0, count);
|
||||
#if NETFRAMEWORK
|
||||
return encoding?.GetString(bytes.ToArray()) ?? Encoding.UTF8.GetString(bytes.ToArray());
|
||||
#else
|
||||
return encoding?.GetString(bytes) ?? Encoding.UTF8.GetString(bytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static string ReadUnicodeStringToNull(this BinaryReader reader, int maxLength)
|
||||
{
|
||||
var bytes = new List<byte>();
|
||||
var count = 0;
|
||||
while (reader.BaseStream.Position != reader.BaseStream.Length && count < maxLength)
|
||||
{
|
||||
var b = reader.ReadBytes(2);
|
||||
if (b.Length < 2 || (b[0] == 0 && b[1] == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
bytes.AddRange(b);
|
||||
count += 2;
|
||||
}
|
||||
return Encoding.Unicode.GetString(bytes.ToArray());
|
||||
}
|
||||
|
||||
public static Quaternion ReadQuaternion(this BinaryReader reader)
|
||||
@@ -72,94 +95,95 @@ namespace AssetStudio
|
||||
return new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
||||
}
|
||||
|
||||
public static System.Drawing.RectangleF ReadRectangleF(this BinaryReader reader)
|
||||
{
|
||||
return new System.Drawing.RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
||||
}
|
||||
|
||||
public static Color ReadColor4(this BinaryReader reader)
|
||||
{
|
||||
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();
|
||||
|
||||
var bytes = reader.ReadBytes(byteLen);
|
||||
|
||||
private static T[] ReadArray<T>(Func<T> del, int length)
|
||||
{
|
||||
var array = new T[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
array[i] = del();
|
||||
}
|
||||
return array;
|
||||
var span = MemoryMarshal.Cast<byte, T>(bytes);
|
||||
return span.ToArray();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return reader.ReadBytes(reader.ReadInt32());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static uint[] ReadUInt32Array(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadUInt32, reader.ReadInt32());
|
||||
if (length == -1)
|
||||
length = reader.ReadInt32();
|
||||
return ReadArray<uint>(reader, length * 4);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
if (length == -1)
|
||||
length = reader.ReadInt32();
|
||||
return ReadArray<float>(reader, length * 4);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return ReadArray(reader.ReadVector2, reader.ReadInt32());
|
||||
return ReadArray<Vector2>(reader, reader.ReadInt32() * 8);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return ReadArray(reader.ReadMatrix, reader.ReadInt32());
|
||||
return ReadArray<Matrix4x4>(reader, reader.ReadInt32() * 64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
145
AssetStudio/FileReader.cs
Normal file
145
AssetStudio/FileReader.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class FileReader : EndianBinaryReader
|
||||
{
|
||||
public string FullPath;
|
||||
public string FileName;
|
||||
public FileType FileType;
|
||||
|
||||
private static readonly byte[] gzipMagic = { 0x1f, 0x8b };
|
||||
private static readonly byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
|
||||
private static readonly byte[] zipMagic = { 0x50, 0x4B, 0x03, 0x04 };
|
||||
private static readonly byte[] zipSpannedMagic = { 0x50, 0x4B, 0x07, 0x08 };
|
||||
private static readonly byte[] unityFsMagic = {0x55, 0x6E, 0x69, 0x74, 0x79, 0x46, 0x53, 0x00};
|
||||
private static readonly int headerBuffLen = 1152;
|
||||
private static byte[] headerBuff = new byte[headerBuffLen];
|
||||
|
||||
public FileReader(string path) : this(path, File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { }
|
||||
|
||||
public FileReader(string path, Stream stream) : base(stream, EndianType.BigEndian)
|
||||
{
|
||||
FullPath = Path.GetFullPath(path);
|
||||
FileName = Path.GetFileName(path);
|
||||
FileType = CheckFileType();
|
||||
}
|
||||
|
||||
private FileType CheckFileType()
|
||||
{
|
||||
var buff = headerBuff.AsSpan();
|
||||
buff.Clear();
|
||||
var dataLen = Read(headerBuff, 0, headerBuffLen);
|
||||
Position = 0;
|
||||
|
||||
var signature = buff.ReadStringToNull(20);
|
||||
switch (signature)
|
||||
{
|
||||
case "UnityWeb":
|
||||
case "UnityRaw":
|
||||
case "UnityArchive":
|
||||
case "UnityFS":
|
||||
CheckBundleDataOffset(buff);
|
||||
return FileType.BundleFile;
|
||||
case "UnityWebData1.0":
|
||||
case "TuanjieWebData1.0":
|
||||
return FileType.WebFile;
|
||||
default:
|
||||
{
|
||||
var magic = Span<byte>.Empty;
|
||||
|
||||
magic = dataLen > 2 ? buff.Slice(0, 2) : magic;
|
||||
if (magic.SequenceEqual(gzipMagic))
|
||||
{
|
||||
return FileType.GZipFile;
|
||||
}
|
||||
|
||||
magic = dataLen > 38 ? buff.Slice(32, 6) : magic;
|
||||
if (magic.SequenceEqual(brotliMagic))
|
||||
{
|
||||
return FileType.BrotliFile;
|
||||
}
|
||||
|
||||
if (IsSerializedFile(buff))
|
||||
{
|
||||
return FileType.AssetsFile;
|
||||
}
|
||||
|
||||
magic = dataLen > 4 ? buff.Slice(0, 4): magic;
|
||||
if (magic.SequenceEqual(zipMagic) || magic.SequenceEqual(zipSpannedMagic))
|
||||
{
|
||||
return FileType.ZipFile;
|
||||
}
|
||||
|
||||
if (CheckBundleDataOffset(buff))
|
||||
{
|
||||
return FileType.BundleFile;
|
||||
}
|
||||
|
||||
return FileType.ResourceFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsSerializedFile(ReadOnlySpan<byte> buff)
|
||||
{
|
||||
var fileSize = BaseStream.Length;
|
||||
if (fileSize < 20)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var isBigEndian = Endian == EndianType.BigEndian;
|
||||
|
||||
//var m_MetadataSize = buff.ReadUInt32(0, isBigEndian);
|
||||
long m_FileSize = buff.ReadUInt32(4, isBigEndian);
|
||||
var m_Version = buff.ReadUInt32(8, isBigEndian);
|
||||
long m_DataOffset = buff.ReadUInt32(12, isBigEndian);
|
||||
//var m_Endianess = buff[16];
|
||||
//var m_Reserved = buff.Slice(17, 3);
|
||||
if (m_Version >= 22)
|
||||
{
|
||||
if (fileSize < 48)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//m_MetadataSize = buff.ReadUInt32(20, isBigEndian);
|
||||
m_FileSize = buff.ReadInt64(24, isBigEndian);
|
||||
m_DataOffset = buff.ReadInt64(32, isBigEndian);
|
||||
}
|
||||
if (m_FileSize != fileSize || m_DataOffset > fileSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
AssetStudio/FileType.cs
Normal file
13
AssetStudio/FileType.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace AssetStudio
|
||||
{
|
||||
public enum FileType
|
||||
{
|
||||
AssetsFile,
|
||||
BundleFile,
|
||||
WebFile,
|
||||
ResourceFile,
|
||||
GZipFile,
|
||||
BrotliFile,
|
||||
ZipFile
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,28 @@ namespace AssetStudio
|
||||
return null;
|
||||
}
|
||||
|
||||
public ImportedFrame FindRelativeFrameWithPath(string path)
|
||||
{
|
||||
var subs = path.Split(new[] { '/' }, 2);
|
||||
foreach (var child in children)
|
||||
{
|
||||
if (child.Name == subs[0])
|
||||
{
|
||||
if (subs.Length == 1)
|
||||
{
|
||||
return child;
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = child.FindRelativeFrameWithPath(subs[1]);
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ImportedFrame FindFrame(string name)
|
||||
{
|
||||
if (Name == name)
|
||||
@@ -132,6 +154,7 @@ namespace AssetStudio
|
||||
public class ImportedMesh
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public List<ImportedVertex> VertexList { get; set; }
|
||||
public List<ImportedSubmesh> SubmeshList { get; set; }
|
||||
public List<ImportedBone> BoneList { get; set; }
|
||||
public bool hasNormal { get; set; }
|
||||
@@ -142,9 +165,9 @@ namespace AssetStudio
|
||||
|
||||
public class ImportedSubmesh
|
||||
{
|
||||
public List<ImportedVertex> VertexList { get; set; }
|
||||
public List<ImportedFace> FaceList { get; set; }
|
||||
public string Material { get; set; }
|
||||
public int BaseVertex { get; set; }
|
||||
}
|
||||
|
||||
public class ImportedVertex
|
||||
|
||||
@@ -16,11 +16,11 @@ namespace AssetStudio
|
||||
|
||||
public interface ILogger
|
||||
{
|
||||
void Log(LoggerEvent loggerEvent, string message);
|
||||
void Log(LoggerEvent loggerEvent, string message, bool ignoreLevel = false);
|
||||
}
|
||||
|
||||
public sealed class DummyLogger : ILogger
|
||||
{
|
||||
public void Log(LoggerEvent loggerEvent, string message) { }
|
||||
public void Log(LoggerEvent loggerEvent, string message, bool ignoreLevel) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public interface IProgress
|
||||
{
|
||||
void Report(int value);
|
||||
}
|
||||
|
||||
public sealed class DummyProgress : IProgress
|
||||
{
|
||||
public void Report(int value) { }
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using Org.Brotli.Dec;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public enum FileType
|
||||
{
|
||||
AssetsFile,
|
||||
BundleFile,
|
||||
WebFile,
|
||||
ResourceFile
|
||||
}
|
||||
|
||||
public static class ImportHelper
|
||||
{
|
||||
public static void MergeSplitAssets(string path, bool allDirectories = false)
|
||||
@@ -20,8 +14,8 @@ namespace AssetStudio
|
||||
foreach (var splitFile in splitFiles)
|
||||
{
|
||||
var destFile = Path.GetFileNameWithoutExtension(splitFile);
|
||||
var destPath = Path.GetDirectoryName(splitFile) + "\\";
|
||||
var destFull = destPath + destFile;
|
||||
var destPath = Path.GetDirectoryName(splitFile);
|
||||
var destFull = Path.Combine(destPath, destFile);
|
||||
if (!File.Exists(destFull))
|
||||
{
|
||||
var splitParts = Directory.GetFiles(destPath, destFile + ".split*");
|
||||
@@ -43,7 +37,7 @@ namespace AssetStudio
|
||||
public static string[] ProcessingSplitFiles(List<string> selectFile)
|
||||
{
|
||||
var splitFiles = selectFile.Where(x => x.Contains(".split"))
|
||||
.Select(x => Path.GetDirectoryName(x) + "\\" + Path.GetFileNameWithoutExtension(x))
|
||||
.Select(x => Path.Combine(Path.GetDirectoryName(x), Path.GetFileNameWithoutExtension(x)))
|
||||
.Distinct()
|
||||
.ToList();
|
||||
selectFile.RemoveAll(x => x.Contains(".split"));
|
||||
@@ -57,55 +51,49 @@ namespace AssetStudio
|
||||
return selectFile.Distinct().ToArray();
|
||||
}
|
||||
|
||||
public static FileType CheckFileType(Stream stream, out EndianBinaryReader reader)
|
||||
public static FileReader DecompressGZip(FileReader reader)
|
||||
{
|
||||
reader = new EndianBinaryReader(stream);
|
||||
return CheckFileType(reader);
|
||||
}
|
||||
|
||||
public static FileType CheckFileType(string fileName, out EndianBinaryReader reader)
|
||||
{
|
||||
reader = new EndianBinaryReader(File.OpenRead(fileName));
|
||||
return CheckFileType(reader);
|
||||
}
|
||||
|
||||
private static FileType CheckFileType(EndianBinaryReader reader)
|
||||
{
|
||||
var signature = reader.ReadStringToNull(20);
|
||||
reader.Position = 0;
|
||||
switch (signature)
|
||||
try
|
||||
{
|
||||
case "UnityWeb":
|
||||
case "UnityRaw":
|
||||
case "UnityArchive":
|
||||
case "UnityFS":
|
||||
return FileType.BundleFile;
|
||||
case "UnityWebData1.0":
|
||||
return FileType.WebFile;
|
||||
default:
|
||||
using (reader)
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
using (var gs = new GZipStream(reader.BaseStream, CompressionMode.Decompress))
|
||||
{
|
||||
var magic = reader.ReadBytes(2);
|
||||
reader.Position = 0;
|
||||
if (WebFile.gzipMagic.SequenceEqual(magic))
|
||||
{
|
||||
return FileType.WebFile;
|
||||
}
|
||||
reader.Position = 0x20;
|
||||
magic = reader.ReadBytes(6);
|
||||
reader.Position = 0;
|
||||
if (WebFile.brotliMagic.SequenceEqual(magic))
|
||||
{
|
||||
return FileType.WebFile;
|
||||
}
|
||||
if (SerializedFile.IsSerializedFile(reader))
|
||||
{
|
||||
return FileType.AssetsFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FileType.ResourceFile;
|
||||
}
|
||||
gs.CopyTo(stream);
|
||||
}
|
||||
stream.Position = 0;
|
||||
return new FileReader(reader.FullPath, stream);
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Logger.Warning($"Error while decompressing Gzip file {reader.FullPath}\n{e}");
|
||||
reader.Dispose();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static FileReader DecompressBrotli(FileReader reader)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (reader)
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
using (var brotliStream = new BrotliInputStream(reader.BaseStream))
|
||||
{
|
||||
brotliStream.CopyTo(stream);
|
||||
}
|
||||
stream.Position = 0;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,5 +14,14 @@ namespace AssetStudio
|
||||
public static void Info(string message) => Default.Log(LoggerEvent.Info, message);
|
||||
public static void Warning(string message) => Default.Log(LoggerEvent.Warning, message);
|
||||
public static void Error(string message) => Default.Log(LoggerEvent.Error, message);
|
||||
|
||||
public static void Error(string message, Exception e)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(message);
|
||||
sb.AppendLine();
|
||||
sb.AppendLine(e.ToString());
|
||||
Default.Log(LoggerEvent.Error, sb.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,540 +0,0 @@
|
||||
#define CHECK_ARGS
|
||||
#define CHECK_EOF
|
||||
//#define LOCAL_SHADOW
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Lz4
|
||||
{
|
||||
public class Lz4DecoderStream : Stream
|
||||
{
|
||||
public Lz4DecoderStream(Stream input, long inputLength = long.MaxValue)
|
||||
{
|
||||
Reset(input, inputLength);
|
||||
}
|
||||
|
||||
private void Reset(Stream input, long inputLength = long.MaxValue)
|
||||
{
|
||||
this.inputLength = inputLength;
|
||||
this.input = input;
|
||||
|
||||
phase = DecodePhase.ReadToken;
|
||||
|
||||
decodeBufferPos = 0;
|
||||
|
||||
litLen = 0;
|
||||
matLen = 0;
|
||||
matDst = 0;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing && input != null)
|
||||
{
|
||||
input.Close();
|
||||
}
|
||||
input = null;
|
||||
decodeBuffer = null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
private long inputLength;
|
||||
private Stream input;
|
||||
|
||||
//because we might not be able to match back across invocations,
|
||||
//we have to keep the last window's worth of bytes around for reuse
|
||||
//we use a circular buffer for this - every time we write into this
|
||||
//buffer, we also write the same into our output buffer
|
||||
|
||||
private const int DecBufLen = 0x10000;
|
||||
private const int DecBufMask = 0xFFFF;
|
||||
|
||||
private const int InBufLen = 128;
|
||||
|
||||
private byte[] decodeBuffer = new byte[DecBufLen + InBufLen];
|
||||
private int decodeBufferPos, inBufPos, inBufEnd;
|
||||
|
||||
//we keep track of which phase we're in so that we can jump right back
|
||||
//into the correct part of decoding
|
||||
|
||||
private DecodePhase phase;
|
||||
|
||||
private enum DecodePhase
|
||||
{
|
||||
ReadToken,
|
||||
ReadExLiteralLength,
|
||||
CopyLiteral,
|
||||
ReadOffset,
|
||||
ReadExMatchLength,
|
||||
CopyMatch,
|
||||
}
|
||||
|
||||
//state within interruptable phases and across phase boundaries is
|
||||
//kept here - again, so that we can punt out and restart freely
|
||||
|
||||
private int litLen, matLen, matDst;
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
#if CHECK_ARGS
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException("buffer");
|
||||
if (offset < 0 || count < 0 || buffer.Length - count < offset)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
if (input == null)
|
||||
throw new InvalidOperationException();
|
||||
#endif
|
||||
int nRead, nToRead = count;
|
||||
|
||||
var decBuf = decodeBuffer;
|
||||
|
||||
//the stringy gotos are obnoxious, but their purpose is to
|
||||
//make it *blindingly* obvious how the state machine transitions
|
||||
//back and forth as it reads - remember, we can yield out of
|
||||
//this routine in several places, and we must be able to re-enter
|
||||
//and pick up where we left off!
|
||||
|
||||
#if LOCAL_SHADOW
|
||||
var phase = this.phase;
|
||||
var inBufPos = this.inBufPos;
|
||||
var inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
switch (phase)
|
||||
{
|
||||
case DecodePhase.ReadToken:
|
||||
goto readToken;
|
||||
|
||||
case DecodePhase.ReadExLiteralLength:
|
||||
goto readExLiteralLength;
|
||||
|
||||
case DecodePhase.CopyLiteral:
|
||||
goto copyLiteral;
|
||||
|
||||
case DecodePhase.ReadOffset:
|
||||
goto readOffset;
|
||||
|
||||
case DecodePhase.ReadExMatchLength:
|
||||
goto readExMatchLength;
|
||||
|
||||
case DecodePhase.CopyMatch:
|
||||
goto copyMatch;
|
||||
}
|
||||
|
||||
readToken:
|
||||
int tok;
|
||||
if (inBufPos < inBufEnd)
|
||||
{
|
||||
tok = decBuf[inBufPos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
|
||||
tok = ReadByteCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if (tok == -1)
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
litLen = tok >> 4;
|
||||
matLen = (tok & 0xF) + 4;
|
||||
|
||||
switch (litLen)
|
||||
{
|
||||
case 0:
|
||||
phase = DecodePhase.ReadOffset;
|
||||
goto readOffset;
|
||||
|
||||
case 0xF:
|
||||
phase = DecodePhase.ReadExLiteralLength;
|
||||
goto readExLiteralLength;
|
||||
|
||||
default:
|
||||
phase = DecodePhase.CopyLiteral;
|
||||
goto copyLiteral;
|
||||
}
|
||||
|
||||
readExLiteralLength:
|
||||
int exLitLen;
|
||||
if (inBufPos < inBufEnd)
|
||||
{
|
||||
exLitLen = decBuf[inBufPos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
exLitLen = ReadByteCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
|
||||
#if CHECK_EOF
|
||||
if (exLitLen == -1)
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
litLen += exLitLen;
|
||||
if (exLitLen == 255)
|
||||
goto readExLiteralLength;
|
||||
|
||||
phase = DecodePhase.CopyLiteral;
|
||||
goto copyLiteral;
|
||||
|
||||
copyLiteral:
|
||||
int nReadLit = litLen < nToRead ? litLen : nToRead;
|
||||
if (nReadLit != 0)
|
||||
{
|
||||
if (inBufPos + nReadLit <= inBufEnd)
|
||||
{
|
||||
int ofs = offset;
|
||||
|
||||
for (int c = nReadLit; c-- != 0;)
|
||||
buffer[ofs++] = decBuf[inBufPos++];
|
||||
|
||||
nRead = nReadLit;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
nRead = ReadCore(buffer, offset, nReadLit);
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if (nRead == 0)
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
offset += nRead;
|
||||
nToRead -= nRead;
|
||||
|
||||
litLen -= nRead;
|
||||
|
||||
if (litLen != 0)
|
||||
goto copyLiteral;
|
||||
}
|
||||
|
||||
if (nToRead == 0)
|
||||
goto finish;
|
||||
|
||||
phase = DecodePhase.ReadOffset;
|
||||
goto readOffset;
|
||||
|
||||
readOffset:
|
||||
if (inBufPos + 1 < inBufEnd)
|
||||
{
|
||||
matDst = (decBuf[inBufPos + 1] << 8) | decBuf[inBufPos];
|
||||
inBufPos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
matDst = ReadOffsetCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if (matDst == -1)
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (matLen == 15 + 4)
|
||||
{
|
||||
phase = DecodePhase.ReadExMatchLength;
|
||||
goto readExMatchLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
phase = DecodePhase.CopyMatch;
|
||||
goto copyMatch;
|
||||
}
|
||||
|
||||
readExMatchLength:
|
||||
int exMatLen;
|
||||
if (inBufPos < inBufEnd)
|
||||
{
|
||||
exMatLen = decBuf[inBufPos++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#if LOCAL_SHADOW
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
exMatLen = ReadByteCore();
|
||||
#if LOCAL_SHADOW
|
||||
inBufPos = this.inBufPos;
|
||||
inBufEnd = this.inBufEnd;
|
||||
#endif
|
||||
#if CHECK_EOF
|
||||
if (exMatLen == -1)
|
||||
goto finish;
|
||||
#endif
|
||||
}
|
||||
|
||||
matLen += exMatLen;
|
||||
if (exMatLen == 255)
|
||||
goto readExMatchLength;
|
||||
|
||||
phase = DecodePhase.CopyMatch;
|
||||
goto copyMatch;
|
||||
|
||||
copyMatch:
|
||||
int nCpyMat = matLen < nToRead ? matLen : nToRead;
|
||||
if (nCpyMat != 0)
|
||||
{
|
||||
nRead = count - nToRead;
|
||||
|
||||
int bufDst = matDst - nRead;
|
||||
if (bufDst > 0)
|
||||
{
|
||||
//offset is fairly far back, we need to pull from the buffer
|
||||
|
||||
int bufSrc = decodeBufferPos - bufDst;
|
||||
if (bufSrc < 0)
|
||||
bufSrc += DecBufLen;
|
||||
int bufCnt = bufDst < nCpyMat ? bufDst : nCpyMat;
|
||||
|
||||
for (int c = bufCnt; c-- != 0;)
|
||||
buffer[offset++] = decBuf[bufSrc++ & DecBufMask];
|
||||
}
|
||||
else
|
||||
{
|
||||
bufDst = 0;
|
||||
}
|
||||
|
||||
int sOfs = offset - matDst;
|
||||
for (int i = bufDst; i < nCpyMat; i++)
|
||||
buffer[offset++] = buffer[sOfs++];
|
||||
|
||||
nToRead -= nCpyMat;
|
||||
matLen -= nCpyMat;
|
||||
}
|
||||
|
||||
if (nToRead == 0)
|
||||
goto finish;
|
||||
|
||||
phase = DecodePhase.ReadToken;
|
||||
goto readToken;
|
||||
|
||||
finish:
|
||||
nRead = count - nToRead;
|
||||
|
||||
int nToBuf = nRead < DecBufLen ? nRead : DecBufLen;
|
||||
int repPos = offset - nToBuf;
|
||||
|
||||
if (nToBuf == DecBufLen)
|
||||
{
|
||||
Buffer.BlockCopy(buffer, repPos, decBuf, 0, DecBufLen);
|
||||
decodeBufferPos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int decPos = decodeBufferPos;
|
||||
|
||||
while (nToBuf-- != 0)
|
||||
decBuf[decPos++ & DecBufMask] = buffer[repPos++];
|
||||
|
||||
decodeBufferPos = decPos & DecBufMask;
|
||||
}
|
||||
|
||||
#if LOCAL_SHADOW
|
||||
this.phase = phase;
|
||||
this.inBufPos = inBufPos;
|
||||
#endif
|
||||
return nRead;
|
||||
}
|
||||
|
||||
private int ReadByteCore()
|
||||
{
|
||||
var buf = decodeBuffer;
|
||||
|
||||
if (inBufPos == inBufEnd)
|
||||
{
|
||||
int nRead = input.Read(buf, DecBufLen,
|
||||
InBufLen < inputLength ? InBufLen : (int)inputLength);
|
||||
|
||||
#if CHECK_EOF
|
||||
if (nRead == 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
inputLength -= nRead;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead;
|
||||
}
|
||||
|
||||
return buf[inBufPos++];
|
||||
}
|
||||
|
||||
private int ReadOffsetCore()
|
||||
{
|
||||
var buf = decodeBuffer;
|
||||
|
||||
if (inBufPos == inBufEnd)
|
||||
{
|
||||
int nRead = input.Read(buf, DecBufLen,
|
||||
InBufLen < inputLength ? InBufLen : (int)inputLength);
|
||||
|
||||
#if CHECK_EOF
|
||||
if (nRead == 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
inputLength -= nRead;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead;
|
||||
}
|
||||
|
||||
if (inBufEnd - inBufPos == 1)
|
||||
{
|
||||
buf[DecBufLen] = buf[inBufPos];
|
||||
|
||||
int nRead = input.Read(buf, DecBufLen + 1,
|
||||
InBufLen - 1 < inputLength ? InBufLen - 1 : (int)inputLength);
|
||||
|
||||
#if CHECK_EOF
|
||||
if (nRead == 0)
|
||||
{
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + 1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
inputLength -= nRead;
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead + 1;
|
||||
}
|
||||
|
||||
int ret = (buf[inBufPos + 1] << 8) | buf[inBufPos];
|
||||
inBufPos += 2;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int ReadCore(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int nToRead = count;
|
||||
|
||||
var buf = decodeBuffer;
|
||||
int inBufLen = inBufEnd - inBufPos;
|
||||
|
||||
int fromBuf = nToRead < inBufLen ? nToRead : inBufLen;
|
||||
if (fromBuf != 0)
|
||||
{
|
||||
var bufPos = inBufPos;
|
||||
|
||||
for (int c = fromBuf; c-- != 0;)
|
||||
buffer[offset++] = buf[bufPos++];
|
||||
|
||||
inBufPos = bufPos;
|
||||
nToRead -= fromBuf;
|
||||
}
|
||||
|
||||
if (nToRead != 0)
|
||||
{
|
||||
int nRead;
|
||||
|
||||
if (nToRead >= InBufLen)
|
||||
{
|
||||
nRead = input.Read(buffer, offset,
|
||||
nToRead < inputLength ? nToRead : (int)inputLength);
|
||||
nToRead -= nRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
nRead = input.Read(buf, DecBufLen,
|
||||
InBufLen < inputLength ? InBufLen : (int)inputLength);
|
||||
|
||||
inBufPos = DecBufLen;
|
||||
inBufEnd = DecBufLen + nRead;
|
||||
|
||||
fromBuf = nToRead < nRead ? nToRead : nRead;
|
||||
|
||||
var bufPos = inBufPos;
|
||||
|
||||
for (int c = fromBuf; c-- != 0;)
|
||||
buffer[offset++] = buf[bufPos++];
|
||||
|
||||
inBufPos = bufPos;
|
||||
nToRead -= fromBuf;
|
||||
}
|
||||
|
||||
inputLength -= nRead;
|
||||
}
|
||||
|
||||
return count - nToRead;
|
||||
}
|
||||
|
||||
#region Stream internals
|
||||
|
||||
public override bool CanRead => true;
|
||||
|
||||
public override bool CanSeek => false;
|
||||
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
}
|
||||
|
||||
public override long Length => throw new NotSupportedException();
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get => throw new NotSupportedException();
|
||||
set => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user