mirror of
https://github.com/putyy/res-downloader.git
synced 2026-01-12 22:34:56 +08:00
292 lines
12 KiB
TypeScript
Executable File
292 lines
12 KiB
TypeScript
Executable File
import fs from 'fs'
|
|
import log from 'electron-log'
|
|
import CONFIG from './const'
|
|
import {closeProxy, setProxy} from './setProxy'
|
|
import {app} from "electron"
|
|
import * as urlTool from "url"
|
|
import {toSize} from "./utils"
|
|
// @ts-ignore
|
|
import {hexMD5} from '../../src/common/md5'
|
|
|
|
const hoXy = require('hoxy')
|
|
|
|
const port = 8899
|
|
|
|
let videoList = {}
|
|
|
|
if (process.platform === 'win32') {
|
|
process.env.OPENSSL_BIN = CONFIG.OPEN_SSL_BIN_PATH
|
|
process.env.OPENSSL_CONF = CONFIG.OPEN_SSL_CNF_PATH
|
|
}
|
|
|
|
// setTimeout to allow working in macOS
|
|
// in windows: H5ExtTransfer:ok
|
|
// in macOS: finderH5ExtTransfer:ok
|
|
|
|
const injection_script1 = `
|
|
setTimeout(() => {
|
|
let receiver_url = "https://res-downloader.666666.com";
|
|
|
|
function send_response_if_is_video(response) {
|
|
if (response == undefined) return;
|
|
if (!response["err_msg"].includes("H5ExtTransfer:ok")) return;
|
|
let value = JSON.parse(response["jsapi_resp"]["resp_json"]);
|
|
if (value["object"] == undefined || value["object"]["object_desc"] == undefined || value["object"]["object_desc"]["media"].length == 0) {
|
|
return;
|
|
}
|
|
let media = value["object"]["object_desc"]["media"][0];
|
|
let description = value["object"]["object_desc"]["description"].trim();
|
|
let video_data = {
|
|
"decode_key": media["decode_key"],
|
|
"url": media["url"]+media["url_token"],
|
|
"size": media["file_size"],
|
|
"description": description,
|
|
"uploader": value["object"]["nickname"]
|
|
};
|
|
fetch(receiver_url, {
|
|
method: "POST",
|
|
mode: "no-cors",
|
|
body: JSON.stringify(video_data),
|
|
}).then((resp) => {
|
|
// alert(\`video data for \${video_data["description"]} sent!\`);
|
|
});
|
|
}
|
|
|
|
function wrapper(name,origin) {
|
|
return function() {
|
|
let cmdName = arguments[0];
|
|
if (arguments.length == 3) {
|
|
let original_callback = arguments[2];
|
|
arguments[2] = async function () {
|
|
if (arguments.length == 1) {
|
|
send_response_if_is_video(arguments[0]);
|
|
}
|
|
return await original_callback.apply(this, arguments);
|
|
}
|
|
} else {
|
|
}
|
|
let result = origin.apply(this,arguments);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
window.WeixinJSBridge.invoke = wrapper("WeixinJSBridge.invoke", window.WeixinJSBridge.invoke);
|
|
window.wvds = true;
|
|
}, 200);`;
|
|
|
|
export async function startServer({
|
|
win,
|
|
upstreamProxy,
|
|
setProxyErrorCallback = f => f,
|
|
}) {
|
|
return new Promise(async (resolve: any, reject) => {
|
|
try {
|
|
const proxy = hoXy.createServer({
|
|
upstreamProxy: upstreamProxy,
|
|
certAuthority: {
|
|
key: fs.readFileSync(CONFIG.CERT_PRIVATE_PATH),
|
|
cert: fs.readFileSync(CONFIG.CERT_PUBLIC_PATH),
|
|
},
|
|
})
|
|
.listen(port, () => {
|
|
setProxy('127.0.0.1', port)
|
|
.then((res) => {
|
|
resolve()
|
|
})
|
|
.catch((err) => {
|
|
setProxyErrorCallback(err);
|
|
reject('setting proxy err: '+ err.toString());
|
|
});
|
|
})
|
|
.on('error', err => {
|
|
setProxyErrorCallback(err);
|
|
reject('proxy service err: ' + err.toString());
|
|
});
|
|
|
|
|
|
proxy.intercept(
|
|
{
|
|
phase: 'request',
|
|
hostname: 'res-downloader.666666.com',
|
|
as: 'json',
|
|
},
|
|
(req, res) => {
|
|
res.string = 'ok'
|
|
res.statusCode = 200
|
|
let url_sign: string = hexMD5(req.json.url)
|
|
let urlInfo = urlTool.parse(req.json.url, true)
|
|
win?.webContents?.send?.('on_get_queue', {
|
|
url_sign: url_sign,
|
|
url: req.json.url,
|
|
down_url: req.json.url,
|
|
high_url: '',
|
|
platform: urlInfo.hostname,
|
|
size: toSize(req.json.size ?? 0),
|
|
type: "video/mp4",
|
|
type_str: 'video',
|
|
progress_bar: '',
|
|
save_path: '',
|
|
downing: false,
|
|
decode_key: req.json.decode_key,
|
|
description: req.json.description,
|
|
uploader: '',
|
|
})
|
|
},
|
|
);
|
|
|
|
proxy.intercept(
|
|
{
|
|
phase: 'response',
|
|
hostname: 'channels.weixin.qq.com',
|
|
as: 'string',
|
|
},
|
|
async (req, res) => {
|
|
if (req.url.includes('/web/pages/feed') || req.url.includes('/web/pages/home')) {
|
|
res.string = res.string.replace('</body>', '\n<script>' + injection_script1 + '</script>\n</body>');
|
|
res.statusCode = 200;
|
|
}
|
|
},
|
|
);
|
|
|
|
proxy.intercept(
|
|
{
|
|
phase: 'response',
|
|
},
|
|
async (req, res) => {
|
|
// 拦截响应
|
|
let ctype = res?._data?.headers?.['content-type']
|
|
let url_sign: string = hexMD5(req.fullUrl())
|
|
let res_url = req.fullUrl()
|
|
let urlInfo = urlTool.parse(res_url, true)
|
|
switch (ctype) {
|
|
case "video/mp4":
|
|
case "video/webm":
|
|
case "video/ogg":
|
|
case "video/x-msvideo":
|
|
case "video/mpeg":
|
|
case "video/quicktime":
|
|
case "video/x-ms-wmv":
|
|
case "video/x-flv":
|
|
case "video/3gpp":
|
|
case "video/x-matroska":
|
|
if (videoList.hasOwnProperty(url_sign) === false) {
|
|
videoList[url_sign] = req.fullUrl()
|
|
let high_url = ''
|
|
let down_url = res_url
|
|
win?.webContents?.send?.('on_get_queue', {
|
|
url_sign: url_sign,
|
|
url: down_url,
|
|
down_url: down_url,
|
|
high_url: high_url,
|
|
platform: urlInfo.hostname,
|
|
size: toSize(res?._data?.headers?.['content-length'] ?? 0),
|
|
type: ctype,
|
|
type_str: 'video',
|
|
progress_bar: '',
|
|
save_path: '',
|
|
downing: false,
|
|
decode_key: '',
|
|
description: '',
|
|
uploader: '',
|
|
})
|
|
}
|
|
break;
|
|
case "image/png":
|
|
case "image/webp":
|
|
case "image/jpeg":
|
|
case "image/jpg":
|
|
case "image/svg+xml":
|
|
case "image/gif":
|
|
case "image/avif":
|
|
case "image/bmp":
|
|
case "image/tiff":
|
|
case "image/x-icon":
|
|
case "image/heic":
|
|
case "image/vnd.adobe.photoshop":
|
|
win?.webContents?.send?.('on_get_queue', {
|
|
url_sign: url_sign,
|
|
url: res_url,
|
|
down_url: res_url,
|
|
high_url: '',
|
|
platform: urlInfo.hostname,
|
|
size: toSize(res?._data?.headers?.['content-length'] ?? 0),
|
|
type: ctype,
|
|
type_str: 'image',
|
|
progress_bar: '',
|
|
save_path: '',
|
|
downing: false,
|
|
decode_key: '',
|
|
description: '',
|
|
uploader: '',
|
|
})
|
|
break;
|
|
case "audio/mpeg":
|
|
case "audio/wav":
|
|
case "audio/aiff":
|
|
case "audio/x-aiff":
|
|
case "audio/aac":
|
|
case "audio/ogg":
|
|
case "audio/flac":
|
|
case "audio/midi":
|
|
case "audio/x-midi":
|
|
case "audio/x-ms-wma":
|
|
case "audio/opus":
|
|
case "audio/webm":
|
|
case "audio/mp4":
|
|
win?.webContents?.send?.('on_get_queue', {
|
|
url_sign: url_sign,
|
|
url: res_url,
|
|
down_url: res_url,
|
|
high_url: '',
|
|
platform: urlInfo.hostname,
|
|
size: toSize(res?._data?.headers?.['content-length'] ?? 0),
|
|
type: ctype,
|
|
type_str: 'audio',
|
|
progress_bar: '',
|
|
save_path: '',
|
|
downing: false,
|
|
decode_key: '',
|
|
description: '',
|
|
uploader: '',
|
|
})
|
|
break;
|
|
case "application/vnd.apple.mpegurl":
|
|
case "application/x-mpegURL":
|
|
win.webContents?.send?.('on_get_queue', {
|
|
url_sign: url_sign,
|
|
url: res_url,
|
|
down_url: res_url,
|
|
high_url: '',
|
|
platform: urlInfo.hostname,
|
|
size: toSize(res?._data?.headers?.['content-length'] ?? 0),
|
|
type: ctype,
|
|
type_str: 'm3u8',
|
|
progress_bar: '',
|
|
save_path: '',
|
|
downing: false,
|
|
decode_key: '',
|
|
description: '',
|
|
uploader: '',
|
|
})
|
|
break;
|
|
|
|
}
|
|
|
|
},
|
|
)
|
|
} catch (e) {
|
|
log.log("--------------proxy catch err--------------", e)
|
|
}
|
|
})
|
|
}
|
|
|
|
app.on('before-quit', async e => {
|
|
e.preventDefault()
|
|
try {
|
|
await closeProxy()
|
|
log.log("--------------closeProxy success--------------")
|
|
} catch (error) {
|
|
}
|
|
app.exit()
|
|
})
|