228 Commits

Author SHA1 Message Date
Perfare
8ea998b81f separate code into library
misc
2018-11-19 06:48:06 +08:00
Perfare
b93866d196 Fixed #308 2018-11-15 05:11:16 +08:00
Perfare
c0a5a7a5dd improve 2018-11-14 21:16:17 +08:00
Perfare
6d68f2bde5 Fixed 2018-11-14 16:01:52 +08:00
Perfare
a89fd049f1 improve Shader export 2018-11-14 12:20:11 +08:00
Perfare
e7c5976f7c Add scaleFactor option 2018-11-13 01:07:24 +08:00
Perfare
798a63e33c improve Sprite export 2018-11-08 17:30:12 +08:00
Perfare
e13b4489c3 improve Sprite export 2018-11-08 09:09:55 +08:00
Perfare
c6484ba77e improved 2018-11-08 06:45:33 +08:00
Perfare
a98fd52831 improved 2018-11-08 05:00:53 +08:00
Perfare
9d3cae8b28 new icon 2018-11-07 17:54:46 +08:00
Perfare
f5aef9486f Fixed bug 2018-11-07 17:15:54 +08:00
Perfare
c2ae9e63e0 Fixed bug 2018-11-07 06:11:39 +08:00
Perfare
b04cdbf12b Fixed bug 2018-11-01 19:15:15 +08:00
Perfare
1f897cf431 Delete obsolete code 2018-10-27 09:39:45 +08:00
Perfare
d380c38710 Fixed #282 2018-10-27 08:30:43 +08:00
Perfare
3cd6126ed9 Fixed bug 2018-10-25 15:02:57 +08:00
Perfare
22b2d472bc Fixed #272 2018-10-23 01:18:19 +08:00
Perfare
2c58fae804 Fixed bug 2018-10-22 22:37:24 +08:00
Perfare
1e9b8037ab Fixed bug 2018-10-22 13:23:49 +08:00
Perfare
0dbd5b52f0 Fixed bug 2018-10-17 01:59:14 +08:00
Perfare
21a8d7ef49 continue work 2018-10-17 01:51:25 +08:00
Perfare
17bd7a210a continue work 2018-10-17 00:43:34 +08:00
Perfare
40b191f039 Fixed 2018-10-16 12:39:20 +08:00
Perfare
3442b39784 rewrite some code to make it closer to the source code 2018-10-16 11:48:23 +08:00
Perfare
f15ee038b4 improved 2018-10-16 00:42:56 +08:00
Perfare
ec8b41155a Update README.md 2018-10-07 19:54:32 +08:00
Perfare
d54bfbdfe7 improved & fixed 2018-10-07 19:38:07 +08:00
Perfare
a1f491af25 modify project 2018-09-29 00:48:35 +08:00
Perfare
f2b041741b improved 2018-09-27 05:23:10 +08:00
Perfare
97169ff6dd Fixed bug 2018-09-27 04:16:59 +08:00
Perfare
11019a8473 improved 2018-09-27 01:28:03 +08:00
Perfare
767e4d0bf6 improved 2018-09-27 01:15:37 +08:00
Perfare
250856598b Fixed bug 2018-09-26 15:19:59 +08:00
Perfare
61751eeb1b Fixes 2018-09-25 22:30:59 +08:00
Perfare
99651a5d77 Fixed #266 2018-09-19 21:10:47 +08:00
Perfare
b31614641d Fixed Mesh in Xbox 2018-09-19 16:00:24 +08:00
Perfare
310c165824 FIxed #258 2018-09-13 20:52:17 +08:00
Perfare
a233af5b8f fixes 2018-09-10 13:45:12 +08:00
Perfare
2d0278db87 support optimized transform hierarchy 2018-09-09 17:32:12 +08:00
Perfare
18af0a8856 preparation work 2018-09-09 14:26:34 +08:00
Perfare
d7d56b4ad8 completed CompressedMesh 2018-09-09 05:06:34 +08:00
Perfare
3034dbc392 improve Mesh (VertexData) 2018-09-09 01:19:49 +08:00
Perfare
0b508509af Fixed bug 2018-09-08 23:45:13 +08:00
Perfare
14ad9431b9 more complete CompressedMesh (m_Skin, m_Normals, m_Tangents) 2018-09-08 23:14:18 +08:00
Perfare
c9a98d7163 compressed AnimationClip supported 2018-09-08 10:01:44 +08:00
Perfare
afae830ece improved AnimationClip export 2018-09-03 15:13:18 +08:00
Perfare
ec8c3e71d6 Fixed #249 2018-09-01 07:23:37 +08:00
Perfare
a7c5330042 Fixed #257 2018-09-01 07:07:26 +08:00
Perfare
10f02af70b Fixed #256 2018-08-30 21:34:41 +08:00
Perfare
2fd2b71148 UI update 2018-08-30 09:35:18 +08:00
Perfare
d1bec6a672 UI update 2018-08-30 09:27:19 +08:00
Perfare
9336613755 UI update 2018-08-30 06:45:08 +08:00
Perfare
9f482b7cf9 Fixed some bugs 2018-08-16 20:46:23 +08:00
Perfare
0c8fcb07b1 UI adjust 2018-08-16 06:43:26 +08:00
Perfare
eb302be569 add model preview mouse control 2018-08-15 08:40:46 +08:00
Perfare
cb3cf2a5ea Try fix bug 2018-08-15 04:53:11 +08:00
Perfare
9e5a06c107 Merge pull request #243 from qiankanglai/improveGlControl
improve GLControl:
2018-08-15 02:23:36 +08:00
Kanglai Qian
b49d5bdeb4 improve GLControl:
- resize when form changes size
- keep aspect
2018-08-06 20:52:42 +08:00
Perfare
0c23548817 improve 2018-08-05 20:03:54 +08:00
Perfare
cdaeb36e06 Update README.md 2018-08-05 06:12:35 +08:00
Perfare
114073f359 rename 2018-08-05 05:25:26 +08:00
Perfare
959a1a65b9 update OpenTK 2018-08-05 05:11:23 +08:00
Perfare
3e59a78376 add MonoScript to dump MonoBehaviour 2018-08-05 04:46:27 +08:00
Perfare
2bd4729fe7 Fixed #242 2018-08-03 13:01:51 +08:00
Perfare
84054428a8 Fixed #237 2018-07-29 04:53:56 +08:00
Perfare
9ad063bd0a improve 2018-07-26 10:00:32 +08:00
Perfare
9d1fd2f945 Fixed bug 2018-07-24 23:25:17 +08:00
Perfare
35edb9d391 optimizing 2018-07-24 22:05:02 +08:00
Perfare
d523862fac Fixed bug 2018-07-24 20:48:09 +08:00
Perfare
21ff88c890 Fixed #234 2018-07-24 13:02:08 +08:00
Perfare
e034ac5c1e Fixed #228 2018-07-19 17:58:20 +08:00
Perfare
adf39dde27 Fixed #225 2018-07-17 02:19:11 +08:00
Perfare
9b1e3435d6 try to fix combined mesh export error 2018-07-17 01:47:55 +08:00
Perfare
66a2dbe730 Fixed bug 2018-07-15 13:43:24 +08:00
Perfare
28a3b6cb23 Fixed bug 2018-07-15 05:15:05 +08:00
Perfare
2adda81b28 change the brotli library 2018-07-15 04:36:28 +08:00
Perfare
380afbf295 Fixed bug 2018-07-15 03:36:51 +08:00
Perfare
d39e24246e support load over 2GB file, Fixed #149 2018-07-14 23:46:32 +08:00
Perfare
a3e430d98d Fixed #223 2018-07-14 18:22:14 +08:00
Perfare
e0dcd6ac10 Fixed bug 2018-07-14 17:57:30 +08:00
Perfare
02f8d46620 Fixed #217 2018-07-13 01:20:31 +08:00
Perfare
dc6b9748a3 Add ResourcesHelper 2018-07-13 01:08:28 +08:00
Perfare
54c2bdc728 2018.2 support 2018-07-13 00:54:38 +08:00
Perfare
18275557df Fixed #218 2018-07-07 02:59:44 +08:00
Perfare
453f6b6e36 Fixed #213 2018-06-26 20:29:25 +08:00
Perfare
7236136cf1 Fixed #211 2018-06-24 18:35:34 +08:00
Perfare
ac6bd5236e Fixed #204 Fixed #207 2018-06-20 23:27:50 +08:00
Perfare
b2acf9a2a7 fixed bug 2018-06-20 23:02:21 +08:00
Perfare
7a8ac79ec4 fixed bug 2018-06-20 22:48:44 +08:00
Perfare
70c9d0edb3 Fixed #203 2018-06-20 22:36:45 +08:00
Perfare
18e934dd7e fixed bug 2018-06-10 05:11:44 +08:00
Perfare
3457d4d22c fixed struct read & write 2018-06-10 05:03:39 +08:00
Perfare
f65514b320 rebuild libraries 2018-05-26 16:40:53 +08:00
Perfare
0a0b172a09 add: read asset to c# dynamic class & write c# dynamic class to asset file 2018-05-09 23:13:30 +08:00
Perfare
3e2d0935b8 split code 2018-05-09 22:48:50 +08:00
Perfare
71c633b506 change structure read logic 2018-05-09 02:55:24 +08:00
Perfare
79af119cf4 Fixed #190 2018-05-06 16:46:23 +08:00
Perfare
9385b4da76 Fixed #186
Fixed #187
Fixed #188
2018-05-05 01:32:55 +08:00
Perfare
75985c8bf0 fixed bug 2018-05-04 23:14:18 +08:00
Perfare
9c8601a665 fixed bug 2018-05-04 23:03:42 +08:00
Perfare
8218662548 support 2018.1.0
some improvements
2018-05-03 02:41:47 +08:00
Perfare
52ba354dc5 Some improvements 2018-04-21 21:52:15 +08:00
Perfare
87d6a26232 Improve search 2018-04-21 16:36:18 +08:00
Perfare
546fe52ff0 Improve Filter 2018-04-21 15:50:13 +08:00
Perfare
674c634c2c Some improvements 2018-04-21 09:36:10 +08:00
Perfare
a3c92ddb8f add jump to scene hierarchy
some improvements
2018-04-19 07:06:52 +08:00
Perfare
4bcc16245c Improve extract file 2018-04-18 12:04:46 +08:00
Perfare
bd5eb3be5d Some improvements 2018-04-18 11:17:33 +08:00
Perfare
ffda15a1a5 Add FixRotation option 2018-04-18 10:36:57 +08:00
Perfare
5354506315 Improve model export 2018-04-18 08:19:30 +08:00
Perfare
ed569bfaf8 UI improvements 2018-04-18 07:11:10 +08:00
Perfare
592bfb64e7 add show type feature 2018-04-18 05:05:17 +08:00
Perfare
17b986f5df new icon 2018-04-18 02:13:23 +08:00
Perfare
de464dfe10 Some improvements 2018-04-18 01:29:18 +08:00
Perfare
906149a58a Fixed #177 2018-04-13 03:16:09 +08:00
Perfare
e3a0ab4e4a Separate code
Delete some useless code
2018-04-11 23:45:39 +08:00
Perfare
500f7788d4 Fixed bug 2018-04-11 17:17:27 +08:00
Perfare
af80b270cf Export objects with Animation 2018-04-11 15:52:37 +08:00
Perfare
8031d1a03f Add right-mouse menu export function 2018-04-10 04:45:09 +08:00
Perfare
bc2469e11a improve QuaternionToEuler 2018-04-09 08:18:45 +08:00
Perfare
9e4be3e082 Some improvements 2018-04-09 02:43:58 +08:00
Perfare
7410511c40 Update README.md 2018-04-08 05:39:36 +08:00
Perfare
8906c856e8 Update README.md 2018-04-07 08:41:48 +08:00
Perfare
dec672f9e2 Fixed appveyor build 2018-04-07 08:24:59 +08:00
Perfare
0b111d5f79 Prototype animation export 2018-04-07 07:51:33 +08:00
Perfare
4bcbdbc57d Fixed #170 2018-04-07 00:10:13 +08:00
Perfare
d5d937247e Add animation related classes 2018-04-06 23:57:36 +08:00
Perfare
4ab513002f New project name 2018-04-03 06:51:22 +08:00
Perfare
140a732046 Fixed #165 2018-03-29 01:29:51 +08:00
Perfare
e5104d5cc7 some changes 2018-03-28 06:29:28 +08:00
Perfare
f87390cc2b Update README.md
Updated project
Support 2017.4
2018-03-25 13:53:52 +08:00
Perfare
a062905734 platform update 2018-03-05 06:02:19 +08:00
Perfare
62206f8977 add brotli compression support 2018-03-05 05:07:41 +08:00
Perfare
8891414f60 fixed bug 2018-03-05 03:05:06 +08:00
Perfare
90dce1c17d fixed bug 2018-03-05 02:39:16 +08:00
Perfare
a9f1bd320e support UnityWebData 2018-03-05 02:35:53 +08:00
Perfare
c8393e165f Separate code
rename
2018-03-01 20:01:25 +08:00
Perfare
9d7c3b9f64 Merge pull request #154 from mafaca/master
Fixed sprite reading for Unity 4.x
2018-03-01 16:38:13 +08:00
mafaca
aa653cd508 Merge branch 'master' of https://github.com/Perfare/UnityStudio
merge
2018-03-01 02:32:09 +03:00
Perfare
3d60c5a7f6 Improve file import
fixed bug
2018-03-01 03:42:43 +08:00
Perfare
4ef160de34 Improve Sprite export 2018-02-28 19:10:36 +08:00
mafaca
8f7def379d fixed sprite reading for Unity 4.x 2018-02-28 13:52:38 +03:00
Perfare
351228e45c Improve external file reading 2018-02-27 18:20:12 +08:00
Perfare
ee6c050330 new crunch library after Unity 2017.3 2018-02-27 17:23:15 +08:00
Perfare
b4ce12a9e8 Split Texture2D conversion code 2018-02-27 17:11:08 +08:00
Perfare
8664531c47 Merge pull request #151 from mafaca/master
fixed compressed mesh reading
2018-02-19 14:52:11 +08:00
mafaca
40f6dbcc06 fixed compressed mesh reading 2018-02-17 23:15:45 +03:00
Perfare
1f21a67610 fixed bug 2018-01-31 07:09:46 +08:00
Perfare
929781a380 Release 0.9.0 2018-01-22 04:02:18 +08:00
Perfare
4d85c7f665 improve AudioClip export 2018-01-22 03:55:30 +08:00
Perfare
7e67f354e4 fixed some bug 2018-01-19 10:25:37 +08:00
Perfare
0cd8d51526 move file
UI adjust
2018-01-18 22:08:44 +08:00
Perfare
6f2c4521b2 Update README.md 2018-01-18 09:56:19 +08:00
Perfare
738e7d3785 Update README.md 2018-01-18 09:31:15 +08:00
Perfare
fc44ba373b add Sprite support 2018-01-18 08:08:48 +08:00
Perfare
468976db58 improve the speed of loading a large number of files
Rewriting folder related functions
fixed some bug
2018-01-17 09:57:05 +08:00
Perfare
647ce56f81 Fixed #121
clean up code
2018-01-17 06:20:06 +08:00
Perfare
db92daedf0 Update README.md 2018-01-15 10:08:02 +08:00
Perfare
6969412385 support new TextureFormat 2018-01-15 08:16:55 +08:00
Perfare
8da4c4623f update OpenTK to 3.0.0-pre 2018-01-15 06:27:23 +08:00
Perfare
50265c1d57 Fixed #129 2018-01-15 06:07:10 +08:00
Perfare
c00da37267 Fixed #130 2018-01-08 23:53:15 +08:00
Perfare
17d2140909 support Unity 2017.3, Fixed #126 2018-01-03 04:24:17 +08:00
Perfare
40153f6f19 fixed bug 2017-11-29 03:57:32 +08:00
Perfare
e75b9858da Merge pull request #122 from mafaca/master
fix skin indexes
2017-11-29 02:13:37 +08:00
mafaca
1f69f476f9 fix skin indexes 2017-11-25 02:17:31 +03:00
Perfare
b2ecc65885 support export MovieTexture 2017-11-13 17:46:26 +08:00
Perfare
682ef4552e clean up code 2017-11-13 17:04:29 +08:00
Perfare
96c7aaabb0 Support export VideoClip 2017-11-10 22:00:09 +08:00
Perfare
38f1f068d2 update ClassID 2017-11-10 19:18:42 +08:00
Perfare
0359169802 fixed #103 2017-11-10 07:58:53 +08:00
Perfare
a49d409619 fixed #110 2017-11-10 07:11:27 +08:00
Perfare
7e6ef31875 Update README.md 2017-11-10 04:34:03 +08:00
Perfare
5dd9f31398 Add Unity 2017.2 Shader support
Stop decompress Shader
2017-11-10 04:24:12 +08:00
Perfare
120c3e235d fixed bug 2017-11-10 03:39:35 +08:00
Perfare
3a6ebf7ce6 clean up code 2017-11-10 03:36:08 +08:00
Perfare
9d505c8900 change Audio related code 2017-11-10 02:27:36 +08:00
Perfare
d0486d855a Add fullSize 2017-11-10 00:04:27 +08:00
Perfare
7ddbf3ce3e fixed bug 2017-10-23 22:22:24 +08:00
Perfare
4666b378b3 fixed #107 2017-10-23 00:05:55 +08:00
Perfare
2a7d40616d add OpenFolderDialog 2017-10-22 23:48:31 +08:00
Kanglai Qian
96b8732d91 fix rotation&translation order (#101) 2017-09-30 15:32:09 +08:00
Kanglai Qian
e19ecf4770 we don't need matrix[] in fact (#98)
fix scale to avoid near face cull
2017-09-30 07:26:27 +08:00
Perfare
df45fa9b8e Fixes #99 2017-09-29 05:21:53 +08:00
Kanglai Qian
bd7a43f0dc better shader with sky/ground light, along with half lambert (#96)
* better shader with sky/ground light, along with half lambert

* force recalculate normal

* more wireframe/shade/normal mode!
2017-09-29 05:08:59 +08:00
Kanglai Qian
01f1d7c14e normalize model to center (#95)
* normalize model to center

* force same scale on XYZ
2017-09-27 01:57:47 +08:00
Perfare
cc74130ad4 display message if resource file can't be found 2017-09-24 08:27:49 +08:00
Perfare
dc8990115a modify export UI
delete AboutBox
2017-09-24 07:14:18 +08:00
Perfare
1c777aa1a8 Fixes #91 2017-09-21 05:50:14 +08:00
Perfare
6d019e6e8a When open multiple bundle files, first extract all the assets files into memory,and then parse the file to make sure the sharedfile index is correct 2017-09-19 04:34:58 +08:00
Perfare
2d7fd68ff5 Merge branch 'master' of https://github.com/Perfare/UnityStudio.git 2017-09-19 01:02:13 +08:00
Perfare
cdfc9cf2e6 fixed PlayerSettings in unity 2017.1
split code
improve read struct
2017-09-19 01:01:14 +08:00
Perfare
6e3c808799 Update README.md 2017-09-06 01:30:05 +08:00
Perfare
1ecf4c8c27 Release 0.8.0 2017-09-06 01:12:55 +08:00
Perfare
3dea2936d7 fixed bug 2017-09-06 01:03:54 +08:00
Perfare
e4533b4ec3 Add json file to read Shader 2017-08-21 22:00:28 +08:00
Perfare
9d87fead21 move glsl file to resource file 2017-08-21 19:51:32 +08:00
Perfare
14bd7f9789 try to read shader after Unity 5.4 2017-08-21 09:20:00 +08:00
Perfare
d02a4ea02e rewrite TextAsset.cs and Shader.cs 2017-08-21 07:10:30 +08:00
Perfare
14829c5e1b update TextureFormat 2017-08-21 06:52:31 +08:00
Perfare
ef29d220e0 Fixes #73 2017-08-21 06:46:46 +08:00
Perfare
14ec7c8259 support Unity 2017.1.0
fixed show "bundle file" original file
2017-07-15 15:27:09 +08:00
Perfare
9687f823fb Add "show original file" right click menu 2017-06-30 16:11:16 +08:00
Perfare
bb36839774 fix bug in export RGB565 format texture 2017-06-22 15:31:38 +08:00
Perfare
b0114520a8 fixed bug 2017-06-22 08:51:20 +08:00
Perfare
8a3af0bfba rewrite export mesh 2017-06-22 06:59:16 +08:00
Perfare
65a13e97c4 Add some simple judgment 2017-06-22 05:29:51 +08:00
Perfare
fe6b7760b0 fixed bug 2017-06-20 17:14:27 +08:00
Perfare
b319e92b3e fixed bug 2017-04-21 11:14:05 +08:00
Perfare
06b8fcea64 fix vertex color 2017-04-13 15:21:57 +08:00
Perfare
100238d232 fixed bug 2017-04-12 14:43:41 +08:00
Perfare
df3e5b31cd Release 0.7.0 2017-04-11 16:21:37 +08:00
Perfare
a04c0d0223 Update README.md 2017-04-11 15:06:40 +08:00
Perfare
d1ec1c29a4 cleanup code 2017-04-10 03:13:08 +08:00
Perfare
a928660dd3 Fixed some bugs 2017-04-10 00:50:33 +08:00
Perfare
e37a04e05b Modify project file
Fixed some bugs
2017-04-09 09:59:31 +08:00
Perfare
2c721272dd support Unity 5.6.0f3 2017-04-04 08:19:26 +08:00
Perfare
6f3b438d92 Fixed read struct 2017-04-04 05:49:26 +08:00
Perfare
f8e7303169 support use asset original name when display and export 2017-04-01 04:28:46 +08:00
Perfare
bd18bfb8ea Move code
Fixed some bugs
2017-04-01 00:41:18 +08:00
Perfare
86843f81da Fix FileName 2017-03-31 16:41:36 +08:00
ordigdug
60cc81b2dd Added 32bit ManagedFbx.dll (#32) 2017-03-07 23:30:50 +08:00
ordigdug
cfbcdecfe6 Added ExportMesh support -- (#31)
utilizing a modified ManagedFbx
2017-03-07 00:20:21 +08:00
Perfare
45b9b781b1 Clean up code
Adjust UI
Fixed some bugs
2017-02-27 23:56:24 +08:00
Perfare
29068481f5 Move file
Update OpenTK to 2.0
Fixed bug in high resolution
2017-02-26 01:40:14 +08:00
ordigdug
384dd2e4e3 Mesh Preview Support (#26)
* Added OpenTK preview

* Bug fix

* Cleanup

* Initial Mesh preview support

* Mesh preview support

* Mesh preview - lighting and color
2017-02-25 18:04:05 +08:00
Perfare
b4bce77381 Support Wii U Asset
All types selection
2017-02-24 15:39:06 +08:00
213 changed files with 21031 additions and 11365 deletions

61
AssetStudio.sln Normal file
View File

@@ -0,0 +1,61 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2024
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioGUI", "AssetStudioGUI\AssetStudioGUI.csproj", "{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AssetStudioFBX", "AssetStudioFBX\AssetStudioFBX.vcxproj", "{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudioTools", "AssetStudioTools\AssetStudioTools.csproj", "{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetStudio", "AssetStudio\AssetStudio.csproj", "{AF56B63C-1764-41B7-9E60-8D485422AC3B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Debug|x64.ActiveCfg = Debug|x64
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Debug|x64.Build.0 = Debug|x64
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Debug|x86.ActiveCfg = Debug|x86
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Debug|x86.Build.0 = Debug|x86
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Release|x64.ActiveCfg = Release|x64
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Release|x64.Build.0 = Release|x64
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Release|x86.ActiveCfg = Release|x86
{24551E2D-E9B6-4CD6-8F2A-D9F4A13E7853}.Release|x86.Build.0 = Release|x86
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Debug|x64.ActiveCfg = Debug|x64
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Debug|x64.Build.0 = Debug|x64
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Debug|x86.ActiveCfg = Debug|Win32
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Debug|x86.Build.0 = Debug|Win32
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x64.ActiveCfg = Release|x64
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x64.Build.0 = Release|x64
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x86.ActiveCfg = Release|Win32
{4F8EF5EF-732B-49CF-9EB3-B23E19AE6267}.Release|x86.Build.0 = Release|Win32
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x64.ActiveCfg = Debug|x64
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x64.Build.0 = Debug|x64
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.ActiveCfg = Debug|x86
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Debug|x86.Build.0 = Debug|x86
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.ActiveCfg = Release|x64
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x64.Build.0 = Release|x64
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.ActiveCfg = Release|x86
{9131C403-7FE8-444D-9AF5-5FE5DF76FF24}.Release|x86.Build.0 = Release|x86
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x64.ActiveCfg = Debug|Any CPU
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x64.Build.0 = Debug|Any CPU
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x86.ActiveCfg = Debug|Any CPU
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Debug|x86.Build.0 = Debug|Any CPU
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x64.ActiveCfg = Release|Any CPU
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x64.Build.0 = Release|Any CPU
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x86.ActiveCfg = Release|Any CPU
{AF56B63C-1764-41B7-9E60-8D485422AC3B}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F5C476A6-2B3B-416F-8BD5-6FE454FF3972}
EndGlobalSection
EndGlobal

View File

@@ -2,7 +2,7 @@
namespace SevenZip
{
class CRC
public class CRC
{
public static readonly uint[] Table;

View File

@@ -0,0 +1,148 @@
<?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')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{AF56B63C-1764-41B7-9E60-8D485422AC3B}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AssetStudio</RootNamespace>
<AssemblyName>AssetStudio</AssemblyName>
<TargetFrameworkVersion>v4.0</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>
</PropertyGroup>
<ItemGroup>
<Reference Include="SharpDX.Mathematics">
<HintPath>Libraries\SharpDX.Mathematics.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Half">
<HintPath>Libraries\System.Half.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</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="Utility\IImported.cs" />
<Compile Include="SerializedFile.cs" />
<Compile Include="AssetsManager.cs" />
<Compile Include="Extensions\BinaryReaderExtensions.cs" />
<Compile Include="Extensions\BinaryWriterExtensions.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\RectTransform.cs" />
<Compile Include="Classes\Renderer.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="FileIdentifier.cs" />
<Compile Include="Utility\ILogger.cs" />
<Compile Include="ImportHelper.cs" />
<Compile Include="Utility\IProgress.cs" />
<Compile Include="LocalSerializedObjectIdentifier.cs" />
<Compile Include="Utility\Logger.cs" />
<Compile Include="Lz4DecoderStream.cs" />
<Compile Include="ObjectInfo.cs" />
<Compile Include="ObjectReader.cs" />
<Compile Include="Classes\PPtr.cs" />
<Compile Include="Utility\Progress.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ResourcesHelper.cs" />
<Compile Include="SerializedFileHeader.cs" />
<Compile Include="SerializedType.cs" />
<Compile Include="SevenZipHelper.cs" />
<Compile Include="Extensions\StreamExtensions.cs" />
<Compile Include="TypeTreeHelper.cs" />
<Compile Include="TypeTreeNode.cs" />
<Compile Include="WebFile.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,192 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using static AssetStudio.ImportHelper;
namespace AssetStudio
{
public class AssetsManager
{
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>();
internal Dictionary<string, EndianBinaryReader> resourceFileReaders = new Dictionary<string, EndianBinaryReader>();
private List<string> importFiles = new List<string>();
private HashSet<string> importFilesHash = new HashSet<string>();
private HashSet<string> assetsfileListHash = new HashSet<string>();
public void LoadFiles(string[] files)
{
var path = Path.GetDirectoryName(files[0]);
MergeSplitAssets(path);
var toReadFile = ProcessingSplitFiles(files.ToList());
Load(toReadFile);
}
public void LoadFolder(string path)
{
MergeSplitAssets(path, true);
var files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).ToList();
var toReadFile = ProcessingSplitFiles(files);
Load(toReadFile);
}
private void Load(string[] files)
{
foreach (var file in files)
{
importFiles.Add(file);
importFilesHash.Add(Path.GetFileName(file).ToUpper());
}
Progress.Reset();
//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);
}
importFiles.Clear();
importFilesHash.Clear();
assetsfileListHash.Clear();
}
private void 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;
}
}
private void LoadAssetsFile(string fullName, EndianBinaryReader reader)
{
var fileName = Path.GetFileName(fullName);
if (!assetsfileListHash.Contains(fileName.ToUpper()))
{
Logger.Info($"Loading {fileName}");
var assetsFile = new SerializedFile(this, fullName, reader);
if (assetsFile.valid)
{
assetsFileList.Add(assetsFile);
assetsfileListHash.Add(assetsFile.upperFileName);
foreach (var sharedFile in assetsFile.m_Externals)
{
var sharedFilePath = Path.GetDirectoryName(fullName) + "\\" + sharedFile.fileName;
var sharedFileName = sharedFile.fileName;
if (!importFilesHash.Contains(sharedFileName.ToUpper()))
{
if (!File.Exists(sharedFilePath))
{
var findFiles = Directory.GetFiles(Path.GetDirectoryName(fullName), sharedFileName, SearchOption.AllDirectories);
if (findFiles.Length > 0)
{
sharedFilePath = findFiles[0];
}
}
if (File.Exists(sharedFilePath))
{
importFiles.Add(sharedFilePath);
importFilesHash.Add(sharedFileName.ToUpper());
}
}
}
}
else
{
reader.Dispose();
}
}
else
{
reader.Dispose();
}
}
private void LoadAssetsFromMemory(string fullName, EndianBinaryReader reader, string originalPath, string unityVersion = null)
{
var fileName = Path.GetFileName(fullName);
if (!assetsfileListHash.Contains(fileName.ToUpper()))
{
Logger.Info($"Loading {fileName}");
var assetsFile = new SerializedFile(this, fullName, reader);
if (assetsFile.valid)
{
assetsFile.originalPath = originalPath;
if (assetsFile.header.m_Version < 7)
{
assetsFile.SetVersion(unityVersion);
}
assetsFileList.Add(assetsFile);
assetsfileListHash.Add(assetsFile.upperFileName);
}
else
{
resourceFileReaders.Add(assetsFile.upperFileName, assetsFile.reader);
}
}
}
private void LoadBundleFile(string fullName, EndianBinaryReader reader, string parentPath = null)
{
var fileName = Path.GetFileName(fullName);
Logger.Info("Decompressing " + fileName);
var bundleFile = new BundleFile(reader, fullName);
reader.Dispose();
foreach (var file in bundleFile.fileList)
{
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
LoadAssetsFromMemory(dummyPath, new EndianBinaryReader(file.stream), parentPath ?? fullName, bundleFile.versionEngine);
}
}
private void LoadWebFile(string fullName, EndianBinaryReader reader)
{
var fileName = Path.GetFileName(fullName);
Logger.Info("Loading " + fileName);
var webFile = new WebFile(reader);
reader.Dispose();
foreach (var file in webFile.fileList)
{
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
switch (CheckFileType(file.stream, out reader))
{
case FileType.AssetsFile:
LoadAssetsFromMemory(dummyPath, reader, fullName);
break;
case FileType.BundleFile:
LoadBundleFile(dummyPath, reader, fullName);
break;
case FileType.WebFile:
LoadWebFile(dummyPath, reader);
break;
}
}
}
public void Clear()
{
foreach (var assetsFile in assetsFileList)
{
assetsFile.reader.Close();
}
assetsFileList.Clear();
foreach (var resourceFileReader in resourceFileReaders)
{
resourceFileReader.Value.Close();
}
resourceFileReaders.Clear();
assetsFileIndexCache.Clear();
}
}
}

View File

@@ -0,0 +1,271 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>Bit reading helpers.</summary>
internal sealed class BitReader
{
/// <summary>
/// Input byte buffer, consist of a ring-buffer and a "slack" region where bytes from the start of
/// the ring-buffer are copied.
/// </summary>
private const int Capacity = 1024;
private const int Slack = 16;
private const int IntBufferSize = Capacity + Slack;
private const int ByteReadSize = Capacity << 2;
private const int ByteBufferSize = IntBufferSize << 2;
private readonly byte[] byteBuffer = new byte[ByteBufferSize];
private readonly int[] intBuffer = new int[IntBufferSize];
private readonly Org.Brotli.Dec.IntReader intReader = new Org.Brotli.Dec.IntReader();
private System.IO.Stream input;
/// <summary>Input stream is finished.</summary>
private bool endOfStreamReached;
/// <summary>Pre-fetched bits.</summary>
internal long accumulator;
/// <summary>Current bit-reading position in accumulator.</summary>
internal int bitOffset;
/// <summary>Offset of next item in intBuffer.</summary>
private int intOffset;
private int tailBytes = 0;
/* Number of bytes in unfinished "int" item. */
/// <summary>Fills up the input buffer.</summary>
/// <remarks>
/// Fills up the input buffer.
/// <p> No-op if there are at least 36 bytes present after current position.
/// <p> After encountering the end of the input stream, 64 additional zero bytes are copied to the
/// buffer.
/// </remarks>
internal static void ReadMoreInput(Org.Brotli.Dec.BitReader br)
{
// TODO: Split to check and read; move read outside of decoding loop.
if (br.intOffset <= Capacity - 9)
{
return;
}
if (br.endOfStreamReached)
{
if (IntAvailable(br) >= -2)
{
return;
}
throw new Org.Brotli.Dec.BrotliRuntimeException("No more input");
}
int readOffset = br.intOffset << 2;
int bytesRead = ByteReadSize - readOffset;
System.Array.Copy(br.byteBuffer, readOffset, br.byteBuffer, 0, bytesRead);
br.intOffset = 0;
try
{
while (bytesRead < ByteReadSize)
{
int len = br.input.Read(br.byteBuffer, bytesRead, ByteReadSize - bytesRead);
// EOF is -1 in Java, but 0 in C#.
if (len <= 0)
{
br.endOfStreamReached = true;
br.tailBytes = bytesRead;
bytesRead += 3;
break;
}
bytesRead += len;
}
}
catch (System.IO.IOException e)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Failed to read input", e);
}
Org.Brotli.Dec.IntReader.Convert(br.intReader, bytesRead >> 2);
}
internal static void CheckHealth(Org.Brotli.Dec.BitReader br, bool endOfStream)
{
if (!br.endOfStreamReached)
{
return;
}
int byteOffset = (br.intOffset << 2) + ((br.bitOffset + 7) >> 3) - 8;
if (byteOffset > br.tailBytes)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Read after end");
}
if (endOfStream && (byteOffset != br.tailBytes))
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Unused bytes after end");
}
}
/// <summary>Advances the Read buffer by 5 bytes to make room for reading next 24 bits.</summary>
internal static void FillBitWindow(Org.Brotli.Dec.BitReader br)
{
if (br.bitOffset >= 32)
{
br.accumulator = ((long)br.intBuffer[br.intOffset++] << 32) | ((long)(((ulong)br.accumulator) >> 32));
br.bitOffset -= 32;
}
}
/// <summary>Reads the specified number of bits from Read Buffer.</summary>
internal static int ReadBits(Org.Brotli.Dec.BitReader br, int n)
{
FillBitWindow(br);
int val = (int)((long)(((ulong)br.accumulator) >> br.bitOffset)) & ((1 << n) - 1);
br.bitOffset += n;
return val;
}
/// <summary>Initialize bit reader.</summary>
/// <remarks>
/// Initialize bit reader.
/// <p> Initialisation turns bit reader to a ready state. Also a number of bytes is prefetched to
/// accumulator. Because of that this method may block until enough data could be read from input.
/// </remarks>
/// <param name="br">BitReader POJO</param>
/// <param name="input">data source</param>
internal static void Init(Org.Brotli.Dec.BitReader br, System.IO.Stream input)
{
if (br.input != null)
{
throw new System.InvalidOperationException("Bit reader already has associated input stream");
}
Org.Brotli.Dec.IntReader.Init(br.intReader, br.byteBuffer, br.intBuffer);
br.input = input;
br.accumulator = 0;
br.bitOffset = 64;
br.intOffset = Capacity;
br.endOfStreamReached = false;
Prepare(br);
}
private static void Prepare(Org.Brotli.Dec.BitReader br)
{
ReadMoreInput(br);
CheckHealth(br, false);
FillBitWindow(br);
FillBitWindow(br);
}
internal static void Reload(Org.Brotli.Dec.BitReader br)
{
if (br.bitOffset == 64)
{
Prepare(br);
}
}
/// <exception cref="System.IO.IOException"/>
internal static void Close(Org.Brotli.Dec.BitReader br)
{
System.IO.Stream @is = br.input;
br.input = null;
if (@is != null)
{
@is.Close();
}
}
internal static void JumpToByteBoundary(Org.Brotli.Dec.BitReader br)
{
int padding = (64 - br.bitOffset) & 7;
if (padding != 0)
{
int paddingBits = Org.Brotli.Dec.BitReader.ReadBits(br, padding);
if (paddingBits != 0)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Corrupted padding bits");
}
}
}
internal static int IntAvailable(Org.Brotli.Dec.BitReader br)
{
int limit = Capacity;
if (br.endOfStreamReached)
{
limit = (br.tailBytes + 3) >> 2;
}
return limit - br.intOffset;
}
internal static void CopyBytes(Org.Brotli.Dec.BitReader br, byte[] data, int offset, int length)
{
if ((br.bitOffset & 7) != 0)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Unaligned copyBytes");
}
// Drain accumulator.
while ((br.bitOffset != 64) && (length != 0))
{
data[offset++] = unchecked((byte)((long)(((ulong)br.accumulator) >> br.bitOffset)));
br.bitOffset += 8;
length--;
}
if (length == 0)
{
return;
}
// Get data from shadow buffer with "sizeof(int)" granularity.
int copyInts = System.Math.Min(IntAvailable(br), length >> 2);
if (copyInts > 0)
{
int readOffset = br.intOffset << 2;
System.Array.Copy(br.byteBuffer, readOffset, data, offset, copyInts << 2);
offset += copyInts << 2;
length -= copyInts << 2;
br.intOffset += copyInts;
}
if (length == 0)
{
return;
}
// Read tail bytes.
if (IntAvailable(br) > 0)
{
// length = 1..3
FillBitWindow(br);
while (length != 0)
{
data[offset++] = unchecked((byte)((long)(((ulong)br.accumulator) >> br.bitOffset)));
br.bitOffset += 8;
length--;
}
CheckHealth(br, false);
return;
}
// Now it is possible to copy bytes directly.
try
{
while (length > 0)
{
int len = br.input.Read(data, offset, length);
if (len == -1)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Unexpected end of input");
}
offset += len;
length -= len;
}
}
catch (System.IO.IOException e)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Failed to read input", e);
}
}
}
}

View File

@@ -0,0 +1,223 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>
/// <see cref="System.IO.Stream"/>
/// decorator that decompresses brotli data.
/// <p> Not thread-safe.
/// </summary>
public class BrotliInputStream : System.IO.Stream
{
public const int DefaultInternalBufferSize = 16384;
/// <summary>Internal buffer used for efficient byte-by-byte reading.</summary>
private byte[] buffer;
/// <summary>Number of decoded but still unused bytes in internal buffer.</summary>
private int remainingBufferBytes;
/// <summary>Next unused byte offset.</summary>
private int bufferOffset;
/// <summary>Decoder state.</summary>
private readonly Org.Brotli.Dec.State state = new Org.Brotli.Dec.State();
/// <summary>
/// Creates a
/// <see cref="System.IO.Stream"/>
/// wrapper that decompresses brotli data.
/// <p> For byte-by-byte reading (
/// <see cref="ReadByte()"/>
/// ) internal buffer with
/// <see cref="DefaultInternalBufferSize"/>
/// size is allocated and used.
/// <p> Will block the thread until first kilobyte of data of source is available.
/// </summary>
/// <param name="source">underlying data source</param>
/// <exception cref="System.IO.IOException">in case of corrupted data or source stream problems</exception>
public BrotliInputStream(System.IO.Stream source)
: this(source, DefaultInternalBufferSize, null)
{
}
/// <summary>
/// Creates a
/// <see cref="System.IO.Stream"/>
/// wrapper that decompresses brotli data.
/// <p> For byte-by-byte reading (
/// <see cref="ReadByte()"/>
/// ) internal buffer of specified size is
/// allocated and used.
/// <p> Will block the thread until first kilobyte of data of source is available.
/// </summary>
/// <param name="source">compressed data source</param>
/// <param name="byteReadBufferSize">
/// size of internal buffer used in case of
/// byte-by-byte reading
/// </param>
/// <exception cref="System.IO.IOException">in case of corrupted data or source stream problems</exception>
public BrotliInputStream(System.IO.Stream source, int byteReadBufferSize)
: this(source, byteReadBufferSize, null)
{
}
/// <summary>
/// Creates a
/// <see cref="System.IO.Stream"/>
/// wrapper that decompresses brotli data.
/// <p> For byte-by-byte reading (
/// <see cref="ReadByte()"/>
/// ) internal buffer of specified size is
/// allocated and used.
/// <p> Will block the thread until first kilobyte of data of source is available.
/// </summary>
/// <param name="source">compressed data source</param>
/// <param name="byteReadBufferSize">
/// size of internal buffer used in case of
/// byte-by-byte reading
/// </param>
/// <param name="customDictionary">
/// custom dictionary data;
/// <see langword="null"/>
/// if not used
/// </param>
/// <exception cref="System.IO.IOException">in case of corrupted data or source stream problems</exception>
public BrotliInputStream(System.IO.Stream source, int byteReadBufferSize, byte[] customDictionary)
{
if (byteReadBufferSize <= 0)
{
throw new System.ArgumentException("Bad buffer size:" + byteReadBufferSize);
}
else if (source == null)
{
throw new System.ArgumentException("source is null");
}
this.buffer = new byte[byteReadBufferSize];
this.remainingBufferBytes = 0;
this.bufferOffset = 0;
try
{
Org.Brotli.Dec.State.SetInput(state, source);
}
catch (Org.Brotli.Dec.BrotliRuntimeException ex)
{
throw new System.IO.IOException("Brotli decoder initialization failed", ex);
}
if (customDictionary != null)
{
Org.Brotli.Dec.Decode.SetCustomDictionary(state, customDictionary);
}
}
/// <summary><inheritDoc/></summary>
/// <exception cref="System.IO.IOException"/>
public override void Close()
{
Org.Brotli.Dec.State.Close(state);
}
/// <summary><inheritDoc/></summary>
/// <exception cref="System.IO.IOException"/>
public override int ReadByte()
{
if (bufferOffset >= remainingBufferBytes)
{
remainingBufferBytes = Read(buffer, 0, buffer.Length);
bufferOffset = 0;
if (remainingBufferBytes == -1)
{
return -1;
}
}
return buffer[bufferOffset++] & unchecked((int)(0xFF));
}
/// <summary><inheritDoc/></summary>
/// <exception cref="System.IO.IOException"/>
public override int Read(byte[] destBuffer, int destOffset, int destLen)
{
if (destOffset < 0)
{
throw new System.ArgumentException("Bad offset: " + destOffset);
}
else if (destLen < 0)
{
throw new System.ArgumentException("Bad length: " + destLen);
}
else if (destOffset + destLen > destBuffer.Length)
{
throw new System.ArgumentException("Buffer overflow: " + (destOffset + destLen) + " > " + destBuffer.Length);
}
else if (destLen == 0)
{
return 0;
}
int copyLen = System.Math.Max(remainingBufferBytes - bufferOffset, 0);
if (copyLen != 0)
{
copyLen = System.Math.Min(copyLen, destLen);
System.Array.Copy(buffer, bufferOffset, destBuffer, destOffset, copyLen);
bufferOffset += copyLen;
destOffset += copyLen;
destLen -= copyLen;
if (destLen == 0)
{
return copyLen;
}
}
try
{
state.output = destBuffer;
state.outputOffset = destOffset;
state.outputLength = destLen;
state.outputUsed = 0;
Org.Brotli.Dec.Decode.Decompress(state);
if (state.outputUsed == 0)
{
return 0;
}
return state.outputUsed + copyLen;
}
catch (Org.Brotli.Dec.BrotliRuntimeException ex)
{
throw new System.IO.IOException("Brotli stream decoding failed", ex);
}
}
// <{[INJECTED CODE]}>
public override bool CanRead {
get {return true;}
}
public override bool CanSeek {
get {return false;}
}
public override long Length {
get {throw new System.NotSupportedException();}
}
public override long Position {
get {throw new System.NotSupportedException();}
set {throw new System.NotSupportedException();}
}
public override long Seek(long offset, System.IO.SeekOrigin origin) {
throw new System.NotSupportedException();
}
public override void SetLength(long value){
throw new System.NotSupportedException();
}
public override bool CanWrite{get{return false;}}
public override System.IAsyncResult BeginWrite(byte[] buffer, int offset,
int count, System.AsyncCallback callback, object state) {
throw new System.NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count) {
throw new System.NotSupportedException();
}
public override void Flush() {}
}
}

View File

@@ -0,0 +1,22 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>Unchecked exception used internally.</summary>
[System.Serializable]
internal class BrotliRuntimeException : System.Exception
{
internal BrotliRuntimeException(string message)
: base(message)
{
}
internal BrotliRuntimeException(string message, System.Exception cause)
: base(message, cause)
{
}
}
}

View File

@@ -0,0 +1,57 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>Common context lookup table for all context modes.</summary>
internal sealed class Context
{
internal static readonly int[] Lookup = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12, 44, 44, 44, 44, 44, 44, 44, 44
, 44, 44, 32, 32, 24, 40, 28, 12, 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, 60, 60, 60, 60
, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
40, 40, 40, 40, 40, 40, 40, 40, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38
, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,
10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24,
25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39,
40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54,
55, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
internal static readonly int[] LookupOffsets = new int[] { 1024, 1536, 1280, 1536, 0, 256, 768, 512 };
// CONTEXT_UTF8, last byte.
// ASCII range.
// UTF8 continuation byte range.
// UTF8 lead byte range.
// CONTEXT_UTF8 second last byte.
// ASCII range.
// UTF8 continuation byte range.
// UTF8 lead byte range.
// CONTEXT_SIGNED, second last byte.
// CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits.
// CONTEXT_LSB6, last byte.
// CONTEXT_MSB6, last byte.
// CONTEXT_{M,L}SB6, second last byte,
// CONTEXT_LSB6
// CONTEXT_MSB6
// CONTEXT_UTF8
// CONTEXT_SIGNED
}
}

View File

@@ -0,0 +1,992 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>API for Brotli decompression.</summary>
internal sealed class Decode
{
private const int DefaultCodeLength = 8;
private const int CodeLengthRepeatCode = 16;
private const int NumLiteralCodes = 256;
private const int NumInsertAndCopyCodes = 704;
private const int NumBlockLengthCodes = 26;
private const int LiteralContextBits = 6;
private const int DistanceContextBits = 2;
private const int HuffmanTableBits = 8;
private const int HuffmanTableMask = unchecked((int)(0xFF));
private const int CodeLengthCodes = 18;
private static readonly int[] CodeLengthCodeOrder = new int[] { 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
private const int NumDistanceShortCodes = 16;
private static readonly int[] DistanceShortCodeIndexOffset = new int[] { 3, 2, 1, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
private static readonly int[] DistanceShortCodeValueOffset = new int[] { 0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3 };
/// <summary>Static Huffman code for the code length code lengths.</summary>
private static readonly int[] FixedTable = new int[] { unchecked((int)(0x020000)), unchecked((int)(0x020004)), unchecked((int)(0x020003)), unchecked((int)(0x030002)), unchecked((int)(0x020000)), unchecked((int)(0x020004)), unchecked((int)(0x020003
)), unchecked((int)(0x040001)), unchecked((int)(0x020000)), unchecked((int)(0x020004)), unchecked((int)(0x020003)), unchecked((int)(0x030002)), unchecked((int)(0x020000)), unchecked((int)(0x020004)), unchecked((int)(0x020003)), unchecked((int
)(0x040005)) };
/// <summary>Decodes a number in the range [0..255], by reading 1 - 11 bits.</summary>
private static int DecodeVarLenUnsignedByte(Org.Brotli.Dec.BitReader br)
{
if (Org.Brotli.Dec.BitReader.ReadBits(br, 1) != 0)
{
int n = Org.Brotli.Dec.BitReader.ReadBits(br, 3);
if (n == 0)
{
return 1;
}
else
{
return Org.Brotli.Dec.BitReader.ReadBits(br, n) + (1 << n);
}
}
return 0;
}
private static void DecodeMetaBlockLength(Org.Brotli.Dec.BitReader br, Org.Brotli.Dec.State state)
{
state.inputEnd = Org.Brotli.Dec.BitReader.ReadBits(br, 1) == 1;
state.metaBlockLength = 0;
state.isUncompressed = false;
state.isMetadata = false;
if (state.inputEnd && Org.Brotli.Dec.BitReader.ReadBits(br, 1) != 0)
{
return;
}
int sizeNibbles = Org.Brotli.Dec.BitReader.ReadBits(br, 2) + 4;
if (sizeNibbles == 7)
{
state.isMetadata = true;
if (Org.Brotli.Dec.BitReader.ReadBits(br, 1) != 0)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Corrupted reserved bit");
}
int sizeBytes = Org.Brotli.Dec.BitReader.ReadBits(br, 2);
if (sizeBytes == 0)
{
return;
}
for (int i = 0; i < sizeBytes; i++)
{
int bits = Org.Brotli.Dec.BitReader.ReadBits(br, 8);
if (bits == 0 && i + 1 == sizeBytes && sizeBytes > 1)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Exuberant nibble");
}
state.metaBlockLength |= bits << (i * 8);
}
}
else
{
for (int i = 0; i < sizeNibbles; i++)
{
int bits = Org.Brotli.Dec.BitReader.ReadBits(br, 4);
if (bits == 0 && i + 1 == sizeNibbles && sizeNibbles > 4)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Exuberant nibble");
}
state.metaBlockLength |= bits << (i * 4);
}
}
state.metaBlockLength++;
if (!state.inputEnd)
{
state.isUncompressed = Org.Brotli.Dec.BitReader.ReadBits(br, 1) == 1;
}
}
/// <summary>Decodes the next Huffman code from bit-stream.</summary>
private static int ReadSymbol(int[] table, int offset, Org.Brotli.Dec.BitReader br)
{
int val = (int)((long)(((ulong)br.accumulator) >> br.bitOffset));
offset += val & HuffmanTableMask;
int bits = table[offset] >> 16;
int sym = table[offset] & unchecked((int)(0xFFFF));
if (bits <= HuffmanTableBits)
{
br.bitOffset += bits;
return sym;
}
offset += sym;
int mask = (1 << bits) - 1;
offset += (int)(((uint)(val & mask)) >> HuffmanTableBits);
br.bitOffset += ((table[offset] >> 16) + HuffmanTableBits);
return table[offset] & unchecked((int)(0xFFFF));
}
private static int ReadBlockLength(int[] table, int offset, Org.Brotli.Dec.BitReader br)
{
Org.Brotli.Dec.BitReader.FillBitWindow(br);
int code = ReadSymbol(table, offset, br);
int n = Org.Brotli.Dec.Prefix.BlockLengthNBits[code];
return Org.Brotli.Dec.Prefix.BlockLengthOffset[code] + Org.Brotli.Dec.BitReader.ReadBits(br, n);
}
private static int TranslateShortCodes(int code, int[] ringBuffer, int index)
{
if (code < NumDistanceShortCodes)
{
index += DistanceShortCodeIndexOffset[code];
index &= 3;
return ringBuffer[index] + DistanceShortCodeValueOffset[code];
}
return code - NumDistanceShortCodes + 1;
}
private static void MoveToFront(int[] v, int index)
{
int value = v[index];
for (; index > 0; index--)
{
v[index] = v[index - 1];
}
v[0] = value;
}
private static void InverseMoveToFrontTransform(byte[] v, int vLen)
{
int[] mtf = new int[256];
for (int i = 0; i < 256; i++)
{
mtf[i] = i;
}
for (int i = 0; i < vLen; i++)
{
int index = v[i] & unchecked((int)(0xFF));
v[i] = unchecked((byte)mtf[index]);
if (index != 0)
{
MoveToFront(mtf, index);
}
}
}
private static void ReadHuffmanCodeLengths(int[] codeLengthCodeLengths, int numSymbols, int[] codeLengths, Org.Brotli.Dec.BitReader br)
{
int symbol = 0;
int prevCodeLen = DefaultCodeLength;
int repeat = 0;
int repeatCodeLen = 0;
int space = 32768;
int[] table = new int[32];
Org.Brotli.Dec.Huffman.BuildHuffmanTable(table, 0, 5, codeLengthCodeLengths, CodeLengthCodes);
while (symbol < numSymbols && space > 0)
{
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
Org.Brotli.Dec.BitReader.FillBitWindow(br);
int p = (int)(((long)(((ulong)br.accumulator) >> br.bitOffset))) & 31;
br.bitOffset += table[p] >> 16;
int codeLen = table[p] & unchecked((int)(0xFFFF));
if (codeLen < CodeLengthRepeatCode)
{
repeat = 0;
codeLengths[symbol++] = codeLen;
if (codeLen != 0)
{
prevCodeLen = codeLen;
space -= 32768 >> codeLen;
}
}
else
{
int extraBits = codeLen - 14;
int newLen = 0;
if (codeLen == CodeLengthRepeatCode)
{
newLen = prevCodeLen;
}
if (repeatCodeLen != newLen)
{
repeat = 0;
repeatCodeLen = newLen;
}
int oldRepeat = repeat;
if (repeat > 0)
{
repeat -= 2;
repeat <<= extraBits;
}
repeat += Org.Brotli.Dec.BitReader.ReadBits(br, extraBits) + 3;
int repeatDelta = repeat - oldRepeat;
if (symbol + repeatDelta > numSymbols)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("symbol + repeatDelta > numSymbols");
}
// COV_NF_LINE
for (int i = 0; i < repeatDelta; i++)
{
codeLengths[symbol++] = repeatCodeLen;
}
if (repeatCodeLen != 0)
{
space -= repeatDelta << (15 - repeatCodeLen);
}
}
}
if (space != 0)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Unused space");
}
// COV_NF_LINE
// TODO: Pass max_symbol to Huffman table builder instead?
Org.Brotli.Dec.Utils.FillWithZeroes(codeLengths, symbol, numSymbols - symbol);
}
// TODO: Use specialized versions for smaller tables.
internal static void ReadHuffmanCode(int alphabetSize, int[] table, int offset, Org.Brotli.Dec.BitReader br)
{
bool ok = true;
int simpleCodeOrSkip;
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
// TODO: Avoid allocation.
int[] codeLengths = new int[alphabetSize];
simpleCodeOrSkip = Org.Brotli.Dec.BitReader.ReadBits(br, 2);
if (simpleCodeOrSkip == 1)
{
// Read symbols, codes & code lengths directly.
int maxBitsCounter = alphabetSize - 1;
int maxBits = 0;
int[] symbols = new int[4];
int numSymbols = Org.Brotli.Dec.BitReader.ReadBits(br, 2) + 1;
while (maxBitsCounter != 0)
{
maxBitsCounter >>= 1;
maxBits++;
}
// TODO: uncomment when codeLengths is reused.
// Utils.fillWithZeroes(codeLengths, 0, alphabetSize);
for (int i = 0; i < numSymbols; i++)
{
symbols[i] = Org.Brotli.Dec.BitReader.ReadBits(br, maxBits) % alphabetSize;
codeLengths[symbols[i]] = 2;
}
codeLengths[symbols[0]] = 1;
switch (numSymbols)
{
case 1:
{
break;
}
case 2:
{
ok = symbols[0] != symbols[1];
codeLengths[symbols[1]] = 1;
break;
}
case 3:
{
ok = symbols[0] != symbols[1] && symbols[0] != symbols[2] && symbols[1] != symbols[2];
break;
}
case 4:
default:
{
ok = symbols[0] != symbols[1] && symbols[0] != symbols[2] && symbols[0] != symbols[3] && symbols[1] != symbols[2] && symbols[1] != symbols[3] && symbols[2] != symbols[3];
if (Org.Brotli.Dec.BitReader.ReadBits(br, 1) == 1)
{
codeLengths[symbols[2]] = 3;
codeLengths[symbols[3]] = 3;
}
else
{
codeLengths[symbols[0]] = 2;
}
break;
}
}
}
else
{
// Decode Huffman-coded code lengths.
int[] codeLengthCodeLengths = new int[CodeLengthCodes];
int space = 32;
int numCodes = 0;
for (int i = simpleCodeOrSkip; i < CodeLengthCodes && space > 0; i++)
{
int codeLenIdx = CodeLengthCodeOrder[i];
Org.Brotli.Dec.BitReader.FillBitWindow(br);
int p = (int)((long)(((ulong)br.accumulator) >> br.bitOffset)) & 15;
// TODO: Demultiplex FIXED_TABLE.
br.bitOffset += FixedTable[p] >> 16;
int v = FixedTable[p] & unchecked((int)(0xFFFF));
codeLengthCodeLengths[codeLenIdx] = v;
if (v != 0)
{
space -= (32 >> v);
numCodes++;
}
}
ok = (numCodes == 1 || space == 0);
ReadHuffmanCodeLengths(codeLengthCodeLengths, alphabetSize, codeLengths, br);
}
if (!ok)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Can't readHuffmanCode");
}
// COV_NF_LINE
Org.Brotli.Dec.Huffman.BuildHuffmanTable(table, offset, HuffmanTableBits, codeLengths, alphabetSize);
}
private static int DecodeContextMap(int contextMapSize, byte[] contextMap, Org.Brotli.Dec.BitReader br)
{
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
int numTrees = DecodeVarLenUnsignedByte(br) + 1;
if (numTrees == 1)
{
Org.Brotli.Dec.Utils.FillWithZeroes(contextMap, 0, contextMapSize);
return numTrees;
}
bool useRleForZeros = Org.Brotli.Dec.BitReader.ReadBits(br, 1) == 1;
int maxRunLengthPrefix = 0;
if (useRleForZeros)
{
maxRunLengthPrefix = Org.Brotli.Dec.BitReader.ReadBits(br, 4) + 1;
}
int[] table = new int[Org.Brotli.Dec.Huffman.HuffmanMaxTableSize];
ReadHuffmanCode(numTrees + maxRunLengthPrefix, table, 0, br);
for (int i = 0; i < contextMapSize; )
{
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
Org.Brotli.Dec.BitReader.FillBitWindow(br);
int code = ReadSymbol(table, 0, br);
if (code == 0)
{
contextMap[i] = 0;
i++;
}
else if (code <= maxRunLengthPrefix)
{
int reps = (1 << code) + Org.Brotli.Dec.BitReader.ReadBits(br, code);
while (reps != 0)
{
if (i >= contextMapSize)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Corrupted context map");
}
// COV_NF_LINE
contextMap[i] = 0;
i++;
reps--;
}
}
else
{
contextMap[i] = unchecked((byte)(code - maxRunLengthPrefix));
i++;
}
}
if (Org.Brotli.Dec.BitReader.ReadBits(br, 1) == 1)
{
InverseMoveToFrontTransform(contextMap, contextMapSize);
}
return numTrees;
}
private static void DecodeBlockTypeAndLength(Org.Brotli.Dec.State state, int treeType)
{
Org.Brotli.Dec.BitReader br = state.br;
int[] ringBuffers = state.blockTypeRb;
int offset = treeType * 2;
Org.Brotli.Dec.BitReader.FillBitWindow(br);
int blockType = ReadSymbol(state.blockTypeTrees, treeType * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize, br);
state.blockLength[treeType] = ReadBlockLength(state.blockLenTrees, treeType * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize, br);
if (blockType == 1)
{
blockType = ringBuffers[offset + 1] + 1;
}
else if (blockType == 0)
{
blockType = ringBuffers[offset];
}
else
{
blockType -= 2;
}
if (blockType >= state.numBlockTypes[treeType])
{
blockType -= state.numBlockTypes[treeType];
}
ringBuffers[offset] = ringBuffers[offset + 1];
ringBuffers[offset + 1] = blockType;
}
private static void DecodeLiteralBlockSwitch(Org.Brotli.Dec.State state)
{
DecodeBlockTypeAndLength(state, 0);
int literalBlockType = state.blockTypeRb[1];
state.contextMapSlice = literalBlockType << LiteralContextBits;
state.literalTreeIndex = state.contextMap[state.contextMapSlice] & unchecked((int)(0xFF));
state.literalTree = state.hGroup0.trees[state.literalTreeIndex];
int contextMode = state.contextModes[literalBlockType];
state.contextLookupOffset1 = Org.Brotli.Dec.Context.LookupOffsets[contextMode];
state.contextLookupOffset2 = Org.Brotli.Dec.Context.LookupOffsets[contextMode + 1];
}
private static void DecodeCommandBlockSwitch(Org.Brotli.Dec.State state)
{
DecodeBlockTypeAndLength(state, 1);
state.treeCommandOffset = state.hGroup1.trees[state.blockTypeRb[3]];
}
private static void DecodeDistanceBlockSwitch(Org.Brotli.Dec.State state)
{
DecodeBlockTypeAndLength(state, 2);
state.distContextMapSlice = state.blockTypeRb[5] << DistanceContextBits;
}
private static void MaybeReallocateRingBuffer(Org.Brotli.Dec.State state)
{
int newSize = state.maxRingBufferSize;
if ((long)newSize > state.expectedTotalSize)
{
/* TODO: Handle 2GB+ cases more gracefully. */
int minimalNewSize = (int)state.expectedTotalSize + state.customDictionary.Length;
while ((newSize >> 1) > minimalNewSize)
{
newSize >>= 1;
}
if (!state.inputEnd && newSize < 16384 && state.maxRingBufferSize >= 16384)
{
newSize = 16384;
}
}
if (newSize <= state.ringBufferSize)
{
return;
}
int ringBufferSizeWithSlack = newSize + Org.Brotli.Dec.Dictionary.MaxTransformedWordLength;
byte[] newBuffer = new byte[ringBufferSizeWithSlack];
if (state.ringBuffer != null)
{
System.Array.Copy(state.ringBuffer, 0, newBuffer, 0, state.ringBufferSize);
}
else if (state.customDictionary.Length != 0)
{
/* Prepend custom dictionary, if any. */
int length = state.customDictionary.Length;
int offset = 0;
if (length > state.maxBackwardDistance)
{
offset = length - state.maxBackwardDistance;
length = state.maxBackwardDistance;
}
System.Array.Copy(state.customDictionary, offset, newBuffer, 0, length);
state.pos = length;
state.bytesToIgnore = length;
}
state.ringBuffer = newBuffer;
state.ringBufferSize = newSize;
}
/// <summary>Reads next metablock header.</summary>
/// <param name="state">decoding state</param>
private static void ReadMetablockInfo(Org.Brotli.Dec.State state)
{
Org.Brotli.Dec.BitReader br = state.br;
if (state.inputEnd)
{
state.nextRunningState = Org.Brotli.Dec.RunningState.Finished;
state.bytesToWrite = state.pos;
state.bytesWritten = 0;
state.runningState = Org.Brotli.Dec.RunningState.Write;
return;
}
// TODO: Reset? Do we need this?
state.hGroup0.codes = null;
state.hGroup0.trees = null;
state.hGroup1.codes = null;
state.hGroup1.trees = null;
state.hGroup2.codes = null;
state.hGroup2.trees = null;
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
DecodeMetaBlockLength(br, state);
if (state.metaBlockLength == 0 && !state.isMetadata)
{
return;
}
if (state.isUncompressed || state.isMetadata)
{
Org.Brotli.Dec.BitReader.JumpToByteBoundary(br);
state.runningState = state.isMetadata ? Org.Brotli.Dec.RunningState.ReadMetadata : Org.Brotli.Dec.RunningState.CopyUncompressed;
}
else
{
state.runningState = Org.Brotli.Dec.RunningState.CompressedBlockStart;
}
if (state.isMetadata)
{
return;
}
state.expectedTotalSize += state.metaBlockLength;
if (state.ringBufferSize < state.maxRingBufferSize)
{
MaybeReallocateRingBuffer(state);
}
}
private static void ReadMetablockHuffmanCodesAndContextMaps(Org.Brotli.Dec.State state)
{
Org.Brotli.Dec.BitReader br = state.br;
for (int i = 0; i < 3; i++)
{
state.numBlockTypes[i] = DecodeVarLenUnsignedByte(br) + 1;
state.blockLength[i] = 1 << 28;
if (state.numBlockTypes[i] > 1)
{
ReadHuffmanCode(state.numBlockTypes[i] + 2, state.blockTypeTrees, i * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize, br);
ReadHuffmanCode(NumBlockLengthCodes, state.blockLenTrees, i * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize, br);
state.blockLength[i] = ReadBlockLength(state.blockLenTrees, i * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize, br);
}
}
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
state.distancePostfixBits = Org.Brotli.Dec.BitReader.ReadBits(br, 2);
state.numDirectDistanceCodes = NumDistanceShortCodes + (Org.Brotli.Dec.BitReader.ReadBits(br, 4) << state.distancePostfixBits);
state.distancePostfixMask = (1 << state.distancePostfixBits) - 1;
int numDistanceCodes = state.numDirectDistanceCodes + (48 << state.distancePostfixBits);
// TODO: Reuse?
state.contextModes = new byte[state.numBlockTypes[0]];
for (int i = 0; i < state.numBlockTypes[0]; )
{
/* Ensure that less than 256 bits read between readMoreInput. */
int limit = System.Math.Min(i + 96, state.numBlockTypes[0]);
for (; i < limit; ++i)
{
state.contextModes[i] = unchecked((byte)(Org.Brotli.Dec.BitReader.ReadBits(br, 2) << 1));
}
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
}
// TODO: Reuse?
state.contextMap = new byte[state.numBlockTypes[0] << LiteralContextBits];
int numLiteralTrees = DecodeContextMap(state.numBlockTypes[0] << LiteralContextBits, state.contextMap, br);
state.trivialLiteralContext = true;
for (int j = 0; j < state.numBlockTypes[0] << LiteralContextBits; j++)
{
if (state.contextMap[j] != j >> LiteralContextBits)
{
state.trivialLiteralContext = false;
break;
}
}
// TODO: Reuse?
state.distContextMap = new byte[state.numBlockTypes[2] << DistanceContextBits];
int numDistTrees = DecodeContextMap(state.numBlockTypes[2] << DistanceContextBits, state.distContextMap, br);
Org.Brotli.Dec.HuffmanTreeGroup.Init(state.hGroup0, NumLiteralCodes, numLiteralTrees);
Org.Brotli.Dec.HuffmanTreeGroup.Init(state.hGroup1, NumInsertAndCopyCodes, state.numBlockTypes[1]);
Org.Brotli.Dec.HuffmanTreeGroup.Init(state.hGroup2, numDistanceCodes, numDistTrees);
Org.Brotli.Dec.HuffmanTreeGroup.Decode(state.hGroup0, br);
Org.Brotli.Dec.HuffmanTreeGroup.Decode(state.hGroup1, br);
Org.Brotli.Dec.HuffmanTreeGroup.Decode(state.hGroup2, br);
state.contextMapSlice = 0;
state.distContextMapSlice = 0;
state.contextLookupOffset1 = Org.Brotli.Dec.Context.LookupOffsets[state.contextModes[0]];
state.contextLookupOffset2 = Org.Brotli.Dec.Context.LookupOffsets[state.contextModes[0] + 1];
state.literalTreeIndex = 0;
state.literalTree = state.hGroup0.trees[0];
state.treeCommandOffset = state.hGroup1.trees[0];
// TODO: == 0?
state.blockTypeRb[0] = state.blockTypeRb[2] = state.blockTypeRb[4] = 1;
state.blockTypeRb[1] = state.blockTypeRb[3] = state.blockTypeRb[5] = 0;
}
private static void CopyUncompressedData(Org.Brotli.Dec.State state)
{
Org.Brotli.Dec.BitReader br = state.br;
byte[] ringBuffer = state.ringBuffer;
// Could happen if block ends at ring buffer end.
if (state.metaBlockLength <= 0)
{
Org.Brotli.Dec.BitReader.Reload(br);
state.runningState = Org.Brotli.Dec.RunningState.BlockStart;
return;
}
int chunkLength = System.Math.Min(state.ringBufferSize - state.pos, state.metaBlockLength);
Org.Brotli.Dec.BitReader.CopyBytes(br, ringBuffer, state.pos, chunkLength);
state.metaBlockLength -= chunkLength;
state.pos += chunkLength;
if (state.pos == state.ringBufferSize)
{
state.nextRunningState = Org.Brotli.Dec.RunningState.CopyUncompressed;
state.bytesToWrite = state.ringBufferSize;
state.bytesWritten = 0;
state.runningState = Org.Brotli.Dec.RunningState.Write;
return;
}
Org.Brotli.Dec.BitReader.Reload(br);
state.runningState = Org.Brotli.Dec.RunningState.BlockStart;
}
private static bool WriteRingBuffer(Org.Brotli.Dec.State state)
{
/* Ignore custom dictionary bytes. */
if (state.bytesToIgnore != 0)
{
state.bytesWritten += state.bytesToIgnore;
state.bytesToIgnore = 0;
}
int toWrite = System.Math.Min(state.outputLength - state.outputUsed, state.bytesToWrite - state.bytesWritten);
if (toWrite != 0)
{
System.Array.Copy(state.ringBuffer, state.bytesWritten, state.output, state.outputOffset + state.outputUsed, toWrite);
state.outputUsed += toWrite;
state.bytesWritten += toWrite;
}
return state.outputUsed < state.outputLength;
}
internal static void SetCustomDictionary(Org.Brotli.Dec.State state, byte[] data)
{
state.customDictionary = (data == null) ? new byte[0] : data;
}
/// <summary>Actual decompress implementation.</summary>
internal static void Decompress(Org.Brotli.Dec.State state)
{
if (state.runningState == Org.Brotli.Dec.RunningState.Uninitialized)
{
throw new System.InvalidOperationException("Can't decompress until initialized");
}
if (state.runningState == Org.Brotli.Dec.RunningState.Closed)
{
throw new System.InvalidOperationException("Can't decompress after close");
}
Org.Brotli.Dec.BitReader br = state.br;
int ringBufferMask = state.ringBufferSize - 1;
byte[] ringBuffer = state.ringBuffer;
while (state.runningState != Org.Brotli.Dec.RunningState.Finished)
{
switch (state.runningState)
{
case Org.Brotli.Dec.RunningState.BlockStart:
{
// TODO: extract cases to methods for the better readability.
if (state.metaBlockLength < 0)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Invalid metablock length");
}
ReadMetablockInfo(state);
/* Ring-buffer would be reallocated here. */
ringBufferMask = state.ringBufferSize - 1;
ringBuffer = state.ringBuffer;
continue;
}
case Org.Brotli.Dec.RunningState.CompressedBlockStart:
{
ReadMetablockHuffmanCodesAndContextMaps(state);
state.runningState = Org.Brotli.Dec.RunningState.MainLoop;
goto case Org.Brotli.Dec.RunningState.MainLoop;
}
case Org.Brotli.Dec.RunningState.MainLoop:
{
// Fall through
if (state.metaBlockLength <= 0)
{
state.runningState = Org.Brotli.Dec.RunningState.BlockStart;
continue;
}
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
if (state.blockLength[1] == 0)
{
DecodeCommandBlockSwitch(state);
}
state.blockLength[1]--;
Org.Brotli.Dec.BitReader.FillBitWindow(br);
int cmdCode = ReadSymbol(state.hGroup1.codes, state.treeCommandOffset, br);
int rangeIdx = (int)(((uint)cmdCode) >> 6);
state.distanceCode = 0;
if (rangeIdx >= 2)
{
rangeIdx -= 2;
state.distanceCode = -1;
}
int insertCode = Org.Brotli.Dec.Prefix.InsertRangeLut[rangeIdx] + (((int)(((uint)cmdCode) >> 3)) & 7);
int copyCode = Org.Brotli.Dec.Prefix.CopyRangeLut[rangeIdx] + (cmdCode & 7);
state.insertLength = Org.Brotli.Dec.Prefix.InsertLengthOffset[insertCode] + Org.Brotli.Dec.BitReader.ReadBits(br, Org.Brotli.Dec.Prefix.InsertLengthNBits[insertCode]);
state.copyLength = Org.Brotli.Dec.Prefix.CopyLengthOffset[copyCode] + Org.Brotli.Dec.BitReader.ReadBits(br, Org.Brotli.Dec.Prefix.CopyLengthNBits[copyCode]);
state.j = 0;
state.runningState = Org.Brotli.Dec.RunningState.InsertLoop;
goto case Org.Brotli.Dec.RunningState.InsertLoop;
}
case Org.Brotli.Dec.RunningState.InsertLoop:
{
// Fall through
if (state.trivialLiteralContext)
{
while (state.j < state.insertLength)
{
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
if (state.blockLength[0] == 0)
{
DecodeLiteralBlockSwitch(state);
}
state.blockLength[0]--;
Org.Brotli.Dec.BitReader.FillBitWindow(br);
ringBuffer[state.pos] = unchecked((byte)ReadSymbol(state.hGroup0.codes, state.literalTree, br));
state.j++;
if (state.pos++ == ringBufferMask)
{
state.nextRunningState = Org.Brotli.Dec.RunningState.InsertLoop;
state.bytesToWrite = state.ringBufferSize;
state.bytesWritten = 0;
state.runningState = Org.Brotli.Dec.RunningState.Write;
break;
}
}
}
else
{
int prevByte1 = ringBuffer[(state.pos - 1) & ringBufferMask] & unchecked((int)(0xFF));
int prevByte2 = ringBuffer[(state.pos - 2) & ringBufferMask] & unchecked((int)(0xFF));
while (state.j < state.insertLength)
{
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
if (state.blockLength[0] == 0)
{
DecodeLiteralBlockSwitch(state);
}
int literalTreeIndex = state.contextMap[state.contextMapSlice + (Org.Brotli.Dec.Context.Lookup[state.contextLookupOffset1 + prevByte1] | Org.Brotli.Dec.Context.Lookup[state.contextLookupOffset2 + prevByte2])] & unchecked((int)(0xFF));
state.blockLength[0]--;
prevByte2 = prevByte1;
Org.Brotli.Dec.BitReader.FillBitWindow(br);
prevByte1 = ReadSymbol(state.hGroup0.codes, state.hGroup0.trees[literalTreeIndex], br);
ringBuffer[state.pos] = unchecked((byte)prevByte1);
state.j++;
if (state.pos++ == ringBufferMask)
{
state.nextRunningState = Org.Brotli.Dec.RunningState.InsertLoop;
state.bytesToWrite = state.ringBufferSize;
state.bytesWritten = 0;
state.runningState = Org.Brotli.Dec.RunningState.Write;
break;
}
}
}
if (state.runningState != Org.Brotli.Dec.RunningState.InsertLoop)
{
continue;
}
state.metaBlockLength -= state.insertLength;
if (state.metaBlockLength <= 0)
{
state.runningState = Org.Brotli.Dec.RunningState.MainLoop;
continue;
}
if (state.distanceCode < 0)
{
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
if (state.blockLength[2] == 0)
{
DecodeDistanceBlockSwitch(state);
}
state.blockLength[2]--;
Org.Brotli.Dec.BitReader.FillBitWindow(br);
state.distanceCode = ReadSymbol(state.hGroup2.codes, state.hGroup2.trees[state.distContextMap[state.distContextMapSlice + (state.copyLength > 4 ? 3 : state.copyLength - 2)] & unchecked((int)(0xFF))], br);
if (state.distanceCode >= state.numDirectDistanceCodes)
{
state.distanceCode -= state.numDirectDistanceCodes;
int postfix = state.distanceCode & state.distancePostfixMask;
state.distanceCode = (int)(((uint)state.distanceCode) >> state.distancePostfixBits);
int n = ((int)(((uint)state.distanceCode) >> 1)) + 1;
int offset = ((2 + (state.distanceCode & 1)) << n) - 4;
state.distanceCode = state.numDirectDistanceCodes + postfix + ((offset + Org.Brotli.Dec.BitReader.ReadBits(br, n)) << state.distancePostfixBits);
}
}
// Convert the distance code to the actual distance by possibly looking up past distances
// from the ringBuffer.
state.distance = TranslateShortCodes(state.distanceCode, state.distRb, state.distRbIdx);
if (state.distance < 0)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Negative distance");
}
// COV_NF_LINE
if (state.maxDistance != state.maxBackwardDistance && state.pos < state.maxBackwardDistance)
{
state.maxDistance = state.pos;
}
else
{
state.maxDistance = state.maxBackwardDistance;
}
state.copyDst = state.pos;
if (state.distance > state.maxDistance)
{
state.runningState = Org.Brotli.Dec.RunningState.Transform;
continue;
}
if (state.distanceCode > 0)
{
state.distRb[state.distRbIdx & 3] = state.distance;
state.distRbIdx++;
}
if (state.copyLength > state.metaBlockLength)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Invalid backward reference");
}
// COV_NF_LINE
state.j = 0;
state.runningState = Org.Brotli.Dec.RunningState.CopyLoop;
goto case Org.Brotli.Dec.RunningState.CopyLoop;
}
case Org.Brotli.Dec.RunningState.CopyLoop:
{
// fall through
int src = (state.pos - state.distance) & ringBufferMask;
int dst = state.pos;
int copyLength = state.copyLength - state.j;
if ((src + copyLength < ringBufferMask) && (dst + copyLength < ringBufferMask))
{
for (int k = 0; k < copyLength; ++k)
{
ringBuffer[dst++] = ringBuffer[src++];
}
state.j += copyLength;
state.metaBlockLength -= copyLength;
state.pos += copyLength;
}
else
{
for (; state.j < state.copyLength; )
{
ringBuffer[state.pos] = ringBuffer[(state.pos - state.distance) & ringBufferMask];
state.metaBlockLength--;
state.j++;
if (state.pos++ == ringBufferMask)
{
state.nextRunningState = Org.Brotli.Dec.RunningState.CopyLoop;
state.bytesToWrite = state.ringBufferSize;
state.bytesWritten = 0;
state.runningState = Org.Brotli.Dec.RunningState.Write;
break;
}
}
}
if (state.runningState == Org.Brotli.Dec.RunningState.CopyLoop)
{
state.runningState = Org.Brotli.Dec.RunningState.MainLoop;
}
continue;
}
case Org.Brotli.Dec.RunningState.Transform:
{
if (state.copyLength >= Org.Brotli.Dec.Dictionary.MinWordLength && state.copyLength <= Org.Brotli.Dec.Dictionary.MaxWordLength)
{
int offset = Org.Brotli.Dec.Dictionary.OffsetsByLength[state.copyLength];
int wordId = state.distance - state.maxDistance - 1;
int shift = Org.Brotli.Dec.Dictionary.SizeBitsByLength[state.copyLength];
int mask = (1 << shift) - 1;
int wordIdx = wordId & mask;
int transformIdx = (int)(((uint)wordId) >> shift);
offset += wordIdx * state.copyLength;
if (transformIdx < Org.Brotli.Dec.Transform.Transforms.Length)
{
int len = Org.Brotli.Dec.Transform.TransformDictionaryWord(ringBuffer, state.copyDst, Org.Brotli.Dec.Dictionary.GetData(), offset, state.copyLength, Org.Brotli.Dec.Transform.Transforms[transformIdx]);
state.copyDst += len;
state.pos += len;
state.metaBlockLength -= len;
if (state.copyDst >= state.ringBufferSize)
{
state.nextRunningState = Org.Brotli.Dec.RunningState.CopyWrapBuffer;
state.bytesToWrite = state.ringBufferSize;
state.bytesWritten = 0;
state.runningState = Org.Brotli.Dec.RunningState.Write;
continue;
}
}
else
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Invalid backward reference");
}
}
else
{
// COV_NF_LINE
throw new Org.Brotli.Dec.BrotliRuntimeException("Invalid backward reference");
}
// COV_NF_LINE
state.runningState = Org.Brotli.Dec.RunningState.MainLoop;
continue;
}
case Org.Brotli.Dec.RunningState.CopyWrapBuffer:
{
System.Array.Copy(ringBuffer, state.ringBufferSize, ringBuffer, 0, state.copyDst - state.ringBufferSize);
state.runningState = Org.Brotli.Dec.RunningState.MainLoop;
continue;
}
case Org.Brotli.Dec.RunningState.ReadMetadata:
{
while (state.metaBlockLength > 0)
{
Org.Brotli.Dec.BitReader.ReadMoreInput(br);
// Optimize
Org.Brotli.Dec.BitReader.ReadBits(br, 8);
state.metaBlockLength--;
}
state.runningState = Org.Brotli.Dec.RunningState.BlockStart;
continue;
}
case Org.Brotli.Dec.RunningState.CopyUncompressed:
{
CopyUncompressedData(state);
continue;
}
case Org.Brotli.Dec.RunningState.Write:
{
if (!WriteRingBuffer(state))
{
// Output buffer is full.
return;
}
if (state.pos >= state.maxBackwardDistance)
{
state.maxDistance = state.maxBackwardDistance;
}
state.pos &= ringBufferMask;
state.runningState = state.nextRunningState;
continue;
}
default:
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Unexpected state " + state.runningState);
}
}
}
if (state.runningState == Org.Brotli.Dec.RunningState.Finished)
{
if (state.metaBlockLength < 0)
{
throw new Org.Brotli.Dec.BrotliRuntimeException("Invalid metablock length");
}
Org.Brotli.Dec.BitReader.JumpToByteBoundary(br);
Org.Brotli.Dec.BitReader.CheckHealth(state.br, true);
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,149 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>Utilities for building Huffman decoding tables.</summary>
internal sealed class Huffman
{
/// <summary>
/// Maximum possible Huffman table size for an alphabet size of 704, max code length 15 and root
/// table bits 8.
/// </summary>
internal const int HuffmanMaxTableSize = 1080;
private const int MaxLength = 15;
/// <summary>Returns reverse(reverse(key, len) + 1, len).</summary>
/// <remarks>
/// Returns reverse(reverse(key, len) + 1, len).
/// <p> reverse(key, len) is the bit-wise reversal of the len least significant bits of key.
/// </remarks>
private static int GetNextKey(int key, int len)
{
int step = 1 << (len - 1);
while ((key & step) != 0)
{
step >>= 1;
}
return (key & (step - 1)) + step;
}
/// <summary>
/// Stores
/// <paramref name="item"/>
/// in
/// <c>table[0], table[step], table[2 * step] .., table[end]</c>
/// .
/// <p> Assumes that end is an integer multiple of step.
/// </summary>
private static void ReplicateValue(int[] table, int offset, int step, int end, int item)
{
do
{
end -= step;
table[offset + end] = item;
}
while (end > 0);
}
/// <param name="count">histogram of bit lengths for the remaining symbols,</param>
/// <param name="len">code length of the next processed symbol.</param>
/// <returns>table width of the next 2nd level table.</returns>
private static int NextTableBitSize(int[] count, int len, int rootBits)
{
int left = 1 << (len - rootBits);
while (len < MaxLength)
{
left -= count[len];
if (left <= 0)
{
break;
}
len++;
left <<= 1;
}
return len - rootBits;
}
/// <summary>Builds Huffman lookup table assuming code lengths are in symbol order.</summary>
internal static void BuildHuffmanTable(int[] rootTable, int tableOffset, int rootBits, int[] codeLengths, int codeLengthsSize)
{
int key;
// Reversed prefix code.
int[] sorted = new int[codeLengthsSize];
// Symbols sorted by code length.
// TODO: fill with zeroes?
int[] count = new int[MaxLength + 1];
// Number of codes of each length.
int[] offset = new int[MaxLength + 1];
// Offsets in sorted table for each length.
int symbol;
// Build histogram of code lengths.
for (symbol = 0; symbol < codeLengthsSize; symbol++)
{
count[codeLengths[symbol]]++;
}
// Generate offsets into sorted symbol table by code length.
offset[1] = 0;
for (int len = 1; len < MaxLength; len++)
{
offset[len + 1] = offset[len] + count[len];
}
// Sort symbols by length, by symbol order within each length.
for (symbol = 0; symbol < codeLengthsSize; symbol++)
{
if (codeLengths[symbol] != 0)
{
sorted[offset[codeLengths[symbol]]++] = symbol;
}
}
int tableBits = rootBits;
int tableSize = 1 << tableBits;
int totalSize = tableSize;
// Special case code with only one value.
if (offset[MaxLength] == 1)
{
for (key = 0; key < totalSize; key++)
{
rootTable[tableOffset + key] = sorted[0];
}
return;
}
// Fill in root table.
key = 0;
symbol = 0;
for (int len = 1, step = 2; len <= rootBits; len++, step <<= 1)
{
for (; count[len] > 0; count[len]--)
{
ReplicateValue(rootTable, tableOffset + key, step, tableSize, len << 16 | sorted[symbol++]);
key = GetNextKey(key, len);
}
}
// Fill in 2nd level tables and add pointers to root table.
int mask = totalSize - 1;
int low = -1;
int currentOffset = tableOffset;
for (int len = rootBits + 1, step = 2; len <= MaxLength; len++, step <<= 1)
{
for (; count[len] > 0; count[len]--)
{
if ((key & mask) != low)
{
currentOffset += tableSize;
tableBits = NextTableBitSize(count, len, rootBits);
tableSize = 1 << tableBits;
totalSize += tableSize;
low = key & mask;
rootTable[tableOffset + low] = (tableBits + rootBits) << 16 | (currentOffset - tableOffset - low);
}
ReplicateValue(rootTable, currentOffset + (key >> rootBits), step, tableSize, (len - rootBits) << 16 | sorted[symbol++]);
key = GetNextKey(key, len);
}
}
}
}
}

View File

@@ -0,0 +1,50 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>Contains a collection of huffman trees with the same alphabet size.</summary>
internal sealed class HuffmanTreeGroup
{
/// <summary>The maximal alphabet size in this group.</summary>
private int alphabetSize;
/// <summary>Storage for Huffman lookup tables.</summary>
internal int[] codes;
/// <summary>
/// Offsets of distinct lookup tables in
/// <see cref="codes"/>
/// storage.
/// </summary>
internal int[] trees;
/// <summary>Initializes the Huffman tree group.</summary>
/// <param name="group">POJO to be initialised</param>
/// <param name="alphabetSize">the maximal alphabet size in this group</param>
/// <param name="n">number of Huffman codes</param>
internal static void Init(Org.Brotli.Dec.HuffmanTreeGroup group, int alphabetSize, int n)
{
group.alphabetSize = alphabetSize;
group.codes = new int[n * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize];
group.trees = new int[n];
}
/// <summary>Decodes Huffman trees from input stream and constructs lookup tables.</summary>
/// <param name="group">target POJO</param>
/// <param name="br">data source</param>
internal static void Decode(Org.Brotli.Dec.HuffmanTreeGroup group, Org.Brotli.Dec.BitReader br)
{
int next = 0;
int n = group.trees.Length;
for (int i = 0; i < n; i++)
{
group.trees[i] = next;
Org.Brotli.Dec.Decode.ReadHuffmanCode(group.alphabetSize, group.codes, next, br);
next += Org.Brotli.Dec.Huffman.HuffmanMaxTableSize;
}
}
}
}

View File

@@ -0,0 +1,36 @@
/* Copyright 2017 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>Byte-to-int conversion magic.</summary>
internal sealed class IntReader
{
private byte[] byteBuffer;
private int[] intBuffer;
internal static void Init(Org.Brotli.Dec.IntReader ir, byte[] byteBuffer, int[] intBuffer)
{
ir.byteBuffer = byteBuffer;
ir.intBuffer = intBuffer;
}
/// <summary>Translates bytes to ints.</summary>
/// <remarks>
/// Translates bytes to ints.
/// NB: intLen == 4 * byteSize!
/// NB: intLen should be less or equal to intBuffer length.
/// </remarks>
internal static void Convert(Org.Brotli.Dec.IntReader ir, int intLen)
{
for (int i = 0; i < intLen; ++i)
{
ir.intBuffer[i] = ((ir.byteBuffer[i * 4] & unchecked((int)(0xFF)))) | ((ir.byteBuffer[(i * 4) + 1] & unchecked((int)(0xFF))) << 8) | ((ir.byteBuffer[(i * 4) + 2] & unchecked((int)(0xFF))) << 16) | ((ir.byteBuffer[(i * 4) + 3] & unchecked((int
)(0xFF))) << 24);
}
}
}
}

View File

@@ -0,0 +1,33 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>Lookup tables to map prefix codes to value ranges.</summary>
/// <remarks>
/// Lookup tables to map prefix codes to value ranges.
/// <p> This is used during decoding of the block lengths, literal insertion lengths and copy
/// lengths.
/// <p> Range represents values: [offset, offset + 2 ^ n_bits)
/// </remarks>
internal sealed class Prefix
{
internal static readonly int[] BlockLengthOffset = new int[] { 1, 5, 9, 13, 17, 25, 33, 41, 49, 65, 81, 97, 113, 145, 177, 209, 241, 305, 369, 497, 753, 1265, 2289, 4337, 8433, 16625 };
internal static readonly int[] BlockLengthNBits = new int[] { 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 24 };
internal static readonly int[] InsertLengthOffset = new int[] { 0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, 34, 50, 66, 98, 130, 194, 322, 578, 1090, 2114, 6210, 22594 };
internal static readonly int[] InsertLengthNBits = new int[] { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 12, 14, 24 };
internal static readonly int[] CopyLengthOffset = new int[] { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, 22, 30, 38, 54, 70, 102, 134, 198, 326, 582, 1094, 2118 };
internal static readonly int[] CopyLengthNBits = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 24 };
internal static readonly int[] InsertRangeLut = new int[] { 0, 0, 8, 8, 0, 16, 8, 16, 16 };
internal static readonly int[] CopyRangeLut = new int[] { 0, 8, 0, 8, 16, 0, 16, 8, 16 };
}
}

View File

@@ -0,0 +1,37 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>Enumeration of decoding state-machine.</summary>
internal sealed class RunningState
{
internal const int Uninitialized = 0;
internal const int BlockStart = 1;
internal const int CompressedBlockStart = 2;
internal const int MainLoop = 3;
internal const int ReadMetadata = 4;
internal const int CopyUncompressed = 5;
internal const int InsertLoop = 6;
internal const int CopyLoop = 7;
internal const int CopyWrapBuffer = 8;
internal const int Transform = 9;
internal const int Finished = 10;
internal const int Closed = 11;
internal const int Write = 12;
}
}

171
AssetStudio/Brotli/State.cs Normal file
View File

@@ -0,0 +1,171 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
internal sealed class State
{
internal int runningState = Org.Brotli.Dec.RunningState.Uninitialized;
internal int nextRunningState;
internal readonly Org.Brotli.Dec.BitReader br = new Org.Brotli.Dec.BitReader();
internal byte[] ringBuffer;
internal readonly int[] blockTypeTrees = new int[3 * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize];
internal readonly int[] blockLenTrees = new int[3 * Org.Brotli.Dec.Huffman.HuffmanMaxTableSize];
internal int metaBlockLength;
internal bool inputEnd;
internal bool isUncompressed;
internal bool isMetadata;
internal readonly Org.Brotli.Dec.HuffmanTreeGroup hGroup0 = new Org.Brotli.Dec.HuffmanTreeGroup();
internal readonly Org.Brotli.Dec.HuffmanTreeGroup hGroup1 = new Org.Brotli.Dec.HuffmanTreeGroup();
internal readonly Org.Brotli.Dec.HuffmanTreeGroup hGroup2 = new Org.Brotli.Dec.HuffmanTreeGroup();
internal readonly int[] blockLength = new int[3];
internal readonly int[] numBlockTypes = new int[3];
internal readonly int[] blockTypeRb = new int[6];
internal readonly int[] distRb = new int[] { 16, 15, 11, 4 };
internal int pos = 0;
internal int maxDistance = 0;
internal int distRbIdx = 0;
internal bool trivialLiteralContext = false;
internal int literalTreeIndex = 0;
internal int literalTree;
internal int j;
internal int insertLength;
internal byte[] contextModes;
internal byte[] contextMap;
internal int contextMapSlice;
internal int distContextMapSlice;
internal int contextLookupOffset1;
internal int contextLookupOffset2;
internal int treeCommandOffset;
internal int distanceCode;
internal byte[] distContextMap;
internal int numDirectDistanceCodes;
internal int distancePostfixMask;
internal int distancePostfixBits;
internal int distance;
internal int copyLength;
internal int copyDst;
internal int maxBackwardDistance;
internal int maxRingBufferSize;
internal int ringBufferSize = 0;
internal long expectedTotalSize = 0;
internal byte[] customDictionary = new byte[0];
internal int bytesToIgnore = 0;
internal int outputOffset;
internal int outputLength;
internal int outputUsed;
internal int bytesWritten;
internal int bytesToWrite;
internal byte[] output;
// Current meta-block header information.
// TODO: Update to current spec.
private static int DecodeWindowBits(Org.Brotli.Dec.BitReader br)
{
if (Org.Brotli.Dec.BitReader.ReadBits(br, 1) == 0)
{
return 16;
}
int n = Org.Brotli.Dec.BitReader.ReadBits(br, 3);
if (n != 0)
{
return 17 + n;
}
n = Org.Brotli.Dec.BitReader.ReadBits(br, 3);
if (n != 0)
{
return 8 + n;
}
return 17;
}
/// <summary>Associate input with decoder state.</summary>
/// <param name="state">uninitialized state without associated input</param>
/// <param name="input">compressed data source</param>
internal static void SetInput(Org.Brotli.Dec.State state, System.IO.Stream input)
{
if (state.runningState != Org.Brotli.Dec.RunningState.Uninitialized)
{
throw new System.InvalidOperationException("State MUST be uninitialized");
}
Org.Brotli.Dec.BitReader.Init(state.br, input);
int windowBits = DecodeWindowBits(state.br);
if (windowBits == 9)
{
/* Reserved case for future expansion. */
throw new Org.Brotli.Dec.BrotliRuntimeException("Invalid 'windowBits' code");
}
state.maxRingBufferSize = 1 << windowBits;
state.maxBackwardDistance = state.maxRingBufferSize - 16;
state.runningState = Org.Brotli.Dec.RunningState.BlockStart;
}
/// <exception cref="System.IO.IOException"/>
internal static void Close(Org.Brotli.Dec.State state)
{
if (state.runningState == Org.Brotli.Dec.RunningState.Uninitialized)
{
throw new System.InvalidOperationException("State MUST be initialized");
}
if (state.runningState == Org.Brotli.Dec.RunningState.Closed)
{
return;
}
state.runningState = Org.Brotli.Dec.RunningState.Closed;
Org.Brotli.Dec.BitReader.Close(state.br);
}
}
}

View File

@@ -0,0 +1,154 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>Transformations on dictionary words.</summary>
internal sealed class Transform
{
private readonly byte[] prefix;
private readonly int type;
private readonly byte[] suffix;
internal Transform(string prefix, int type, string suffix)
{
this.prefix = ReadUniBytes(prefix);
this.type = type;
this.suffix = ReadUniBytes(suffix);
}
internal static byte[] ReadUniBytes(string uniBytes)
{
byte[] result = new byte[uniBytes.Length];
for (int i = 0; i < result.Length; ++i)
{
result[i] = unchecked((byte)uniBytes[i]);
}
return result;
}
internal static readonly Org.Brotli.Dec.Transform[] Transforms = new Org.Brotli.Dec.Transform[] { new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, string.Empty), new Org.Brotli.Dec.Transform(string.Empty,
Org.Brotli.Dec.WordTransformType.Identity, " "), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.Identity, " "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitFirst1, string.Empty), new Org.Brotli.Dec.Transform
(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseFirst, " "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " the "), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.Identity
, string.Empty), new Org.Brotli.Dec.Transform("s ", Org.Brotli.Dec.WordTransformType.Identity, " "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " of "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType
.UppercaseFirst, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " and "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitFirst2, string.Empty), new Org.Brotli.Dec.Transform
(string.Empty, Org.Brotli.Dec.WordTransformType.OmitLast1, string.Empty), new Org.Brotli.Dec.Transform(", ", Org.Brotli.Dec.WordTransformType.Identity, " "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity
, ", "), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.UppercaseFirst, " "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " in "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType
.Identity, " to "), new Org.Brotli.Dec.Transform("e ", Org.Brotli.Dec.WordTransformType.Identity, " "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "\""), new Org.Brotli.Dec.Transform(string.Empty,
Org.Brotli.Dec.WordTransformType.Identity, "."), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "\">"), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "\n"), new
Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitLast3, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "]"), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType
.Identity, " for "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitFirst3, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitLast2, string.Empty), new Org.Brotli.Dec.Transform
(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " a "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " that "), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.UppercaseFirst
, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, ". "), new Org.Brotli.Dec.Transform(".", Org.Brotli.Dec.WordTransformType.Identity, string.Empty), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType
.Identity, ", "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitFirst4, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " with "), new Org.Brotli.Dec.Transform
(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "'"), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " from "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity
, " by "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitFirst5, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitFirst6, string.Empty), new Org.Brotli.Dec.Transform
(" the ", Org.Brotli.Dec.WordTransformType.Identity, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitLast4, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType
.Identity, ". The "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseAll, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " on "), new Org.Brotli.Dec.Transform
(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " as "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " is "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitLast7
, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitLast1, "ing "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "\n\t"), new Org.Brotli.Dec.Transform(string.Empty
, Org.Brotli.Dec.WordTransformType.Identity, ":"), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.Identity, ". "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "ed "), new Org.Brotli.Dec.Transform
(string.Empty, Org.Brotli.Dec.WordTransformType.OmitFirst9, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitFirst7, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType
.OmitLast6, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "("), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseFirst, ", "), new Org.Brotli.Dec.Transform
(string.Empty, Org.Brotli.Dec.WordTransformType.OmitLast8, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " at "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType
.Identity, "ly "), new Org.Brotli.Dec.Transform(" the ", Org.Brotli.Dec.WordTransformType.Identity, " of "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.OmitLast5, string.Empty), new Org.Brotli.Dec.Transform(
string.Empty, Org.Brotli.Dec.WordTransformType.OmitLast9, string.Empty), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.UppercaseFirst, ", "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseFirst
, "\""), new Org.Brotli.Dec.Transform(".", Org.Brotli.Dec.WordTransformType.Identity, "("), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseAll, " "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType
.UppercaseFirst, "\">"), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "=\""), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.Identity, "."), new Org.Brotli.Dec.Transform(".com/",
Org.Brotli.Dec.WordTransformType.Identity, string.Empty), new Org.Brotli.Dec.Transform(" the ", Org.Brotli.Dec.WordTransformType.Identity, " of the "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseFirst
, "'"), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, ". This "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, ","), new Org.Brotli.Dec.Transform(".", Org.Brotli.Dec.WordTransformType
.Identity, " "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseFirst, "("), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseFirst, "."), new Org.Brotli.Dec.Transform
(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, " not "), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.Identity, "=\""), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "er "
), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.UppercaseAll, " "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "al "), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType
.UppercaseAll, string.Empty), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "='"), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseAll, "\""), new Org.Brotli.Dec.Transform
(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseFirst, ". "), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.Identity, "("), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity,
"ful "), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.UppercaseFirst, ". "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "ive "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType
.Identity, "less "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseAll, "'"), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "est "), new Org.Brotli.Dec.Transform
(" ", Org.Brotli.Dec.WordTransformType.UppercaseFirst, "."), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseAll, "\">"), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.Identity, "='"
), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseFirst, ","), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity, "ize "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType
.UppercaseAll, "."), new Org.Brotli.Dec.Transform("\u00c2\u00a0", Org.Brotli.Dec.WordTransformType.Identity, string.Empty), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.Identity, ","), new Org.Brotli.Dec.Transform(string.Empty
, Org.Brotli.Dec.WordTransformType.UppercaseFirst, "=\""), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseAll, "=\""), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.Identity
, "ous "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseAll, ", "), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseFirst, "='"), new Org.Brotli.Dec.Transform(" ",
Org.Brotli.Dec.WordTransformType.UppercaseFirst, ","), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.UppercaseAll, "=\""), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.UppercaseAll, ", "), new Org.Brotli.Dec.Transform
(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseAll, ","), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseAll, "("), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.
UppercaseAll, ". "), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.UppercaseAll, "."), new Org.Brotli.Dec.Transform(string.Empty, Org.Brotli.Dec.WordTransformType.UppercaseAll, "='"), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType
.UppercaseAll, ". "), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.UppercaseFirst, "=\""), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType.UppercaseAll, "='"), new Org.Brotli.Dec.Transform(" ", Org.Brotli.Dec.WordTransformType
.UppercaseFirst, "='") };
internal static int TransformDictionaryWord(byte[] dst, int dstOffset, byte[] word, int wordOffset, int len, Org.Brotli.Dec.Transform transform)
{
int offset = dstOffset;
// Copy prefix.
byte[] @string = transform.prefix;
int tmp = @string.Length;
int i = 0;
// In most cases tmp < 10 -> no benefits from System.arrayCopy
while (i < tmp)
{
dst[offset++] = @string[i++];
}
// Copy trimmed word.
int op = transform.type;
tmp = Org.Brotli.Dec.WordTransformType.GetOmitFirst(op);
if (tmp > len)
{
tmp = len;
}
wordOffset += tmp;
len -= tmp;
len -= Org.Brotli.Dec.WordTransformType.GetOmitLast(op);
i = len;
while (i > 0)
{
dst[offset++] = word[wordOffset++];
i--;
}
if (op == Org.Brotli.Dec.WordTransformType.UppercaseAll || op == Org.Brotli.Dec.WordTransformType.UppercaseFirst)
{
int uppercaseOffset = offset - len;
if (op == Org.Brotli.Dec.WordTransformType.UppercaseFirst)
{
len = 1;
}
while (len > 0)
{
tmp = dst[uppercaseOffset] & unchecked((int)(0xFF));
if (tmp < unchecked((int)(0xc0)))
{
if (tmp >= 'a' && tmp <= 'z')
{
dst[uppercaseOffset] ^= unchecked((byte)32);
}
uppercaseOffset += 1;
len -= 1;
}
else if (tmp < unchecked((int)(0xe0)))
{
dst[uppercaseOffset + 1] ^= unchecked((byte)32);
uppercaseOffset += 2;
len -= 2;
}
else
{
dst[uppercaseOffset + 2] ^= unchecked((byte)5);
uppercaseOffset += 3;
len -= 3;
}
}
}
// Copy suffix.
@string = transform.suffix;
tmp = @string.Length;
i = 0;
while (i < tmp)
{
dst[offset++] = @string[i++];
}
return offset - dstOffset;
}
}
}

View File

@@ -0,0 +1,59 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>A set of utility methods.</summary>
internal sealed class Utils
{
private static readonly byte[] ByteZeroes = new byte[1024];
private static readonly int[] IntZeroes = new int[1024];
/// <summary>Fills byte array with zeroes.</summary>
/// <remarks>
/// Fills byte array with zeroes.
/// <p> Current implementation uses
/// <see cref="System.Array.Copy(object, int, object, int, int)"/>
/// , so it should be used for length not
/// less than 16.
/// </remarks>
/// <param name="dest">array to fill with zeroes</param>
/// <param name="offset">the first byte to fill</param>
/// <param name="length">number of bytes to change</param>
internal static void FillWithZeroes(byte[] dest, int offset, int length)
{
int cursor = 0;
while (cursor < length)
{
int step = System.Math.Min(cursor + 1024, length) - cursor;
System.Array.Copy(ByteZeroes, 0, dest, offset + cursor, step);
cursor += step;
}
}
/// <summary>Fills int array with zeroes.</summary>
/// <remarks>
/// Fills int array with zeroes.
/// <p> Current implementation uses
/// <see cref="System.Array.Copy(object, int, object, int, int)"/>
/// , so it should be used for length not
/// less than 16.
/// </remarks>
/// <param name="dest">array to fill with zeroes</param>
/// <param name="offset">the first item to fill</param>
/// <param name="length">number of item to change</param>
internal static void FillWithZeroes(int[] dest, int offset, int length)
{
int cursor = 0;
while (cursor < length)
{
int step = System.Math.Min(cursor + 1024, length) - cursor;
System.Array.Copy(IntZeroes, 0, dest, offset + cursor, step);
cursor += step;
}
}
}
}

View File

@@ -0,0 +1,68 @@
/* Copyright 2015 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
namespace Org.Brotli.Dec
{
/// <summary>Enumeration of all possible word transformations.</summary>
/// <remarks>
/// Enumeration of all possible word transformations.
/// <p>There are two simple types of transforms: omit X first/last symbols, two character-case
/// transforms and the identity transform.
/// </remarks>
internal sealed class WordTransformType
{
internal const int Identity = 0;
internal const int OmitLast1 = 1;
internal const int OmitLast2 = 2;
internal const int OmitLast3 = 3;
internal const int OmitLast4 = 4;
internal const int OmitLast5 = 5;
internal const int OmitLast6 = 6;
internal const int OmitLast7 = 7;
internal const int OmitLast8 = 8;
internal const int OmitLast9 = 9;
internal const int UppercaseFirst = 10;
internal const int UppercaseAll = 11;
internal const int OmitFirst1 = 12;
internal const int OmitFirst2 = 13;
internal const int OmitFirst3 = 14;
internal const int OmitFirst4 = 15;
internal const int OmitFirst5 = 16;
internal const int OmitFirst6 = 17;
internal const int OmitFirst7 = 18;
internal const int OmitFirst8 = 19;
internal const int OmitFirst9 = 20;
internal static int GetOmitFirst(int type)
{
return type >= OmitFirst1 ? (type - OmitFirst1 + 1) : 0;
}
internal static int GetOmitLast(int type)
{
return type <= OmitLast9 ? (type - OmitLast1 + 1) : 0;
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public enum BuildTarget
{
UnknownPlatform = 3716,
DashboardWidget = 1,
StandaloneOSX = 2,
StandaloneOSXPPC = 3,
StandaloneOSXIntel = 4,
StandaloneWindows,
WebPlayer,
WebPlayerStreamed,
Wii = 8,
iOS = 9,
PS3,
XBOX360,
Android = 13,
StandaloneGLESEmu = 14,
NaCl = 16,
StandaloneLinux = 17,
FlashPlayer = 18,
StandaloneWindows64 = 19,
WebGL,
WSAPlayer,
StandaloneLinux64 = 24,
StandaloneLinuxUniversal,
WP8Player,
StandaloneOSXIntel64,
BlackBerry,
Tizen,
PSP2,
PS4,
PSM,
XboxOne,
SamsungTV,
N3DS,
WiiU,
tvOS,
Switch,
NoTarget = -2
}
}

20
AssetStudio/BuildType.cs Normal file
View File

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

246
AssetStudio/BundleFile.cs Normal file
View File

@@ -0,0 +1,246 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Lz4;
namespace AssetStudio
{
public class StreamFile
{
public string fileName;
public Stream stream;
}
public class BlockInfo
{
public uint compressedSize;
public uint uncompressedSize;
public short flag;
}
public class BundleFile
{
private string path;
public string versionPlayer;
public string versionEngine;
public List<StreamFile> fileList = new List<StreamFile>();
public BundleFile(EndianBinaryReader bundleReader, string path)
{
this.path = path;
var signature = bundleReader.ReadStringToNull();
switch (signature)
{
case "UnityWeb":
case "UnityRaw":
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA":
{
var format = bundleReader.ReadInt32();
versionPlayer = bundleReader.ReadStringToNull();
versionEngine = bundleReader.ReadStringToNull();
if (format < 6)
{
int bundleSize = bundleReader.ReadInt32();
}
else if (format == 6)
{
ReadFormat6(bundleReader, true);
return;
}
short dummy2 = bundleReader.ReadInt16();
int offset = bundleReader.ReadInt16();
int dummy3 = bundleReader.ReadInt32();
int lzmaChunks = bundleReader.ReadInt32();
int lzmaSize = 0;
long streamSize = 0;
for (int i = 0; i < lzmaChunks; i++)
{
lzmaSize = bundleReader.ReadInt32();
streamSize = bundleReader.ReadInt32();
}
bundleReader.Position = offset;
switch (signature)
{
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA": //.bytes
case "UnityWeb":
{
var lzmaBuffer = bundleReader.ReadBytes(lzmaSize);
using (var lzmaStream = new EndianBinaryReader(SevenZipHelper.StreamDecompress(new MemoryStream(lzmaBuffer))))
{
GetAssetsFiles(lzmaStream, 0);
}
break;
}
case "UnityRaw":
{
GetAssetsFiles(bundleReader, offset);
break;
}
}
break;
}
case "UnityFS":
{
var format = bundleReader.ReadInt32();
versionPlayer = bundleReader.ReadStringToNull();
versionEngine = bundleReader.ReadStringToNull();
if (format == 6)
{
ReadFormat6(bundleReader);
}
break;
}
}
}
private void GetAssetsFiles(EndianBinaryReader reader, int offset)
{
int fileCount = reader.ReadInt32();
for (int i = 0; i < fileCount; i++)
{
var file = new StreamFile();
file.fileName = Path.GetFileName(reader.ReadStringToNull());
int fileOffset = reader.ReadInt32();
fileOffset += offset;
int fileSize = reader.ReadInt32();
long nextFile = reader.Position;
reader.Position = fileOffset;
var buffer = reader.ReadBytes(fileSize);
file.stream = new MemoryStream(buffer);
fileList.Add(file);
reader.Position = nextFile;
}
}
private void ReadFormat6(EndianBinaryReader bundleReader, bool padding = false)
{
var bundleSize = bundleReader.ReadInt64();
int compressedSize = bundleReader.ReadInt32();
int uncompressedSize = bundleReader.ReadInt32();
int flag = bundleReader.ReadInt32();
if (padding)
bundleReader.ReadByte();
byte[] blocksInfoBytes;
if ((flag & 0x80) != 0)//at end of file
{
var position = bundleReader.Position;
bundleReader.Position = bundleReader.BaseStream.Length - compressedSize;
blocksInfoBytes = bundleReader.ReadBytes(compressedSize);
bundleReader.Position = position;
}
else
{
blocksInfoBytes = bundleReader.ReadBytes(compressedSize);
}
MemoryStream blocksInfoStream;
switch (flag & 0x3F)
{
default://None
{
blocksInfoStream = new MemoryStream(blocksInfoBytes);
break;
}
case 1://LZMA
{
blocksInfoStream = SevenZipHelper.StreamDecompress(new MemoryStream(blocksInfoBytes));
break;
}
case 2://LZ4
case 3://LZ4HC
{
byte[] uncompressedBytes = new byte[uncompressedSize];
using (var decoder = new Lz4DecoderStream(new MemoryStream(blocksInfoBytes)))
{
decoder.Read(uncompressedBytes, 0, uncompressedSize);
}
blocksInfoStream = new MemoryStream(uncompressedBytes);
break;
}
//case 4:LZHAM?
}
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoStream))
{
blocksInfoReader.Position = 0x10;
int blockcount = blocksInfoReader.ReadInt32();
var blockInfos = new BlockInfo[blockcount];
for (int i = 0; i < blockcount; i++)
{
blockInfos[i] = new BlockInfo
{
uncompressedSize = blocksInfoReader.ReadUInt32(),
compressedSize = blocksInfoReader.ReadUInt32(),
flag = blocksInfoReader.ReadInt16()
};
}
Stream dataStream;
var uncompressedSizeSum = blockInfos.Sum(x => x.uncompressedSize);
if (uncompressedSizeSum > int.MaxValue)
{
/*var memoryMappedFile = MemoryMappedFile.CreateNew(Path.GetFileName(path), uncompressedSizeSum);
assetsDataStream = memoryMappedFile.CreateViewStream();*/
dataStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
}
else
{
dataStream = new MemoryStream();
}
foreach (var blockInfo in blockInfos)
{
switch (blockInfo.flag & 0x3F)
{
default://None
{
bundleReader.BaseStream.CopyTo(dataStream, blockInfo.compressedSize);
break;
}
case 1://LZMA
{
SevenZipHelper.StreamDecompress(bundleReader.BaseStream, dataStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
break;
}
case 2://LZ4
case 3://LZ4HC
{
var lz4Stream = new Lz4DecoderStream(bundleReader.BaseStream, blockInfo.compressedSize);
lz4Stream.CopyTo(dataStream, blockInfo.uncompressedSize);
break;
}
//case 4:LZHAM?
}
}
dataStream.Position = 0;
using (dataStream)
{
var entryinfo_count = blocksInfoReader.ReadInt32();
for (int i = 0; i < entryinfo_count; i++)
{
var file = new StreamFile();
var entryinfo_offset = blocksInfoReader.ReadInt64();
var entryinfo_size = blocksInfoReader.ReadInt64();
flag = blocksInfoReader.ReadInt32();
file.fileName = Path.GetFileName(blocksInfoReader.ReadStringToNull());
if (entryinfo_size > int.MaxValue)
{
/*var memoryMappedFile = MemoryMappedFile.CreateNew(file.fileName, entryinfo_size);
file.stream = memoryMappedFile.CreateViewStream();*/
var extractPath = path + "_unpacked\\";
Directory.CreateDirectory(extractPath);
file.stream = File.Create(extractPath + file.fileName);
}
else
{
file.stream = new MemoryStream();
}
dataStream.Position = entryinfo_offset;
dataStream.CopyTo(file.stream, entryinfo_size);
file.stream.Position = 0;
fileList.Add(file);
}
}
}
}
}
}

286
AssetStudio/ClassIDType.cs Normal file
View File

@@ -0,0 +1,286 @@
namespace AssetStudio
{
public enum ClassIDType
{
UnknownType = -1,
Object = 0,
GameObject = 1,
Component = 2,
LevelGameManager = 3,
Transform = 4,
TimeManager = 5,
GlobalGameManager = 6,
Behaviour = 8,
GameManager = 9,
AudioManager = 11,
ParticleAnimator = 12,
InputManager = 13,
EllipsoidParticleEmitter = 15,
Pipeline = 17,
EditorExtension = 18,
Physics2DSettings = 19,
Camera = 20,
Material = 21,
MeshRenderer = 23,
Renderer = 25,
ParticleRenderer = 26,
Texture = 27,
Texture2D = 28,
SceneSettings = 29,
GraphicsSettings = 30,
MeshFilter = 33,
OcclusionPortal = 41,
Mesh = 43,
Skybox = 45,
QualitySettings = 47,
Shader = 48,
TextAsset = 49,
Rigidbody2D = 50,
Physics2DManager = 51,
Collider2D = 53,
Rigidbody = 54,
PhysicsManager = 55,
Collider = 56,
Joint = 57,
CircleCollider2D = 58,
HingeJoint = 59,
PolygonCollider2D = 60,
BoxCollider2D = 61,
PhysicsMaterial2D = 62,
MeshCollider = 64,
BoxCollider = 65,
SpriteCollider2D = 66,
EdgeCollider2D = 68,
CapsuleCollider2D = 70,
ComputeShader = 72,
AnimationClip = 74,
ConstantForce = 75,
WorldParticleCollider = 76,
TagManager = 78,
AudioListener = 81,
AudioSource = 82,
AudioClip = 83,
RenderTexture = 84,
CustomRenderTexture = 86,
MeshParticleEmitter = 87,
ParticleEmitter = 88,
Cubemap = 89,
Avatar = 90,
AnimatorController = 91,
GUILayer = 92,
RuntimeAnimatorController = 93,
ScriptMapper = 94,
Animator = 95,
TrailRenderer = 96,
DelayedCallManager = 98,
TextMesh = 102,
RenderSettings = 104,
Light = 108,
CGProgram = 109,
BaseAnimationTrack = 110,
Animation = 111,
MonoBehaviour = 114,
MonoScript = 115,
MonoManager = 116,
Texture3D = 117,
NewAnimationTrack = 118,
Projector = 119,
LineRenderer = 120,
Flare = 121,
Halo = 122,
LensFlare = 123,
FlareLayer = 124,
HaloLayer = 125,
NavMeshAreas = 126,
HaloManager = 127,
Font = 128,
PlayerSettings = 129,
NamedObject = 130,
GUITexture = 131,
GUIText = 132,
GUIElement = 133,
PhysicMaterial = 134,
SphereCollider = 135,
CapsuleCollider = 136,
SkinnedMeshRenderer = 137,
FixedJoint = 138,
RaycastCollider = 140,
BuildSettings = 141,
AssetBundle = 142,
CharacterController = 143,
CharacterJoint = 144,
SpringJoint = 145,
WheelCollider = 146,
ResourceManager = 147,
NetworkView = 148,
NetworkManager = 149,
PreloadData = 150,
MovieTexture = 152,
ConfigurableJoint = 153,
TerrainCollider = 154,
MasterServerInterface = 155,
TerrainData = 156,
LightmapSettings = 157,
WebCamTexture = 158,
EditorSettings = 159,
InteractiveCloth = 160,
ClothRenderer = 161,
EditorUserSettings = 162,
SkinnedCloth = 163,
AudioReverbFilter = 164,
AudioHighPassFilter = 165,
AudioChorusFilter = 166,
AudioReverbZone = 167,
AudioEchoFilter = 168,
AudioLowPassFilter = 169,
AudioDistortionFilter = 170,
SparseTexture = 171,
AudioBehaviour = 180,
AudioFilter = 181,
WindZone = 182,
Cloth = 183,
SubstanceArchive = 184,
ProceduralMaterial = 185,
ProceduralTexture = 186,
Texture2DArray = 187,
CubemapArray = 188,
OffMeshLink = 191,
OcclusionArea = 192,
Tree = 193,
NavMeshObsolete = 194,
NavMeshAgent = 195,
NavMeshSettings = 196,
LightProbesLegacy = 197,
ParticleSystem = 198,
ParticleSystemRenderer = 199,
ShaderVariantCollection = 200,
LODGroup = 205,
BlendTree = 206,
Motion = 207,
NavMeshObstacle = 208,
TerrainInstance = 210,
SpriteRenderer = 212,
Sprite = 213,
CachedSpriteAtlas = 214,
ReflectionProbe = 215,
ReflectionProbes = 216,
Terrain = 218,
LightProbeGroup = 220,
AnimatorOverrideController = 221,
CanvasRenderer = 222,
Canvas = 223,
RectTransform = 224,
CanvasGroup = 225,
BillboardAsset = 226,
BillboardRenderer = 227,
SpeedTreeWindAsset = 228,
AnchoredJoint2D = 229,
Joint2D = 230,
SpringJoint2D = 231,
DistanceJoint2D = 232,
HingeJoint2D = 233,
SliderJoint2D = 234,
WheelJoint2D = 235,
ClusterInputManager = 236,
BaseVideoTexture = 237,
NavMeshData = 238,
AudioMixer = 240,
AudioMixerController = 241,
AudioMixerGroupController = 243,
AudioMixerEffectController = 244,
AudioMixerSnapshotController = 245,
PhysicsUpdateBehaviour2D = 246,
ConstantForce2D = 247,
Effector2D = 248,
AreaEffector2D = 249,
PointEffector2D = 250,
PlatformEffector2D = 251,
SurfaceEffector2D = 252,
BuoyancyEffector2D = 253,
RelativeJoint2D = 254,
FixedJoint2D = 255,
FrictionJoint2D = 256,
TargetJoint2D = 257,
LightProbes = 258,
LightProbeProxyVolume = 259,
SampleClip = 271,
AudioMixerSnapshot = 272,
AudioMixerGroup = 273,
NScreenBridge = 280,
AssetBundleManifest = 290,
UnityAdsManager = 292,
RuntimeInitializeOnLoadManager = 300,
CloudWebServicesManager = 301,
UnityAnalyticsManager = 303,
CrashReportManager = 304,
PerformanceReportingManager = 305,
UnityConnectSettings = 310,
AvatarMask = 319,
VideoPlayer = 328,
VideoClip = 329,
OcclusionCullingData = 363,
//kLargestRuntimeClassID = 364
SmallestEditorClassID = 1000,
Prefab = 1001,
EditorExtensionImpl = 1002,
AssetImporter = 1003,
AssetDatabase = 1004,
Mesh3DSImporter = 1005,
TextureImporter = 1006,
ShaderImporter = 1007,
ComputeShaderImporter = 1008,
AudioImporter = 1020,
HierarchyState = 1026,
GUIDSerializer = 1027,
AssetMetaData = 1028,
DefaultAsset = 1029,
DefaultImporter = 1030,
TextScriptImporter = 1031,
SceneAsset = 1032,
NativeFormatImporter = 1034,
MonoImporter = 1035,
AssetServerCache = 1037,
LibraryAssetImporter = 1038,
ModelImporter = 1040,
FBXImporter = 1041,
TrueTypeFontImporter = 1042,
MovieImporter = 1044,
EditorBuildSettings = 1045,
DDSImporter = 1046,
InspectorExpandedState = 1048,
AnnotationManager = 1049,
PluginImporter = 1050,
EditorUserBuildSettings = 1051,
PVRImporter = 1052,
ASTCImporter = 1053,
KTXImporter = 1054,
IHVImageFormatImporter = 1055,
AnimatorStateTransition = 1101,
AnimatorState = 1102,
HumanTemplate = 1105,
AnimatorStateMachine = 1107,
PreviewAssetType = 1108,
AnimatorTransition = 1109,
SpeedTreeImporter = 1110,
AnimatorTransitionBase = 1111,
SubstanceImporter = 1112,
LightmapParameters = 1113,
LightmapSnapshot = 1120,
GISRaster = 1121,
GISRasterImporter = 1122,
CadImporter = 1123,
SketchUpImporter = 1124,
BuildReport = 1125,
PackedAssets = 1126,
VideoClipImporter = 1127,
ActivationLogComponent = 2000,
//kLargestEditorClassID = 2001
//kClassIdOutOfHierarchy = 100000
SubDerived = 367388927,
SiblingDerived = 334799969,
SpriteAtlas = 687078895,
Derived = 1091556383,
LowerResBlitTexture = 1480428607,
RenderPassAttachment = 1571458007
}
}

View File

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

View File

@@ -0,0 +1,973 @@
using System;
using System.Collections.Generic;
using System.IO;
using SharpDX;
namespace AssetStudio
{
public class Keyframe<T>
{
public float time;
public T value;
public T inSlope;
public T outSlope;
public int weightedMode;
public T inWeight;
public T outWeight;
public Keyframe(ObjectReader reader, Func<T> readerFunc)
{
time = reader.ReadSingle();
value = readerFunc();
inSlope = readerFunc();
outSlope = readerFunc();
if (reader.version[0] >= 2018)
{
weightedMode = reader.ReadInt32();
inWeight = readerFunc();
outWeight = readerFunc();
}
}
}
public class AnimationCurve<T>
{
public List<Keyframe<T>> m_Curve;
public int m_PreInfinity;
public int m_PostInfinity;
public int m_RotationOrder;
public AnimationCurve(ObjectReader reader, Func<T> readerFunc)
{
var version = reader.version;
int numCurves = reader.ReadInt32();
m_Curve = new List<Keyframe<T>>(numCurves);
for (int i = 0; i < numCurves; i++)
{
m_Curve.Add(new Keyframe<T>(reader, readerFunc));
}
m_PreInfinity = reader.ReadInt32();
m_PostInfinity = reader.ReadInt32();
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3))//5.3 and up
{
m_RotationOrder = reader.ReadInt32();
}
}
}
public class QuaternionCurve
{
public AnimationCurve<Quaternion> curve;
public string path;
public QuaternionCurve(ObjectReader reader)
{
curve = new AnimationCurve<Quaternion>(reader, reader.ReadQuaternion);
path = reader.ReadAlignedString();
}
}
public class PackedFloatVector
{
public uint m_NumItems;
public float m_Range;
public float m_Start;
public byte[] m_Data;
public byte m_BitSize;
public PackedFloatVector(ObjectReader reader)
{
m_NumItems = reader.ReadUInt32();
m_Range = reader.ReadSingle();
m_Start = reader.ReadSingle();
int numData = reader.ReadInt32();
m_Data = reader.ReadBytes(numData);
reader.AlignStream(4);
m_BitSize = reader.ReadByte();
reader.AlignStream(4);
}
public float[] UnpackFloats(int itemCountInChunk, int chunkStride, int start = 0, int numChunks = -1)
{
int bitPos = m_BitSize * start;
int indexPos = bitPos / 8;
bitPos %= 8;
float scale = 1.0f / m_Range;
if (numChunks == -1)
numChunks = (int)m_NumItems / itemCountInChunk;
var end = chunkStride * numChunks / 4;
var data = new List<float>();
for (var index = 0; index != end; index += chunkStride / 4)
{
for (int i = 0; i < itemCountInChunk; ++i)
{
uint x = 0;
int bits = 0;
while (bits < m_BitSize)
{
x |= (uint)((m_Data[indexPos] >> bitPos) << bits);
int num = Math.Min(m_BitSize - bits, 8 - bitPos);
bitPos += num;
bits += num;
if (bitPos == 8)
{
indexPos++;
bitPos = 0;
}
}
x &= (uint)(1 << m_BitSize) - 1u;
data.Add(x / (scale * ((1 << m_BitSize) - 1)) + m_Start);
}
}
return data.ToArray();
}
}
public class PackedIntVector
{
public uint m_NumItems;
public byte[] m_Data;
public byte m_BitSize;
public PackedIntVector(ObjectReader reader)
{
m_NumItems = reader.ReadUInt32();
int numData = reader.ReadInt32();
m_Data = reader.ReadBytes(numData);
reader.AlignStream(4);
m_BitSize = reader.ReadByte();
reader.AlignStream(4);
}
public int[] UnpackInts()
{
var data = new int[m_NumItems];
int indexPos = 0;
int bitPos = 0;
for (int i = 0; i < m_NumItems; i++)
{
int bits = 0;
data[i] = 0;
while (bits < m_BitSize)
{
data[i] |= (m_Data[indexPos] >> bitPos) << bits;
int num = Math.Min(m_BitSize - bits, 8 - bitPos);
bitPos += num;
bits += num;
if (bitPos == 8)
{
indexPos++;
bitPos = 0;
}
}
data[i] &= (1 << m_BitSize) - 1;
}
return data;
}
}
public class PackedQuatVector
{
public uint m_NumItems;
public byte[] m_Data;
public PackedQuatVector(ObjectReader reader)
{
m_NumItems = reader.ReadUInt32();
int numData = reader.ReadInt32();
m_Data = reader.ReadBytes(numData);
reader.AlignStream(4);
}
public Quaternion[] UnpackQuats()
{
var data = new Quaternion[m_NumItems];
int indexPos = 0;
int bitPos = 0;
for (int i = 0; i < m_NumItems; i++)
{
uint flags = 0;
int bits = 0;
while (bits < 3)
{
flags |= (uint)((m_Data[indexPos] >> bitPos) << bits);
int num = Math.Min(3 - bits, 8 - bitPos);
bitPos += num;
bits += num;
if (bitPos == 8)
{
indexPos++;
bitPos = 0;
}
}
flags &= 7;
var q = new Quaternion();
float sum = 0;
for (int j = 0; j < 4; j++)
{
if ((flags & 3) != j)
{
int bitSize = ((flags & 3) + 1) % 4 == j ? 9 : 10;
uint x = 0;
bits = 0;
while (bits < bitSize)
{
x |= (uint)((m_Data[indexPos] >> bitPos) << bits);
int num = Math.Min(bitSize - bits, 8 - bitPos);
bitPos += num;
bits += num;
if (bitPos == 8)
{
indexPos++;
bitPos = 0;
}
}
x &= (uint)((1 << bitSize) - 1);
q[j] = x / (0.5f * ((1 << bitSize) - 1)) - 1;
sum += q[j] * q[j];
}
}
int lastComponent = (int)(flags & 3);
q[lastComponent] = (float)Math.Sqrt(1 - sum);
if ((flags & 4) != 0u)
q[lastComponent] = -q[lastComponent];
data[i] = q;
}
return data;
}
}
public class CompressedAnimationCurve
{
public string m_Path;
public PackedIntVector m_Times;
public PackedQuatVector m_Values;
public PackedFloatVector m_Slopes;
public int m_PreInfinity;
public int m_PostInfinity;
public CompressedAnimationCurve(ObjectReader reader)
{
m_Path = reader.ReadAlignedString();
m_Times = new PackedIntVector(reader);
m_Values = new PackedQuatVector(reader);
m_Slopes = new PackedFloatVector(reader);
m_PreInfinity = reader.ReadInt32();
m_PostInfinity = reader.ReadInt32();
}
}
public class Vector3Curve
{
public AnimationCurve<Vector3> curve;
public string path;
public Vector3Curve(ObjectReader reader)
{
curve = new AnimationCurve<Vector3>(reader, reader.ReadVector3);
path = reader.ReadAlignedString();
}
}
public class FloatCurve
{
public AnimationCurve<float> curve;
public string attribute;
public string path;
public int classID;
public PPtr script;
public FloatCurve(ObjectReader reader)
{
curve = new AnimationCurve<float>(reader, reader.ReadSingle);
attribute = reader.ReadAlignedString();
path = reader.ReadAlignedString();
classID = reader.ReadInt32();
script = reader.ReadPPtr();
}
}
public class PPtrKeyframe
{
public float time;
public PPtr value;
public PPtrKeyframe(ObjectReader reader)
{
time = reader.ReadSingle();
value = reader.ReadPPtr();
}
}
public class PPtrCurve
{
public List<PPtrKeyframe> curve;
public string attribute;
public string path;
public int classID;
public PPtr script;
public PPtrCurve(ObjectReader reader)
{
int numCurves = reader.ReadInt32();
curve = new List<PPtrKeyframe>(numCurves);
for (int i = 0; i < numCurves; i++)
{
curve.Add(new PPtrKeyframe(reader));
}
attribute = reader.ReadAlignedString();
path = reader.ReadAlignedString();
classID = reader.ReadInt32();
script = reader.ReadPPtr();
}
}
public class AABB
{
public Vector3 m_Center;
public Vector3 m_Extend;
public AABB(ObjectReader reader)
{
m_Center = reader.ReadVector3();
m_Extend = reader.ReadVector3();
}
}
public class xform
{
public object t;
public Quaternion q;
public object s;
public xform(ObjectReader reader)
{
var version = reader.version;
t = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up
q = reader.ReadQuaternion();
s = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up
}
}
public class HandPose
{
public xform m_GrabX;
public float[] m_DoFArray;
public float m_Override;
public float m_CloseOpen;
public float m_InOut;
public float m_Grab;
public HandPose(ObjectReader reader)
{
m_GrabX = new xform(reader);
int numDoFs = reader.ReadInt32();
m_DoFArray = reader.ReadSingleArray(numDoFs);
m_Override = reader.ReadSingle();
m_CloseOpen = reader.ReadSingle();
m_InOut = reader.ReadSingle();
m_Grab = reader.ReadSingle();
}
}
public class HumanGoal
{
public xform m_X;
public float m_WeightT;
public float m_WeightR;
public object m_HintT;
public float m_HintWeightT;
public HumanGoal(ObjectReader reader)
{
var version = reader.version;
m_X = new xform(reader);
m_WeightT = reader.ReadSingle();
m_WeightR = reader.ReadSingle();
if (version[0] >= 5)//5.0 and up
{
m_HintT = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up
m_HintWeightT = reader.ReadSingle();
}
}
}
public class HumanPose
{
public xform m_RootX;
public object m_LookAtPosition;
public Vector4 m_LookAtWeight;
public List<HumanGoal> m_GoalArray;
public HandPose m_LeftHandPose;
public HandPose m_RightHandPose;
public float[] m_DoFArray;
public object[] m_TDoFArray;
public HumanPose(ObjectReader reader)
{
var version = reader.version;
m_RootX = new xform(reader);
m_LookAtPosition = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up
m_LookAtWeight = reader.ReadVector4();
int numGoals = reader.ReadInt32();
m_GoalArray = new List<HumanGoal>(numGoals);
for (int i = 0; i < numGoals; i++)
{
m_GoalArray.Add(new HumanGoal(reader));
}
m_LeftHandPose = new HandPose(reader);
m_RightHandPose = new HandPose(reader);
int numDoFs = reader.ReadInt32();
m_DoFArray = reader.ReadSingleArray(numDoFs);
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2))//5.2 and up
{
int numTDof = reader.ReadInt32();
m_TDoFArray = new object[numTDof];
for (int i = 0; i < numTDof; i++)
{
m_TDoFArray[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up
}
}
}
}
public class StreamedClip
{
public uint[] data;
public uint curveCount;
public StreamedClip(ObjectReader reader)
{
int numData = reader.ReadInt32();
data = reader.ReadUInt32Array(numData);
curveCount = reader.ReadUInt32();
}
public class StreamedCurveKey
{
public int index;
public float[] coeff;
public float value;
public float outSlope;
public float inSlope;
public StreamedCurveKey(BinaryReader reader)
{
index = reader.ReadInt32();
coeff = reader.ReadSingleArray(4);
outSlope = coeff[2];
value = coeff[3];
}
public float CalculateNextInSlope(float dx, StreamedCurveKey rhs)
{
//Stepped
if (coeff[0] == 0f && coeff[1] == 0f && coeff[2] == 0f)
{
return float.PositiveInfinity;
}
dx = Math.Max(dx, 0.0001f);
var dy = rhs.value - value;
var length = 1.0f / (dx * dx);
var d1 = outSlope * dx;
var d2 = dy + dy + dy - d1 - d1 - coeff[1] / length;
return d2 / dx;
}
}
public class StreamedFrame
{
public float time;
public List<StreamedCurveKey> keyList;
public StreamedFrame(BinaryReader reader)
{
time = reader.ReadSingle();
int numKeys = reader.ReadInt32();
keyList = new List<StreamedCurveKey>(numKeys);
for (int i = 0; i < numKeys; i++)
{
keyList.Add(new StreamedCurveKey(reader));
}
}
}
public List<StreamedFrame> ReadData()
{
var frameList = new List<StreamedFrame>();
using (Stream stream = new MemoryStream())
{
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(data);
stream.Position = 0;
while (stream.Position < stream.Length)
{
frameList.Add(new StreamedFrame(new BinaryReader(stream)));
}
}
for (int frameIndex = 2; frameIndex < frameList.Count - 1; frameIndex++)
{
var frame = frameList[frameIndex];
foreach (var curveKey in frame.keyList)
{
for (int i = frameIndex - 1; i >= 0; i--)
{
var preFrame = frameList[i];
var preCurveKey = preFrame.keyList.Find(x => x.index == curveKey.index);
if (preCurveKey != null)
{
curveKey.inSlope = preCurveKey.CalculateNextInSlope(frame.time - preFrame.time, curveKey);
break;
}
}
}
}
return frameList;
}
}
public class DenseClip
{
public int m_FrameCount;
public uint m_CurveCount;
public float m_SampleRate;
public float m_BeginTime;
public float[] m_SampleArray;
public DenseClip(ObjectReader reader)
{
m_FrameCount = reader.ReadInt32();
m_CurveCount = reader.ReadUInt32();
m_SampleRate = reader.ReadSingle();
m_BeginTime = reader.ReadSingle();
int numSamples = reader.ReadInt32();
m_SampleArray = reader.ReadSingleArray(numSamples);
}
}
public class ConstantClip
{
public float[] data;
public ConstantClip(ObjectReader reader)
{
int numData = reader.ReadInt32();
data = reader.ReadSingleArray(numData);
}
}
public class ValueConstant
{
public uint m_ID;
public uint m_TypeID;
public uint m_Type;
public uint m_Index;
public ValueConstant(ObjectReader reader)
{
var version = reader.version;
m_ID = reader.ReadUInt32();
if (version[0] < 5 || (version[0] == 5 && version[1] < 5))//5.5 down
{
m_TypeID = reader.ReadUInt32();
}
m_Type = reader.ReadUInt32();
m_Index = reader.ReadUInt32();
}
}
public class ValueArrayConstant
{
public List<ValueConstant> m_ValueArray;
public ValueArrayConstant(ObjectReader reader)
{
int numVals = reader.ReadInt32();
m_ValueArray = new List<ValueConstant>(numVals);
for (int i = 0; i < numVals; i++)
{
m_ValueArray.Add(new ValueConstant(reader));
}
}
}
public class Clip
{
public StreamedClip m_StreamedClip;
public DenseClip m_DenseClip;
public ConstantClip m_ConstantClip;
public ValueArrayConstant m_Binding;
public Clip(ObjectReader reader)
{
var version = reader.version;
m_StreamedClip = new StreamedClip(reader);
m_DenseClip = new DenseClip(reader);
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_ConstantClip = new ConstantClip(reader);
}
m_Binding = new ValueArrayConstant(reader);
}
}
public class ValueDelta
{
public float m_Start;
public float m_Stop;
public ValueDelta(ObjectReader reader)
{
m_Start = reader.ReadSingle();
m_Stop = reader.ReadSingle();
}
}
public class ClipMuscleConstant
{
public HumanPose m_DeltaPose;
public xform m_StartX;
public xform m_StopX;
public xform m_LeftFootStartX;
public xform m_RightFootStartX;
public xform m_MotionStartX;
public xform m_MotionStopX;
public object m_AverageSpeed;
public Clip m_Clip;
public float m_StartTime;
public float m_StopTime;
public float m_OrientationOffsetY;
public float m_Level;
public float m_CycleOffset;
public float m_AverageAngularSpeed;
public int[] m_IndexArray;
public List<ValueDelta> m_ValueArrayDelta;
public float[] m_ValueArrayReferencePose;
public bool m_Mirror;
public bool m_LoopTime;
public bool m_LoopBlend;
public bool m_LoopBlendOrientation;
public bool m_LoopBlendPositionY;
public bool m_LoopBlendPositionXZ;
public bool m_StartAtOrigin;
public bool m_KeepOriginalOrientation;
public bool m_KeepOriginalPositionY;
public bool m_KeepOriginalPositionXZ;
public bool m_HeightFromFeet;
public ClipMuscleConstant(ObjectReader reader)
{
var version = reader.version;
m_DeltaPose = new HumanPose(reader);
m_StartX = new xform(reader);
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5))//5.5 and up
{
m_StopX = new xform(reader);
}
m_LeftFootStartX = new xform(reader);
m_RightFootStartX = new xform(reader);
if (version[0] < 5)//5.0 down
{
m_MotionStartX = new xform(reader);
m_MotionStopX = new xform(reader);
}
m_AverageSpeed = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4();//5.4 and up
m_Clip = new Clip(reader);
m_StartTime = reader.ReadSingle();
m_StopTime = reader.ReadSingle();
m_OrientationOffsetY = reader.ReadSingle();
m_Level = reader.ReadSingle();
m_CycleOffset = reader.ReadSingle();
m_AverageAngularSpeed = reader.ReadSingle();
int numIndices = reader.ReadInt32();
m_IndexArray = reader.ReadInt32Array(numIndices);
if (version[0] < 4 || (version[0] == 4 && version[1] < 3)) //4.3 down
{
int numAdditionalCurveIndexs = reader.ReadInt32();
var m_AdditionalCurveIndexArray = new List<int>(numAdditionalCurveIndexs);
for (int i = 0; i < numAdditionalCurveIndexs; i++)
{
m_AdditionalCurveIndexArray.Add(reader.ReadInt32());
}
}
int numDeltas = reader.ReadInt32();
m_ValueArrayDelta = new List<ValueDelta>(numDeltas);
for (int i = 0; i < numDeltas; i++)
{
m_ValueArrayDelta.Add(new ValueDelta(reader));
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3))//5.3 and up
{
m_ValueArrayReferencePose = reader.ReadSingleArray(reader.ReadInt32());
}
m_Mirror = reader.ReadBoolean();
m_LoopTime = reader.ReadBoolean();
m_LoopBlend = reader.ReadBoolean();
m_LoopBlendOrientation = reader.ReadBoolean();
m_LoopBlendPositionY = reader.ReadBoolean();
m_LoopBlendPositionXZ = reader.ReadBoolean();
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5))//5.5 and up
{
m_StartAtOrigin = reader.ReadBoolean();
}
m_KeepOriginalOrientation = reader.ReadBoolean();
m_KeepOriginalPositionY = reader.ReadBoolean();
m_KeepOriginalPositionXZ = reader.ReadBoolean();
m_HeightFromFeet = reader.ReadBoolean();
reader.AlignStream(4);
}
}
public class GenericBinding
{
public uint path;
public uint attribute;
public PPtr script;
public ClassIDType typeID;
public byte customType;
public byte isPPtrCurve;
public GenericBinding(ObjectReader reader)
{
var version = reader.version;
path = reader.ReadUInt32();
attribute = reader.ReadUInt32();
script = reader.ReadPPtr();
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
typeID = (ClassIDType)reader.ReadInt32();
}
else
{
typeID = (ClassIDType)reader.ReadUInt16();
}
customType = reader.ReadByte();
isPPtrCurve = reader.ReadByte();
reader.AlignStream(4);
}
}
public class AnimationClipBindingConstant
{
public List<GenericBinding> genericBindings;
public List<PPtr> pptrCurveMapping;
public AnimationClipBindingConstant(ObjectReader reader)
{
int numBindings = reader.ReadInt32();
genericBindings = new List<GenericBinding>(numBindings);
for (int i = 0; i < numBindings; i++)
{
genericBindings.Add(new GenericBinding(reader));
}
int numMappings = reader.ReadInt32();
pptrCurveMapping = new List<PPtr>(numMappings);
for (int i = 0; i < numMappings; i++)
{
pptrCurveMapping.Add(reader.ReadPPtr());
}
}
public GenericBinding FindBinding(int index)
{
int curves = 0;
foreach (var b in genericBindings)
{
if (b.typeID == ClassIDType.Transform)
{
switch (b.attribute)
{
case 1: //kBindTransformPosition
case 3: //kBindTransformScale
case 4: //kBindTransformEuler
curves += 3;
break;
case 2: //kBindTransformRotation
curves += 4;
break;
default:
curves += 1;
break;
}
}
else
{
curves += 1;
}
if (curves > index)
{
return b;
}
}
return null;
}
}
public enum AnimationType
{
kLegacy = 1,
kGeneric = 2,
kHumanoid = 3
};
public sealed class AnimationClip : NamedObject
{
public AnimationType m_AnimationType;
public bool m_Legacy;
public bool m_Compressed;
public bool m_UseHighQualityCurve;
public List<QuaternionCurve> m_RotationCurves;
public List<CompressedAnimationCurve> m_CompressedRotationCurves;
public List<Vector3Curve> m_EulerCurves;
public List<Vector3Curve> m_PositionCurves;
public List<Vector3Curve> m_ScaleCurves;
public List<FloatCurve> m_FloatCurves;
public List<PPtrCurve> m_PPtrCurves;
public float m_SampleRate;
public int m_WrapMode;
public AABB m_Bounds;
public uint m_MuscleClipSize;
public ClipMuscleConstant m_MuscleClip;
public AnimationClipBindingConstant m_ClipBindingConstant;
//public List<AnimationEvent> m_Events;
public AnimationClip(ObjectReader reader) : base(reader)
{
if (version[0] >= 5)//5.0 and up
{
m_Legacy = reader.ReadBoolean();
}
else if (version[0] >= 4)//4.0 and up
{
m_AnimationType = (AnimationType)reader.ReadInt32();
if (m_AnimationType == AnimationType.kLegacy)
m_Legacy = true;
}
else
{
m_Legacy = true;
}
m_Compressed = reader.ReadBoolean();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3))//4.3 and up
{
m_UseHighQualityCurve = reader.ReadBoolean();
}
reader.AlignStream(4);
int numRCurves = reader.ReadInt32();
m_RotationCurves = new List<QuaternionCurve>(numRCurves);
for (int i = 0; i < numRCurves; i++)
{
m_RotationCurves.Add(new QuaternionCurve(reader));
}
int numCRCurves = reader.ReadInt32();
m_CompressedRotationCurves = new List<CompressedAnimationCurve>(numCRCurves);
for (int i = 0; i < numCRCurves; i++)
{
m_CompressedRotationCurves.Add(new CompressedAnimationCurve(reader));
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3))//5.3 and up
{
int numEulerCurves = reader.ReadInt32();
m_EulerCurves = new List<Vector3Curve>(numEulerCurves);
for (int i = 0; i < numEulerCurves; i++)
{
m_EulerCurves.Add(new Vector3Curve(reader));
}
}
int numPCurves = reader.ReadInt32();
m_PositionCurves = new List<Vector3Curve>(numPCurves);
for (int i = 0; i < numPCurves; i++)
{
m_PositionCurves.Add(new Vector3Curve(reader));
}
int numSCurves = reader.ReadInt32();
m_ScaleCurves = new List<Vector3Curve>(numSCurves);
for (int i = 0; i < numSCurves; i++)
{
m_ScaleCurves.Add(new Vector3Curve(reader));
}
int numFCurves = reader.ReadInt32();
m_FloatCurves = new List<FloatCurve>(numFCurves);
for (int i = 0; i < numFCurves; i++)
{
m_FloatCurves.Add(new FloatCurve(reader));
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
int numPtrCurves = reader.ReadInt32();
m_PPtrCurves = new List<PPtrCurve>(numPtrCurves);
for (int i = 0; i < numPtrCurves; i++)
{
m_PPtrCurves.Add(new PPtrCurve(reader));
}
}
m_SampleRate = reader.ReadSingle();
m_WrapMode = reader.ReadInt32();
if (version[0] > 3 || (version[0] == 3 && version[1] >= 4)) //3.4 and up
{
m_Bounds = new AABB(reader);
}
if (version[0] >= 4)//4.0 and up
{
m_MuscleClipSize = reader.ReadUInt32();
m_MuscleClip = new ClipMuscleConstant(reader);
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_ClipBindingConstant = new AnimationClipBindingConstant(reader);
}
/*int numEvents = reader.ReadInt32();
m_Events = new List<AnimationEvent>(numEvents);
for (int i = 0; i < numEvents; i++)
{
m_Events.Add(new AnimationEvent(stream, file.Version[0] - '0'));
}*/
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class Animator : Behaviour
{
public PPtr m_Avatar;
public PPtr m_Controller;
public bool m_HasTransformHierarchy;
public Animator(ObjectReader reader) : base(reader)
{
m_Avatar = reader.ReadPPtr();
m_Controller = reader.ReadPPtr();
var m_CullingMode = reader.ReadInt32();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
var m_UpdateMode = reader.ReadInt32();
}
var m_ApplyRootMotion = reader.ReadBoolean();
if (version[0] == 4 && version[1] >= 5) //4.5 and up - 5.0 down
{
reader.AlignStream(4);
}
if (version[0] >= 5) //5.0 and up
{
var m_LinearVelocityBlending = reader.ReadBoolean();
reader.AlignStream(4);
}
if (version[0] < 4 || (version[0] == 4 && version[1] < 5)) //4.5 down
{
var m_AnimatePhysics = reader.ReadBoolean();
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_HasTransformHierarchy = reader.ReadBoolean();
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
var m_AllowConstantClipSamplingOptimization = reader.ReadBoolean();
}
if (version[0] >= 5 && version[0] < 2018) //5.0 and up - 2018 down
{
reader.AlignStream(4);
}
if (version[0] >= 2018) //2018 and up
{
var m_KeepAnimatorControllerStateOnDisable = reader.ReadBoolean();
reader.AlignStream(4);
}
}
}
}

View File

@@ -0,0 +1,558 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpDX;
namespace AssetStudio
{
public class HumanPoseMask
{
public uint word0;
public uint word1;
public uint word2;
public HumanPoseMask(ObjectReader reader)
{
word0 = reader.ReadUInt32();
word1 = reader.ReadUInt32();
if (reader.version[0] >= 5) //5.0 and up
{
word2 = reader.ReadUInt32();
}
}
}
public class SkeletonMaskElement
{
public uint m_PathHash;
public float m_Weight;
public SkeletonMaskElement(ObjectReader reader)
{
m_PathHash = reader.ReadUInt32();
m_Weight = reader.ReadSingle();
}
}
public class SkeletonMask
{
public 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[i] = new SkeletonMaskElement(reader);
}
}
}
public class LayerConstant
{
public uint m_StateMachineIndex;
public uint m_StateMachineMotionSetIndex;
public HumanPoseMask m_BodyMask;
public SkeletonMask m_SkeletonMask;
public uint m_Binding;
public int m_LayerBlendingMode;
public float m_DefaultWeight;
public bool m_IKPass;
public bool m_SyncedLayerAffectsTiming;
public LayerConstant(ObjectReader reader)
{
m_StateMachineIndex = reader.ReadUInt32();
m_StateMachineMotionSetIndex = reader.ReadUInt32();
m_BodyMask = new HumanPoseMask(reader);
m_SkeletonMask = new SkeletonMask(reader);
m_Binding = reader.ReadUInt32();
m_LayerBlendingMode = reader.ReadInt32();
m_DefaultWeight = reader.ReadSingle();
m_IKPass = reader.ReadBoolean();
m_SyncedLayerAffectsTiming = reader.ReadBoolean();
reader.AlignStream(4);
}
}
public class ConditionConstant
{
public uint m_ConditionMode;
public uint m_EventID;
public float m_EventThreshold;
public float m_ExitTime;
public ConditionConstant(ObjectReader reader)
{
m_ConditionMode = reader.ReadUInt32();
m_EventID = reader.ReadUInt32();
m_EventThreshold = reader.ReadSingle();
m_ExitTime = reader.ReadSingle();
}
}
public class TransitionConstant
{
public ConditionConstant[] m_ConditionConstantArray;
public uint m_DestinationState;
public uint m_FullPathID;
public uint m_ID;
public uint m_UserID;
public float m_TransitionDuration;
public float m_TransitionOffset;
public float m_ExitTime;
public bool m_HasExitTime;
public bool m_HasFixedDuration;
public int m_InterruptionSource;
public bool m_OrderedInterruption;
public bool m_Atomic;
public bool m_CanTransitionToSelf;
public TransitionConstant(ObjectReader reader)
{
var version = reader.version;
int numConditions = reader.ReadInt32();
m_ConditionConstantArray = new ConditionConstant[numConditions];
for (int i = 0; i < numConditions; i++)
{
m_ConditionConstantArray[i] = new ConditionConstant(reader);
}
m_DestinationState = reader.ReadUInt32();
if (version[0] >= 5) //5.0 and up
{
m_FullPathID = reader.ReadUInt32();
}
m_ID = reader.ReadUInt32();
m_UserID = reader.ReadUInt32();
m_TransitionDuration = reader.ReadSingle();
m_TransitionOffset = reader.ReadSingle();
if (version[0] >= 5) //5.0 and up
{
m_ExitTime = reader.ReadSingle();
m_HasExitTime = reader.ReadBoolean();
m_HasFixedDuration = reader.ReadBoolean();
reader.AlignStream(4);
m_InterruptionSource = reader.ReadInt32();
m_OrderedInterruption = reader.ReadBoolean();
}
else
{
m_Atomic = reader.ReadBoolean();
}
m_CanTransitionToSelf = reader.ReadBoolean();
reader.AlignStream(4);
}
}
public class LeafInfoConstant
{
public uint[] m_IDArray;
public uint m_IndexOffset;
public LeafInfoConstant(ObjectReader reader)
{
m_IDArray = reader.ReadUInt32Array(reader.ReadInt32());
m_IndexOffset = reader.ReadUInt32();
}
}
public class MotionNeighborList
{
public uint[] m_NeighborArray;
public MotionNeighborList(ObjectReader reader)
{
m_NeighborArray = reader.ReadUInt32Array(reader.ReadInt32());
}
}
public class Blend2dDataConstant
{
public Vector2[] m_ChildPositionArray;
public float[] m_ChildMagnitudeArray;
public Vector2[] m_ChildPairVectorArray;
public float[] m_ChildPairAvgMagInvArray;
public MotionNeighborList[] m_ChildNeighborListArray;
public Blend2dDataConstant(ObjectReader reader)
{
m_ChildPositionArray = reader.ReadVector2Array(reader.ReadInt32());
m_ChildMagnitudeArray = reader.ReadSingleArray(reader.ReadInt32());
m_ChildPairVectorArray = reader.ReadVector2Array(reader.ReadInt32());
m_ChildPairAvgMagInvArray = reader.ReadSingleArray(reader.ReadInt32());
int numNeighbours = reader.ReadInt32();
m_ChildNeighborListArray = new MotionNeighborList[numNeighbours];
for (int i = 0; i < numNeighbours; i++)
{
m_ChildNeighborListArray[i] = new MotionNeighborList(reader);
}
}
}
public class Blend1dDataConstant // wrong labeled
{
public float[] m_ChildThresholdArray;
public Blend1dDataConstant(ObjectReader reader)
{
m_ChildThresholdArray = reader.ReadSingleArray(reader.ReadInt32());
}
}
public class BlendDirectDataConstant
{
public uint[] m_ChildBlendEventIDArray;
public bool m_NormalizedBlendValues;
public BlendDirectDataConstant(ObjectReader reader)
{
m_ChildBlendEventIDArray = reader.ReadUInt32Array(reader.ReadInt32());
m_NormalizedBlendValues = reader.ReadBoolean();
reader.AlignStream(4);
}
}
public class BlendTreeNodeConstant
{
public uint m_BlendType;
public uint m_BlendEventID;
public uint m_BlendEventYID;
public uint[] m_ChildIndices;
public Blend1dDataConstant m_Blend1dData;
public Blend2dDataConstant m_Blend2dData;
public BlendDirectDataConstant m_BlendDirectData;
public uint m_ClipID;
public uint m_ClipIndex;
public float m_Duration;
public float m_CycleOffset;
public bool m_Mirror;
public BlendTreeNodeConstant(ObjectReader reader)
{
var version = reader.version;
m_BlendType = reader.ReadUInt32();
m_BlendEventID = reader.ReadUInt32();
m_BlendEventYID = reader.ReadUInt32();
m_ChildIndices = reader.ReadUInt32Array(reader.ReadInt32());
m_Blend1dData = new Blend1dDataConstant(reader);
m_Blend2dData = new Blend2dDataConstant(reader);
if (version[0] >= 5) //5.0 and up
{
m_BlendDirectData = new BlendDirectDataConstant(reader);
}
m_ClipID = reader.ReadUInt32();
if (version[0] < 5) //5.0 down
{
m_ClipIndex = reader.ReadUInt32();
}
m_Duration = reader.ReadSingle();
m_CycleOffset = reader.ReadSingle();
m_Mirror = reader.ReadBoolean();
reader.AlignStream(4);
}
}
public class BlendTreeConstant
{
public BlendTreeNodeConstant[] m_NodeArray;
public BlendTreeConstant(ObjectReader reader)
{
int numNodes = reader.ReadInt32();
m_NodeArray = new BlendTreeNodeConstant[numNodes];
for (int i = 0; i < numNodes; i++)
{
m_NodeArray[i] = new BlendTreeNodeConstant(reader);
}
}
}
public class StateConstant
{
public TransitionConstant[] m_TransitionConstantArray;
public int[] m_BlendTreeConstantIndexArray;
public LeafInfoConstant[] m_LeafInfoArray;
public BlendTreeConstant[] m_BlendTreeConstantArray;
public uint m_NameID;
public uint m_PathID;
public uint m_FullPathID;
public uint m_TagID;
public uint m_SpeedParamID;
public uint m_MirrorParamID;
public uint m_CycleOffsetParamID;
public float m_Speed;
public float m_CycleOffset;
public bool m_IKOnFeet;
public bool m_WriteDefaultValues;
public bool m_Loop;
public bool m_Mirror;
public StateConstant(ObjectReader reader)
{
var version = reader.version;
int numTransistions = reader.ReadInt32();
m_TransitionConstantArray = new TransitionConstant[numTransistions];
for (int i = 0; i < numTransistions; i++)
{
m_TransitionConstantArray[i] = new TransitionConstant(reader);
}
int numBlendIndices = reader.ReadInt32();
m_BlendTreeConstantIndexArray = new int[numBlendIndices];
for (int i = 0; i < numBlendIndices; i++)
{
m_BlendTreeConstantIndexArray[i] = reader.ReadInt32();
}
if (version[0] < 5) //5.0 down
{
int numInfos = reader.ReadInt32();
m_LeafInfoArray = new LeafInfoConstant[numInfos];
for (int i = 0; i < numInfos; i++)
{
m_LeafInfoArray[i] = new LeafInfoConstant(reader);
}
}
int numBlends = reader.ReadInt32();
m_BlendTreeConstantArray = new BlendTreeConstant[numBlends];
for (int i = 0; i < numBlends; i++)
{
m_BlendTreeConstantArray[i] = new BlendTreeConstant(reader);
}
m_NameID = reader.ReadUInt32();
m_PathID = reader.ReadUInt32();
if (version[0] >= 5) //5.0 and up
{
m_FullPathID = reader.ReadUInt32();
}
m_TagID = reader.ReadUInt32();
if (version[0] >= 5) //5.0 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
{
var m_TimeParamID = reader.ReadUInt32();
}
m_Speed = reader.ReadSingle();
m_CycleOffset = reader.ReadSingle();
m_IKOnFeet = reader.ReadBoolean();
if (version[0] >= 5) //5.0 and up
{
m_WriteDefaultValues = reader.ReadBoolean();
}
m_Loop = reader.ReadBoolean();
m_Mirror = reader.ReadBoolean();
reader.AlignStream(4);
}
}
public class SelectorTransitionConstant
{
public uint m_Destination;
public ConditionConstant[] m_ConditionConstantArray;
public SelectorTransitionConstant(ObjectReader reader)
{
m_Destination = reader.ReadUInt32();
int numConditions = reader.ReadInt32();
m_ConditionConstantArray = new ConditionConstant[numConditions];
for (int i = 0; i < numConditions; i++)
{
m_ConditionConstantArray[i] = new ConditionConstant(reader);
}
}
}
public class SelectorStateConstant
{
public SelectorTransitionConstant[] m_TransitionConstantArray;
public uint m_FullPathID;
public bool m_isEntry;
public SelectorStateConstant(ObjectReader reader)
{
int numTransitions = reader.ReadInt32();
m_TransitionConstantArray = new SelectorTransitionConstant[numTransitions];
for (int i = 0; i < numTransitions; i++)
{
m_TransitionConstantArray[i] = new SelectorTransitionConstant(reader);
}
m_FullPathID = reader.ReadUInt32();
m_isEntry = reader.ReadBoolean();
reader.AlignStream(4);
}
}
public class StateMachineConstant
{
public StateConstant[] m_StateConstantArray;
public TransitionConstant[] m_AnyStateTransitionConstantArray;
public SelectorStateConstant[] m_SelectorStateConstantArray;
public uint m_DefaultState;
public uint m_MotionSetCount;
public StateMachineConstant(ObjectReader reader)
{
var version = reader.version;
int numStates = reader.ReadInt32();
m_StateConstantArray = new StateConstant[numStates];
for (int i = 0; i < numStates; i++)
{
m_StateConstantArray[i] = new StateConstant(reader);
}
int numAnyStates = reader.ReadInt32();
m_AnyStateTransitionConstantArray = new TransitionConstant[numAnyStates];
for (int i = 0; i < numAnyStates; i++)
{
m_AnyStateTransitionConstantArray[i] = new TransitionConstant(reader);
}
if (version[0] >= 5) //5.0 and up
{
int numSelectors = reader.ReadInt32();
m_SelectorStateConstantArray = new SelectorStateConstant[numSelectors];
for (int i = 0; i < numSelectors; i++)
{
m_SelectorStateConstantArray[i] = new SelectorStateConstant(reader);
}
}
m_DefaultState = reader.ReadUInt32();
m_MotionSetCount = reader.ReadUInt32();
}
}
public class ValueArray
{
public bool[] m_BoolValues;
public int[] m_IntValues;
public float[] m_FloatValues;
public object[] m_PositionValues;
public Vector4[] m_QuaternionValues;
public object[] m_ScaleValues;
public ValueArray(ObjectReader reader)
{
var version = reader.version;
if (version[0] < 5 || (version[0] == 5 && version[1] < 5)) //5.5 down
{
int numBools = reader.ReadInt32();
m_BoolValues = new bool[numBools];
for (int i = 0; i < numBools; i++)
{
m_BoolValues[i] = reader.ReadBoolean();
}
reader.AlignStream(4);
m_IntValues = reader.ReadInt32Array(reader.ReadInt32());
m_FloatValues = reader.ReadSingleArray(reader.ReadInt32());
}
int numPosValues = reader.ReadInt32();
m_PositionValues = new object[numPosValues];
for (int i = 0; i < numPosValues; i++)
{
m_PositionValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4(); //5.4 and up
}
m_QuaternionValues = reader.ReadVector4Array(reader.ReadInt32());
int numScaleValues = reader.ReadInt32();
m_ScaleValues = new object[numScaleValues];
for (int i = 0; i < numScaleValues; i++)
{
m_ScaleValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? (object)reader.ReadVector3() : (object)reader.ReadVector4(); //5.4 adn up
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
{
m_FloatValues = reader.ReadSingleArray(reader.ReadInt32());
m_IntValues = reader.ReadInt32Array(reader.ReadInt32());
int numBools = reader.ReadInt32();
m_BoolValues = new bool[numBools];
for (int i = 0; i < numBools; i++)
{
m_BoolValues[i] = reader.ReadBoolean();
}
reader.AlignStream(4);
}
}
}
public class ControllerConstant
{
public LayerConstant[] m_LayerArray;
public StateMachineConstant[] m_StateMachineArray;
public ValueArrayConstant m_Values;
public ValueArray m_DefaultValues;
public ControllerConstant(ObjectReader reader)
{
int numLayers = reader.ReadInt32();
m_LayerArray = new LayerConstant[numLayers];
for (int i = 0; i < numLayers; i++)
{
m_LayerArray[i] = new LayerConstant(reader);
}
int numStates = reader.ReadInt32();
m_StateMachineArray = new StateMachineConstant[numStates];
for (int i = 0; i < numStates; i++)
{
m_StateMachineArray[i] = new StateMachineConstant(reader);
}
m_Values = new ValueArrayConstant(reader);
m_DefaultValues = new ValueArray(reader);
}
}
public sealed class AnimatorController : NamedObject
{
public PPtr[] m_AnimationClips;
public AnimatorController(ObjectReader reader) : base(reader)
{
var m_ControllerSize = reader.ReadUInt32();
var m_Controller = new ControllerConstant(reader);
int tosSize = reader.ReadInt32();
var m_TOS = new List<KeyValuePair<uint, string>>(tosSize);
for (int i = 0; i < tosSize; i++)
{
m_TOS.Add(new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString()));
}
int numClips = reader.ReadInt32();
m_AnimationClips = new PPtr[numClips];
for (int i = 0; i < numClips; i++)
{
m_AnimationClips[i] = reader.ReadPPtr();
}
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class AnimatorOverrideController : NamedObject
{
public PPtr m_Controller;
public PPtr[][] m_Clips;
public AnimatorOverrideController(ObjectReader reader) : base(reader)
{
m_Controller = reader.ReadPPtr();
int numOverrides = reader.ReadInt32();
m_Clips = new PPtr[numOverrides][];
for (int i = 0; i < numOverrides; i++)
{
m_Clips[i] = new PPtr[2];
m_Clips[i][0] = reader.ReadPPtr();
m_Clips[i][1] = reader.ReadPPtr();
}
}
}
}

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class AssetBundle : NamedObject
{
public class AssetInfo
{
public int preloadIndex;
public int preloadSize;
public PPtr asset;
}
public class ContainerData
{
public string first;
public AssetInfo second;
}
public List<ContainerData> m_Container = new List<ContainerData>();
public AssetBundle(ObjectReader reader) : base(reader)
{
var size = reader.ReadInt32();
for (int i = 0; i < size; i++)
{
reader.ReadPPtr();
}
size = reader.ReadInt32();
for (int i = 0; i < size; i++)
{
var temp = new ContainerData();
temp.first = reader.ReadAlignedString();
temp.second = new AssetInfo();
temp.second.preloadIndex = reader.ReadInt32();
temp.second.preloadSize = reader.ReadInt32();
temp.second.asset = reader.ReadPPtr();
m_Container.Add(temp);
}
}
}
}

View File

@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class AudioClip : NamedObject
{
public int m_Format;
public AudioType m_Type;
public bool m_3D;
public bool m_UseHardware;
//version 5
public int m_LoadType;
public int m_Channels;
public int m_Frequency;
public int m_BitsPerSample;
public float m_Length;
public bool m_IsTrackerFormat;
public int m_SubsoundIndex;
public bool m_PreloadAudioData;
public bool m_LoadInBackground;
public bool m_Legacy3D;
public AudioCompressionFormat m_CompressionFormat;
public string m_Source;
public long m_Offset;
public long m_Size;
public byte[] m_AudioData;
public AudioClip(ObjectReader reader, bool readData) : base(reader)
{
if (version[0] < 5)
{
m_Format = reader.ReadInt32();
m_Type = (AudioType)reader.ReadInt32();
m_3D = reader.ReadBoolean();
m_UseHardware = reader.ReadBoolean();
reader.AlignStream(4);
if (version[0] >= 4 || (version[0] == 3 && version[1] >= 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_Source = sourceFile.fullName + ".resS";
}
}
else
{
m_Size = reader.ReadInt32();
}
}
else
{
m_LoadType = reader.ReadInt32();
m_Channels = reader.ReadInt32();
m_Frequency = reader.ReadInt32();
m_BitsPerSample = reader.ReadInt32();
m_Length = reader.ReadSingle();
m_IsTrackerFormat = reader.ReadBoolean();
reader.AlignStream(4);
m_SubsoundIndex = reader.ReadInt32();
m_PreloadAudioData = reader.ReadBoolean();
m_LoadInBackground = reader.ReadBoolean();
m_Legacy3D = reader.ReadBoolean();
reader.AlignStream(4);
m_3D = m_Legacy3D;
m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadInt64();
m_Size = reader.ReadInt64();
m_CompressionFormat = (AudioCompressionFormat)reader.ReadInt32();
}
if (readData)
{
if (!string.IsNullOrEmpty(m_Source))
{
m_AudioData = ResourcesHelper.GetData(m_Source, sourceFile, m_Offset, (int)m_Size);
}
else
{
if (m_Size > 0)
m_AudioData = reader.ReadBytes((int)m_Size);
}
}
}
}
public enum AudioType
{
UNKNOWN,
ACC,
AIFF,
IT = 10,
MOD = 12,
MPEG,
OGGVORBIS,
S3M = 17,
WAV = 20,
XM,
XMA,
VAG,
AUDIOQUEUE
}
public enum AudioCompressionFormat
{
PCM,
Vorbis,
ADPCM,
MP3,
VAG,
HEVAG,
XMA,
AAC,
GCADPCM,
ATRAC9
}
}

View File

@@ -0,0 +1,368 @@
using SharpDX;
using System.Collections.Generic;
namespace AssetStudio
{
public class Node
{
public int m_ParentId;
public int m_AxesId;
public Node(ObjectReader reader)
{
m_ParentId = reader.ReadInt32();
m_AxesId = reader.ReadInt32();
}
}
public class Limit
{
public object m_Min;
public object m_Max;
public Limit(ObjectReader reader)
{
var version = reader.version;
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up
{
m_Min = reader.ReadVector3();
m_Max = reader.ReadVector3();
}
else
{
m_Min = reader.ReadVector4();
m_Max = reader.ReadVector4();
}
}
}
public class Axes
{
public Vector4 m_PreQ;
public Vector4 m_PostQ;
public object m_Sgn;
public Limit m_Limit;
public float m_Length;
public uint m_Type;
public Axes(ObjectReader reader)
{
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
{
m_Sgn = reader.ReadVector3();
}
else
{
m_Sgn = reader.ReadVector4();
}
m_Limit = new Limit(reader);
m_Length = reader.ReadSingle();
m_Type = reader.ReadUInt32();
}
}
public class Skeleton
{
public List<Node> m_Node;
public List<uint> m_ID;
public List<Axes> m_AxesArray;
public Skeleton(ObjectReader reader)
{
int numNodes = reader.ReadInt32();
m_Node = new List<Node>(numNodes);
for (int i = 0; i < numNodes; i++)
{
m_Node.Add(new Node(reader));
}
int numIDs = reader.ReadInt32();
m_ID = new List<uint>(numIDs);
for (int i = 0; i < numIDs; i++)
{
m_ID.Add(reader.ReadUInt32());
}
int numAxes = reader.ReadInt32();
m_AxesArray = new List<Axes>(numAxes);
for (int i = 0; i < numAxes; i++)
{
m_AxesArray.Add(new Axes(reader));
}
}
}
public class SkeletonPose
{
public List<xform> m_X;
public SkeletonPose()
{
m_X = new List<xform>();
}
public SkeletonPose(ObjectReader reader)
{
int numXforms = reader.ReadInt32();
m_X = new List<xform>(numXforms);
for (int i = 0; i < numXforms; i++)
{
m_X.Add(new xform(reader));
}
}
}
public class Hand
{
public List<int> m_HandBoneIndex;
public Hand(ObjectReader reader)
{
int numIndexes = reader.ReadInt32();
m_HandBoneIndex = new List<int>(numIndexes);
for (int i = 0; i < numIndexes; i++)
{
m_HandBoneIndex.Add(reader.ReadInt32());
}
}
}
public class Handle
{
public xform m_X;
public uint m_ParentHumanIndex;
public uint m_ID;
public Handle(ObjectReader reader)
{
m_X = new xform(reader);
m_ParentHumanIndex = reader.ReadUInt32();
m_ID = reader.ReadUInt32();
}
}
public class Collider
{
public xform m_X;
public uint m_Type;
public uint m_XMotionType;
public uint m_YMotionType;
public uint m_ZMotionType;
public float m_MinLimitX;
public float m_MaxLimitX;
public float m_MaxLimitY;
public float m_MaxLimitZ;
public Collider(ObjectReader reader)
{
m_X = new xform(reader);
m_Type = reader.ReadUInt32();
m_XMotionType = reader.ReadUInt32();
m_YMotionType = reader.ReadUInt32();
m_ZMotionType = reader.ReadUInt32();
m_MinLimitX = reader.ReadSingle();
m_MaxLimitX = reader.ReadSingle();
m_MaxLimitY = reader.ReadSingle();
m_MaxLimitZ = reader.ReadSingle();
}
}
public class Human
{
public xform m_RootX;
public Skeleton m_Skeleton;
public SkeletonPose m_SkeletonPose;
public Hand m_LeftHand;
public Hand m_RightHand;
public List<Handle> m_Handles;
public List<Collider> m_ColliderArray;
public List<int> m_HumanBoneIndex;
public List<float> m_HumanBoneMass;
public List<int> m_ColliderIndex;
public float m_Scale;
public float m_ArmTwist;
public float m_ForeArmTwist;
public float m_UpperLegTwist;
public float m_LegTwist;
public float m_ArmStretch;
public float m_LegStretch;
public float m_FeetSpacing;
public bool m_HasLeftHand;
public bool m_HasRightHand;
public bool m_HasTDoF;
public Human(ObjectReader reader)
{
var version = reader.version;
m_RootX = new xform(reader);
m_Skeleton = new Skeleton(reader);
m_SkeletonPose = new SkeletonPose(reader);
m_LeftHand = new Hand(reader);
m_RightHand = new Hand(reader);
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
{
int numHandles = reader.ReadInt32();
m_Handles = new List<Handle>(numHandles);
for (int i = 0; i < numHandles; i++)
{
m_Handles.Add(new Handle(reader));
}
int numColliders = reader.ReadInt32();
m_ColliderArray = new List<Collider>(numColliders);
for (int i = 0; i < numColliders; i++)
{
m_ColliderArray.Add(new Collider(reader));
}
}
int numIndexes = reader.ReadInt32();
m_HumanBoneIndex = new List<int>(numIndexes);
for (int i = 0; i < numIndexes; i++)
{
m_HumanBoneIndex.Add(reader.ReadInt32());
}
int numMasses = reader.ReadInt32();
m_HumanBoneMass = new List<float>(numMasses);
for (int i = 0; i < numMasses; i++)
{
m_HumanBoneMass.Add(reader.ReadSingle());
}
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
{
int numColliderIndexes = reader.ReadInt32();
m_ColliderIndex = new List<int>(numColliderIndexes);
for (int i = 0; i < numColliderIndexes; i++)
{
m_ColliderIndex.Add(reader.ReadInt32());
}
}
m_Scale = reader.ReadSingle();
m_ArmTwist = reader.ReadSingle();
m_ForeArmTwist = reader.ReadSingle();
m_UpperLegTwist = reader.ReadSingle();
m_LegTwist = reader.ReadSingle();
m_ArmStretch = reader.ReadSingle();
m_LegStretch = reader.ReadSingle();
m_FeetSpacing = reader.ReadSingle();
m_HasLeftHand = reader.ReadBoolean();
m_HasRightHand = reader.ReadBoolean();
m_HasTDoF = reader.ReadBoolean();
reader.AlignStream(4);
}
}
public class AvatarConstant
{
public Skeleton m_AvatarSkeleton;
public SkeletonPose m_AvatarSkeletonPose;
public SkeletonPose m_DefaultPose;
public List<uint> m_SkeletonNameIDArray;
public Human m_Human;
public List<int> m_HumanSkeletonIndexArray;
public List<int> m_HumanSkeletonReverseIndexArray;
public int m_RootMotionBoneIndex;
public xform m_RootMotionBoneX;
public Skeleton m_RootMotionSkeleton;
public SkeletonPose m_RootMotionSkeletonPose;
public List<int> m_RootMotionSkeletonIndexArray;
public AvatarConstant(ObjectReader reader)
{
var version = reader.version;
m_AvatarSkeleton = new Skeleton(reader);
m_AvatarSkeletonPose = new SkeletonPose(reader);
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_DefaultPose = new SkeletonPose(reader);
int numIDs = reader.ReadInt32();
m_SkeletonNameIDArray = new List<uint>(numIDs);
for (int i = 0; i < numIDs; i++)
{
m_SkeletonNameIDArray.Add(reader.ReadUInt32());
}
}
m_Human = new Human(reader);
int numIndexes = reader.ReadInt32();
m_HumanSkeletonIndexArray = new List<int>(numIndexes);
for (int i = 0; i < numIndexes; i++)
{
m_HumanSkeletonIndexArray.Add(reader.ReadInt32());
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
int numReverseIndexes = reader.ReadInt32();
m_HumanSkeletonReverseIndexArray = new List<int>(numReverseIndexes);
for (int i = 0; i < numReverseIndexes; i++)
{
m_HumanSkeletonReverseIndexArray.Add(reader.ReadInt32());
}
}
m_RootMotionBoneIndex = reader.ReadInt32();
m_RootMotionBoneX = new xform(reader);
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_RootMotionSkeleton = new Skeleton(reader);
m_RootMotionSkeletonPose = new SkeletonPose(reader);
int numMotionIndexes = reader.ReadInt32();
m_RootMotionSkeletonIndexArray = new List<int>(numMotionIndexes);
for (int i = 0; i < numMotionIndexes; i++)
{
m_RootMotionSkeletonIndexArray.Add(reader.ReadInt32());
}
}
}
}
public sealed class Avatar : NamedObject
{
public uint m_AvatarSize;
public AvatarConstant m_Avatar;
public List<KeyValuePair<uint, string>> m_TOS;
public Avatar(ObjectReader reader) : base(reader)
{
m_AvatarSize = reader.ReadUInt32();
m_Avatar = new AvatarConstant(reader);
int numTOS = reader.ReadInt32();
m_TOS = new List<KeyValuePair<uint, string>>(numTOS);
for (int i = 0; i < numTOS; i++)
{
m_TOS.Add(new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString()));
}
}
public string FindBoneName(uint hash)
{
foreach (var pair in m_TOS)
{
if (pair.Key == hash)
{
return pair.Value.Substring(pair.Value.LastIndexOf('/') + 1);
}
}
return null;
}
public string FindBonePath(uint hash)
{
return m_TOS.Find(pair => pair.Key == hash).Value;
}
}
}

View File

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

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class BuildSettings : Object
{
public string m_Version;
public BuildSettings(ObjectReader reader) : base(reader)
{
int levelsNum = reader.ReadInt32();
for (int i = 0; i < levelsNum; i++)
{
var level = reader.ReadAlignedString();
}
var hasRenderTexture = reader.ReadBoolean();
var hasPROVersion = reader.ReadBoolean();
var hasPublishingRights = reader.ReadBoolean();
var hasShadows = reader.ReadBoolean();
m_Version = reader.ReadAlignedString();
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public abstract class Component : EditorExtension
{
public PPtr m_GameObject;
protected Component(ObjectReader reader) : base(reader)
{
m_GameObject = reader.ReadPPtr();
}
}
}

View File

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

121
AssetStudio/Classes/Font.cs Normal file
View File

@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class Font : NamedObject
{
public byte[] m_FontData;
public Font(ObjectReader reader) : base(reader)
{
if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5 and up
{
var m_LineSpacing = reader.ReadSingle();
var m_DefaultMaterial = reader.ReadPPtr();
var m_FontSize = reader.ReadSingle();
var m_Texture = reader.ReadPPtr();
int m_AsciiStartOffset = reader.ReadInt32();
var m_Tracking = reader.ReadSingle();
var m_CharacterSpacing = reader.ReadInt32();
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++)
{
reader.Position += 44;//CharacterInfo data 41
}
int m_KerningValues_size = reader.ReadInt32();
for (int i = 0; i < m_KerningValues_size; i++)
{
reader.Position += 8;
}
var m_PixelScale = reader.ReadSingle();
int m_FontData_size = reader.ReadInt32();
if (m_FontData_size > 0)
{
m_FontData = reader.ReadBytes(m_FontData_size);
}
}
else
{
int m_AsciiStartOffset = reader.ReadInt32();
if (version[0] <= 3)
{
int m_FontCountX = reader.ReadInt32();
int m_FontCountY = reader.ReadInt32();
}
float m_Kerning = reader.ReadSingle();
float m_LineSpacing = reader.ReadSingle();
if (version[0] <= 3)
{
int m_PerCharacterKerning_size = reader.ReadInt32();
for (int i = 0; i < m_PerCharacterKerning_size; i++)
{
int first = reader.ReadInt32();
float second = reader.ReadSingle();
}
}
else
{
int m_CharacterSpacing = reader.ReadInt32();
int m_CharacterPadding = reader.ReadInt32();
}
int m_ConvertCase = reader.ReadInt32();
PPtr m_DefaultMaterial = reader.ReadPPtr();
int m_CharacterRects_size = reader.ReadInt32();
for (int i = 0; i < m_CharacterRects_size; i++)
{
int index = reader.ReadInt32();
//Rectf uv
float uvx = reader.ReadSingle();
float uvy = reader.ReadSingle();
float uvwidth = reader.ReadSingle();
float uvheight = reader.ReadSingle();
//Rectf vert
float vertx = reader.ReadSingle();
float verty = reader.ReadSingle();
float vertwidth = reader.ReadSingle();
float vertheight = reader.ReadSingle();
float width = reader.ReadSingle();
if (version[0] >= 4)
{
var flipped = reader.ReadBoolean();
reader.AlignStream(4);
}
}
PPtr m_Texture = reader.ReadPPtr();
int m_KerningValues_size = reader.ReadInt32();
for (int i = 0; i < m_KerningValues_size; i++)
{
int pairfirst = reader.ReadInt16();
int pairsecond = reader.ReadInt16();
float second = reader.ReadSingle();
}
if (version[0] <= 3)
{
var m_GridFont = reader.ReadBoolean();
reader.AlignStream(4);
}
else { float m_PixelScale = reader.ReadSingle(); }
int m_FontData_size = reader.ReadInt32();
if (m_FontData_size > 0)
{
m_FontData = reader.ReadBytes(m_FontData_size);
}
}
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class GameObject : EditorExtension
{
public List<PPtr> m_Components;
public string m_Name;
public PPtr m_Transform;
public PPtr m_MeshRenderer;
public PPtr m_MeshFilter;
public PPtr m_SkinnedMeshRenderer;
public PPtr m_Animator;
public GameObject(ObjectReader reader) : base(reader)
{
int m_Component_size = reader.ReadInt32();
m_Components = new List<PPtr>(m_Component_size);
for (int j = 0; j < m_Component_size; j++)
{
if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5.0 and up
{
m_Components.Add(reader.ReadPPtr());
}
else
{
int first = reader.ReadInt32();
m_Components.Add(reader.ReadPPtr());
}
}
var m_Layer = reader.ReadInt32();
m_Name = reader.ReadAlignedString();
}
}
}

View File

@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class TexEnv
{
public string name;
public PPtr m_Texture;
public float[] m_Scale;
public float[] m_Offset;
}
public class strFloatPair
{
public string first;
public float second;
}
public class strColorPair
{
public string first;
public float[] second;
}
public sealed class Material : NamedObject
{
public PPtr m_Shader;
public string[] m_ShaderKeywords;
public int m_CustomRenderQueue;
public TexEnv[] m_TexEnvs;
public strFloatPair[] m_Floats;
public strColorPair[] m_Colors;
public Material(ObjectReader reader) : base(reader)
{
m_Shader = reader.ReadPPtr();
if (version[0] == 4 && (version[1] >= 2 || (version[1] == 1 && !buildType.IsAlpha)))
{
m_ShaderKeywords = new string[reader.ReadInt32()];
for (int i = 0; i < m_ShaderKeywords.Length; i++)
{
m_ShaderKeywords[i] = reader.ReadAlignedString();
}
}
else if (version[0] >= 5)//5.0 and up
{
m_ShaderKeywords = new[] { reader.ReadAlignedString() };
uint m_LightmapFlags = reader.ReadUInt32();
if (version[0] == 5 && version[1] >= 6 || version[0] > 5)//5.6.0 and up
{
var m_EnableInstancingVariants = reader.ReadBoolean();
//var m_DoubleSidedGI = a_Stream.ReadBoolean();//2017.x
reader.AlignStream(4);
}
}
if (version[0] > 4 || version[0] == 4 && version[1] >= 3) { m_CustomRenderQueue = reader.ReadInt32(); }
if (version[0] == 5 && version[1] >= 1 || version[0] > 5)//5.1 and up
{
string[][] stringTagMap = new string[reader.ReadInt32()][];
for (int i = 0; i < stringTagMap.Length; i++)
{
stringTagMap[i] = new[] { reader.ReadAlignedString(), reader.ReadAlignedString() };
}
}
//disabledShaderPasses
if ((version[0] == 5 && version[1] >= 6) || version[0] > 5)//5.6.0 and up
{
var size = reader.ReadInt32();
for (int i = 0; i < size; i++)
{
reader.ReadAlignedString();
}
}
//m_SavedProperties
m_TexEnvs = new TexEnv[reader.ReadInt32()];
for (int i = 0; i < m_TexEnvs.Length; i++)
{
TexEnv m_TexEnv = new TexEnv()
{
name = reader.ReadAlignedString(),
m_Texture = reader.ReadPPtr(),
m_Scale = new[] { reader.ReadSingle(), reader.ReadSingle() },
m_Offset = new[] { reader.ReadSingle(), reader.ReadSingle() }
};
m_TexEnvs[i] = m_TexEnv;
}
m_Floats = new strFloatPair[reader.ReadInt32()];
for (int i = 0; i < m_Floats.Length; i++)
{
strFloatPair m_Float = new strFloatPair()
{
first = reader.ReadAlignedString(),
second = reader.ReadSingle()
};
m_Floats[i] = m_Float;
}
m_Colors = new strColorPair[reader.ReadInt32()];
for (int i = 0; i < m_Colors.Length; i++)
{
strColorPair m_Color = new strColorPair()
{
first = reader.ReadAlignedString(),
second = new[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() }
};
m_Colors[i] = m_Color;
}
}
}
}

1138
AssetStudio/Classes/Mesh.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class MeshFilter : Component
{
public long preloadIndex;
public PPtr m_Mesh;
public MeshFilter(ObjectReader reader) : base(reader)
{
m_Mesh = reader.ReadPPtr();
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class MeshRenderer : Renderer
{
public MeshRenderer(ObjectReader reader) : base(reader)
{
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class MonoBehaviour : Behaviour
{
public PPtr m_Script;
public string m_Name;
public MonoBehaviour(ObjectReader reader) : base(reader)
{
m_Script = reader.ReadPPtr();
m_Name = reader.ReadAlignedString();
}
}
}

View File

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

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class MovieTexture : Texture
{
public byte[] m_MovieData;
public MovieTexture(ObjectReader reader) : base(reader)
{
var m_Loop = reader.ReadBoolean();
reader.AlignStream(4);
//PPtr<AudioClip>
reader.ReadPPtr();
m_MovieData = reader.ReadBytes(reader.ReadInt32());
}
}
}

View File

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

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public abstract class Object
{
protected SerializedFile sourceFile;
public ObjectReader reader;
public int[] version;
protected BuildType buildType;
public BuildTarget platform;
protected Object(ObjectReader reader)
{
this.reader = reader;
reader.Reset();
sourceFile = reader.assetsFile;
version = reader.version;
buildType = reader.buildType;
platform = reader.platform;
if (platform == BuildTarget.NoTarget)
{
var m_ObjectHideFlags = reader.ReadUInt32();
}
}
}
}

View File

@@ -0,0 +1,89 @@
namespace AssetStudio
{
public class PPtr
{
public int m_FileID;
public long m_PathID;
public SerializedFile assetsFile;
public int index = -2; //-2 - Prepare, -1 - Missing
private bool TryGetAssetsFile(out SerializedFile result)
{
result = null;
if (m_FileID == 0)
{
result = assetsFile;
return true;
}
if (m_FileID > 0 && m_FileID - 1 < assetsFile.m_Externals.Count)
{
var assetsManager = assetsFile.assetsManager;
var assetsfileList = assetsManager.assetsFileList;
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
if (index == -2)
{
var m_External = assetsFile.m_Externals[m_FileID - 1];
var name = m_External.fileName.ToUpper();
if (!assetsFileIndexCache.TryGetValue(name, out index))
{
index = assetsfileList.FindIndex(x => x.upperFileName == name);
assetsFileIndexCache.Add(name, index);
}
}
if (index >= 0)
{
result = assetsfileList[index];
return true;
}
}
return false;
}
public bool TryGet(out ObjectReader result)
{
result = null;
if (TryGetAssetsFile(out var sourceFile))
{
if (sourceFile.ObjectReaders.TryGetValue(m_PathID, out result))
{
return true;
}
}
return false;
}
public bool TryGetTransform(out Transform m_Transform)
{
if (TryGetAssetsFile(out var sourceFile))
{
if (sourceFile.Transforms.TryGetValue(m_PathID, out m_Transform))
{
return true;
}
}
m_Transform = null;
return false;
}
public bool TryGetGameObject(out GameObject m_GameObject)
{
if (TryGetAssetsFile(out var sourceFile))
{
if (sourceFile.GameObjects.TryGetValue(m_PathID, out m_GameObject))
{
return true;
}
}
m_GameObject = null;
return false;
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class PlayerSettings : Object
{
public string companyName;
public string productName;
public PlayerSettings(ObjectReader reader) : base(reader)
{
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4.0 nad up
{
var productGUID = reader.ReadBytes(16);
}
var AndroidProfiler = reader.ReadBoolean();
//bool AndroidFilterTouchesWhenObscured 2017.2 and up
//bool AndroidEnableSustainedPerformanceMode 2018 and up
reader.AlignStream(4);
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
{
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();
}
}
int targetResolution = reader.ReadInt32();
}
else
{
var useOnDemandResources = reader.ReadBoolean();
reader.AlignStream(4);
}
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 and up
{
var accelerometerFrequency = reader.ReadInt32();
}
companyName = reader.ReadAlignedString();
productName = reader.ReadAlignedString();
}
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class RectTransform : Transform
{
public RectTransform(ObjectReader reader) : base(reader)
{
}
}
}

View File

@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class StaticBatchInfo
{
public ushort firstSubMesh;
public ushort subMeshCount;
}
public abstract class Renderer : Component
{
public PPtr[] m_Materials;
public StaticBatchInfo m_StaticBatchInfo;
public uint[] m_SubsetIndices;
protected Renderer(ObjectReader reader) : base(reader)
{
if (version[0] < 5)
{
var m_Enabled = reader.ReadBoolean();
var m_CastShadows = reader.ReadByte();
var m_ReceiveShadows = reader.ReadBoolean();
var m_LightmapIndex = reader.ReadByte();
}
else
{
var m_Enabled = reader.ReadBoolean();
reader.AlignStream(4);
var m_CastShadows = reader.ReadByte();
var m_ReceiveShadows = reader.ReadBoolean();
reader.AlignStream(4);
if (version[0] >= 2018)//2018 and up
{
var m_RenderingLayerMask = reader.ReadUInt32();
}
var m_LightmapIndex = reader.ReadUInt16();
var m_LightmapIndexDynamic = reader.ReadUInt16();
}
if (version[0] >= 3)
{
reader.Position += 16;//Vector4f m_LightmapTilingOffset
}
if (version[0] >= 5)
{
reader.Position += 16;//Vector4f m_LightmapTilingOffsetDynamic
}
m_Materials = new PPtr[reader.ReadInt32()];
for (int m = 0; m < m_Materials.Length; m++)
{
m_Materials[m] = reader.ReadPPtr();
}
if (version[0] < 3)
{
reader.Position += 16;//m_LightmapTilingOffset vector4d
}
else
{
if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5.0 and up
{
m_StaticBatchInfo = new StaticBatchInfo
{
firstSubMesh = reader.ReadUInt16(),
subMeshCount = reader.ReadUInt16()
};
}
else
{
int numSubsetIndices = reader.ReadInt32();
m_SubsetIndices = reader.ReadUInt32Array(numSubsetIndices);
}
var m_StaticBatchRoot = reader.ReadPPtr();
if ((version[0] == 5 && version[1] >= 4) || version[0] > 5)//5.4.0 and up
{
var m_ProbeAnchor = reader.ReadPPtr();
var m_LightProbeVolumeOverride = reader.ReadPPtr();
}
else if (version[0] >= 4 || (version[0] == 3 && version[1] >= 5))//3.5 - 5.3
{
var m_UseLightProbes = reader.ReadBoolean();
reader.AlignStream(4);
if (version[0] == 5)//5.0 and up
{
int m_ReflectionProbeUsage = reader.ReadInt32();
}
var m_LightProbeAnchor = reader.ReadPPtr();
}
if (version[0] >= 5 || (version[0] == 4 && version[1] >= 3))//4.3 and up
{
if (version[0] == 4 && version[1] == 3)//4.3
{
int m_SortingLayer = reader.ReadInt16();
}
else
{
int m_SortingLayerID = reader.ReadInt32();
//SInt16 m_SortingOrder 5.6 and up
}
int m_SortingOrder = reader.ReadInt16();
reader.AlignStream(4);
}
}
}
}
}

View File

@@ -0,0 +1,796 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace AssetStudio
{
public class StructParameter
{
public List<MatrixParameter> m_MatrixParams;
public List<VectorParameter> m_VectorParams;
public StructParameter(BinaryReader reader)
{
var m_NameIndex = reader.ReadInt32();
var m_Index = reader.ReadInt32();
var m_ArraySize = reader.ReadInt32();
var m_StructSize = reader.ReadInt32();
int numVectorParams = reader.ReadInt32();
m_VectorParams = new List<VectorParameter>(numVectorParams);
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams.Add(new VectorParameter(reader));
}
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new List<MatrixParameter>(numMatrixParams);
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams.Add(new MatrixParameter(reader));
}
}
}
public class SamplerParameter
{
public uint sampler;
public int bindPoint;
public SamplerParameter(BinaryReader reader)
{
sampler = reader.ReadUInt32();
bindPoint = reader.ReadInt32();
}
}
public enum TextureDimension
{
kTexDimUnknown = -1,
kTexDimNone = 0,
kTexDimAny = 1,
kTexDim2D = 2,
kTexDim3D = 3,
kTexDimCUBE = 4,
kTexDim2DArray = 5,
kTexDimCubeArray = 6,
kTexDimForce32Bit = 2147483647
};
public class SerializedTextureProperty
{
public string m_DefaultName;
public TextureDimension m_TexDim;
public SerializedTextureProperty(BinaryReader reader)
{
m_DefaultName = reader.ReadAlignedString();
m_TexDim = (TextureDimension)reader.ReadInt32();
}
}
public enum SerializedPropertyType
{
kColor = 0,
kVector = 1,
kFloat = 2,
kRange = 3,
kTexture = 4
};
public class SerializedProperty
{
public string m_Name;
public string m_Description;
public List<string> m_Attributes;
public SerializedPropertyType m_Type;
public uint m_Flags;
public List<float> m_DefValue;
public SerializedTextureProperty m_DefTexture;
public SerializedProperty(BinaryReader reader)
{
m_Name = reader.ReadAlignedString();
m_Description = reader.ReadAlignedString();
int numAttributes = reader.ReadInt32();
m_Attributes = new List<string>(numAttributes);
for (int i = 0; i < numAttributes; i++)
{
m_Attributes.Add(reader.ReadAlignedString());
}
m_Type = (SerializedPropertyType)reader.ReadInt32();
m_Flags = reader.ReadUInt32();
int numValues = 4;
m_DefValue = new List<float>(numValues);
for (int i = 0; i < numValues; i++)
{
m_DefValue.Add(reader.ReadSingle());
}
m_DefTexture = new SerializedTextureProperty(reader);
}
}
public class SerializedProperties
{
public List<SerializedProperty> m_Props;
public SerializedProperties(BinaryReader reader)
{
int numProps = reader.ReadInt32();
m_Props = new List<SerializedProperty>(numProps);
for (int i = 0; i < numProps; i++)
{
m_Props.Add(new SerializedProperty(reader));
}
}
}
public class SerializedShaderFloatValue
{
public float val;
public string name;
public SerializedShaderFloatValue(BinaryReader reader)
{
val = reader.ReadSingle();
name = reader.ReadAlignedString();
}
}
public class SerializedShaderRTBlendState
{
public SerializedShaderFloatValue srcBlend;
public SerializedShaderFloatValue destBlend;
public SerializedShaderFloatValue srcBlendAlpha;
public SerializedShaderFloatValue destBlendAlpha;
public SerializedShaderFloatValue blendOp;
public SerializedShaderFloatValue blendOpAlpha;
public SerializedShaderFloatValue colMask;
public SerializedShaderRTBlendState(BinaryReader reader)
{
srcBlend = new SerializedShaderFloatValue(reader);
destBlend = new SerializedShaderFloatValue(reader);
srcBlendAlpha = new SerializedShaderFloatValue(reader);
destBlendAlpha = new SerializedShaderFloatValue(reader);
blendOp = new SerializedShaderFloatValue(reader);
blendOpAlpha = new SerializedShaderFloatValue(reader);
colMask = new SerializedShaderFloatValue(reader);
}
}
public class SerializedStencilOp
{
public SerializedShaderFloatValue pass;
public SerializedShaderFloatValue fail;
public SerializedShaderFloatValue zFail;
public SerializedShaderFloatValue comp;
public SerializedStencilOp(BinaryReader reader)
{
pass = new SerializedShaderFloatValue(reader);
fail = new SerializedShaderFloatValue(reader);
zFail = new SerializedShaderFloatValue(reader);
comp = new SerializedShaderFloatValue(reader);
}
}
public class SerializedShaderVectorValue
{
public SerializedShaderFloatValue x;
public SerializedShaderFloatValue y;
public SerializedShaderFloatValue z;
public SerializedShaderFloatValue w;
public string name;
public SerializedShaderVectorValue(BinaryReader reader)
{
x = new SerializedShaderFloatValue(reader);
y = new SerializedShaderFloatValue(reader);
z = new SerializedShaderFloatValue(reader);
w = new SerializedShaderFloatValue(reader);
name = reader.ReadAlignedString();
}
}
public enum FogMode
{
kFogUnknown = -1,
kFogDisabled = 0,
kFogLinear = 1,
kFogExp = 2,
kFogExp2 = 3,
kFogModeCount = 4
};
public class SerializedShaderState
{
public string m_Name;
public SerializedShaderRTBlendState rtBlend0;
public SerializedShaderRTBlendState rtBlend1;
public SerializedShaderRTBlendState rtBlend2;
public SerializedShaderRTBlendState rtBlend3;
public SerializedShaderRTBlendState rtBlend4;
public SerializedShaderRTBlendState rtBlend5;
public SerializedShaderRTBlendState rtBlend6;
public SerializedShaderRTBlendState rtBlend7;
public bool rtSeparateBlend;
public SerializedShaderFloatValue zClip;
public SerializedShaderFloatValue zTest;
public SerializedShaderFloatValue zWrite;
public SerializedShaderFloatValue culling;
public SerializedShaderFloatValue offsetFactor;
public SerializedShaderFloatValue offsetUnits;
public SerializedShaderFloatValue alphaToMask;
public SerializedStencilOp stencilOp;
public SerializedStencilOp stencilOpFront;
public SerializedStencilOp stencilOpBack;
public SerializedShaderFloatValue stencilReadMask;
public SerializedShaderFloatValue stencilWriteMask;
public SerializedShaderFloatValue stencilRef;
public SerializedShaderFloatValue fogStart;
public SerializedShaderFloatValue fogEnd;
public SerializedShaderFloatValue fogDensity;
public SerializedShaderVectorValue fogColor;
public FogMode fogMode;
public int gpuProgramID;
public SerializedTagMap m_Tags;
public int m_LOD;
public bool lighting;
public SerializedShaderState(ObjectReader reader)
{
var version = reader.version;
m_Name = reader.ReadAlignedString();
rtBlend0 = new SerializedShaderRTBlendState(reader);
rtBlend1 = new SerializedShaderRTBlendState(reader);
rtBlend2 = new SerializedShaderRTBlendState(reader);
rtBlend3 = new SerializedShaderRTBlendState(reader);
rtBlend4 = new SerializedShaderRTBlendState(reader);
rtBlend5 = new SerializedShaderRTBlendState(reader);
rtBlend6 = new SerializedShaderRTBlendState(reader);
rtBlend7 = new SerializedShaderRTBlendState(reader);
rtSeparateBlend = reader.ReadBoolean();
reader.AlignStream(4);
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
zClip = new SerializedShaderFloatValue(reader);
}
zTest = new SerializedShaderFloatValue(reader);
zWrite = new SerializedShaderFloatValue(reader);
culling = new SerializedShaderFloatValue(reader);
offsetFactor = new SerializedShaderFloatValue(reader);
offsetUnits = new SerializedShaderFloatValue(reader);
alphaToMask = new SerializedShaderFloatValue(reader);
stencilOp = new SerializedStencilOp(reader);
stencilOpFront = new SerializedStencilOp(reader);
stencilOpBack = new SerializedStencilOp(reader);
stencilReadMask = new SerializedShaderFloatValue(reader);
stencilWriteMask = new SerializedShaderFloatValue(reader);
stencilRef = new SerializedShaderFloatValue(reader);
fogStart = new SerializedShaderFloatValue(reader);
fogEnd = new SerializedShaderFloatValue(reader);
fogDensity = new SerializedShaderFloatValue(reader);
fogColor = new SerializedShaderVectorValue(reader);
fogMode = (FogMode)reader.ReadInt32();
gpuProgramID = reader.ReadInt32();
m_Tags = new SerializedTagMap(reader);
m_LOD = reader.ReadInt32();
lighting = reader.ReadBoolean();
reader.AlignStream(4);
}
}
public class ShaderBindChannel
{
public sbyte source;
public sbyte target;
public ShaderBindChannel(BinaryReader reader)
{
source = reader.ReadSByte();
target = reader.ReadSByte();
}
}
public class ParserBindChannels
{
public List<ShaderBindChannel> m_Channels;
public uint m_SourceMap;
public ParserBindChannels(BinaryReader reader)
{
int numChannels = reader.ReadInt32();
m_Channels = new List<ShaderBindChannel>(numChannels);
for (int i = 0; i < numChannels; i++)
{
m_Channels.Add(new ShaderBindChannel(reader));
}
reader.AlignStream(4);
m_SourceMap = reader.ReadUInt32();
}
}
public class VectorParameter
{
public int m_NameIndex;
public int m_Index;
public int m_ArraySize;
public sbyte m_Type;
public sbyte m_Dim;
public VectorParameter(BinaryReader reader)
{
m_NameIndex = reader.ReadInt32();
m_Index = reader.ReadInt32();
m_ArraySize = reader.ReadInt32();
m_Type = reader.ReadSByte();
m_Dim = reader.ReadSByte();
reader.AlignStream(4);
}
}
public class MatrixParameter
{
public int m_NameIndex;
public int m_Index;
public int m_ArraySize;
public sbyte m_Type;
public sbyte m_RowCount;
public MatrixParameter(BinaryReader reader)
{
m_NameIndex = reader.ReadInt32();
m_Index = reader.ReadInt32();
m_ArraySize = reader.ReadInt32();
m_Type = reader.ReadSByte();
m_RowCount = reader.ReadSByte();
reader.AlignStream(4);
}
}
public class TextureParameter
{
public int m_NameIndex;
public int m_Index;
public int m_SamplerIndex;
public sbyte m_Dim;
public TextureParameter(ObjectReader reader)
{
var version = reader.version;
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
{
var m_MultiSampled = reader.ReadBoolean();
}
m_Dim = reader.ReadSByte();
reader.AlignStream(4);
}
}
public class BufferBinding
{
public int m_NameIndex;
public int m_Index;
public BufferBinding(BinaryReader reader)
{
m_NameIndex = reader.ReadInt32();
m_Index = reader.ReadInt32();
}
}
public class ConstantBuffer
{
public int m_NameIndex;
public List<MatrixParameter> m_MatrixParams;
public List<VectorParameter> m_VectorParams;
public List<StructParameter> m_StructParams;
public int m_Size;
public ConstantBuffer(ObjectReader reader)
{
var version = reader.version;
m_NameIndex = reader.ReadInt32();
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new List<MatrixParameter>(numMatrixParams);
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams.Add(new MatrixParameter(reader));
}
int numVectorParams = reader.ReadInt32();
m_VectorParams = new List<VectorParameter>(numVectorParams);
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams.Add(new VectorParameter(reader));
}
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
{
int numStructParams = reader.ReadInt32();
m_StructParams = new List<StructParameter>(numStructParams);
for (int i = 0; i < numStructParams; i++)
{
m_StructParams.Add(new StructParameter(reader));
}
}
m_Size = reader.ReadInt32();
}
}
public class UAVParameter
{
public int m_NameIndex;
public int m_Index;
public int m_OriginalIndex;
public UAVParameter(BinaryReader reader)
{
m_NameIndex = reader.ReadInt32();
m_Index = reader.ReadInt32();
m_OriginalIndex = reader.ReadInt32();
}
}
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,
};
public class SerializedSubProgram
{
public uint m_BlobIndex;
public ParserBindChannels m_Channels;
public List<ushort> m_KeywordIndices;
public sbyte m_ShaderHardwareTier;
public ShaderGpuProgramType m_GpuProgramType;
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 SerializedSubProgram(ObjectReader reader)
{
var version = reader.version;
m_BlobIndex = reader.ReadUInt32();
m_Channels = new ParserBindChannels(reader);
int numIndices = reader.ReadInt32();
m_KeywordIndices = new List<ushort>(numIndices);
for (int i = 0; i < numIndices; i++)
{
m_KeywordIndices.Add(reader.ReadUInt16());
}
if (version[0] >= 2017) //2017 and up
{
reader.AlignStream(4);
}
m_ShaderHardwareTier = reader.ReadSByte();
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
reader.AlignStream(4);
int numVectorParams = reader.ReadInt32();
m_VectorParams = new List<VectorParameter>(numVectorParams);
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams.Add(new VectorParameter(reader));
}
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new List<MatrixParameter>(numMatrixParams);
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams.Add(new MatrixParameter(reader));
}
int numTextureParams = reader.ReadInt32();
m_TextureParams = new List<TextureParameter>(numTextureParams);
for (int i = 0; i < numTextureParams; i++)
{
m_TextureParams.Add(new TextureParameter(reader));
}
int numBufferParams = reader.ReadInt32();
m_BufferParams = new List<BufferBinding>(numBufferParams);
for (int i = 0; i < numBufferParams; i++)
{
m_BufferParams.Add(new BufferBinding(reader));
}
int numConstantBuffers = reader.ReadInt32();
m_ConstantBuffers = new List<ConstantBuffer>(numConstantBuffers);
for (int i = 0; i < numConstantBuffers; i++)
{
m_ConstantBuffers.Add(new ConstantBuffer(reader));
}
int numConstantBufferBindings = reader.ReadInt32();
m_ConstantBufferBindings = new List<BufferBinding>(numConstantBufferBindings);
for (int i = 0; i < numConstantBufferBindings; i++)
{
m_ConstantBufferBindings.Add(new BufferBinding(reader));
}
int numUAVParams = reader.ReadInt32();
m_UAVParams = new List<UAVParameter>(numUAVParams);
for (int i = 0; i < numUAVParams; i++)
{
m_UAVParams.Add(new UAVParameter(reader));
}
if (version[0] >= 2017) //2017 and up
{
int numSamplers = reader.ReadInt32();
m_Samplers = new List<SamplerParameter>(numSamplers);
for (int i = 0; i < numSamplers; i++)
{
m_Samplers.Add(new SamplerParameter(reader));
}
}
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
var m_ShaderRequirements = reader.ReadInt32();
}
}
}
public class SerializedProgram
{
public List<SerializedSubProgram> m_SubPrograms;
public SerializedProgram(ObjectReader reader)
{
int numSubPrograms = reader.ReadInt32();
m_SubPrograms = new List<SerializedSubProgram>(numSubPrograms);
for (int i = 0; i < numSubPrograms; i++)
{
m_SubPrograms.Add(new SerializedSubProgram(reader));
}
}
}
public enum PassType
{
kPassTypeNormal = 0,
kPassTypeUse = 1,
kPassTypeGrab = 2
};
public class SerializedPass
{
public List<KeyValuePair<string, int>> m_NameIndices;
public PassType m_Type;
public SerializedShaderState m_State;
public uint m_ProgramMask;
public SerializedProgram progVertex;
public SerializedProgram progFragment;
public SerializedProgram progGeometry;
public SerializedProgram progHull;
public SerializedProgram progDomain;
public bool m_HasInstancingVariant;
public string m_UseName;
public string m_Name;
public string m_TextureName;
public SerializedTagMap m_Tags;
public SerializedPass(ObjectReader reader)
{
var version = reader.version;
int numIndices = reader.ReadInt32();
m_NameIndices = new List<KeyValuePair<string, int>>(numIndices);
for (int i = 0; i < numIndices; i++)
{
m_NameIndices.Add(new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32()));
}
m_Type = (PassType)reader.ReadInt32();
m_State = new SerializedShaderState(reader);
m_ProgramMask = reader.ReadUInt32();
progVertex = new SerializedProgram(reader);
progFragment = new SerializedProgram(reader);
progGeometry = new SerializedProgram(reader);
progHull = new SerializedProgram(reader);
progDomain = new SerializedProgram(reader);
m_HasInstancingVariant = reader.ReadBoolean();
if (version[0] >= 2018) //2018 and up
{
var m_HasProceduralInstancingVariant = reader.ReadBoolean();
}
reader.AlignStream(4);
m_UseName = reader.ReadAlignedString();
m_Name = reader.ReadAlignedString();
m_TextureName = reader.ReadAlignedString();
m_Tags = new SerializedTagMap(reader);
}
}
public class SerializedTagMap
{
public List<KeyValuePair<string, string>> tags;
public SerializedTagMap(BinaryReader reader)
{
int numTags = reader.ReadInt32();
tags = new List<KeyValuePair<string, string>>(numTags);
for (int i = 0; i < numTags; i++)
{
tags.Add(new KeyValuePair<string, string>(reader.ReadAlignedString(), reader.ReadAlignedString()));
}
}
}
public class SerializedSubShader
{
public List<SerializedPass> m_Passes;
public SerializedTagMap m_Tags;
public int m_LOD;
public SerializedSubShader(ObjectReader reader)
{
int numPasses = reader.ReadInt32();
m_Passes = new List<SerializedPass>(numPasses);
for (int i = 0; i < numPasses; i++)
{
m_Passes.Add(new SerializedPass(reader));
}
m_Tags = new SerializedTagMap(reader);
m_LOD = reader.ReadInt32();
}
}
public class SerializedShaderDependency
{
public string from;
public string to;
public SerializedShaderDependency(BinaryReader reader)
{
from = reader.ReadAlignedString();
to = reader.ReadAlignedString();
}
}
public class SerializedShader
{
public SerializedProperties m_PropInfo;
public List<SerializedSubShader> m_SubShaders;
public string m_Name;
public string m_CustomEditorName;
public string m_FallbackName;
public List<SerializedShaderDependency> m_Dependencies;
public bool m_DisableNoSubshadersMessage;
public SerializedShader(ObjectReader reader)
{
m_PropInfo = new SerializedProperties(reader);
int numSubShaders = reader.ReadInt32();
m_SubShaders = new List<SerializedSubShader>(numSubShaders);
for (int i = 0; i < numSubShaders; i++)
{
m_SubShaders.Add(new SerializedSubShader(reader));
}
m_Name = reader.ReadAlignedString();
m_CustomEditorName = reader.ReadAlignedString();
m_FallbackName = reader.ReadAlignedString();
int numDependencies = reader.ReadInt32();
m_Dependencies = new List<SerializedShaderDependency>(numDependencies);
for (int i = 0; i < numDependencies; i++)
{
m_Dependencies.Add(new SerializedShaderDependency(reader));
}
m_DisableNoSubshadersMessage = reader.ReadBoolean();
reader.AlignStream(4);
}
}
public class Shader : NamedObject
{
public byte[] m_Script;
//5.3 - 5.4
public uint decompressedSize;
public byte[] m_SubProgramBlob;
//5.5 and up
public SerializedShader m_ParsedForm;
public List<uint> platforms;
public List<uint> offsets;
public List<uint> compressedLengths;
public List<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
{
m_ParsedForm = new SerializedShader(reader);
int numPlatforms = reader.ReadInt32();
platforms = new List<uint>(numPlatforms);
for (int i = 0; i < numPlatforms; i++)
{
platforms.Add(reader.ReadUInt32());
}
int numOffsets = reader.ReadInt32();
offsets = new List<uint>(numOffsets);
for (int i = 0; i < numOffsets; i++)
{
offsets.Add(reader.ReadUInt32());
}
int numCompressedLengths = reader.ReadInt32();
compressedLengths = new List<uint>(numCompressedLengths);
for (int i = 0; i < numCompressedLengths; i++)
{
compressedLengths.Add(reader.ReadUInt32());
}
int numDecompressedLengths = reader.ReadInt32();
decompressedLengths = new List<uint>(numDecompressedLengths);
for (int i = 0; i < numDecompressedLengths; i++)
{
decompressedLengths.Add(reader.ReadUInt32());
}
compressedBlob = reader.ReadBytes(reader.ReadInt32());
}
else
{
m_Script = reader.ReadBytes(reader.ReadInt32());
reader.AlignStream(4);
var m_PathName = reader.ReadAlignedString();
if (version[0] == 5 && version[1] >= 3) //5.3 - 5.4
{
decompressedSize = reader.ReadUInt32();
m_SubProgramBlob = reader.ReadBytes(reader.ReadInt32());
}
}
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class SkinnedMeshRenderer : Renderer
{
public PPtr m_Mesh;
public PPtr[] m_Bones;
public List<float> m_BlendShapeWeights;
public SkinnedMeshRenderer(ObjectReader reader) : base(reader)
{
int m_Quality = reader.ReadInt32();
var m_UpdateWhenOffscreen = reader.ReadBoolean();
var m_SkinNormals = reader.ReadBoolean(); //3.1.0 and below
reader.AlignStream(4);
if (version[0] == 2 && version[1] < 6)//2.6 down
{
var m_DisableAnimationWhenOffscreen = reader.ReadPPtr();
}
m_Mesh = reader.ReadPPtr();
m_Bones = new PPtr[reader.ReadInt32()];
for (int b = 0; b < m_Bones.Length; b++)
{
m_Bones[b] = reader.ReadPPtr();
}
if (version[0] < 3)
{
int m_BindPose = reader.ReadInt32();
reader.Position += m_BindPose * 16 * 4;//Matrix4x4f
}
else
{
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3))//4.3 and up
{
int numBSWeights = reader.ReadInt32();
m_BlendShapeWeights = new List<float>(numBSWeights);
for (int i = 0; i < numBSWeights; i++)
{
m_BlendShapeWeights.Add(reader.ReadSingle());
}
}
}
}
}
}

View File

@@ -0,0 +1,215 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using SharpDX;
using RectangleF = System.Drawing.RectangleF;
namespace AssetStudio
{
public enum SpritePackingRotation
{
kSPRNone = 0,
kSPRFlipHorizontal = 1,
kSPRFlipVertical = 2,
kSPRRotate180 = 3,
kSPRRotate90 = 4
};
public enum SpritePackingMode
{
kSPMTight = 0,
kSPMRectangle
};
public class SpriteSettings
{
public uint settingsRaw;
public uint packed;
public SpritePackingMode packingMode;
public SpritePackingRotation packingRotation;
public SpriteSettings(ObjectReader reader)
{
settingsRaw = reader.ReadUInt32();
packed = settingsRaw & 1; //1
packingMode = (SpritePackingMode)((settingsRaw >> 1) & 1); //1
packingRotation = (SpritePackingRotation)((settingsRaw >> 2) & 0xf); //4
//meshType = (settingsRaw >> 6) & 1; //1
//reserved
}
}
public sealed class Sprite : NamedObject
{
public RectangleF m_Rect;
public float m_PixelsToUnits;
public Vector2 m_Pivot;
public Tuple<Guid, long> m_RenderDataKey;
public PPtr texture;
public PPtr m_SpriteAtlas;
public RectangleF textureRect;
public SpriteSettings settingsRaw;
public PointF[][] m_PhysicsShape; //Vector2[][]
public Sprite(ObjectReader reader) : base(reader)
{
//Rectf m_Rect
m_Rect = reader.ReadRectangleF();
//Vector2f m_Offset
reader.Position += 8;
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
//Vector4f m_Border
reader.Position += 16;
}
m_PixelsToUnits = reader.ReadSingle();
if (version[0] > 5
|| (version[0] == 5 && version[1] > 4)
|| (version[0] == 5 && version[1] == 4 && version[2] >= 2)) //5.4.2 and up
{
//Vector2f m_Pivot
m_Pivot = reader.ReadVector2();
}
var m_Extrude = reader.ReadUInt32();
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up
{
var m_IsPolygon = reader.ReadBoolean();
reader.AlignStream(4);
}
if (version[0] >= 2017) //2017 and up
{
//pair m_RenderDataKey
var first = new Guid(reader.ReadBytes(16));
var second = reader.ReadInt64();
m_RenderDataKey = new Tuple<Guid, long>(first, second);
//vector m_AtlasTags
var size = reader.ReadInt32();
for (int i = 0; i < size; i++)
{
var data = reader.ReadAlignedString();
}
//PPtr<SpriteAtlas> m_SpriteAtlas
m_SpriteAtlas = reader.ReadPPtr();
}
//SpriteRenderData m_RD
// PPtr<Texture2D> texture
texture = reader.ReadPPtr();
// PPtr<Texture2D> alphaTexture
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
{
var alphaTexture = reader.ReadPPtr();
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
// vector m_SubMeshes
var size = reader.ReadInt32();
// SubMesh data
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
{
reader.Position += 48 * size;
}
else
{
reader.Position += 44 * size;
}
// vector m_IndexBuffer
size = reader.ReadInt32();
reader.Position += size; //UInt8 data
reader.AlignStream(4);
// VertexData m_VertexData
if (version[0] < 2018)//2018 down
{
var m_CurrentChannels = reader.ReadInt32();
}
var m_VertexCount = reader.ReadUInt32();
// vector m_Channels
size = reader.ReadInt32();
reader.Position += size * 4; //ChannelInfo data
// TypelessData m_DataSize
size = reader.ReadInt32();
reader.Position += size; //UInt8 data
reader.AlignStream(4);
if (version[0] >= 2018)//2018 and up
{
// vector m_Bindpose
// Matrix4x4f data
size = reader.ReadInt32();
reader.Position += size * 64;
if (version[0] == 2018 && version[1] < 2) //2018.2 down
{
// vector m_SourceSkin
// BoneWeights4 data
size = reader.ReadInt32();
reader.Position += size * 32;
}
}
}
else
{
// vector vertices
var size = reader.ReadInt32();
for (int i = 0; i < size; i++)
{
//SpriteVertex data
reader.Position += 12; //Vector3f pos
if (version[0] < 4 || (version[0] == 4 && version[1] <= 3)) //4.3 and down
reader.Position += 8; //Vector2f uv
}
// vector indices
size = reader.ReadInt32();
reader.Position += 2 * size; //UInt16 data
reader.AlignStream(4);
}
// Rectf textureRect
textureRect = reader.ReadRectangleF();
// Vector2f textureRectOffset
reader.Position += 8;
// Vector2f atlasRectOffset - 5.6 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
reader.Position += 8;
}
// unsigned int settingsRaw
settingsRaw = new SpriteSettings(reader);
// Vector4f uvTransform - 4.5 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
reader.Position += 16;
}
if (version[0] >= 2017) //2017 and up
{
// float downscaleMultiplier - 2017 and up
reader.Position += 4;
//vector m_PhysicsShape - 2017 and up
var m_PhysicsShape_size = reader.ReadInt32();
m_PhysicsShape = new PointF[m_PhysicsShape_size][];
for (int i = 0; i < m_PhysicsShape_size; i++)
{
var data_size = reader.ReadInt32();
//Vector2f
m_PhysicsShape[i] = new PointF[data_size];
for (int j = 0; j < data_size; j++)
{
m_PhysicsShape[i][j] = new PointF(reader.ReadSingle(), reader.ReadSingle());
}
}
}
//vector m_Bones 2018 and up
}
}
}

View File

@@ -0,0 +1,69 @@
using SharpDX;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class SpriteAtlasData
{
public PPtr texture;
public PPtr alphaTexture;
public System.Drawing.RectangleF textureRect;
public Vector2 textureRectOffset;
public Vector2 atlasRectOffset;
public Vector4 uvTransform;
public float downscaleMultiplier;
public SpriteSettings settingsRaw;
public SpriteAtlasData(ObjectReader reader)
{
var version = reader.version;
texture = reader.ReadPPtr();
alphaTexture = reader.ReadPPtr();
textureRect = reader.ReadRectangleF();
textureRectOffset = reader.ReadVector2();
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
atlasRectOffset = reader.ReadVector2();
}
uvTransform = reader.ReadVector4();
downscaleMultiplier = reader.ReadSingle();
settingsRaw = new SpriteSettings(reader);
}
}
public sealed class SpriteAtlas : NamedObject
{
public Dictionary<Tuple<Guid, long>, SpriteAtlasData> m_RenderDataMap;
public SpriteAtlas(ObjectReader reader) : base(reader)
{
var m_PackedSpritesSize = reader.ReadInt32();
for (int i = 0; i < m_PackedSpritesSize; i++)
{
reader.ReadPPtr(); //PPtr<Sprite> data
}
var m_PackedSpriteNamesToIndexSize = reader.ReadInt32();
for (int i = 0; i < m_PackedSpriteNamesToIndexSize; i++)
{
reader.ReadAlignedString();
}
var m_RenderDataMapSize = reader.ReadInt32();
m_RenderDataMap = new Dictionary<Tuple<Guid, long>, SpriteAtlasData>(m_RenderDataMapSize);
for (int 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 Tuple<Guid, long>(first, second), value);
}
//string m_Tag
//bool m_IsVariant
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace AssetStudio
{
public sealed class TextAsset : NamedObject
{
public byte[] m_Script;
public TextAsset(ObjectReader reader) : base(reader)
{
m_Script = reader.ReadBytes(reader.ReadInt32());
}
}
}

View File

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

View File

@@ -0,0 +1,178 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace AssetStudio
{
public sealed class Texture2D : Texture
{
public int m_Width;
public int m_Height;
public int m_CompleteImageSize;
public TextureFormat m_TextureFormat;
public bool m_MipMap;
public int m_MipCount;
public bool m_IsReadable;
public bool m_ReadAllowed;
public int m_ImageCount;
public int m_TextureDimension;
//m_TextureSettings
public int m_FilterMode;
public int m_Aniso;
public float m_MipBias;
public int m_WrapMode;
public int m_LightmapFormat;
public int m_ColorSpace;
//image dataa
public int image_data_size;
public byte[] image_data;
//m_StreamData
public uint offset;
public uint size;
public string path;
public Texture2D(ObjectReader reader, bool readData) : base(reader)
{
m_Width = reader.ReadInt32();
m_Height = reader.ReadInt32();
m_CompleteImageSize = reader.ReadInt32();
m_TextureFormat = (TextureFormat)reader.ReadInt32();
if (version[0] < 5 || (version[0] == 5 && version[1] < 2))
{
m_MipMap = reader.ReadBoolean();
}
else
{
m_MipCount = reader.ReadInt32();
}
m_IsReadable = reader.ReadBoolean(); //2.6.0 and up
m_ReadAllowed = reader.ReadBoolean(); //3.0.0 - 5.4
//m_StreamingMipmaps 2018.2 and up
reader.AlignStream(4);
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
var m_StreamingMipmapsPriority = reader.ReadInt32();
}
else if (reader.HasStructMember("m_StreamingMipmapsPriority")) //will fix in some patch version bundle
{
var m_StreamingMipmapsPriority = reader.ReadInt32();
}
if (reader.HasStructMember("m_StreamingGroupID")) //What the hell is this?
{
var m_StreamingGroupID = reader.ReadUInt32();
}
m_ImageCount = reader.ReadInt32();
m_TextureDimension = reader.ReadInt32();
//m_TextureSettings
m_FilterMode = reader.ReadInt32();
m_Aniso = reader.ReadInt32();
m_MipBias = reader.ReadSingle();
if (version[0] >= 2017)//2017.x and up
{
int m_WrapU = reader.ReadInt32();
int m_WrapV = reader.ReadInt32();
int m_WrapW = reader.ReadInt32();
}
else
{
m_WrapMode = reader.ReadInt32();
}
if (version[0] >= 3)
{
m_LightmapFormat = reader.ReadInt32();
if (version[0] >= 4 || version[1] >= 5)//3.5.0 and up
{
m_ColorSpace = reader.ReadInt32();
}
}
image_data_size = reader.ReadInt32();
if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up
{
offset = reader.ReadUInt32();
size = reader.ReadUInt32();
image_data_size = (int)size;
path = reader.ReadAlignedString();
}
if (readData)
{
if (!string.IsNullOrEmpty(path))
{
image_data = ResourcesHelper.GetData(path, sourceFile, offset, image_data_size);
}
else
{
image_data = reader.ReadBytes(image_data_size);
}
}
}
}
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,
}
}

View File

@@ -0,0 +1,31 @@
using SharpDX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class Transform : Component
{
public float[] m_LocalRotation;
public float[] m_LocalPosition;
public float[] m_LocalScale;
public List<PPtr> m_Children;
public PPtr m_Father;
public Transform(ObjectReader reader) : base(reader)
{
m_LocalRotation = new[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() };
m_LocalPosition = new[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() };
m_LocalScale = new[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() };
int m_ChildrenCount = reader.ReadInt32();
m_Children = new List<PPtr>(m_ChildrenCount);
for (int j = 0; j < m_ChildrenCount; j++)
{
m_Children.Add(reader.ReadPPtr());
}
m_Father = reader.ReadPPtr();
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class VideoClip : NamedObject
{
public byte[] m_VideoData;
public string m_OriginalPath;
public string m_Source;
public ulong m_Size;
public VideoClip(ObjectReader reader, bool readData) : 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)//2017.x and up
{
var m_PixelAspecRatioNum = reader.ReadUInt32();
var m_PixelAspecRatioDen = reader.ReadUInt32();
}
var m_FrameRate = reader.ReadDouble();
var m_FrameCount = reader.ReadUInt64();
var m_Format = reader.ReadInt32();
//m_AudioChannelCount
var size = reader.ReadInt32();
reader.Position += size * 2;
reader.AlignStream(4);
//m_AudioSampleRate
size = reader.ReadInt32();
reader.Position += size * 4;
//m_AudioLanguage
size = reader.ReadInt32();
for (int i = 0; i < size; i++)
{
reader.ReadAlignedString();
}
//StreamedResource m_ExternalResources
m_Source = reader.ReadAlignedString();
var m_Offset = reader.ReadUInt64();
m_Size = reader.ReadUInt64();
var m_HasSplitAlpha = reader.ReadBoolean();
if (readData)
{
if (!string.IsNullOrEmpty(m_Source))
{
m_VideoData = ResourcesHelper.GetData(m_Source, sourceFile, (long)m_Offset, (int)m_Size);
}
else
{
if (m_Size > 0)
m_VideoData = reader.ReadBytes((int)m_Size);
}
}
}
}
}

116
AssetStudio/CommonString.cs Normal file
View File

@@ -0,0 +1,116 @@
using System.Collections.Generic;
namespace AssetStudio
{
public static class CommonString
{
public static readonly Dictionary<int, string> StringBuffer = new Dictionary<int, string>
{
{0, "AABB"},
{5, "AnimationClip"},
{19, "AnimationCurve"},
{34, "AnimationState"},
{49, "Array"},
{55, "Base"},
{60, "BitField"},
{69, "bitset"},
{76, "bool"},
{81, "char"},
{86, "ColorRGBA"},
{96, "Component"},
{106, "data"},
{111, "deque"},
{117, "double"},
{124, "dynamic_array"},
{138, "FastPropertyName"},
{155, "first"},
{161, "float"},
{167, "Font"},
{172, "GameObject"},
{183, "Generic Mono"},
{196, "GradientNEW"},
{208, "GUID"},
{213, "GUIStyle"},
{222, "int"},
{226, "list"},
{231, "long long"},
{241, "map"},
{245, "Matrix4x4f"},
{256, "MdFour"},
{263, "MonoBehaviour"},
{277, "MonoScript"},
{288, "m_ByteSize"},
{299, "m_Curve"},
{307, "m_EditorClassIdentifier"},
{331, "m_EditorHideFlags"},
{349, "m_Enabled"},
{359, "m_ExtensionPtr"},
{374, "m_GameObject"},
{387, "m_Index"},
{395, "m_IsArray"},
{405, "m_IsStatic"},
{416, "m_MetaFlag"},
{427, "m_Name"},
{434, "m_ObjectHideFlags"},
{452, "m_PrefabInternal"},
{469, "m_PrefabParentObject"},
{490, "m_Script"},
{499, "m_StaticEditorFlags"},
{519, "m_Type"},
{526, "m_Version"},
{536, "Object"},
{543, "pair"},
{548, "PPtr<Component>"},
{564, "PPtr<GameObject>"},
{581, "PPtr<Material>"},
{596, "PPtr<MonoBehaviour>"},
{616, "PPtr<MonoScript>"},
{633, "PPtr<Object>"},
{646, "PPtr<Prefab>"},
{659, "PPtr<Sprite>"},
{672, "PPtr<TextAsset>"},
{688, "PPtr<Texture>"},
{702, "PPtr<Texture2D>"},
{718, "PPtr<Transform>"},
{734, "Prefab"},
{741, "Quaternionf"},
{753, "Rectf"},
{759, "RectInt"},
{767, "RectOffset"},
{778, "second"},
{785, "set"},
{789, "short"},
{795, "size"},
{800, "SInt16"},
{807, "SInt32"},
{814, "SInt64"},
{821, "SInt8"},
{827, "staticvector"},
{840, "string"},
{847, "TextAsset"},
{857, "TextMesh"},
{866, "Texture"},
{874, "Texture2D"},
{884, "Transform"},
{894, "TypelessData"},
{907, "UInt16"},
{914, "UInt32"},
{921, "UInt64"},
{928, "UInt8"},
{934, "unsigned int"},
{947, "unsigned long long"},
{966, "unsigned short"},
{981, "vector"},
{988, "Vector2f"},
{997, "Vector3f"},
{1006, "Vector4f"},
{1015, "m_ScriptingClassIdentifier"},
{1042, "Gradient"},
{1051, "Type*"},
{1057, "int2_storage"},
{1070, "int3_storage"},
{1083, "BoundsInt"},
{1092, "m_CorrespondingSourceObject"}
};
}
}

View File

@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace AssetStudio
{
public enum EndianType
{
LittleEndian,
BigEndian
}
public class EndianBinaryReader : BinaryReader
{
public EndianType endian;
public EndianBinaryReader(Stream stream, EndianType endian = EndianType.BigEndian) : base(stream)
{
this.endian = endian;
}
public long Position
{
get => BaseStream.Position;
set => BaseStream.Position = value;
}
public override short ReadInt16()
{
if (endian == EndianType.BigEndian)
{
var buff = ReadBytes(2);
Array.Reverse(buff);
return BitConverter.ToInt16(buff, 0);
}
return base.ReadInt16();
}
public override int ReadInt32()
{
if (endian == EndianType.BigEndian)
{
var buff = ReadBytes(4);
Array.Reverse(buff);
return BitConverter.ToInt32(buff, 0);
}
return base.ReadInt32();
}
public override long ReadInt64()
{
if (endian == EndianType.BigEndian)
{
var buff = ReadBytes(8);
Array.Reverse(buff);
return BitConverter.ToInt64(buff, 0);
}
return base.ReadInt64();
}
public override ushort ReadUInt16()
{
if (endian == EndianType.BigEndian)
{
var buff = ReadBytes(2);
Array.Reverse(buff);
return BitConverter.ToUInt16(buff, 0);
}
return base.ReadUInt16();
}
public override uint ReadUInt32()
{
if (endian == EndianType.BigEndian)
{
var buff = ReadBytes(4);
Array.Reverse(buff);
return BitConverter.ToUInt32(buff, 0);
}
return base.ReadUInt32();
}
public override ulong ReadUInt64()
{
if (endian == EndianType.BigEndian)
{
var buff = ReadBytes(8);
Array.Reverse(buff);
return BitConverter.ToUInt64(buff, 0);
}
return base.ReadUInt64();
}
public override float ReadSingle()
{
if (endian == EndianType.BigEndian)
{
var buff = ReadBytes(4);
Array.Reverse(buff);
return BitConverter.ToSingle(buff, 0);
}
return base.ReadSingle();
}
public override double ReadDouble()
{
if (endian == EndianType.BigEndian)
{
var buff = ReadBytes(8);
Array.Reverse(buff);
return BitConverter.ToUInt64(buff, 0);
}
return base.ReadDouble();
}
}
}

View File

@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using SharpDX;
namespace AssetStudio
{
public static class BinaryReaderExtensions
{
public static void AlignStream(this BinaryReader reader, int alignment)
{
var pos = reader.BaseStream.Position;
var mod = pos % alignment;
if (mod != 0)
{
reader.BaseStream.Position += alignment - mod;
}
}
public static string ReadAlignedString(this BinaryReader reader)
{
var length = reader.ReadInt32();
if (length > 0 && length < (reader.BaseStream.Length - reader.BaseStream.Position))
{
var stringData = reader.ReadBytes(length);
var result = Encoding.UTF8.GetString(stringData);
reader.AlignStream(4);
return result;
}
return "";
}
public static string ReadStringToNull(this BinaryReader reader)
{
var bytes = new List<byte>();
byte b;
while (reader.BaseStream.Position != reader.BaseStream.Length && (b = reader.ReadByte()) != 0)
bytes.Add(b);
return Encoding.UTF8.GetString(bytes.ToArray());
}
public static Quaternion ReadQuaternion(this BinaryReader reader)
{
return new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
public static Vector2 ReadVector2(this BinaryReader reader)
{
return new Vector2(reader.ReadSingle(), reader.ReadSingle());
}
public static Vector3 ReadVector3(this BinaryReader reader)
{
return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
public static Vector4 ReadVector4(this BinaryReader reader)
{
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());
}
private static T[] ReadArray<T>(Func<T> del, int length)
{
var array = new T[length];
for (int i = 0; i < array.Length; i++)
{
array[i] = del();
}
return array;
}
public static int[] ReadInt32Array(this BinaryReader reader, int length)
{
return ReadArray(reader.ReadInt32, length);
}
public static uint[] ReadUInt32Array(this BinaryReader reader, int length)
{
return ReadArray(reader.ReadUInt32, length);
}
public static float[] ReadSingleArray(this BinaryReader reader, int length)
{
return ReadArray(reader.ReadSingle, length);
}
public static Vector2[] ReadVector2Array(this BinaryReader reader, int length)
{
return ReadArray(reader.ReadVector2, length);
}
public static Vector4[] ReadVector4Array(this BinaryReader reader, int length)
{
return ReadArray(reader.ReadVector4, length);
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.IO;
using System.Text;
namespace AssetStudio
{
public static class BinaryWriterExtensions
{
private static void WriteArray<T>(Action<T> del, T[] array)
{
foreach (var item in array)
{
del(item);
}
}
public static void Write(this BinaryWriter writer, uint[] array)
{
WriteArray(writer.Write, array);
}
public static void AlignStream(this BinaryWriter writer, int alignment)
{
var pos = writer.BaseStream.Position;
var mod = pos % alignment;
if (mod != 0)
{
writer.Write(new byte[alignment - mod]);
}
}
public static void WriteAlignedString(this BinaryWriter writer, string str)
{
var bytes = Encoding.UTF8.GetBytes(str);
writer.Write(bytes.Length);
writer.Write(bytes);
writer.AlignStream(4);
}
}
}

View File

@@ -0,0 +1,24 @@
using System.IO;
namespace AssetStudio
{
public static class StreamExtensions
{
private const int BufferSize = 81920;
public static void CopyTo(this Stream source, Stream destination, long size)
{
var buffer = new byte[BufferSize];
for (var left = size; left > 0; left -= BufferSize)
{
int toRead = BufferSize < left ? BufferSize : (int)left;
int read = source.Read(buffer, 0, toRead);
destination.Write(buffer, 0, read);
if (read != toRead)
{
return;
}
}
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class FileIdentifier
{
public Guid guid;
public int type; //enum { kNonAssetType = 0, kDeprecatedCachedAssetType = 1, kSerializedAssetType = 2, kMetaAssetType = 3 };
public string pathName;
//custom
public string fileName;
}
}

104
AssetStudio/ImportHelper.cs Normal file
View File

@@ -0,0 +1,104 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace AssetStudio
{
public enum FileType
{
AssetsFile,
BundleFile,
WebFile
}
public static class ImportHelper
{
public static void MergeSplitAssets(string path, bool allDirectories = false)
{
var splitFiles = Directory.GetFiles(path, "*.split0", allDirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
foreach (var splitFile in splitFiles)
{
var destFile = Path.GetFileNameWithoutExtension(splitFile);
var destPath = Path.GetDirectoryName(splitFile) + "\\";
var destFull = destPath + destFile;
if (!File.Exists(destFull))
{
var splitParts = Directory.GetFiles(destPath, destFile + ".split*");
using (var destStream = File.Create(destFull))
{
for (int i = 0; i < splitParts.Length; i++)
{
var splitPart = destFull + ".split" + i;
using (var sourceStream = File.OpenRead(splitPart))
{
sourceStream.CopyTo(destStream);
}
}
}
}
}
}
public static string[] ProcessingSplitFiles(List<string> selectFile)
{
var splitFiles = selectFile.Where(x => x.Contains(".split"))
.Select(x => Path.GetDirectoryName(x) + "\\" + Path.GetFileNameWithoutExtension(x))
.Distinct()
.ToList();
selectFile.RemoveAll(x => x.Contains(".split"));
foreach (var file in splitFiles)
{
if (File.Exists(file))
{
selectFile.Add(file);
}
}
return selectFile.Distinct().ToArray();
}
public static FileType CheckFileType(Stream stream, out EndianBinaryReader 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();
reader.Position = 0;
switch (signature)
{
case "UnityWeb":
case "UnityRaw":
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA":
case "UnityFS":
return FileType.BundleFile;
case "UnityWebData1.0":
return FileType.WebFile;
default:
{
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;
}
return FileType.AssetsFile;
}
}
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,19 @@
Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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