11import type { Bundle } from './bundle' ;
22import type { AssetObject } from './classes' ;
33import { createAssetObject } from './classes' ;
4+ import { ObjectInfo } from './object' ;
5+ import { SerializedType } from './serializedType' ;
46import { ArrayBufferReader } from './utils/reader' ;
57
6- interface AssetHeader {
8+ export interface AssetHeader {
79 metadataSize : number ;
810 fileSize : number ;
911 version : number ;
1012 dataOffset : number ;
1113 endianness : number ;
1214}
1315
14- interface TypeInfo {
15- classId : number ;
16- }
17-
18- export interface ObjectInfo {
19- getReader : ( ) => ArrayBufferReader ;
20- bundle : Bundle ;
21- buildType : string ;
22- assetVersion : number ;
23- bytesStart : number ;
24- bytesSize : number ;
25- typeId : number ;
26- classId : number ;
27- isDestroyed : number ;
28- stripped : number ;
29- pathId : bigint ;
30- version : number [ ] ;
31- }
32-
3316export class Asset {
34- private readonly reader : ArrayBufferReader ;
35- private readonly header : AssetHeader ;
36- private readonly fileEndianness : number = 0 ;
37- private readonly unityVersion : string = '' ;
38- private readonly version : number [ ] = [ ] ;
39- private readonly buildType : string = '' ;
40- private readonly targetPlatform : number = 0 ;
41- private readonly enableTypeTree : boolean = false ;
42- private readonly enableBigId : boolean = false ;
43- private readonly types : TypeInfo [ ] = [ ] ;
44- private readonly objectInfos : ObjectInfo [ ] = [ ] ;
45- private readonly cloneReader = ( ) => this . reader . clone ( ) ;
17+ readonly header : AssetHeader ;
18+ readonly fileEndianness : number = 0 ;
19+ readonly unityVersion : string = '' ;
20+ readonly version : number [ ] = [ ] ;
21+ readonly buildType : string = '' ;
22+ readonly targetPlatform : number = 0 ;
23+ readonly enableTypeTree : boolean = false ;
24+ readonly enableBigId : boolean = false ;
25+ readonly types : SerializedType [ ] = [ ] ;
26+ readonly typeMap = new Map < number , SerializedType > ( ) ;
27+ readonly objectInfos : ObjectInfo [ ] = [ ] ;
28+ readonly reader : ArrayBufferReader ;
4629
4730 constructor ( bundle : Bundle , data : ArrayBuffer ) {
4831 const r = new ArrayBufferReader ( data ) ;
@@ -88,7 +71,9 @@ export class Asset {
8871
8972 const typeCount = r . readInt32 ( ) ;
9073 for ( let i = 0 ; i < typeCount ; i ++ ) {
91- this . readType ( false ) ;
74+ const type = new SerializedType ( r , header , this . enableTypeTree , false ) ;
75+ this . types . push ( type ) ;
76+ this . typeMap . set ( type . classId , type ) ;
9277 }
9378
9479 if ( header . version >= 7 && header . version < 14 ) {
@@ -97,97 +82,13 @@ export class Asset {
9782
9883 const objectCount = r . readUInt32 ( ) ;
9984 for ( let i = 0 ; i < objectCount ; i ++ ) {
100- const info : ObjectInfo = {
101- getReader : this . cloneReader ,
102- bundle,
103- buildType : this . buildType ,
104- assetVersion : header . version ,
105- bytesStart : 0 ,
106- bytesSize : 0 ,
107- typeId : 0 ,
108- classId : 0 ,
109- isDestroyed : 0 ,
110- stripped : 0 ,
111- pathId : 0n ,
112- version : this . version ,
113- } ;
114-
115- if ( this . enableBigId ) info . pathId = r . readInt64 ( ) ;
116- else if ( header . version < 14 ) info . pathId = BigInt ( r . readInt32 ( ) ) ;
117- else {
118- r . align ( 4 ) ;
119- info . pathId = r . readInt64 ( ) ;
120- }
121- info . bytesStart = header . version >= 22 ? Number ( r . readUInt64 ( ) ) : r . readUInt32 ( ) ;
122- info . bytesStart += header . dataOffset ;
123- info . bytesSize = r . readUInt32 ( ) ;
124- info . typeId = r . readInt32 ( ) ;
125- if ( header . version < 16 ) info . classId = r . readUInt16 ( ) ;
126- else info . classId = this . types [ info . typeId ] . classId ;
127- if ( header . version < 11 ) info . isDestroyed = r . readUInt16 ( ) ;
128- if ( header . version >= 11 && header . version < 17 ) r . move ( 2 ) ;
129- if ( header . version === 15 || header . version === 16 ) info . stripped = r . readUInt8 ( ) ;
130-
131- this . objectInfos . push ( info ) ;
85+ this . objectInfos . push ( new ObjectInfo ( this , bundle ) ) ;
13286 }
13387
13488 // 未实现
13589 }
13690
137- public objects ( ) {
91+ objects ( ) {
13892 return this . objectInfos . map ( createAssetObject ) . filter ( o => o ) as AssetObject [ ] ;
13993 }
140-
141- // 未完整实现,只用于跳过
142- private readType ( isRefType : boolean ) {
143- const r = this . reader ;
144- const { version } = this . header ;
145-
146- const info : TypeInfo = {
147- classId : r . readInt32 ( ) ,
148- } ;
149-
150- if ( version >= 16 ) r . move ( 1 ) ;
151- const scriptTypeIndex = version >= 17 ? r . readInt16 ( ) : null ;
152- if ( version >= 13 ) {
153- if (
154- ( isRefType && scriptTypeIndex !== null ) ||
155- ( version < 16 && info . classId < 0 ) ||
156- ( version >= 16 && info . classId === 114 )
157- ) {
158- r . move ( 16 ) ;
159- }
160- r . move ( 16 ) ;
161- }
162- if ( this . enableTypeTree ) {
163- if ( version >= 12 || version === 10 ) this . readTypeTreeBlob ( ) ;
164- else throw new Error ( `Unsupported asset version: ${ version } ` ) ;
165- if ( version >= 21 ) {
166- if ( isRefType ) {
167- r . readStringUntilZero ( ) ;
168- r . readStringUntilZero ( ) ;
169- r . readStringUntilZero ( ) ;
170- } else {
171- const size = r . readInt32 ( ) ;
172- r . move ( size * 4 ) ;
173- }
174- }
175- }
176-
177- this . types . push ( info ) ;
178- }
179-
180- // 未实现,只用于跳过
181- private readTypeTreeBlob ( ) {
182- const r = this . reader ;
183-
184- const nodeNumber = r . readInt32 ( ) ;
185- const stringBufferSize = r . readInt32 ( ) ;
186-
187- for ( let i = 0 ; i < nodeNumber ; i ++ ) {
188- r . move ( 24 ) ;
189- if ( this . header . version >= 19 ) r . move ( 8 ) ;
190- }
191- r . move ( stringBufferSize ) ;
192- }
19394}
0 commit comments