feat: add per-account socks5 proxy
This commit is contained in:
@@ -2,6 +2,14 @@ const axios = require('axios');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const vm = require('vm');
|
||||
const { AsyncLocalStorage } = require('async_hooks');
|
||||
|
||||
let SocksProxyAgent = null;
|
||||
try {
|
||||
({ SocksProxyAgent } = require('socks-proxy-agent'));
|
||||
} catch (e) {
|
||||
// 未配置代理时不需要安装;配置 SOCKS5 代理时会给出明确提示。
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 大象新闻积分脚本 - Token缓存版
|
||||
@@ -23,6 +31,12 @@ const vm = require('vm');
|
||||
// export dxxwhd="账号1&密码1@账号2&密码2" # 多账号用@分隔
|
||||
// export dxxwhd="账号1&密码1
|
||||
// 账号2&密码2" # 多账号也可用换行分隔
|
||||
// export dxxwhd="账号&密码&支付宝账号&姓名&socks5://127.0.0.1:7890" # 可选账号级 SOCKS5 代理
|
||||
//
|
||||
// 账号字段:账号&密码&支付宝账号&姓名&socks5代理
|
||||
// - 支付宝账号/姓名/代理均可选;如果只想配置代理但不配置支付宝,可写:账号&密码&&&socks5://host:port
|
||||
// - 代理支持 socks5:// / socks5h://,可带认证:socks5h://user:pass@host:port
|
||||
// - 该账号配置代理后,登录、积分、文章、微剧/兑吧等所有 axios 请求均走该代理;未配置则使用本地网络
|
||||
//
|
||||
// 脚本配置(在脚本中修改):
|
||||
// ENABLE_NOTIFY = true # 开启通知(默认false,需要青龙面板环境)
|
||||
@@ -58,6 +72,70 @@ const AXIOS_COMMON_OPTS = {
|
||||
maxContentLength: Infinity
|
||||
};
|
||||
|
||||
// ========== 账号级 SOCKS5 代理 ==========
|
||||
const accountContext = new AsyncLocalStorage();
|
||||
const socksAgentCache = new Map();
|
||||
const axiosRequestRaw = axios.request.bind(axios);
|
||||
|
||||
function normalizeSocksProxy(proxyUrl) {
|
||||
const raw = String(proxyUrl || '').trim();
|
||||
if (!raw) return '';
|
||||
if (/^socks5h?:\/\//i.test(raw)) return raw;
|
||||
// 兼容只填 host:port 的写法,默认按 socks5:// 处理。
|
||||
if (/^[^\s:/]+:\d+$/i.test(raw)) return `socks5://${raw}`;
|
||||
throw new Error(`SOCKS5代理格式不正确: ${raw}`);
|
||||
}
|
||||
|
||||
function maskProxyUrl(proxyUrl) {
|
||||
if (!proxyUrl) return '未配置';
|
||||
try {
|
||||
const u = new URL(proxyUrl);
|
||||
if (u.username || u.password) {
|
||||
u.username = '***';
|
||||
u.password = '***';
|
||||
}
|
||||
return u.toString();
|
||||
} catch (_) {
|
||||
return String(proxyUrl).replace(/:\/\/([^:@/]+):([^@/]+)@/, '://***:***@');
|
||||
}
|
||||
}
|
||||
|
||||
function getSocksAgent(proxyUrl) {
|
||||
const normalized = normalizeSocksProxy(proxyUrl);
|
||||
if (!normalized) return null;
|
||||
if (!SocksProxyAgent) {
|
||||
throw new Error('已配置SOCKS5代理,但缺少依赖 socks-proxy-agent,请先执行: npm install');
|
||||
}
|
||||
if (!socksAgentCache.has(normalized)) {
|
||||
socksAgentCache.set(normalized, new SocksProxyAgent(normalized));
|
||||
}
|
||||
return socksAgentCache.get(normalized);
|
||||
}
|
||||
|
||||
function applyCurrentAccountProxy(config = {}) {
|
||||
const ctx = accountContext.getStore();
|
||||
const proxyUrl = ctx && ctx.socksProxy;
|
||||
if (!proxyUrl) return config;
|
||||
|
||||
const agent = getSocksAgent(proxyUrl);
|
||||
return {
|
||||
...config,
|
||||
proxy: false,
|
||||
httpAgent: config.httpAgent || agent,
|
||||
httpsAgent: config.httpsAgent || agent
|
||||
};
|
||||
}
|
||||
|
||||
axios.request = function patchedAxiosRequest(config) {
|
||||
return axiosRequestRaw(applyCurrentAccountProxy(config || {}));
|
||||
};
|
||||
axios.interceptors.request.use(config => applyCurrentAccountProxy(config || {}));
|
||||
|
||||
function runWithAccountProxy(socksProxy, fn) {
|
||||
const normalized = normalizeSocksProxy(socksProxy);
|
||||
return accountContext.run({ socksProxy: normalized }, fn);
|
||||
}
|
||||
|
||||
function addNotifyStr(str, is_log = true) {
|
||||
if (is_log) console.log(str);
|
||||
msg += `${str}\n`;
|
||||
@@ -1193,12 +1271,15 @@ async function doWeijuSignTask(token, alipay = '', realname = '') {
|
||||
async function executeAccount(accountInfo, index) {
|
||||
const username = accountInfo[0];
|
||||
const password = accountInfo[1];
|
||||
// 账号格式:账号&密码&支付宝账号&姓名(后两项可选;缺则不抽奖、不提现)
|
||||
// 账号格式:账号&密码&支付宝账号&姓名&socks5代理(后三项可选;代理配置后该账号所有请求均走代理)
|
||||
let alipay = (accountInfo[2] || '').trim();
|
||||
let realname = (accountInfo[3] || '').trim();
|
||||
const socksProxy = normalizeSocksProxy(accountInfo.slice(4).join('&'));
|
||||
|
||||
addNotifyStr(`\n==== 开始【第 ${index + 1} 个账号: ${username}】====`);
|
||||
addNotifyStr(`🌐 SOCKS5代理: ${socksProxy ? maskProxyUrl(socksProxy) : '未配置,使用本地网络'}`);
|
||||
|
||||
return runWithAccountProxy(socksProxy, async () => {
|
||||
// 使用新的token获取方法(优先缓存,失效则登录),同时把 alipay/realname 写入缓存
|
||||
const token = await getValidToken(username, password, { alipay, realname });
|
||||
if (!token) {
|
||||
@@ -1337,6 +1418,7 @@ async function executeAccount(accountInfo, index) {
|
||||
if (earnedScore > 0) {
|
||||
addNotifyStr(`🎉 本次获得积分: +${earnedScore}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 主程序 ==========
|
||||
|
||||
Reference in New Issue
Block a user