forked from qwerty472123/wxappUnpacker
-
Notifications
You must be signed in to change notification settings - Fork 227
/
wuWxapkg.js
196 lines (180 loc) · 7.83 KB
/
wuWxapkg.js
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
const wu = require("./wuLib.js");
const wuJs = require("./wuJs.js");
const wuCfg = require("./wuConfig.js");
const wuMl = require("./wuWxml.js");
const wuSs = require("./wuWxss.js");
const path = require("path");
const fs = require("fs");
function header(buf) {
console.log("\nHeader info:");
let firstMark = buf.readUInt8(0);
console.log(" firstMark: 0x%s", firstMark.toString(16));
let unknownInfo = buf.readUInt32BE(1);
console.log(" unknownInfo: ", unknownInfo);
let infoListLength = buf.readUInt32BE(5);
console.log(" infoListLength: ", infoListLength);
let dataLength = buf.readUInt32BE(9);
console.log(" dataLength: ", dataLength);
let lastMark = buf.readUInt8(13);
console.log(" lastMark: 0x%s", lastMark.toString(16));
if (firstMark != 0xbe || lastMark != 0xed) throw Error("Magic number is not correct!");
return [infoListLength, dataLength];
}
function genList(buf) {
console.log("\nFile list info:");
let fileCount = buf.readUInt32BE(0);
console.log(" fileCount: ", fileCount);
let fileInfo = [], off = 4;
for (let i = 0; i < fileCount; i++) {
let info = {};
let nameLen = buf.readUInt32BE(off);
off += 4;
info.name = buf.toString('utf8', off, off + nameLen);
off += nameLen;
info.off = buf.readUInt32BE(off);
off += 4;
info.size = buf.readUInt32BE(off);
off += 4;
fileInfo.push(info);
}
return fileInfo;
}
function saveFile(dir, buf, list) {
console.log("Saving files...");
for (let info of list)
wu.save(path.resolve(dir, (info.name.startsWith("/") ? "." : "") + info.name), buf.slice(info.off, info.off + info.size));
}
function packDone(dir, cb, order) {
console.log("Unpack done.");
let weappEvent = new wu.CntEvent, needDelete = {};
weappEvent.encount(4);
weappEvent.add(() => {
wu.addIO(() => {
console.log("Split and make up done.");
if (!order.includes("d")) {
console.log("Delete files...");
wu.addIO(() => console.log("Deleted.\n\nFile done."));
for (let name in needDelete) if (needDelete[name] >= 8) wu.del(name);
}
cb();
});
});
function doBack(deletable) {
for (let key in deletable) {
if (!needDelete[key]) needDelete[key] = 0;
needDelete[key] += deletable[key];//all file have score bigger than 8 will be delete.
}
weappEvent.decount();
}
function dealThreeThings(dir, mainDir, nowDir) {
console.log("Split app-service.js and make up configs & wxss & wxml & wxs...");
//deal config
if (fs.existsSync(path.resolve(dir, "app-config.json"))) {
wuCfg.doConfig(path.resolve(dir, "app-config.json"), doBack);
console.log('deal config ok');
}
//deal js
if (fs.existsSync(path.resolve(dir, "app-service.js"))) {
wuJs.splitJs(path.resolve(dir, "app-service.js"), doBack, mainDir);
console.log('deal js ok');
}
if (fs.existsSync(path.resolve(dir, "workers.js"))) {
wuJs.splitJs(path.resolve(dir, "workers.js"), doBack, mainDir);
console.log('deal js2 ok');
}
//deal html
if (mainDir) {
if (fs.existsSync(path.resolve(dir, "page-frame.js"))) {
wuMl.doFrame(path.resolve(dir, "page-frame.js"), doBack, order, mainDir);
console.log('deal sub html ok');
}
wuSs.doWxss(dir, doBack, mainDir, nowDir);
} else {
if (fs.existsSync(path.resolve(dir, "page-frame.html"))) {
wuMl.doFrame(path.resolve(dir, "page-frame.html"), doBack, order, mainDir);
console.log('deal html ok');
} else if (fs.existsSync(path.resolve(dir, "app-wxss.js"))) {
wuMl.doFrame(path.resolve(dir, "app-wxss.js"), doBack, order, mainDir);
if (!needDelete[path.resolve(dir, "page-frame.js")]) {
needDelete[path.resolve(dir, "page-frame.js")] = 8;
}
console.log('deal wxss.js ok');
} else {
throw Error("page-frame-like file is not found in the package by auto.");
}
//Force it run at last, becuase lots of error occured in this part
wuSs.doWxss(dir, doBack);
console.log('deal css ok');
}
}
//This will be the only func running this time, so async is needless.
if (fs.existsSync(path.resolve(dir, "app-service.js"))) {
//weapp
dealThreeThings(dir);
} else if (fs.existsSync(path.resolve(dir, "game.js"))) {
//wegame
console.log("Split game.js and rewrite game.json...");
let gameCfg = path.resolve(dir, "app-config.json");
wu.get(gameCfg, cfgPlain => {
let cfg = JSON.parse(cfgPlain);
if (cfg.subContext) {
console.log("Found subContext, splitting it...")
delete cfg.subContext;
let contextPath = path.resolve(dir, "subContext.js");
wuJs.splitJs(contextPath, () => wu.del(contextPath));
}
wu.save(path.resolve(dir, "game.json"), JSON.stringify(cfg, null, 4));
wu.del(gameCfg);
});
wuJs.splitJs(path.resolve(dir, "game.js"), () => {
wu.addIO(() => {
console.log("Split and rewrite done.");
cb();
});
});
} else {//分包
let doSubPkg = false;
for (const orderElement of order) {
if (orderElement.indexOf('s=') !== -1) {
let mainDir = orderElement.substring(2, orderElement.length);
console.log("now dir: " + dir);
console.log("param of mainDir: " + mainDir);
let findDir = function (dir, oldDir) {
let files = fs.readdirSync(dir);
for (const file of files) {
let workDir = path.join(dir, file);
if (fs.existsSync(path.resolve(workDir, "app-service.js"))) {
console.log("sub package word dir: " + workDir);
mainDir = path.resolve(oldDir, mainDir);
console.log("real mainDir: " + mainDir);
dealThreeThings(workDir, mainDir, oldDir);
doSubPkg = true;
return true;
} else {
findDir(workDir, oldDir);
}
}
};
findDir(dir, dir);
}
}
if (!doSubPkg) {
throw new Error("This pkg may be a sub pkg, please add -s=Main Dir, like: node wuWxapkg.js -s=./testpkg/test/ ./testpkg/test-pkg-sub.wxapkg");
}
}
}
function doFile(name, cb, order) {
for (let ord of order) if (ord.startsWith("s=")) global.subPack = ord.slice(3);
console.log("Unpack file " + name + "...");
let dir = path.resolve(name, "..", path.basename(name, ".wxapkg"));
wu.get(name, buf => {
let [infoListLength, dataLength] = header(buf.slice(0, 14));
if (order.includes("o")) wu.addIO(console.log.bind(console), "Unpack done.");
else wu.addIO(packDone, dir, cb, order);
saveFile(dir, buf, genList(buf.slice(14, infoListLength + 14)));
}, {});
}
module.exports = {doFile: doFile};
if (require.main === module) {
wu.commandExecute(doFile, "Unpack a wxapkg file.\n\n[-o] [-d] [-s=<Main Dir>] <files...>\n\n-d Do not delete transformed unpacked files.\n-o Do not execute any operation after unpack.\n-s=<Main Dir> Regard all packages provided as subPackages and\n regard <Main Dir> as the directory of sources of the main package.\n<files...> wxapkg files to unpack");
}