react-native-update-cli 2.4.2 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/README.zh-CN.md +2 -0
- package/cli.json +40 -0
- package/lib/api.js +1 -1
- package/lib/locales/en.js +16 -1
- package/lib/locales/zh.js +16 -1
- package/lib/package.js +60 -6
- package/lib/provider.js +3 -0
- package/lib/utils/app-info-parser/aab.js +230 -0
- package/lib/utils/app-info-parser/apk.js +25 -27
- package/lib/utils/app-info-parser/app.js +10 -11
- package/lib/utils/app-info-parser/index.js +13 -8
- package/lib/utils/app-info-parser/ipa.js +16 -21
- package/lib/utils/app-info-parser/resource-finder.js +365 -305
- package/lib/utils/app-info-parser/utils.js +78 -63
- package/lib/utils/app-info-parser/xml-parser/binary.js +57 -51
- package/lib/utils/app-info-parser/xml-parser/manifest.js +47 -39
- package/lib/utils/app-info-parser/zip.js +21 -11
- package/lib/utils/http-helper.js +1 -1
- package/lib/utils/index.js +137 -0
- package/lib/versions.js +22 -0
- package/package.json +3 -2
- package/proto/Configuration.proto +183 -0
- package/proto/Resources.proto +569 -0
- package/src/api.ts +2 -6
- package/src/locales/en.ts +20 -0
- package/src/locales/zh.ts +18 -0
- package/src/modules/version-module.ts +1 -1
- package/src/package.ts +112 -12
- package/src/provider.ts +3 -0
- package/src/utils/app-info-parser/aab.ts +240 -0
- package/src/utils/app-info-parser/{apk.js → apk.ts} +30 -41
- package/src/utils/app-info-parser/app.ts +3 -0
- package/src/utils/app-info-parser/index.ts +9 -5
- package/src/utils/app-info-parser/{ipa.js → ipa.ts} +17 -31
- package/src/utils/app-info-parser/resource-finder.ts +508 -0
- package/src/utils/app-info-parser/utils.ts +162 -0
- package/src/utils/app-info-parser/xml-parser/{binary.js → binary.ts} +69 -61
- package/src/utils/app-info-parser/xml-parser/{manifest.js → manifest.ts} +50 -51
- package/src/utils/app-info-parser/zip.ts +86 -0
- package/src/utils/dep-versions.ts +7 -4
- package/src/utils/http-helper.ts +1 -1
- package/src/utils/index.ts +154 -0
- package/src/utils/latest-version/index.ts +2 -1
- package/src/versions.ts +27 -2
- package/src/utils/app-info-parser/app.js +0 -16
- package/src/utils/app-info-parser/resource-finder.js +0 -495
- package/src/utils/app-info-parser/utils.js +0 -172
- package/src/utils/app-info-parser/zip.js +0 -66
|
@@ -3,349 +3,409 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Decode binary file `resources.arsc` from a .apk file to a JavaScript Object.
|
|
5
5
|
*/ "use strict";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// The 'data' holds a ResTable_ref, a reference to another resource
|
|
14
|
-
// table entry.
|
|
15
|
-
var TYPE_REFERENCE = 0x01;
|
|
16
|
-
// The 'data' holds an index into the containing resource table's
|
|
17
|
-
// global value string pool.
|
|
18
|
-
var TYPE_STRING = 0x03;
|
|
19
|
-
function ResourceFinder() {
|
|
20
|
-
this.valueStringPool = null;
|
|
21
|
-
this.typeStringPool = null;
|
|
22
|
-
this.keyStringPool = null;
|
|
23
|
-
this.package_id = 0;
|
|
24
|
-
this.responseMap = {};
|
|
25
|
-
this.entryMap = {};
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Same to C# BinaryReader.readBytes
|
|
29
|
-
*
|
|
30
|
-
* @param bb ByteBuffer
|
|
31
|
-
* @param len length
|
|
32
|
-
* @returns {Buffer}
|
|
33
|
-
*/ ResourceFinder.readBytes = (bb, len)=>{
|
|
34
|
-
var uint8Array = new Uint8Array(len);
|
|
35
|
-
for(var i = 0; i < len; i++){
|
|
36
|
-
uint8Array[i] = bb.readUint8();
|
|
37
|
-
}
|
|
38
|
-
return ByteBuffer.wrap(uint8Array, 'binary', true);
|
|
39
|
-
};
|
|
40
|
-
//
|
|
41
|
-
/**
|
|
42
|
-
*
|
|
43
|
-
* @param {ByteBuffer} bb
|
|
44
|
-
* @return {Map<String, Set<String>>}
|
|
45
|
-
*/ ResourceFinder.prototype.processResourceTable = function(resourceBuffer) {
|
|
46
|
-
const bb = ByteBuffer.wrap(resourceBuffer, 'binary', true);
|
|
47
|
-
// Resource table structure
|
|
48
|
-
var type = bb.readShort(), headerSize = bb.readShort(), size = bb.readInt(), packageCount = bb.readInt(), buffer, bb2;
|
|
49
|
-
if (type != RES_TABLE_TYPE) {
|
|
50
|
-
throw new Error('No RES_TABLE_TYPE found!');
|
|
6
|
+
Object.defineProperty(exports, "__esModule", {
|
|
7
|
+
value: true
|
|
8
|
+
});
|
|
9
|
+
Object.defineProperty(exports, "ResourceFinder", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function() {
|
|
12
|
+
return ResourceFinder;
|
|
51
13
|
}
|
|
52
|
-
|
|
53
|
-
|
|
14
|
+
});
|
|
15
|
+
const ByteBuffer = require('bytebuffer');
|
|
16
|
+
const DEBUG = false;
|
|
17
|
+
const RES_STRING_POOL_TYPE = 0x0001;
|
|
18
|
+
const RES_TABLE_TYPE = 0x0002;
|
|
19
|
+
const RES_TABLE_PACKAGE_TYPE = 0x0200;
|
|
20
|
+
const RES_TABLE_TYPE_TYPE = 0x0201;
|
|
21
|
+
const RES_TABLE_TYPE_SPEC_TYPE = 0x0202;
|
|
22
|
+
const TYPE_REFERENCE = 0x01;
|
|
23
|
+
const TYPE_STRING = 0x03;
|
|
24
|
+
class ResourceFinder {
|
|
25
|
+
/**
|
|
26
|
+
* Same to C# BinaryReader.readBytes
|
|
27
|
+
*
|
|
28
|
+
* @param bb ByteBuffer
|
|
29
|
+
* @param len length
|
|
30
|
+
* @returns {Buffer}
|
|
31
|
+
*/ static readBytes(bb, len) {
|
|
32
|
+
const uint8Array = new Uint8Array(len);
|
|
33
|
+
for(let i = 0; i < len; i++){
|
|
34
|
+
uint8Array[i] = bb.readUint8();
|
|
35
|
+
}
|
|
36
|
+
return ByteBuffer.wrap(uint8Array, 'binary', true);
|
|
54
37
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
* @param {ByteBuffer} bb
|
|
41
|
+
* @return {Map<String, Set<String>>}
|
|
42
|
+
*/ processResourceTable(resourceBuffer) {
|
|
43
|
+
const bb = ByteBuffer.wrap(resourceBuffer, 'binary', true);
|
|
44
|
+
const type = bb.readShort();
|
|
45
|
+
const headerSize = bb.readShort();
|
|
46
|
+
const size = bb.readInt();
|
|
47
|
+
const packageCount = bb.readInt();
|
|
48
|
+
let buffer;
|
|
49
|
+
let bb2;
|
|
50
|
+
if (type !== RES_TABLE_TYPE) {
|
|
51
|
+
throw new Error('No RES_TABLE_TYPE found!');
|
|
52
|
+
}
|
|
53
|
+
if (size !== bb.limit) {
|
|
54
|
+
throw new Error('The buffer size not matches to the resource table size.');
|
|
66
55
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
56
|
+
bb.offset = headerSize;
|
|
57
|
+
let realStringPoolCount = 0;
|
|
58
|
+
let realPackageCount = 0;
|
|
59
|
+
while(true){
|
|
60
|
+
let pos = 0;
|
|
61
|
+
let t = 0;
|
|
62
|
+
let hs = 0;
|
|
63
|
+
let s = 0;
|
|
64
|
+
try {
|
|
65
|
+
pos = bb.offset;
|
|
66
|
+
t = bb.readShort();
|
|
67
|
+
hs = bb.readShort();
|
|
68
|
+
s = bb.readInt();
|
|
69
|
+
} catch (e) {
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
if (t === RES_STRING_POOL_TYPE) {
|
|
73
|
+
if (realStringPoolCount === 0) {
|
|
74
|
+
if (DEBUG) {
|
|
75
|
+
console.log('Processing the string pool ...');
|
|
76
|
+
}
|
|
77
|
+
buffer = new ByteBuffer(s);
|
|
78
|
+
bb.offset = pos;
|
|
79
|
+
bb.prependTo(buffer);
|
|
80
|
+
bb2 = ByteBuffer.wrap(buffer, 'binary', true);
|
|
81
|
+
bb2.LE();
|
|
82
|
+
this.valueStringPool = this.processStringPool(bb2);
|
|
83
|
+
}
|
|
84
|
+
realStringPoolCount++;
|
|
85
|
+
} else if (t === RES_TABLE_PACKAGE_TYPE) {
|
|
71
86
|
if (DEBUG) {
|
|
72
|
-
console.log(
|
|
87
|
+
console.log(`Processing the package ${realPackageCount} ...`);
|
|
73
88
|
}
|
|
74
89
|
buffer = new ByteBuffer(s);
|
|
75
90
|
bb.offset = pos;
|
|
76
91
|
bb.prependTo(buffer);
|
|
77
92
|
bb2 = ByteBuffer.wrap(buffer, 'binary', true);
|
|
78
93
|
bb2.LE();
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// Process the package
|
|
84
|
-
if (DEBUG) {
|
|
85
|
-
console.log('Processing the package ' + realPackageCount + ' ...');
|
|
94
|
+
this.processPackage(bb2);
|
|
95
|
+
realPackageCount++;
|
|
96
|
+
} else {
|
|
97
|
+
throw new Error('Unsupported type');
|
|
86
98
|
}
|
|
87
|
-
|
|
88
|
-
bb.
|
|
89
|
-
bb.prependTo(buffer);
|
|
90
|
-
bb2 = ByteBuffer.wrap(buffer, 'binary', true);
|
|
91
|
-
bb2.LE();
|
|
92
|
-
this.processPackage(bb2);
|
|
93
|
-
realPackageCount++;
|
|
94
|
-
} else {
|
|
95
|
-
throw new Error('Unsupported type');
|
|
99
|
+
bb.offset = pos + s;
|
|
100
|
+
if (!bb.remaining()) break;
|
|
96
101
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
throw new Error('Real package count not equals the declared count.');
|
|
105
|
-
}
|
|
106
|
-
return this.responseMap;
|
|
107
|
-
};
|
|
108
|
-
/**
|
|
109
|
-
*
|
|
110
|
-
* @param {ByteBuffer} bb
|
|
111
|
-
*/ ResourceFinder.prototype.processPackage = function(bb) {
|
|
112
|
-
// Package structure
|
|
113
|
-
var type = bb.readShort(), headerSize = bb.readShort(), size = bb.readInt(), id = bb.readInt();
|
|
114
|
-
this.package_id = id;
|
|
115
|
-
for(var i = 0; i < 256; ++i){
|
|
116
|
-
bb.readUint8();
|
|
117
|
-
}
|
|
118
|
-
var typeStrings = bb.readInt(), lastPublicType = bb.readInt(), keyStrings = bb.readInt(), lastPublicKey = bb.readInt();
|
|
119
|
-
if (typeStrings != headerSize) {
|
|
120
|
-
throw new Error('TypeStrings must immediately following the package structure header.');
|
|
121
|
-
}
|
|
122
|
-
if (DEBUG) {
|
|
123
|
-
console.log('Type strings:');
|
|
124
|
-
}
|
|
125
|
-
var lastPosition = bb.offset;
|
|
126
|
-
bb.offset = typeStrings;
|
|
127
|
-
var bbTypeStrings = ResourceFinder.readBytes(bb, bb.limit - bb.offset);
|
|
128
|
-
bb.offset = lastPosition;
|
|
129
|
-
this.typeStringPool = this.processStringPool(bbTypeStrings);
|
|
130
|
-
// Key strings
|
|
131
|
-
if (DEBUG) {
|
|
132
|
-
console.log('Key strings:');
|
|
102
|
+
if (realStringPoolCount !== 1) {
|
|
103
|
+
throw new Error('More than 1 string pool found!');
|
|
104
|
+
}
|
|
105
|
+
if (realPackageCount !== packageCount) {
|
|
106
|
+
throw new Error('Real package count not equals the declared count.');
|
|
107
|
+
}
|
|
108
|
+
return this.responseMap;
|
|
133
109
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
var pos = bb.offset;
|
|
148
|
-
try {
|
|
149
|
-
var t = bb.readShort();
|
|
150
|
-
var hs = bb.readShort();
|
|
151
|
-
var s = bb.readInt();
|
|
152
|
-
} catch (e) {
|
|
153
|
-
break;
|
|
110
|
+
/**
|
|
111
|
+
*
|
|
112
|
+
* @param {ByteBuffer} bb
|
|
113
|
+
*/ processPackage(bb) {
|
|
114
|
+
const type = bb.readShort();
|
|
115
|
+
const headerSize = bb.readShort();
|
|
116
|
+
const size = bb.readInt();
|
|
117
|
+
const id = bb.readInt();
|
|
118
|
+
void type;
|
|
119
|
+
void size;
|
|
120
|
+
this.packageId = id;
|
|
121
|
+
for(let i = 0; i < 256; ++i){
|
|
122
|
+
bb.readUint8();
|
|
154
123
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
this.processType(bb2);
|
|
164
|
-
typeCount++;
|
|
124
|
+
const typeStrings = bb.readInt();
|
|
125
|
+
const lastPublicType = bb.readInt();
|
|
126
|
+
const keyStrings = bb.readInt();
|
|
127
|
+
const lastPublicKey = bb.readInt();
|
|
128
|
+
void lastPublicType;
|
|
129
|
+
void lastPublicKey;
|
|
130
|
+
if (typeStrings !== headerSize) {
|
|
131
|
+
throw new Error('TypeStrings must immediately following the package structure header.');
|
|
165
132
|
}
|
|
166
|
-
if (
|
|
167
|
-
|
|
133
|
+
if (DEBUG) {
|
|
134
|
+
console.log('Type strings:');
|
|
168
135
|
}
|
|
169
|
-
bb.offset
|
|
170
|
-
|
|
171
|
-
|
|
136
|
+
let lastPosition = bb.offset;
|
|
137
|
+
bb.offset = typeStrings;
|
|
138
|
+
const bbTypeStrings = ResourceFinder.readBytes(bb, bb.limit - bb.offset);
|
|
139
|
+
bb.offset = lastPosition;
|
|
140
|
+
this.typeStringPool = this.processStringPool(bbTypeStrings);
|
|
141
|
+
if (DEBUG) {
|
|
142
|
+
console.log('Key strings:');
|
|
172
143
|
}
|
|
144
|
+
bb.offset = keyStrings;
|
|
145
|
+
const keyType = bb.readShort();
|
|
146
|
+
const keyHeaderSize = bb.readShort();
|
|
147
|
+
const keySize = bb.readInt();
|
|
148
|
+
void keyType;
|
|
149
|
+
void keyHeaderSize;
|
|
150
|
+
lastPosition = bb.offset;
|
|
151
|
+
bb.offset = keyStrings;
|
|
152
|
+
const bbKeyStrings = ResourceFinder.readBytes(bb, bb.limit - bb.offset);
|
|
153
|
+
bb.offset = lastPosition;
|
|
154
|
+
this.keyStringPool = this.processStringPool(bbKeyStrings);
|
|
155
|
+
let typeSpecCount = 0;
|
|
156
|
+
let typeCount = 0;
|
|
157
|
+
bb.offset = keyStrings + keySize;
|
|
158
|
+
let bb2;
|
|
159
|
+
while(true){
|
|
160
|
+
const pos = bb.offset;
|
|
161
|
+
try {
|
|
162
|
+
const t = bb.readShort();
|
|
163
|
+
const hs = bb.readShort();
|
|
164
|
+
const s = bb.readInt();
|
|
165
|
+
void hs;
|
|
166
|
+
if (t === RES_TABLE_TYPE_SPEC_TYPE) {
|
|
167
|
+
bb.offset = pos;
|
|
168
|
+
bb2 = ResourceFinder.readBytes(bb, s);
|
|
169
|
+
this.processTypeSpec(bb2);
|
|
170
|
+
typeSpecCount++;
|
|
171
|
+
} else if (t === RES_TABLE_TYPE_TYPE) {
|
|
172
|
+
bb.offset = pos;
|
|
173
|
+
bb2 = ResourceFinder.readBytes(bb, s);
|
|
174
|
+
this.processType(bb2);
|
|
175
|
+
typeCount++;
|
|
176
|
+
}
|
|
177
|
+
if (s === 0) {
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
bb.offset = pos + s;
|
|
181
|
+
if (!bb.remaining()) {
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
} catch (e) {
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
void typeSpecCount;
|
|
189
|
+
void typeCount;
|
|
173
190
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
var pos = bb.offset, entry_size, entry_flag, entry_key, value_size, value_res0, value_dataType, value_data;
|
|
197
|
-
try {
|
|
198
|
-
entry_size = bb.readShort();
|
|
199
|
-
entry_flag = bb.readShort();
|
|
200
|
-
entry_key = bb.readInt();
|
|
201
|
-
} catch (e) {
|
|
202
|
-
break;
|
|
191
|
+
/**
|
|
192
|
+
*
|
|
193
|
+
* @param {ByteBuffer} bb
|
|
194
|
+
*/ processType(bb) {
|
|
195
|
+
const type = bb.readShort();
|
|
196
|
+
const headerSize = bb.readShort();
|
|
197
|
+
const size = bb.readInt();
|
|
198
|
+
const id = bb.readByte();
|
|
199
|
+
const res0 = bb.readByte();
|
|
200
|
+
const res1 = bb.readShort();
|
|
201
|
+
const entryCount = bb.readInt();
|
|
202
|
+
const entriesStart = bb.readInt();
|
|
203
|
+
void type;
|
|
204
|
+
void size;
|
|
205
|
+
void res0;
|
|
206
|
+
void res1;
|
|
207
|
+
const refKeys = {};
|
|
208
|
+
const configSize = bb.readInt();
|
|
209
|
+
void configSize;
|
|
210
|
+
bb.offset = headerSize;
|
|
211
|
+
if (headerSize + entryCount * 4 !== entriesStart) {
|
|
212
|
+
throw new Error('HeaderSize, entryCount and entriesStart are not valid.');
|
|
203
213
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (entryArr == null) {
|
|
221
|
-
entryArr = [];
|
|
214
|
+
const entryIndices = new Array(entryCount);
|
|
215
|
+
for(let i = 0; i < entryCount; ++i){
|
|
216
|
+
entryIndices[i] = bb.readInt();
|
|
217
|
+
}
|
|
218
|
+
for(let i = 0; i < entryCount; ++i){
|
|
219
|
+
if (entryIndices[i] === -1) continue;
|
|
220
|
+
const resourceId = this.packageId << 24 | id << 16 | i;
|
|
221
|
+
let entrySize = 0;
|
|
222
|
+
let entryFlag = 0;
|
|
223
|
+
let entryKey = 0;
|
|
224
|
+
try {
|
|
225
|
+
entrySize = bb.readShort();
|
|
226
|
+
entryFlag = bb.readShort();
|
|
227
|
+
entryKey = bb.readInt();
|
|
228
|
+
} catch (e) {
|
|
229
|
+
break;
|
|
222
230
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (
|
|
226
|
-
|
|
231
|
+
void entrySize;
|
|
232
|
+
const FLAG_COMPLEX = 0x0001;
|
|
233
|
+
if ((entryFlag & FLAG_COMPLEX) === 0) {
|
|
234
|
+
const valueSize = bb.readShort();
|
|
235
|
+
const valueRes0 = bb.readByte();
|
|
236
|
+
const valueDataType = bb.readByte();
|
|
237
|
+
const valueData = bb.readInt();
|
|
238
|
+
void valueSize;
|
|
239
|
+
void valueRes0;
|
|
240
|
+
const idStr = Number(resourceId).toString(16);
|
|
241
|
+
const keyStr = this.keyStringPool ? this.keyStringPool[entryKey] : '';
|
|
242
|
+
let data = null;
|
|
227
243
|
if (DEBUG) {
|
|
228
|
-
console.log(
|
|
244
|
+
console.log(`Entry 0x${idStr}, key: ${keyStr}, simple value type: `);
|
|
245
|
+
}
|
|
246
|
+
const key = Number.parseInt(idStr, 16);
|
|
247
|
+
var _this_entryMap_key;
|
|
248
|
+
const entryArr = (_this_entryMap_key = this.entryMap[key]) != null ? _this_entryMap_key : [];
|
|
249
|
+
entryArr.push(keyStr);
|
|
250
|
+
this.entryMap[key] = entryArr;
|
|
251
|
+
if (valueDataType === TYPE_STRING) {
|
|
252
|
+
data = this.valueStringPool ? this.valueStringPool[valueData] : null;
|
|
253
|
+
if (DEBUG && this.valueStringPool) {
|
|
254
|
+
console.log(`, data: ${this.valueStringPool[valueData]}`);
|
|
255
|
+
}
|
|
256
|
+
} else if (valueDataType === TYPE_REFERENCE) {
|
|
257
|
+
refKeys[idStr] = valueData;
|
|
258
|
+
} else {
|
|
259
|
+
data = `${valueData}`;
|
|
260
|
+
if (DEBUG) {
|
|
261
|
+
console.log(`, data: ${valueData}`);
|
|
262
|
+
}
|
|
229
263
|
}
|
|
230
|
-
|
|
231
|
-
var hexIndex = Number(value_data).toString(16);
|
|
232
|
-
refKeys[idStr] = value_data;
|
|
264
|
+
this.putIntoMap(`@${idStr}`, data);
|
|
233
265
|
} else {
|
|
234
|
-
|
|
266
|
+
const entryParent = bb.readInt();
|
|
267
|
+
const entryCountValue = bb.readInt();
|
|
268
|
+
void entryParent;
|
|
269
|
+
for(let j = 0; j < entryCountValue; ++j){
|
|
270
|
+
const refName = bb.readInt();
|
|
271
|
+
const valueSize = bb.readShort();
|
|
272
|
+
const valueRes0 = bb.readByte();
|
|
273
|
+
const valueDataType = bb.readByte();
|
|
274
|
+
const valueData = bb.readInt();
|
|
275
|
+
void refName;
|
|
276
|
+
void valueSize;
|
|
277
|
+
void valueRes0;
|
|
278
|
+
void valueDataType;
|
|
279
|
+
void valueData;
|
|
280
|
+
}
|
|
235
281
|
if (DEBUG) {
|
|
236
|
-
|
|
282
|
+
const keyStr = this.keyStringPool ? this.keyStringPool[entryKey] : '';
|
|
283
|
+
console.log(`Entry 0x${Number(resourceId).toString(16)}, key: ${keyStr}, complex value, not printed.`);
|
|
237
284
|
}
|
|
238
285
|
}
|
|
239
|
-
this.putIntoMap('@' + idStr, data);
|
|
240
|
-
} else {
|
|
241
|
-
// Complex case
|
|
242
|
-
var entry_parent = bb.readInt();
|
|
243
|
-
var entry_count = bb.readInt();
|
|
244
|
-
for(var j = 0; j < entry_count; ++j){
|
|
245
|
-
var ref_name = bb.readInt();
|
|
246
|
-
value_size = bb.readShort();
|
|
247
|
-
value_res0 = bb.readByte();
|
|
248
|
-
value_dataType = bb.readByte();
|
|
249
|
-
value_data = bb.readInt();
|
|
250
|
-
}
|
|
251
|
-
if (DEBUG) {
|
|
252
|
-
console.log('Entry 0x' + Number(resource_id).toString(16) + ', key: ' + this.keyStringPool[entry_key] + ', complex value, not printed.');
|
|
253
|
-
}
|
|
254
286
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
287
|
+
for(const refKey in refKeys){
|
|
288
|
+
const values = this.responseMap[`@${Number(refKeys[refKey]).toString(16).toUpperCase()}`];
|
|
289
|
+
if (values != null && Object.keys(values).length < 1000) {
|
|
290
|
+
for (const value of values){
|
|
291
|
+
this.putIntoMap(`@${refKey}`, value);
|
|
292
|
+
}
|
|
261
293
|
}
|
|
262
294
|
}
|
|
263
295
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if (
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
296
|
+
/**
|
|
297
|
+
*
|
|
298
|
+
* @param {ByteBuffer} bb
|
|
299
|
+
* @return {Array}
|
|
300
|
+
*/ processStringPool(bb) {
|
|
301
|
+
const type = bb.readShort();
|
|
302
|
+
const headerSize = bb.readShort();
|
|
303
|
+
const size = bb.readInt();
|
|
304
|
+
const stringCount = bb.readInt();
|
|
305
|
+
const styleCount = bb.readInt();
|
|
306
|
+
const flags = bb.readInt();
|
|
307
|
+
const stringsStart = bb.readInt();
|
|
308
|
+
const stylesStart = bb.readInt();
|
|
309
|
+
void type;
|
|
310
|
+
void headerSize;
|
|
311
|
+
void size;
|
|
312
|
+
void styleCount;
|
|
313
|
+
void stylesStart;
|
|
314
|
+
const isUtf8 = (flags & 256) !== 0;
|
|
315
|
+
const offsets = new Array(stringCount);
|
|
316
|
+
for(let i = 0; i < stringCount; ++i){
|
|
317
|
+
offsets[i] = bb.readInt();
|
|
318
|
+
}
|
|
319
|
+
const strings = new Array(stringCount);
|
|
320
|
+
for(let i = 0; i < stringCount; ++i){
|
|
321
|
+
const pos = stringsStart + offsets[i];
|
|
322
|
+
bb.offset = pos;
|
|
323
|
+
strings[i] = '';
|
|
324
|
+
if (isUtf8) {
|
|
325
|
+
let u16len = bb.readUint8();
|
|
326
|
+
if ((u16len & 0x80) !== 0) {
|
|
327
|
+
u16len = ((u16len & 0x7f) << 8) + bb.readUint8();
|
|
328
|
+
}
|
|
329
|
+
let u8len = bb.readUint8();
|
|
330
|
+
if ((u8len & 0x80) !== 0) {
|
|
331
|
+
u8len = ((u8len & 0x7f) << 8) + bb.readUint8();
|
|
332
|
+
}
|
|
333
|
+
if (u8len > 0) {
|
|
334
|
+
const buffer = ResourceFinder.readBytes(bb, u8len);
|
|
335
|
+
try {
|
|
336
|
+
strings[i] = ByteBuffer.wrap(buffer, 'utf8', true).toString('utf8');
|
|
337
|
+
} catch (e) {
|
|
338
|
+
if (DEBUG) {
|
|
339
|
+
console.error(e);
|
|
340
|
+
console.log('Error when turning buffer to utf-8 string.');
|
|
341
|
+
}
|
|
300
342
|
}
|
|
343
|
+
} else {
|
|
344
|
+
strings[i] = '';
|
|
301
345
|
}
|
|
302
346
|
} else {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if (DEBUG) {
|
|
318
|
-
console.error(e);
|
|
319
|
-
console.log('Error when turning buffer to utf-8 string.');
|
|
347
|
+
let u16len = bb.readUint16();
|
|
348
|
+
if ((u16len & 0x8000) !== 0) {
|
|
349
|
+
u16len = ((u16len & 0x7fff) << 16) + bb.readUint16();
|
|
350
|
+
}
|
|
351
|
+
if (u16len > 0) {
|
|
352
|
+
const len = u16len * 2;
|
|
353
|
+
const buffer = ResourceFinder.readBytes(bb, len);
|
|
354
|
+
try {
|
|
355
|
+
strings[i] = ByteBuffer.wrap(buffer, 'utf8', true).toString('utf8');
|
|
356
|
+
} catch (e) {
|
|
357
|
+
if (DEBUG) {
|
|
358
|
+
console.error(e);
|
|
359
|
+
console.log('Error when turning buffer to utf-8 string.');
|
|
360
|
+
}
|
|
320
361
|
}
|
|
321
362
|
}
|
|
322
363
|
}
|
|
364
|
+
if (DEBUG) {
|
|
365
|
+
console.log('Parsed value: {0}', strings[i]);
|
|
366
|
+
}
|
|
323
367
|
}
|
|
324
|
-
|
|
325
|
-
console.log('Parsed value: {0}', strings[i]);
|
|
326
|
-
}
|
|
368
|
+
return strings;
|
|
327
369
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
370
|
+
/**
|
|
371
|
+
*
|
|
372
|
+
* @param {ByteBuffer} bb
|
|
373
|
+
*/ processTypeSpec(bb) {
|
|
374
|
+
const type = bb.readShort();
|
|
375
|
+
const headerSize = bb.readShort();
|
|
376
|
+
const size = bb.readInt();
|
|
377
|
+
const id = bb.readByte();
|
|
378
|
+
const res0 = bb.readByte();
|
|
379
|
+
const res1 = bb.readShort();
|
|
380
|
+
const entryCount = bb.readInt();
|
|
381
|
+
void type;
|
|
382
|
+
void headerSize;
|
|
383
|
+
void size;
|
|
384
|
+
void res0;
|
|
385
|
+
void res1;
|
|
386
|
+
if (DEBUG && this.typeStringPool) {
|
|
387
|
+
console.log(`Processing type spec ${this.typeStringPool[id - 1]}...`);
|
|
388
|
+
}
|
|
389
|
+
const flags = new Array(entryCount);
|
|
390
|
+
for(let i = 0; i < entryCount; ++i){
|
|
391
|
+
flags[i] = bb.readInt();
|
|
392
|
+
}
|
|
341
393
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
394
|
+
putIntoMap(resId, value) {
|
|
395
|
+
const key = resId.toUpperCase();
|
|
396
|
+
if (this.responseMap[key] == null) {
|
|
397
|
+
this.responseMap[key] = [];
|
|
398
|
+
}
|
|
399
|
+
if (value) {
|
|
400
|
+
this.responseMap[key].push(value);
|
|
401
|
+
}
|
|
346
402
|
}
|
|
347
|
-
|
|
348
|
-
this.
|
|
403
|
+
constructor(){
|
|
404
|
+
this.valueStringPool = null;
|
|
405
|
+
this.typeStringPool = null;
|
|
406
|
+
this.keyStringPool = null;
|
|
407
|
+
this.packageId = 0;
|
|
408
|
+
this.responseMap = {};
|
|
409
|
+
this.entryMap = {};
|
|
349
410
|
}
|
|
350
|
-
}
|
|
351
|
-
module.exports = ResourceFinder;
|
|
411
|
+
}
|