Files
Ytong825-mao/快手极速版25-10-18免费版.js
Ytong 207c42fe73 0
2025-10-18 22:32:03 +08:00

1197 lines
35 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 当前脚本来自于http://script.345yun.cn脚本库下载
//变量名称: ksck 变量值格式: ck#salt#代理
//大佬鹿飞提供的免费算法接口,快手极速版开源免费版 2025-10-18
const qs = require("querystring");
const axios = require("axios");
const querystring = require("querystring");
const { SocksProxyAgent } = require("socks-proxy-agent");
// 生成随机交互消息
function generateRandomInteractionMessage() {
const messages = [
"正在观看广告",
"认真观看中...",
"浏览广告内容",
"模拟用户行为",
"观看视频广告",
"保持活跃状态",
"广告浏览中",
"正常观看时长",
];
return messages[Math.floor(Math.random() * messages.length)];
}
// 开发模式和环境变量检测
const isDevMode =
process.env.DEV_MODE === "1" || process.env.DEV_MODE === "true";
// 获取环境变量值,带默认值
function getEnvNumber(envKey, defaultValue) {
const value = parseInt(process.env[envKey], 10);
return isNaN(value) ? defaultValue : value;
}
// 环境变量配置
const KSLOW_REWARD_THRESHOLD = getEnvNumber("KSLOW_REWARD_THRESHOLD", 10); // 低奖励阈值
const KSROUNDS = getEnvNumber("KSROUNDS", 35); // 任务轮数
const KSCOIN_LIMIT = getEnvNumber("KSCOIN_LIMIT", 500000); // 金币上限
const KSLOW_REWARD_LIMIT = getEnvNumber("KSLOW_REWARD_LIMIT", 3); // 连续低奖励上限
// 获取要执行的任务列表
function getTasksToExecute() {
const taskEnv = process.env.Task;
if (!taskEnv) {
console.log("📝 未设置Task环境变量将执行所有任务 (food, box, look)");
return ["food", "box", "look"];
}
const tasks = taskEnv
.split(",")
.map((task) => task.trim().toLowerCase())
.filter(Boolean);
const validTasks = ["food", "box", "look"];
const filteredTasks = tasks.filter((task) => validTasks.includes(task));
if (filteredTasks.length === 0) {
console.log("📝 Task环境变量中没有有效任务将执行所有任务 (food, box, look)");
return ["food", "box", "look"];
}
console.log("🎯 从Task环境变量中解析到要执行的任务: " + filteredTasks.join(", "));
return filteredTasks;
}
// 从 ksck, ksck1 到 ksck666 读取账号配置
function getAccountConfigsFromEnv() {
const configs = [];
const seenConfigs = new Set();
// 读取ksck主配置
if (process.env.ksck) {
const ksckValue = process.env.ksck;
const configStrings = ksckValue
.split("&")
.map((config) => config.trim())
.filter(Boolean);
configs.push(...configStrings);
}
// 读取ksck1到ksck666配置
for (let i = 1; i <= 666; i++) {
const ksckKey = `ksck${i}`;
if (process.env[ksckKey]) {
const ksckValue = process.env[ksckKey];
const configStrings = ksckValue
.split("&")
.map((config) => config.trim())
.filter(Boolean);
configs.push(...configStrings);
}
}
// 去重处理
const uniqueConfigs = [];
for (const config of configs) {
if (!seenConfigs.has(config)) {
seenConfigs.add(config);
uniqueConfigs.push(config);
}
}
console.log(`📊 从环境变量中解析到 ${uniqueConfigs.length} 个唯一配置`);
return uniqueConfigs;
}
const accountConfigs = getAccountConfigsFromEnv();
const accountCount = accountConfigs.length;
const tasksToExecute = getTasksToExecute();
// 美化打印:简洁的启动信息
console.log("\n" + "=".repeat(50));
console.log("🚀 快手至尊金币版 - 启动成功");
console.log("=".repeat(50));
console.log(`📱 账号数量: ${accountCount}`);
console.log(`🎯 执行任务: ${tasksToExecute.join(", ")}`);
console.log(`⚙️ 配置参数: 轮数=${KSROUNDS}, 金币上限=${KSCOIN_LIMIT}`);
console.log("=".repeat(50) + "\n");
if (accountCount > (process.env.MAX_CONCURRENCY || 999)) {
console.log(`❌ 错误: 检测到 ${accountCount} 个账号配置,最多只允许${process.env.MAX_CONCURRENCY || 999}`);
process.exit(1);
}
// 生成快手设备ID
function generateKuaishouDid() {
try {
const generateRandomHexString = (length) => {
const hexChars = "0123456789abcdef";
let result = "";
for (let i = 0; i < length; i++) {
result += hexChars.charAt(Math.floor(Math.random() * hexChars.length));
}
return result;
};
const randomId = generateRandomHexString(16);
const deviceId = "ANDROID_" + randomId;
return deviceId;
} catch (error) {
console.log("❌ 生成did失败: " + error.message);
const timestamp = Date.now().toString(16).toUpperCase();
return "ANDROID_" + timestamp.substring(0, 16);
}
}
// 发送网络请求
async function sendRequest(
requestOptions,
proxyUrl = null,
description = "Unknown Request"
) {
const finalOptions = { ...requestOptions };
// 配置代理
let agent = null;
if (proxyUrl) {
try {
agent = new SocksProxyAgent(proxyUrl);
} catch (proxyError) {
console.log(`${description} 代理URL无效尝试直连模式`);
}
}
try {
const axiosConfig = {
method: finalOptions.method || "GET",
url: finalOptions.url,
headers: finalOptions.headers || {},
data: finalOptions.body || finalOptions.form,
timeout: finalOptions.timeout || 30000,
...(agent && {
httpAgent: agent,
httpsAgent: agent,
}),
};
const response = await axios(axiosConfig);
return { response: response, body: response.data };
} catch (error) {
return { response: null, body: null };
}
}
// 测试代理连通性
async function testProxyConnectivity(proxyUrl, description = "代理连通性检测") {
if (!proxyUrl) {
return {
ok: true,
msg: "✅ 未配置代理(直连模式)",
ip: "localhost",
};
}
const { response: baiduResponse, body: baiduResult } = await sendRequest(
{
method: "GET",
url: "https://httpbin.org/ip",
headers: {
"User-Agent": "ProxyTester/1.0",
},
timeout: 8000,
},
proxyUrl,
description + " → baidu.com"
);
if (baiduResult) {
return {
ok: true,
msg: `✅ SOCKS5代理正常出口IP: ${baiduResult.origin}`,
ip: baiduResult.origin,
};
}
return {
ok: false,
msg: "❌ 代理连接失败",
ip: null
};
}
const usedProxies = new Set();
// 获取账号基本信息
async function getAccountBasicInfo(cookie, proxyUrl, accountId = "?") {
const url =
"https://nebula.kuaishou.com/rest/n/nebula/activity/earn/overview/basicInfo?source=bottom_guide_first";
const { body: result } = await sendRequest(
{
method: "GET",
url: url,
headers: {
Host: "nebula.kuaishou.com",
"User-Agent": "kwai-android aegon/3.56.0",
Cookie: cookie,
"Content-Type": "application/x-www-form-urlencoded",
},
timeout: 12000,
},
proxyUrl,
"获取账号基本信息"
);
if (result && result.result === 1 && result.data) {
return {
nickname: result.data.userData?.nickname || null,
totalCoin: result.data.totalCoin ?? null,
allCash: result.data.allCash ?? null,
};
}
return null;
}
// 快手广告任务类
class KuaishouAdTask {
constructor({
index,
salt,
cookie,
nickname = "",
proxyUrl = null,
tasksToExecute = ["food", "box", "look"],
remark = "",
}) {
this.index = index;
this.salt = salt;
this.cookie = cookie;
this.nickname = nickname || remark || "账号" + index;
this.remark = remark;
this.proxyUrl = proxyUrl;
this.coinLimit = KSCOIN_LIMIT;
this.coinExceeded = false;
this.tasksToExecute = tasksToExecute;
this.extractCookieInfo();
// 请求头配置
this.headers = {
Host: "nebula.kuaishou.com",
Connection: "keep-alive",
"User-Agent": "Mozilla/5.0 (Linux; Android 10; MI 8 Lite Build/QKQ1.190910.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.101 Mobile Safari/537.36",
Cookie: this.cookie,
"content-type": "application/json",
};
this.taskReportPath = "/rest/r/ad/task/report";
this.startTime = Date.now();
this.endTime = this.startTime - 30000;
this.queryParams =
"mod=Xiaomi(MI 11)&appver=" +
this.appver +
"&egid=" +
this.egid +
"&did=" +
this.did;
// 任务配置
this.taskConfigs = {
box: {
name: "宝箱广告",
businessId: 606,
posId: 20346,
subPageId: 100024064,
requestSceneType: 1,
taskType: 1,
},
look: {
name: "看广告得金币",
businessId: 672,
posId: 24067,
subPageId: 100026367,
requestSceneType: 1,
taskType: 1,
},
food: {
name: "饭补广告",
businessId: 9362,
posId: 24067,
subPageId: 100026367,
requestSceneType: 7,
taskType: 2,
},
};
// 任务统计
this.taskStats = {};
this.tasksToExecute.forEach((taskKey) => {
if (this.taskConfigs[taskKey]) {
this.taskStats[taskKey] = {
success: 0,
failed: 0,
totalReward: 0,
};
}
});
// 低奖励控制
this.lowRewardStreak = 0;
this.lowRewardThreshold = KSLOW_REWARD_THRESHOLD;
this.lowRewardLimit = KSLOW_REWARD_LIMIT;
this.stopAllTasks = false;
// 任务上限标记
this.taskLimitReached = {};
this.tasksToExecute.forEach((taskKey) => {
if (this.taskConfigs[taskKey]) {
this.taskLimitReached[taskKey] = false;
}
});
}
// 检查金币上限
async checkCoinLimit() {
try {
const accountInfo = await getAccountBasicInfo(
this.cookie,
this.proxyUrl,
this.index
);
if (accountInfo && accountInfo.totalCoin) {
const currentCoin = parseInt(accountInfo.totalCoin);
if (currentCoin >= this.coinLimit) {
console.log(`💰 ${this.getAccountDisplayName()} 金币已达 ${currentCoin},超过阈值 ${this.coinLimit},停止任务`);
this.coinExceeded = true;
this.stopAllTasks = true;
return true;
}
}
return false;
} catch (error) {
console.log(`${this.getAccountDisplayName()} 金币检查异常: ${error.message}`);
return false;
}
}
// 获取账号显示名称
getAccountDisplayName() {
return `账号[${this.nickname}]${this.remark ? "(" + this.remark + ")" : ""}`;
}
// 从cookie中提取信息
extractCookieInfo() {
try {
const egidMatch = this.cookie.match(/egid=([^;]+)/);
const didMatch = this.cookie.match(/did=([^;]+)/);
const userIdMatch = this.cookie.match(/userId=([^;]+)/);
const apiStMatch = this.cookie.match(/kuaishou\.api_st=([^;]+)/);
const appverMatch = this.cookie.match(/appver=([^;]+)/);
this.egid = egidMatch ? egidMatch[1] : "";
this.did = didMatch ? didMatch[1] : "";
this.userId = userIdMatch ? userIdMatch[1] : "";
this.kuaishouApiSt = apiStMatch ? apiStMatch[1] : "";
this.appver = appverMatch ? appverMatch[1] : "13.7.20.10468";
if (!this.egid || !this.did) {
console.log(`⚠️ ${this.getAccountDisplayName()} cookie格式可能无egid或did继续尝试...`);
}
} catch (error) {
console.log(`${this.getAccountDisplayName()} 解析cookie失败: ${error.message}`);
}
}
getTaskStats() {
return this.taskStats;
}
// 打印任务统计
printTaskStats() {
console.log(`\n📊 ${this.getAccountDisplayName()} 任务统计:`);
for (const [taskKey, stats] of Object.entries(this.taskStats)) {
const taskName = this.taskConfigs[taskKey].name;
console.log(` ${taskName}: 成功${stats.success}次, 失败${stats.failed}次, 奖励${stats.totalReward}金币`);
}
}
// 重试操作
async retryOperation(operation, description, maxRetries = 3, delay = 2000) {
let attempts = 0;
let lastError = null;
while (attempts < maxRetries) {
try {
const result = await operation();
if (result) {
return result;
}
lastError = new Error(description + " 返回空结果");
} catch (error) {
lastError = error;
}
attempts++;
if (attempts < maxRetries) {
console.log(`🔄 ${this.getAccountDisplayName()} ${description} 失败,重试 ${attempts}/${maxRetries}`);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
return null;
}
// 获取广告信息
async getAdInfo(taskConfig) {
try {
const adPath = "/rest/e/reward/mixed/ad";
const formData = {
encData: "|encData|",
sign: "|sign|",
cs: "false",
client_key: "2ac2a76d",
videoModelCrowdTag: "1_23",
os: "android",
"kuaishou.api_st": this.kuaishouApiSt,
uQaTag: "1##swLdgl:99#ecPp:-9#cmNt:-0#cmHs:-3#cmMnsl:-0",
};
const queryData = {
earphoneMode: "1",
mod: "Xiaomi(23116PN5BC)",
appver: this.appver,
isp: "CUCC",
language: "zh-cn",
ud: this.userId,
did_tag: "0",
net: "WIFI",
kcv: "1599",
app: "0",
kpf: "ANDROID_PHONE",
ver: "11.6",
android_os: "0",
boardPlatform: "pineapple",
kpn: "NEBULA",
androidApiLevel: "35",
country_code: "cn",
sys: "ANDROID_15",
sw: "1080",
sh: "2400",
abi: "arm64",
userRecoBit: "0",
};
const requestBody = {
appInfo: {
appId: "kuaishou_nebula",
name: "快手极速版",
packageName: "com.kuaishou.nebula",
version: this.appver,
versionCode: -1,
},
deviceInfo: {
osType: 1,
osVersion: "15",
deviceId: this.did,
screenSize: {
width: 1080,
height: 2249,
},
ftt: "",
},
userInfo: {
userId: this.userId,
age: 0,
gender: "",
},
impInfo: [
{
pageId: 11101,
subPageId: taskConfig.subPageId,
action: 0,
browseType: 3,
impExtData: "{}",
mediaExtData: "{}",
},
],
};
const encodedBody = Buffer.from(JSON.stringify(requestBody)).toString("base64");
let encsign = await this.getSign(encodedBody);
formData.encData = encsign.encdata;
formData.sign = encsign.sign;
let nesig = await this.requestSignService({
urlpath: adPath,
reqdata: qs.stringify(formData) + "&" + qs.stringify(queryData),
api_client_salt: this.salt,
});
const finalQueryData = {
...queryData,
sig: nesig.sig,
__NS_sig3: nesig.__NS_sig3,
__NS_xfalcon: "",
__NStokensig: nesig.__NStokensig,
};
const url = "https://api.e.kuaishou.com" + adPath + "?" + querystring.stringify(finalQueryData);
const { response, body: result } = await sendRequest(
{
method: "POST",
url: url,
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
Host: "api.e.kuaishou.com",
"User-Agent": "kwai-android aegon/3.56.0",
Cookie: "kuaishou_api_st=" + this.kuaishouApiSt,
},
form: formData,
timeout: 12000,
},
this.proxyUrl,
`${this.getAccountDisplayName()} 获取广告`
);
if (!result) {
return null;
}
if (result.errorMsg === "OK" && result.feeds && result.feeds[0] && result.feeds[0].ad) {
const caption = result.feeds[0].caption || result.feeds[0].ad?.caption || "";
if (caption) {
console.log(`${this.getAccountDisplayName()} 成功获取广告:${caption}`);
}
const expTag = result.feeds[0].exp_tag || "";
const llsid = expTag.split("/")[1]?.split("_")?.[0] || "";
return {
cid: result.feeds[0].ad.creativeId,
llsid: llsid,
};
}
return null;
} catch (error) {
console.log(`${this.getAccountDisplayName()} 获取广告异常: ${error.message}`);
return null;
}
}
// 生成签名
async generateSignature(creativeId, llsid, taskKey, taskConfig) {
try {
const bizData = JSON.stringify({
businessId: taskConfig.businessId,
endTime: this.endTime,
extParams: "",
mediaScene: "video",
neoInfos: [
{
creativeId: creativeId,
extInfo: "",
llsid: llsid,
requestSceneType: taskConfig.requestSceneType,
taskType: taskConfig.taskType,
watchExpId: "",
watchStage: 0,
},
],
pageId: 11101,
posId: taskConfig.posId,
reportType: 0,
sessionId: "",
startTime: this.startTime,
subPageId: taskConfig.subPageId,
});
const postData = "bizStr=" + encodeURIComponent(bizData) + "&cs=false&client_key=2ac2a76d&kuaishou.api_st=" + this.kuaishouApiSt;
const urlData = this.queryParams + "&" + postData;
const signResult = await this.requestSignService(
{
urlpath: this.taskReportPath,
reqdata: urlData,
api_client_salt: this.salt,
},
`${this.getAccountDisplayName()} 生成报告签名`
);
return {
sig: signResult.sig,
sig3: signResult.__NS_sig3,
sigtoken: signResult.__NStokensig,
post: postData,
};
} catch (error) {
console.log(`${this.getAccountDisplayName()} 生成签名异常: ${error.message}`);
return null;
}
}
// 获取签名
async getSign(requestData) {
try {
const { response, body: result } = await sendRequest({
method: "POST",
url: "https://ks.smallfawn.top/encsign",
body: JSON.stringify({
data: requestData,
}),
headers: {
"Content-Type": "application/json",
},
});
if (result.status) {
return result.data;
}
} catch (error) {
console.log(`${this.getAccountDisplayName()} 获取签名失败`);
}
}
// 请求签名服务
async requestSignService(requestData, description) {
let returnData = {};
let newreqdata = {
path: requestData.urlpath,
data: requestData.reqdata,
salt: requestData.api_client_salt,
};
const { response, body: result } = await sendRequest(
{
method: "POST",
url: "https://ks.smallfawn.top/nssig",
headers: {
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0",
},
body: JSON.stringify(newreqdata),
timeout: 15000,
},
null,
description
);
if (result) {
let __NS_sig3 = result.data.nssig3;
let __NStokensig = result.data.nstokensig;
Object.assign(returnData, {
__NS_sig3,
__NStokensig,
sig: result.data.sig,
});
return returnData;
}
return null;
}
// 提交报告
async submitReport(sig, sig3, sigtoken, postData, taskKey, taskConfig) {
try {
const url = "https://api.e.kuaishou.com" + this.taskReportPath + "?" + (this.queryParams + "&sig=" + sig + "&__NS_sig3=" + sig3 + "&__NS_xfalcon=&__NStokensig=" + sigtoken);
const { response, body: result } = await sendRequest(
{
method: "POST",
url: url,
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
Host: "api.e.kuaishou.cn",
"User-Agent": "kwai-android aegon/3.56.0",
"Content-Type": "application/x-www-form-urlencoded",
},
body: postData,
timeout: 12000,
},
this.proxyUrl,
`${this.getAccountDisplayName()} 提交任务`
);
if (!result) {
return {
success: false,
reward: 0,
};
}
if (result.result === 1) {
const reward = result.data?.neoAmount || 0;
console.log(`💰 ${this.getAccountDisplayName()} ${taskConfig.name}获得${reward}金币奖励!`);
if (reward <= this.lowRewardThreshold) {
this.lowRewardStreak++;
this.did = generateKuaishouDid();
console.log(`⚠️ ${this.getAccountDisplayName()} 金币奖励(${reward})低于阈值,当前连续低奖励次数:${this.lowRewardStreak}/${this.lowRewardLimit}`);
if (this.lowRewardStreak >= this.lowRewardLimit) {
console.log(`🏁 ${this.getAccountDisplayName()} 连续${this.lowRewardLimit}次低奖励,停止全部任务`);
this.stopAllTasks = true;
}
} else {
this.lowRewardStreak = 0;
}
return {
success: true,
reward: reward,
};
}
if ([20107, 20108, 1003, 415].includes(result.result)) {
console.log(`⚠️ ${this.getAccountDisplayName()} ${taskConfig.name} 已达上限`);
this.taskLimitReached[taskKey] = true;
return {
success: false,
reward: 0,
};
}
console.log(`${this.getAccountDisplayName()} ${taskConfig.name} 奖励失败`);
return {
success: false,
reward: 0,
};
} catch (error) {
console.log(`${this.getAccountDisplayName()} 提交任务异常: ${error.message}`);
return {
success: false,
reward: 0,
};
}
}
// 执行单个任务
async executeTask(taskKey) {
const taskConfig = this.taskConfigs[taskKey];
if (!taskConfig) {
console.log(`${this.getAccountDisplayName()} 未知任务: ${taskKey}`);
return false;
}
if (this.taskLimitReached[taskKey]) {
return false;
}
try {
const adInfo = await this.retryOperation(
() => this.getAdInfo(taskConfig),
`获取${taskConfig.name}信息`,
3
);
if (!adInfo) {
this.taskStats[taskKey].failed++;
return false;
}
const watchTime = Math.floor(Math.random() * 10000) + 30000;
console.log(`👀 ${this.getAccountDisplayName()} ${taskConfig.name} ${generateRandomInteractionMessage()} ${Math.round(watchTime / 1000)}`);
await new Promise((resolve) => setTimeout(resolve, watchTime));
const signature = await this.retryOperation(
() => this.generateSignature(adInfo.cid, adInfo.llsid, taskKey, taskConfig),
`生成${taskConfig.name}签名`,
3
);
if (!signature) {
this.taskStats[taskKey].failed++;
return false;
}
const submitResult = await this.retryOperation(
() => this.submitReport(signature.sig, signature.sig3, signature.sigtoken, signature.post, taskKey, taskConfig),
`提交${taskConfig.name}报告`,
3
);
if (submitResult?.success) {
this.taskStats[taskKey].success++;
this.taskStats[taskKey].totalReward += submitResult.reward || 0;
return true;
}
this.taskStats[taskKey].failed++;
return false;
} catch (error) {
console.log(`${this.getAccountDisplayName()} 任务异常(${taskKey}): ${error.message}`);
this.taskStats[taskKey].failed++;
return false;
}
}
// 按优先级执行所有任务
async executeAllTasksByPriority() {
const results = {};
for (const taskKey of this.tasksToExecute) {
if (this.stopAllTasks) {
break;
}
if (!this.taskConfigs[taskKey]) {
console.log(`⚠️ ${this.getAccountDisplayName()} 跳过未知任务: ${taskKey}`);
continue;
}
console.log(`🚀 ${this.getAccountDisplayName()} 开始任务:${this.taskConfigs[taskKey].name}`);
results[taskKey] = await this.executeTask(taskKey);
if (this.stopAllTasks) {
break;
}
if (taskKey !== this.tasksToExecute[this.tasksToExecute.length - 1]) {
const waitTime = Math.floor(Math.random() * 8000) + 7000;
console.log(`${this.getAccountDisplayName()} 等待 ${Math.round(waitTime / 1000)}秒进入下一任务`);
await new Promise((resolve) => setTimeout(resolve, waitTime));
}
}
return results;
}
}
// 解析账号配置
function parseAccountConfig(configString) {
const parts = String(configString || "").trim().split("#");
if (parts.length < 2) {
return null;
}
let remark = "";
let cookie = "";
let salt = "";
let proxyUrl = null;
if (parts.length === 2) {
// 格式: ck#salt
cookie = parts[0];
salt = parts[1];
} else if (parts.length === 3) {
// 格式: remark#ck#salt 或 ck#salt#proxy
if (/socks5:\/\//i.test(parts[2])) {
cookie = parts[0];
salt = parts[1];
proxyUrl = parts[2];
} else {
remark = parts[0];
cookie = parts[1];
salt = parts[2];
}
} else if (parts.length >= 4) {
// 格式: remark#ck#salt#proxy
remark = parts[0];
cookie = parts[1];
salt = parts.slice(2, parts.length - 1).join("#");
proxyUrl = parts[parts.length - 1];
}
if (proxyUrl) {
if (proxyUrl.includes("|")) {
console.log(`🔧 解析代理格式: ${proxyUrl}`);
const proxyParts = proxyUrl.split("|");
if (proxyParts.length >= 2) {
const [ip, port, username, password] = proxyParts;
proxyUrl = `socks5://${username}:${password}@${ip}:${port}`;
} else {
proxyUrl = null;
console.log(`⚠️ 代理字段格式错误,忽略:${proxyUrl}`);
}
} else if (!/^socks5:\/\//i.test(proxyUrl)) {
console.log(`⚠️ 代理字段不是 socks5:// URL忽略${proxyUrl}`);
proxyUrl = null;
}
}
return {
remark: remark || "",
salt: salt,
cookie: cookie,
proxyUrl: proxyUrl,
};
}
// 从环境变量加载账号
function loadAccountsFromEnv() {
const accountConfigs = getAccountConfigsFromEnv();
const accounts = [];
for (const configString of accountConfigs) {
const accountConfig = parseAccountConfig(configString);
if (accountConfig) {
accounts.push(accountConfig);
} else {
console.log(`❌ 账号格式错误:${configString}`);
}
}
accounts.forEach((account, index) => {
account.index = index + 1;
});
return accounts;
}
// 并发执行
async function concurrentExecute(items, concurrency, processor) {
const results = new Array(items.length);
let currentIndex = 0;
async function worker() {
while (true) {
const index = currentIndex++;
if (index >= items.length) {
return;
}
const item = items[index];
try {
results[index] = await processor(item, index);
} catch (error) {
console.log(`❌ 并发执行异常index=${index + 1}${error.message}`);
results[index] = null;
}
}
}
const workers = Array.from({ length: Math.min(concurrency, items.length) }, worker);
await Promise.all(workers);
return results;
}
// 处理单个账号
async function processAccount(accountConfig) {
const getAccountDisplayName = () => {
return `账号[${accountConfig.index}]${accountConfig.remark ? "(" + accountConfig.remark + ")" : ""}`;
};
if (accountConfig.proxyUrl) {
console.log(`🔌 ${getAccountDisplayName()} 测试代理连接中...`);
const proxyTest = await testProxyConnectivity(accountConfig.proxyUrl, getAccountDisplayName());
console.log(` ${proxyTest.ok ? "✅" : "❌"} ${proxyTest.msg}`);
} else {
console.log(`🌐 ${getAccountDisplayName()} 未配置代理,使用直连`);
}
console.log(`🔍 ${getAccountDisplayName()} 获取账号信息中...`);
let initialAccountInfo = await getAccountBasicInfo(accountConfig.cookie, accountConfig.proxyUrl, accountConfig.index);
let nickname = initialAccountInfo?.nickname || "账号" + accountConfig.index;
if (initialAccountInfo) {
const totalCoin = initialAccountInfo.totalCoin != null ? initialAccountInfo.totalCoin : "未知";
const allCash = initialAccountInfo.allCash != null ? initialAccountInfo.allCash : "未知";
console.log(`${getAccountDisplayName()} 登录成功,金币: ${totalCoin},余额: ${allCash}`);
} else {
console.log(`${getAccountDisplayName()} 基本信息获取失败,继续执行`);
}
const adTask = new KuaishouAdTask({
...accountConfig,
nickname: nickname,
tasksToExecute: tasksToExecute,
});
await adTask.checkCoinLimit();
if (adTask.coinExceeded) {
console.log(`💰 ${getAccountDisplayName()} 初始金币已超过阈值,不执行任务`);
return {
index: accountConfig.index,
remark: accountConfig.remark || "无备注",
nickname: nickname,
initialCoin: initialAccountInfo?.totalCoin || 0,
finalCoin: initialAccountInfo?.totalCoin || 0,
coinChange: 0,
initialCash: initialAccountInfo?.allCash || 0,
finalCash: initialAccountInfo?.allCash || 0,
cashChange: 0,
stats: adTask.getTaskStats(),
coinLimitExceeded: true,
};
}
for (let round = 0; round < KSROUNDS; round++) {
const waitTime = Math.floor(Math.random() * 8000) + 8000;
console.log(`${getAccountDisplayName()}${round + 1}轮,等待 ${Math.round(waitTime / 1000)}`);
console.log(`🚀 ${getAccountDisplayName()} 开始第${round + 1}轮任务`);
const roundResults = await adTask.executeAllTasksByPriority();
if (Object.values(roundResults).some(Boolean)) {
console.log(`${getAccountDisplayName()}${round + 1}轮执行完成`);
} else {
console.log(`⚠️ ${getAccountDisplayName()}${round + 1}轮没有成功任务`);
}
if (adTask.stopAllTasks) {
console.log(`🏁 ${getAccountDisplayName()} 达到停止条件,终止后续轮次`);
break;
}
if (round < KSROUNDS - 1) {
const nextWaitTime = Math.floor(Math.random() * 10000) + 10000;
console.log(`${getAccountDisplayName()} 等待 ${Math.round(nextWaitTime / 1000)}秒进入下一轮`);
await new Promise((resolve) => setTimeout(resolve, nextWaitTime));
}
}
const finalAccountInfo = await getAccountBasicInfo(accountConfig.cookie, accountConfig.proxyUrl, accountConfig.index);
const initialCoin = initialAccountInfo?.totalCoin || 0;
const finalCoin = finalAccountInfo?.totalCoin || 0;
const coinChange = finalCoin - initialCoin;
const initialCash = initialAccountInfo?.allCash || 0;
const finalCash = finalAccountInfo?.allCash || 0;
const cashChange = finalCash - initialCash;
adTask.printTaskStats();
return {
index: accountConfig.index,
remark: accountConfig.remark || "无备注",
nickname: nickname,
initialCoin: initialCoin,
finalCoin: finalCoin,
coinChange: coinChange,
initialCash: initialCash,
finalCash: finalCash,
cashChange: cashChange,
stats: adTask.getTaskStats(),
coinLimitExceeded: adTask.coinExceeded,
};
}
// 美化打印:简洁的结果汇总
function printAccountsSummary(accountResults) {
if (!accountResults.length) {
console.log("\n❌ 没有可显示的账号信息。");
return;
}
// 计算统计数据
const totalInitialCoin = accountResults.reduce((sum, account) => sum + (parseInt(account.initialCoin) || 0), 0);
const totalFinalCoin = accountResults.reduce((sum, account) => sum + (parseInt(account.finalCoin) || 0), 0);
const totalCoinChange = totalFinalCoin - totalInitialCoin;
const totalInitialCash = accountResults.reduce((sum, account) => sum + (parseFloat(account.initialCash) || 0), 0);
const totalFinalCash = accountResults.reduce((sum, account) => sum + (parseFloat(account.finalCash) || 0), 0);
const totalCashChange = totalFinalCash - totalInitialCash;
let totalTasks = 0;
let totalSuccessTasks = 0;
let totalReward = 0;
accountResults.forEach((account) => {
if (account.stats) {
Object.values(account.stats).forEach((stat) => {
totalTasks += stat.success + stat.failed;
totalSuccessTasks += stat.success;
totalReward += stat.totalReward;
});
}
});
const successRate = totalTasks > 0 ? ((totalSuccessTasks / totalTasks) * 100).toFixed(1) : "0.0";
const coinLimitExceededCount = accountResults.filter((account) => account.coinLimitExceeded).length;
// 美化输出
console.log("\n" + "=".repeat(60));
console.log("📊 任务执行结果汇总");
console.log("=".repeat(60));
console.log(`👥 总账号数: ${accountResults.length}`);
console.log(`💰 超过金币阈值: ${coinLimitExceededCount}`);
console.log(`📈 总任务数: ${totalTasks} (成功率: ${successRate}%)`);
console.log(`🎯 总金币变化: ${totalCoinChange >= 0 ? '+' : ''}${totalCoinChange}`);
console.log(`🏆 总金币奖励: ${totalReward}`);
console.log(`💵 总余额变化: ${totalCashChange >= 0 ? '+' : ''}${totalCashChange.toFixed(2)}`);
console.log("-".repeat(60));
// 账号详情表格
console.log("\n📋 账号详情:");
console.log("序号".padEnd(6) + "备注".padEnd(16) + "昵称".padEnd(20) + "金币变化".padEnd(12) + "余额变化");
console.log("-".repeat(60));
accountResults.forEach((account) => {
const coinChangeStr = account.coinChange >= 0 ? `+${account.coinChange}` : `${account.coinChange}`;
const cashChangeStr = account.cashChange >= 0 ? `+${account.cashChange.toFixed(2)}` : `${account.cashChange.toFixed(2)}`;
const status = account.coinLimitExceeded ? " ⚠️" : "";
console.log(
`${account.index}`.padEnd(6) +
`${account.remark}`.substring(0, 14).padEnd(16) +
`${account.nickname}${status}`.substring(0, 18).padEnd(20) +
coinChangeStr.padEnd(12) +
cashChangeStr
);
});
console.log("=".repeat(60));
console.log("✅ 任务执行完成");
console.log("=".repeat(60));
}
// 主函数
(async () => {
const accounts = loadAccountsFromEnv();
console.log(`📊 共找到 ${accounts.length} 个有效账号`);
if (!accounts.length) {
console.log("❌ 没有找到有效账号,程序退出");
process.exit(1);
}
const maxConcurrency = getEnvNumber("MAX_CONCURRENCY", 888);
console.log(`\n⚡ 并发数: ${maxConcurrency} 轮数: ${KSROUNDS}\n`);
const results = [];
await concurrentExecute(accounts, maxConcurrency, async (account) => {
console.log(`\n── 🚀 开始处理 ${account.index}号账号${account.remark ? "(" + account.remark + ")" : ""} ──`);
try {
const result = await processAccount(account);
results.push({
index: account.index,
remark: account.remark || "无备注",
nickname: result?.nickname || `账号${account.index}`,
initialCoin: result?.initialCoin || 0,
finalCoin: result?.finalCoin || 0,
coinChange: result?.coinChange || 0,
initialCash: result?.initialCash || 0,
finalCash: result?.finalCash || 0,
cashChange: result?.cashChange || 0,
stats: result?.stats || {},
coinLimitExceeded: result?.coinLimitExceeded || false,
});
} catch (error) {
console.log(`❌ 账号[${account.index}] 执行异常:${error.message}`);
results.push({
index: account.index,
remark: account.remark || "无备注",
nickname: `账号${account.index}`,
initialCoin: 0,
finalCoin: 0,
coinChange: 0,
initialCash: 0,
finalCash: 0,
cashChange: 0,
error: error.message,
});
}
});
results.sort((a, b) => a.index - b.index);
console.log("\n🎉 全部任务完成!");
printAccountsSummary(results);
})();
[file content end]
// 当前脚本来自于http://script.345yun.cn脚本库下载