-
Notifications
You must be signed in to change notification settings - Fork 18
/
proxyServer.ts
130 lines (127 loc) · 3.88 KB
/
proxyServer.ts
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
import * as http from 'http';
import * as request from 'request';
import * as express from 'express';
import * as Agent from 'socks5-http-client/lib/Agent';
import * as fs from 'fs';
import { parseAL, AL } from 'aigis-fuel';
import * as path from 'path';
import * as log from 'electron-log';
log.transports.file.level = 'info';
let mainFontPath = '';
function parse(buffer) {
const result = parseAL(buffer);
return result;
}
export class ProxyServer {
FileList = {};
ProxyHost = '127.0.0.1';
ProxyPort = 1080;
ProxyEnable = false;
ProxyIsSocks5 = false;
Port = 0;
createServer(userDataPath: string) {
const app = express();
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Cache-Control', 'immutable');
next();
});
app.use((req, res) => {
const headers = req.headers;
headers.host = 'assets.millennium-war.net';
// 设置代理
const options: any = {
url: 'http://assets.millennium-war.net' + req.path,
headers: headers,
encoding: null,
};
if (this.ProxyEnable === true && this.ProxyIsSocks5 === true) {
options.agentClass = Agent;
options.agentOptions = {
socksHost: this.ProxyHost,
socksPort: this.ProxyPort,
};
}
if (this.ProxyEnable === true && this.ProxyIsSocks5 === false) {
options.proxy = `http://${this.ProxyHost}:${this.ProxyPort}`;
}
let requestFileName = this.FileList[req.path];
if (req.path.indexOf(mainFontPath) !== -1) {
requestFileName = 'MainFont.aft';
}
let modifyFileName = '';
if (requestFileName) {
switch (path.extname(requestFileName)) {
case '.atb':
modifyFileName = requestFileName.replace('.atb', '.txt');
break;
case '.aar':
modifyFileName = requestFileName.replace('.aar', '');
break;
default:
modifyFileName = requestFileName;
}
}
console.log(modifyFileName);
// 文件热封装
const protoablePath = process.env.PORTABLE_EXECUTABLE_DIR;
const modPath = protoablePath
? protoablePath + '/mods'
: path.join(userDataPath, 'mods');
if (!fs.existsSync(modPath)) {
fs.mkdirSync(modPath);
}
const modifyFilePath = path.join(modPath, modifyFileName);
if (modifyFileName !== '' && fs.existsSync(modifyFilePath)) {
log.info(requestFileName, 'modify by Server');
// AFT和PNG文件直接回传
if (
modifyFileName === 'MainFont.aft' ||
path.extname(modifyFileName) === 'png'
) {
fs.createReadStream(modifyFilePath).pipe(res);
return;
}
// 其他文件
let result: AL;
options.gzip = true;
request(options, (err, response, body) => {
result = parse(body);
// 这边也需要添加一个任务队列,不然会爆炸
const packaged = result.Package(modifyFilePath);
// fs.writeFile('./test/' + requestFileName, packaged);
res.send(packaged);
// res.send(body);
});
} else {
request(options, (err, res, body) => {
if (body === undefined) {
console.log('Error on ' + req.path);
}
}).pipe(res);
}
});
const server = http.createServer(app);
server.on('error', (e) => {
console.log(e);
});
server.listen('19980', () => {
this.Port = server.address()['port'];
console.log('listen at ' + this.Port);
});
}
setFileList(fileList) {
this.FileList = fileList;
}
setFontPath(path: string) {
mainFontPath = path;
}
setProxy(enable, isSocks5, host, port) {
this.ProxyEnable = enable;
this.ProxyIsSocks5 = isSocks5;
if (enable) {
this.ProxyHost = host;
this.ProxyPort = port;
}
}
}