// # Source: https://github.com/DearSong15/ql-scripts/blob/main/ks_yanghao_v1.js
// # Raw: https://raw.githubusercontent.com/DearSong15/ql-scripts/main/ks_yanghao_v1.js
// # Repo: DearSong15/ql-scripts
// # Path: ks_yanghao_v1.js
// # UploadedAt: 2026-05-18T09:30:28Z
// # SHA256: e24abf45a7c194b2aa3750474f59ec9d8218c59b78af77cb1ac378682c19a9dc
// # Category: 微信小程序/抓包版
// # Evidence: appid/openid/session_key/encryptedData等小程序字段
// 

//new Env("快手养号")

// 接口配置
const SIGN_API_URL = "http://127.0.0.1:8889";
const encryptTag = "jsjiami.com.v7";
const fs = require("fs");
const path = require("path");
const childProcess = require("child_process");
const querystring = require("querystring");
const { SocksProxyAgent } = require("socks-proxy-agent");

// 依赖自动安装
function checkAndInstall(pkg, versionSuffix = "") {
  try {
    require.resolve(pkg);
    console.log("[依赖检查] " + pkg + " 已安装.");
  } catch (err) {
    console.log("[依赖检查] " + pkg + " 缺失，正在自动安装" + (versionSuffix ? " (" + versionSuffix + ")" : "") + "...");
    try {
      childProcess.execSync("npm install " + pkg + versionSuffix, { stdio: "inherit" });
      console.log("[依赖修补] " + pkg + " 安装成功，继续运行.");
    } catch (installErr) {
      console.error("[依赖修补失败] 无法安装 " + pkg + ": " + installErr.message);
      process.exit(1);
    }
  }
}

// Node 版本检测
const nodeVersion = process.versions.node;
const [majorVer, minorVer] = nodeVersion.split(".").map(Number);
console.log("[Node.js 版本检测] 当前版本: " + nodeVersion + " (major: " + majorVer + ", minor: " + minorVer + ")");

let requestVer = "";
let socksAgentVer = "";

if (majorVer >= 18) {
  console.log("[Node.js 版本兼容] Node.js 18+ 检测到，使用 request 默认版本（若有警告，可忽略或升级脚本）");
  process.noDeprecation = true;
} else if (majorVer < 14) {
  socksAgentVer = "@^5.0.0";
  console.log("[Node.js 版本兼容] Node.js < 14 检测到，使用 socks-proxy-agent 旧版以兼容.");
} else {
  console.log("[Node.js 版本兼容] Node.js 14-17 检测到，使用默认依赖版本.");
}

checkAndInstall("request", requestVer);
checkAndInstall("socks-proxy-agent", socksAgentVer);

const request = require("request");
process.noDeprecation = true;


// ==================== 养号配置 ====================
const FARM_CONFIG = {
    ENABLE_FARM: process.env.ENABLE_FARM === "1" || process.env.ENABLE_FARM === "true" || true,
    LOW_REWARD_FARM_THRESHOLD: parseInt(process.env.LOW_REWARD_FARM_THRESHOLD) || 200,
    // 刷视频配置：每个视频60-90秒，总时长15-20分钟
    SINGLE_VIDEO_WATCH_MIN: parseInt(process.env.SINGLE_VIDEO_WATCH_MIN) || 60,
    SINGLE_VIDEO_WATCH_MAX: parseInt(process.env.SINGLE_VIDEO_WATCH_MAX) || 90,
    FARM_VIDEO_TIME_MIN: parseInt(process.env.FARM_VIDEO_TIME_MIN) || 15,
    FARM_VIDEO_TIME_MAX: parseInt(process.env.FARM_VIDEO_TIME_MAX) || 20,
    // 小说阅读配置：看几章（3-8章）
    NOVEL_CHAPTERS_MIN: parseInt(process.env.NOVEL_CHAPTERS_MIN) || 3,
    NOVEL_CHAPTERS_MAX: parseInt(process.env.NOVEL_CHAPTERS_MAX) || 8,
    // 直播配置：3-5分钟
    LIVE_WATCH_TIME_MIN: parseInt(process.env.LIVE_WATCH_TIME_MIN) || 3,
    LIVE_WATCH_TIME_MAX: parseInt(process.env.LIVE_WATCH_TIME_MAX) || 5,
    // 小游戏试玩：15-25分钟
    MINI_GAME_PLAY_MIN: parseInt(process.env.MINI_GAME_PLAY_MIN) || 15,
    MINI_GAME_PLAY_MAX: parseInt(process.env.MINI_GAME_PLAY_MAX) || 25,
    // 商城浏览：3-6个商品，每个60-90秒
    SHOP_BROWSE_ITEMS_MIN: parseInt(process.env.SHOP_BROWSE_ITEMS_MIN) || 3,
    SHOP_BROWSE_ITEMS_MAX: parseInt(process.env.SHOP_BROWSE_ITEMS_MAX) || 6,
    SHOP_ITEM_BROWSE_MIN: parseInt(process.env.SHOP_ITEM_BROWSE_MIN) || 60,
    SHOP_ITEM_BROWSE_MAX: parseInt(process.env.SHOP_ITEM_BROWSE_MAX) || 90,
    // 互动概率
    FARM_LIKE_RATE: parseInt(process.env.FARM_LIKE_RATE) || 40,
    FARM_COLLECT_RATE: parseInt(process.env.FARM_COLLECT_RATE) || 15,
    FARM_COMMENT_RATE: parseInt(process.env.FARM_COMMENT_RATE) || 10,
    FARM_DAILY_LIMIT: parseInt(process.env.FARM_DAILY_LIMIT) || 3
};

// 搜索关键词
const SEARCH_KEYWORDS = ["DNF", "传奇", "游戏推荐"];

// 商城搜索关键词
const SHOP_SEARCH_KEYWORDS = ["笔记本","游戏机", "小米手机", "投资金条", "冲锋衣", "按摩枕"];

// 评论库
const COMMENT_LIST = [
    "真的非常的好，很喜欢这个作品",
    "确实是这样的",
    "喜欢，多发，爱看",
    "可以的，有点猛的",
    "爱了，爱了，多发一点就爱看这种",
    "孔子没看懂，老子也没看懂这是干啥的",
    "太有意思了，笑死我了",
    "学到了，感谢分享",
    "这个必须支持一下",
    "说的太对了，深有感触"
];

// 直播评论库
const LIVE_COMMENT_LIST = [
    "主播讲得真好",
    "支持主播",
    "666",
    "太精彩了",
    "学到了学到了",
    "点赞支持",
    "来了来了",
    "不错不错",
    "主播加油",
    "这个直播太有意思了"
];

// ==================== 养号功能函数 ====================
function randomDelay(minMs, maxMs) {
    const ms = Math.floor(Math.random() * (maxMs - minMs + 1)) + minMs;
    return new Promise(resolve => setTimeout(resolve, ms));
}

function getRandomComment() {
    return COMMENT_LIST[Math.floor(Math.random() * COMMENT_LIST.length)];
}

function getRandomLiveComment() {
    return LIVE_COMMENT_LIST[Math.floor(Math.random() * LIVE_COMMENT_LIST.length)];
}

// 模拟浏览小说（看几章）
async function simulateNovelReading(accountName) {
    const chaptersCount = Math.floor(Math.random() * (FARM_CONFIG.NOVEL_CHAPTERS_MAX - FARM_CONFIG.NOVEL_CHAPTERS_MIN + 1)) + FARM_CONFIG.NOVEL_CHAPTERS_MIN;
    console.log(`📖 [${accountName}] 进入小说广告页面，开始阅读 ${chaptersCount} 章...`);

    for (let i = 1; i <= chaptersCount; i++) {
        const readTime = Math.floor(Math.random() * 60000) + 30000; // 30-90秒每章
        console.log(`📖 [${accountName}] 阅读第 ${i}/${chaptersCount} 章，约 ${Math.round(readTime/1000)} 秒`);
        await randomDelay(readTime, readTime + 10000);
    }

    console.log(`📖 [${accountName}] 小说阅读完成，共 ${chaptersCount} 章`);
    await randomDelay(2000, 5000);
}

// 模拟下载安装试玩App（通用）
async function simulateAppPlay(accountName, appName = "游戏") {
    const playTime = Math.floor(Math.random() * (FARM_CONFIG.MINI_GAME_PLAY_MAX - FARM_CONFIG.MINI_GAME_PLAY_MIN) * 60000) + FARM_CONFIG.MINI_GAME_PLAY_MIN * 60000;
    const playMinutes = Math.round(playTime / 60000);

    console.log(`📱 [${accountName}] 进入${appName}广告页面，开始下载...`);
    await randomDelay(5000, 15000);
    console.log(`📱 [${accountName}] 下载完成，开始安装...`);
    await randomDelay(3000, 8000);
    console.log(`📱 [${accountName}] 安装完成，开始试玩 ${playMinutes} 分钟...`);

    const gameStages = ["新手引导", "完成第一关", "查看奖励", "继续游戏", "完成每日任务"];
    const stageCount = Math.min(gameStages.length, Math.ceil(playTime / 60000));
    for (let i = 0; i < stageCount; i++) {
        await randomDelay(30000, 90000);
        console.log(`📱 [${accountName}] ${appName}进度: ${gameStages[i % gameStages.length]}`);
    }

    console.log(`📱 [${accountName}] 试玩完成，共 ${playMinutes} 分钟`);
    await randomDelay(2000, 5000);
}

// 模拟观看直播并互动（3-5分钟）
async function simulateLiveWatch(accountName, hasMiniGame = false) {
    const watchTime = Math.floor(Math.random() * (FARM_CONFIG.LIVE_WATCH_TIME_MAX - FARM_CONFIG.LIVE_WATCH_TIME_MIN) * 60000) + FARM_CONFIG.LIVE_WATCH_TIME_MIN * 60000;
    const watchMinutes = Math.round(watchTime / 60000);

    console.log(`🎥 [${accountName}] 进入直播间，开始观看 ${watchMinutes} 分钟...`);

    let likeCount = 0;
    let commentCount = 0;
    let giftCount = 0;
    const startTime = Date.now();

    // 如果直播间有小游戏，先试玩
    if (hasMiniGame) {
        console.log(`🎮 [${accountName}] 直播间发现挂载小游戏，开始试玩...`);
        await simulateAppPlay(accountName, "直播间小游戏");
    }

    while (Date.now() - startTime < watchTime) {
        await randomDelay(15000, 45000);

        // 随机点赞
        if (Math.random() * 100 < 50) {
            likeCount++;
            console.log(`❤️ [${accountName}] 点赞直播 (${likeCount}次)`);
        }

        // 随机评论
        if (Math.random() * 100 < 25) {
            commentCount++;
            const comment = getRandomLiveComment();
            console.log(`💬 [${accountName}] 直播评论: "${comment}"`);
            await randomDelay(2000, 5000);
        }

        // 随机送小礼物（10%概率）
        if (Math.random() * 100 < 10) {
            giftCount++;
            console.log(`🎁 [${accountName}] 赠送小礼物 (${giftCount}次)`);
            await randomDelay(1000, 3000);
        }

        const elapsed = Math.round((Date.now() - startTime) / 60000);
        console.log(`🎥 [${accountName}] 观看直播中... ${elapsed}/${watchMinutes}分钟`);
    }

    console.log(`🎥 [${accountName}] 直播观看完成，共 ${watchMinutes} 分钟，点赞${likeCount}次，评论${commentCount}次，送礼${giftCount}次`);
}

// 模拟商城商品浏览
async function simulateShopBrowsing(accountName) {
    const itemsCount = Math.floor(Math.random() * (FARM_CONFIG.SHOP_BROWSE_ITEMS_MAX - FARM_CONFIG.SHOP_BROWSE_ITEMS_MIN + 1)) + FARM_CONFIG.SHOP_BROWSE_ITEMS_MIN;
    const searchKeyword = SHOP_SEARCH_KEYWORDS[Math.floor(Math.random() * SHOP_SEARCH_KEYWORDS.length)];

    console.log(`🛒 [${accountName}] 进入商城，搜索: "${searchKeyword}"`);
    await randomDelay(2000, 5000);

    const addedToCart = Math.floor(Math.random() * itemsCount); // 随机选择一个商品加入购物车
    const browseResults = [];

    for (let i = 0; i < itemsCount; i++) {
        const browseTime = Math.floor(Math.random() * (FARM_CONFIG.SHOP_ITEM_BROWSE_MAX - FARM_CONFIG.SHOP_ITEM_BROWSE_MIN) * 1000) + FARM_CONFIG.SHOP_ITEM_BROWSE_MIN * 1000;
        const productId = i + 1;

        console.log(`🛒 [${accountName}] 浏览商品 ${productId}/${itemsCount}，${Math.round(browseTime/1000)}秒`);

        // 模拟浏览商品图片
        await randomDelay(2000, 5000);
        console.log(`   📷 查看商品图片...`);

        // 模拟查看商品参数
        await randomDelay(3000, 8000);
        console.log(`   📋 查看商品参数详情...`);

        // 模拟查看评论区
        await randomDelay(5000, 12000);
        const commentCount = Math.floor(Math.random() * 10) + 1;
        console.log(`   💬 浏览评论区，查看了 ${commentCount} 条评论和图片`);

        // 总浏览时间
        await randomDelay(browseTime - 10000, browseTime);

        browseResults.push({ id: productId, name: `${searchKeyword}商品${productId}` });

        // 随机将商品加入购物车
        if (i === addedToCart) {
            console.log(`🛒 [${accountName}] 将商品 ${productId} 加入购物车！`);
            await randomDelay(1000, 3000);
        }

        if (i < itemsCount - 1) {
            await randomDelay(2000, 5000);
        }
    }

    console.log(`🛒 [${accountName}] 商城浏览完成！浏览了 ${itemsCount} 个商品，1个商品已加入购物车`);
}

// 模拟首页搜索和刷视频
async function farmBrowseVideos(accountName) {
    const farmTime = Math.floor(Math.random() * (FARM_CONFIG.FARM_VIDEO_TIME_MAX - FARM_CONFIG.FARM_VIDEO_TIME_MIN) * 60000) + FARM_CONFIG.FARM_VIDEO_TIME_MIN * 60000;
    const farmMinutes = Math.round(farmTime / 60000);
    console.log(`🌾 [${accountName}] 开始养号刷视频 ${farmMinutes}分钟...`);

    const startTime = Date.now();
    let videoCount = 0;
    let likeCount = 0;
    let collectCount = 0;
    let commentCount = 0;
    let adEncounterCount = 0;
    let searchCount = 0;
    let hasSearched = false;

    while (Date.now() - startTime < farmTime) {
        // 随机进行搜索（每2-3个视频搜索一次）
        if (!hasSearched && (videoCount > 0 && videoCount % 2 === 0) && Math.random() < 0.5) {
            searchCount++;
            const keyword = SEARCH_KEYWORDS[Math.floor(Math.random() * SEARCH_KEYWORDS.length)];
            console.log(`🔍 [${accountName}] 搜索关键词: "${keyword}"`);
            await randomDelay(3000, 8000);
            hasSearched = true;

            // 搜索后刷几个相关视频
            const searchVideos = Math.floor(Math.random() * 3) + 2;
            for (let sv = 0; sv < searchVideos; sv++) {
                if (Date.now() - startTime >= farmTime) break;
                videoCount++;
                const watchTime = Math.floor(Math.random() * (FARM_CONFIG.SINGLE_VIDEO_WATCH_MAX - FARM_CONFIG.SINGLE_VIDEO_WATCH_MIN) * 1000) + FARM_CONFIG.SINGLE_VIDEO_WATCH_MIN * 1000;
                console.log(`📺 [${accountName}] 观看搜索相关视频 #${videoCount}，${Math.round(watchTime/1000)}秒`);
                await randomDelay(watchTime, watchTime + 5000);

                // 互动
                if (Math.random() * 100 < FARM_CONFIG.FARM_LIKE_RATE) {
                    likeCount++;
                    console.log(`❤️ [${accountName}] 点赞视频 (#${videoCount})`);
                    await randomDelay(1000, 3000);
                }
            }
            hasSearched = false;
            continue;
        }

        videoCount++;
        const watchTime = Math.floor(Math.random() * (FARM_CONFIG.SINGLE_VIDEO_WATCH_MAX - FARM_CONFIG.SINGLE_VIDEO_WATCH_MIN) * 1000) + FARM_CONFIG.SINGLE_VIDEO_WATCH_MIN * 1000;
        console.log(`📺 [${accountName}] 观看第 ${videoCount} 个视频，${Math.round(watchTime/1000)}秒`);
        await randomDelay(watchTime, watchTime + 3000);

        // 随机遇到广告（30%概率），遇到小说就看几章
        if (Math.random() < 0.3) {
            adEncounterCount++;
            // 随机决定广告类型：小说、游戏、直播
            const adTypes = ["novel", "app", "live"];
            const randomAdType = adTypes[Math.floor(Math.random() * adTypes.length)];
            let adTitle = "";

            if (randomAdType === "novel") {
                adTitle = "小说推荐_精彩阅读";
                console.log(`📢 [${accountName}] 刷视频时遇到小说广告: ${adTitle}`);
                await simulateNovelReading(accountName);
            } else if (randomAdType === "app") {
                adTitle = "游戏推荐_下载试玩";
                console.log(`📢 [${accountName}] 刷视频时遇到游戏广告: ${adTitle}`);
                await simulateAppPlay(accountName, "推荐游戏");
            } else {
                adTitle = "直播推荐";
                console.log(`📢 [${accountName}] 刷视频时遇到直播广告: ${adTitle}`);
                // 直播广告模拟观看30-60秒
                const shortWatchTime = Math.floor(Math.random() * 30000) + 30000;
                await randomDelay(shortWatchTime, shortWatchTime + 10000);
                console.log(`🎥 [${accountName}] 观看直播广告 ${Math.round(shortWatchTime/1000)}秒`);
            }
        }

        // 随机点赞
        if (Math.random() * 100 < FARM_CONFIG.FARM_LIKE_RATE) {
            likeCount++;
            console.log(`❤️ [${accountName}] 点赞视频 (#${videoCount})`);
            await randomDelay(1000, 3000);
        }

        // 随机收藏
        if (Math.random() * 100 < FARM_CONFIG.FARM_COLLECT_RATE) {
            collectCount++;
            console.log(`⭐ [${accountName}] 收藏视频 (#${videoCount})`);
            await randomDelay(1000, 3000);
        }

        // 随机评论
        if (Math.random() * 100 < FARM_CONFIG.FARM_COMMENT_RATE) {
            commentCount++;
            const comment = getRandomComment();
            console.log(`💬 [${accountName}] 评论: "${comment}"`);
            await randomDelay(2000, 5000);
        }

        // 滑动切换视频
        await randomDelay(500, 1500);
    }

    console.log(`🌾 [${accountName}] 刷视频养号完成！`);
    console.log(`   观看视频: ${videoCount}个 | 搜索: ${searchCount}次 | 点赞: ${likeCount}次 | 收藏: ${collectCount}次 | 评论: ${commentCount}次 | 广告转化: ${adEncounterCount}次`);
}

// 执行直播间养号（随机进入直播间待20-30分钟）
async function farmLiveWatch(accountName) {
    console.log(`🎥 [${accountName}] 随机进入直播间...`);
    await randomDelay(2000, 5000);

    // 随机决定直播间是否有小游戏（30%概率）
    const hasMiniGame = Math.random() < 0.3;
    await simulateLiveWatch(accountName, hasMiniGame);
}

// 执行商城养号
async function farmShopBrowsing(accountName) {
    await simulateShopBrowsing(accountName);
}

// 完整养号流程
async function doFarming(accountName, triggerReason) {
    console.log(`\n🌾 ========== 开始养号 [${accountName}] ==========`);
    console.log(`🌾 触发原因: ${triggerReason}`);

    // 1. 刷视频养号（15-20分钟）
    await farmBrowseVideos(accountName);

    // 2. 随机进入直播间（20-30分钟），50%概率执行
    if (Math.random() < 0.5) {
        await farmLiveWatch(accountName);
    }

    // 3. 商城浏览（3-6个商品），50%概率执行
    if (Math.random() < 0.5) {
        await farmShopBrowsing(accountName);
    }

    console.log(`🌾 ========== 养号完成 [${accountName}] ==========\n`);
}

// 随机状态文案
function randomAdStatus() {
  const list = ["正在观看广告", "认真观看中...", "浏览广告内容", "模拟用户行为", "观看视频广告", "保持活跃状态", "广告浏览中", "正常观看时长"];
  return list[Math.floor(Math.random() * list.length)];
}

// 环境开关
const DEV_MODE = process.env.DEV_MODE === "1" || process.env.DEV_MODE === "true";
const ENABLE_DID_CHANGE = process.env.ENABLE_DID_CHANGE === "1" || process.env.ENABLE_DID_CHANGE === "true";

// 读取数字环境变量
function getEnvInt(key, defaultValue) {
  const val = parseInt(process.env[key], 10);
  return isNaN(val) ? defaultValue : val;
}

const LOW_REWARD_THRESHOLD = getEnvInt("KSLOW_REWARD_THRESHOLD", 10);
const TOTAL_ROUNDS = getEnvInt("KSROUNDS", 100);
const COIN_LIMIT = getEnvInt("KSCOIN_LIMIT", 100000);
const LOW_REWARD_MAX_TIMES = getEnvInt("KSLOW_REWARD_LIMIT", 3);

// 解析任务列表
function parseTaskList() {
  // 已禁用广告任务，仅保留养号功能（刷视频/小说/直播/商城等）
  console.log("⚙️ 广告任务已禁用，将仅执行养号模块");
  return [];
  const taskEnv = process.env.Task;
  if (!taskEnv) {
    console.log("未设置Task环境变量，将执行所有任务 (look, looks, looks, looks, looks)");
    return ["look", "looks", "looks", "looks", "looks"];
  }
  const inputTasks = taskEnv.split(",").map(t => t.trim().toLowerCase()).filter(Boolean);
  const validTasks = ["food", "box", "look", "looks"];
  const finalTasks = inputTasks.filter(t => validTasks.includes(t));
  if (finalTasks.length === 0) {
    console.log("Task环境变量中没有有效任务，将执行所有任务 (food, box, look, looks)");
    return validTasks;
  }
  console.log("从Task环境变量中解析到要执行的任务: " + finalTasks.join(", "));
  return finalTasks;
}

// 解析所有账号配置 ksptck / ksptck1~666
function parseAllAccounts() {
  const all = [];
  const uniqueSet = new Set();

  if (process.env.ksptck) {
    const parts = process.env.ksptck.split("&").map(p => p.trim()).filter(Boolean);
    all.push(...parts);
  }

  for (let i = 1; i <= 666; i++) {
    const key = "ksptck" + i;
    if (process.env[key]) {
      const parts = process.env[key].split("&").map(p => p.trim()).filter(Boolean);
      all.push(...parts);
    }
  }

  const uniqueList = [];
  for (const item of all) {
    if (!uniqueSet.has(item)) {
      uniqueSet.add(item);
      uniqueList.push(item);
    }
  }

  console.log("从ksptck及ksptck1到ksptck666环境变量中解析到 " + uniqueList.length + " 个唯一配置");
  return uniqueList;
}

// 全局任务名称映射
const TASK_NAME_MAP = {
  food: "food（看广告得金币1）",
  box: "box（宝箱广告）",
  look: "look（看广告得金币）",
  looks: "looks（看广告得金币追加）"
};

// 并发控制
const DEFAULT_CONCURRENCY = 10;
const MAX_CONCURRENCY_ALLOW = 200;
const userConcurrency = getEnvInt("MAX_CONCURRENCY", NaN);
const CONCURRENCY = isNaN(userConcurrency)
  ? DEFAULT_CONCURRENCY
  : Math.min(Math.max(userConcurrency, 1), MAX_CONCURRENCY_ALLOW);

console.log("================================================================================");
console.log(" ⭐ 快手至尊金币版（广告转化+养号版）⭐ ");
console.log("🏆 安全稳定 · 高效收益 · 尊贵体验 🏆                        ");
console.log("🏆 代理购买2.1r一月· http://www.gzsk5.com/#/register?invitation=hnking2&shareid=516                  ");
console.log("🏆 接口工具脚本获取ck获取· https://pan.quark.cn/s/41d4dae92896                  ");
console.log("🏆 云手机· https://cloud.ace-bot.cn/#/inviteReg?invite=501891                  ");
console.log("================================================================================");
console.log("🎯 新增功能:");
console.log("   - 广告自动转化（小说阅读/APP试玩/直播互动）");
console.log("   - 低奖励自动养号（<200金币触发）");
console.log("   - 刷视频随机点赞/收藏/评论（每个视频60-90秒，总15-20分钟）");
console.log("   - 首页搜索捕鱼游戏/传奇/游戏推荐");
console.log("   - 直播间互动（20-30分钟，随机小游戏试玩）");
console.log("   - 商城浏览（黑丝/学习机/投资金条/冲锋衣/按摩枕，3-6个商品）");
console.log("================================================================================");
console.log("🎉 系统初始化完成，快手至尊金币版（广告转化+养号版）启动成功！🎉");

const accountStrings = parseAllAccounts();
const ACCOUNT_COUNT = accountStrings.length;
const TASKS_TO_RUN = parseTaskList();

console.log("💎 检测到环境变量配置：" + ACCOUNT_COUNT + "个账号");
console.log("🎯 将执行以下任务：" + TASKS_TO_RUN.map(t => TASK_NAME_MAP[t] || t).join(", "));
console.log("🎯 配置参数：");
console.log("   - 任务配置变量=Task (可选: food看广告得金币1, box宝箱广告, look看广告得金币, looks看广告得金币追加, 多个用逗号分隔)");
console.log("   - 账号配置变量=ksptck, 卡密变量=ptkm");
console.log("   - KS_SIGN_API_URL: 签名服务 API 地址");
console.log("   - 轮数变量=KSROUNDS (当前: " + TOTAL_ROUNDS + ", 默认100)");
console.log("   - 金币上限变量=KSCOIN_LIMIT (当前: " + COIN_LIMIT + ", 默认100000)");
console.log("   - 低奖励阈值变量=KSLOW_REWARD_THRESHOLD (当前: " + LOW_REWARD_THRESHOLD + ", 默认10)");
console.log("   - 连续低奖励上限变量=KSLOW_REWARD_LIMIT (当前: " + LOW_REWARD_MAX_TIMES + ", 默认3)");
console.log("   - 并发数变量=MAX_CONCURRENCY (当前: " + CONCURRENCY + ", 默认10, 最大200)");
console.log("🌾 养号配置:");
console.log("   - 养号开关: " + (FARM_CONFIG.ENABLE_FARM ? "✅ 已启用" : "❌ 已禁用"));
console.log("   - 低奖励阈值: " + FARM_CONFIG.LOW_REWARD_FARM_THRESHOLD + "金币");
console.log("   - 每个视频时长: " + FARM_CONFIG.SINGLE_VIDEO_WATCH_MIN + "-" + FARM_CONFIG.SINGLE_VIDEO_WATCH_MAX + "秒");
console.log("   - 刷视频总时长: " + FARM_CONFIG.FARM_VIDEO_TIME_MIN + "-" + FARM_CONFIG.FARM_VIDEO_TIME_MAX + "分钟");
console.log("   - 直播时长: " + FARM_CONFIG.LIVE_WATCH_TIME_MIN + "-" + FARM_CONFIG.LIVE_WATCH_TIME_MAX + "分钟");
console.log("   - 小游戏试玩: " + FARM_CONFIG.MINI_GAME_PLAY_MIN + "-" + FARM_CONFIG.MINI_GAME_PLAY_MAX + "分钟");
console.log("   - 商城浏览商品数: " + FARM_CONFIG.SHOP_BROWSE_ITEMS_MIN + "-" + FARM_CONFIG.SHOP_BROWSE_ITEMS_MAX + "个");
console.log("   - 每日养号上限: " + FARM_CONFIG.FARM_DAILY_LIMIT + "次");
console.log("🔧 DID更换功能：" + (ENABLE_DID_CHANGE ? "✅ 已启用 (ENABLE_DID_CHANGE=1)" : "❌ 已禁用 (设置 ENABLE_DID_CHANGE=1 启用)"));

if (ACCOUNT_COUNT > MAX_CONCURRENCY_ALLOW) {
  console.log("错误: 检测到 " + ACCOUNT_COUNT + " 个账号配置，最多只允许" + MAX_CONCURRENCY_ALLOW + "个");
  process.exit(1);
}

// 生成随机 DID
function generateAndroidDID() {
  try {
    const hex = "0123456789abcdef";
    let rand = "";
    for (let i = 0; i < 16; i++) {
      rand += hex.charAt(Math.floor(Math.random() * hex.length));
    }
    return "ANDROID_" + rand;
  } catch (e) {
    console.log("生成did失败: " + e.message);
    const fallback = Date.now().toString(16).toUpperCase();
    return "ANDROID_" + fallback.substring(0, 16);
  }
}

// 通用请求（带代理）
async function requestWrapper(options, proxyUrl = null, title = "Unknown Request") {
  const opt = { ...options };
  if (proxyUrl) {
    try {
      opt.agent = new SocksProxyAgent(proxyUrl);
    } catch (e) {
      console.log("[错误] " + title + " 代理URL无效(" + e.message + ")，尝试直连模式");
    }
  }

  return new Promise(resolve => {
    request(opt, (err, response, body) => {
      if (err) {
        return resolve({ response: null, body: null });
      }
      if (!response || response.statusCode !== 200) {
        return resolve({ response, body: null });
      }
      try {
        resolve({ response, body: JSON.parse(body) });
      } catch {
        resolve({ response, body });
      }
    });
  });
}

// 代理 IP 连通性检测
async function checkProxyConnect(proxyUrl, title = "代理检测") {
  if (!proxyUrl) {
    return { ok: true, msg: "✅ 未配置代理（直连模式）", ip: "localhost" };
  }
  const { response, body } = await requestWrapper({
    method: "GET",
    url: "https://ip9.com.cn/get",
    headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" },
    timeout: 8000
  }, proxyUrl, title + " → ip9.com.cn");

  if (!body) return { ok: false, msg: "❌ 无法通过代理访问 ip9.com.cn", ip: "" };

  let ip = "";
  if (typeof body === "string") {
    try {
      const j = JSON.parse(body);
      ip = j.ip || j.IP || j.addr || j.ip_address || j.query || (j.data && j.data.ip) || "";
    } catch {
      const match = body.match(/\b(?:\d{1,3}\.){3}\d{1,3}\b/);
      ip = match ? match[0] : "";
    }
  } else if (body && typeof body === "object") {
    ip = body.ip || body.IP || body.addr || body.ip_address || body.query || (body.data && body.data.ip) || "";
  }

  return {
    ok: true,
    msg: "✅ SOCKS5代理正常，出口IP: " + (ip || "未知"),
    ip: ip || "未知"
  };
}

const usedIPSet = new Set();

// 获取账号基本信息
async function getAccountBasic(cookie, proxyUrl, tag) {
  const url = "https://encourage.kuaishou.com/rest/wd/encourage/account/basicInfo";
  const { response, body } = await requestWrapper({
    method: "GET",
    url,
    headers: {
      Host: "encourage.kuaishou.com",
      "User-Agent": "kwai-android aegon/3.56.0",
      Cookie: cookie,
      "Content-Type": "application/x-www-form-urlencoded"
    },
    timeout: 12000
  }, proxyUrl, "账号[" + tag + "] 获取基本信息");

  if (body && body.result === 1 && body.data) {
    return {
      nickname: body.data.userData?.nickname || tag,
      totalCoin: body.data.coinAmount ?? null,
      allCash: body.data.cashAmountDisplay ?? null
    };
  }
  return null;
}

// 居中填充（表格用）
function padCenter(str, len) {
  str = String(str || "").substring(0, len);
  if (str.length >= len) return str;
  const totalPad = len - str.length;
  const left = Math.floor(totalPad / 2);
  return " ".repeat(left) + str + " ".repeat(totalPad - left);
}

// 账号任务执行器（增强版）
class AccountRunner {
  constructor({ index, salt, cookie, nickname = "", proxyUrl = null, tasksToExecute = [], remark = "" }) {
    this.index = index;
    this.salt = salt;
    this.cookie = cookie;
    this.nickname = nickname || remark || "账号" + index;
    this.remark = remark;
    this.proxyUrl = proxyUrl;
    this.coinLimit = COIN_LIMIT;
    this.coinExceeded = false;
    this.tasksToExecute = tasksToExecute;

    this.egid = "";
    this.did = "";
    this.userId = "";
    this.kuaishouApiSt = "";
    this.appver = "13.7.20.10468";
    this.parseCookieFields();

    this.headers = {
      Host: "nebula.kuaishou.com",
      "User-Agent": "kwai-android aegon/4.28.0",
      "Accept-Language": "zh-cn",
      kaw: "MDHkM+9FrbzVSEAqyw6KYWaDbX//YWh3HL3RNoTk0mflLjaw17zmC5Wgx5HS/kdo8uJyFtQMxCHt4jfkbu9FqpqmnO/5L67iloqkSzUuRt4OomU1jJGFzdZMalsksJeN75Aw0w+eS2PMus7fga6twyLPbI9Ku1xGWINrZFVxaFtQkweesxPN0tRRwfb98Vxi+sOIlaDxUM03svdfQpthP2HlXcOTkKBqV8bxwv8I5GCGZydEmtEA",
      kas: "0013db77e6dbe18ab159e21bc94e8cd224",
      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.taskDef = {
      box: { name: "宝箱广告", businessId: 604, posId: 20347, subPageId: 100024063, pageId: 100011251, requestSceneType: 1, taskType: 1 },
      look: { name: "看广告得金币", businessId: 671, posId: 24068, subPageId: 100026368, pageId: 100011251, requestSceneType: 1, taskType: 1 },
      looks: { name: "看广告得金币[追加]", businessId: 671, posId: 24068, subPageId: 100026368, pageId: 100011251, requestSceneType: 7, taskType: 2 },
      food: { name: "看广告得金币1", businessId: 671, posId: 24068, subPageId: 100026368, pageId: 100011251, requestSceneType: 7, taskType: 2 }
    };

    this.taskStats = {};
    this.tasksToExecute.forEach(t => {
      if (this.taskDef[t]) this.taskStats[t] = { success: 0, failed: 0, totalReward: 0 };
    });

    this.lowRewardStreak = 0;
    this.lowRewardThreshold = LOW_REWARD_THRESHOLD;
    this.lowRewardLimit = LOW_REWARD_MAX_TIMES;
    this.stopAllTasks = false;
    this.taskLimitReached = {};
    this.tasksToExecute.forEach(t => {
      if (this.taskDef[t]) this.taskLimitReached[t] = false;
    });

    // 新增：养号计数
    this.farmCountToday = 0;
    this.totalRewardThisRun = 0;
    // 是否已执行过初始养号
    this.hasDoneInitialFarm = false;
  }

  parseCookieFields() {
    try {
      const egidMatch = this.cookie.match(/egid=([^;]+)/);
      const didMatch = this.cookie.match(/did=([^;]+)/);
      const uidMatch = this.cookie.match(/userId=([^;]+)/);
      const stMatch = this.cookie.match(/kuaishou\.api_st=([^;]+)/);
      const appverMatch = this.cookie.match(/appver=([^;]+)/);

      this.egid = egidMatch ? egidMatch[1] : "";
      this.did = didMatch ? didMatch[1] : "";
      this.userId = uidMatch ? uidMatch[1] : "";
      this.kuaishouApiSt = stMatch ? stMatch[1] : "";
      this.appver = appverMatch ? appverMatch[1] : "13.7.20.10468";

      if (!this.egid || !this.did) {
        console.log(`账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} cookie格式可能无 egid 或 did，但继续尝试...`);
      }
    } catch (e) {
      console.log(`账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} 解析cookie失败: ${e.message}`);
    }
  }

  async checkCoinIsOverLimit() {
    try {
      const info = await getAccountBasic(this.cookie, this.proxyUrl, this.index);
      if (info && info.totalCoin != null) {
        const coin = parseInt(info.totalCoin);
        if (coin >= this.coinLimit) {
          console.log(`⚠️ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} 金币已达 ${coin}，超过 ${this.coinLimit} 阈值，将停止任务`);
          this.coinExceeded = true;
          this.stopAllTasks = true;
          return true;
        }
      }
      return false;
    } catch (e) {
      console.log(`账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} 金币检查异常: ${e.message}`);
      return false;
    }
  }

  // 新增：获取当前总金币的方法
  async getCurrentTotalCoin() {
    try {
      const info = await getAccountBasic(this.cookie, this.proxyUrl, this.index);
      if (info && info.totalCoin != null) {
        return parseInt(info.totalCoin);
      }
      return null;
    } catch (e) {
      console.log(`账号[${this.nickname}] 获取总金币失败: ${e.message}`);
      return null;
    }
  }

  async retry(fn, desc, maxRetries = 3, delayMs = 2000) {
    let attempt = 0;
    let lastErr = null;
    while (attempt < maxRetries) {
      try {
        const res = await fn();
        if (res) return res;
        lastErr = new Error(desc + " 返回空");
      } catch (e) {
        lastErr = e;
        console.log(`账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} ${desc} 异常: ${e.message}`);
      }
      attempt++;
      if (attempt < maxRetries) {
        console.log(`账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} ${desc} 失败，重试 ${attempt}/${maxRetries}`);
        await new Promise(r => setTimeout(r, delayMs));
      }
    }
    console.log(`❌ ${desc} 最终失败`);
    return null;
  }

  async getEncSign(base64Data) {
    try {
      const { body } = await requestWrapper({
        method: "POST",
        url: SIGN_API_URL + "/encsign",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ data: base64Data }),
        timeout: 10000
      }, null, `账号[${this.nickname}] 加密签名`);

      if (body && body.status) return body.data;
      console.log(`❌ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} encsign 签名服务失败: ${body?.message || "无响应"}`);
      return null;
    } catch (e) {
      console.log(`❌ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} encsign 请求异常: ${e.message}`);
      return null;
    }
  }

  async getNsSig(urlPath, postData, apiSalt) {
    try {
      const payload = { path: urlPath, data: postData, salt: apiSalt };
      const { body } = await requestWrapper({
        method: "POST",
        url: SIGN_API_URL + "/nssig",
        headers: { "Content-Type": "application/json", "User-Agent": "Mozilla/5.0" },
        body: JSON.stringify(payload),
        timeout: 15000
      }, null, `账号[${this.nickname}] 签名服务`);

      if (body && body.data) {
        return {
          __NS_sig3: body.data.nssig3,
          __NStokensig: body.data.nstokensig,
          sig: body.data.sig,
          __NS_xfalcon: body.data.nssig4 || ""
        };
      }
      console.log(`❌ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} nssig 签名失败: ${body?.error || body?.message || "无响应"}`);
      return null;
    } catch (e) {
      console.log(`❌ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} nssig 请求异常: ${e.message}`);
      return null;
    }
  }

  async getAdInfo(taskCfg) {
    try {
      const apiPath = "/rest/e/reward/mixed/ad";
      const commonQuery = {
        encData: "|encData|",
        sign: "|sign|",
        cs: "false",
        client_key: "3c2cd3f3",
        videoModelCrowdTag: "1_23",
        os: "android",
        "kuaishou.api_st": this.kuaishouApiSt,
        uQaTag: "1##swLdgl:99#ecPp:-9#cmNt:-0#cmHs:-3#cmMnsl:-0"
      };
      const deviceQuery = {
        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: "KUAISHOU",
        androidApiLevel: "35",
        country_code: "cn",
        sys: "ANDROID_15",
        sw: "1080",
        sh: "2400",
        abi: "arm64",
        userRecoBit: "0"
      };

      const impBody = {
        appInfo: { appId: "kuaishou", name: "快手", packageName: "com.smile.gifmaker", 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: taskCfg.pageId,
          subPageId: taskCfg.subPageId,
          action: 0,
          browseType: 3,
          impExtData: "{}",
          mediaExtData: "{}"
        }]
      };

      const b64 = Buffer.from(JSON.stringify(impBody)).toString("base64");
      const encSign = await this.getEncSign(b64);
      if (!encSign) return null;

      commonQuery.encData = encSign.encdata;
      commonQuery.sign = encSign.sign;

      const qsDevice = querystring.stringify(deviceQuery);
      const qsCommon = querystring.stringify(commonQuery);
      const postData = qsDevice + "&" + qsCommon;

      const sigRes = await this.getNsSig(apiPath, postData, this.salt);
      if (!sigRes) return null;

      const fullQuery = { ...deviceQuery, sig: sigRes.sig, __NS_sig3: sigRes.__NS_sig3, __NS_xfalcon: sigRes.__NS_xfalcon, __NStokensig: sigRes.__NStokensig };
      const fullUrl = "https://api.e.kuaishou.com" + apiPath + "?" + querystring.stringify(fullQuery);

      const { body } = await requestWrapper({
        method: "POST",
        url: fullUrl,
        headers: {
          Host: "api.e.kuaishou.com",
          "User-Agent": "kwai-android aegon/3.56.0",
          Cookie: "kuaishou_api_st=" + this.kuaishouApiSt,
          kaw: this.headers.kaw,
          kas: this.headers.kas
        },
        form: commonQuery,
        timeout: 12000
      }, this.proxyUrl, `账号[${this.nickname}] 获取广告`);

      if (!body) return null;
      if (body.errorMsg === "OK" && body.feeds?.[0]?.ad) {
        const title = body.feeds[0].caption || body.feeds[0].ad?.caption || "";
        if (title) console.log(`✅ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} 成功获取广告：${title}`);
        const expTag = body.feeds[0].exp_tag || "";
        const llsid = expTag.split("/")[1]?.split("_")?.[0] || "";
        return { cid: body.feeds[0].ad.creativeId, llsid, title };
      }
      return null;
    } catch (e) {
      console.log(`❌ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} 获取广告异常: ${e.message}`);
      return null;
    }
  }

  async makeReportSign(cid, llsid, taskKey, taskCfg) {
    try {
      const bizJson = JSON.stringify({
        businessId: taskCfg.businessId,
        endTime: this.endTime,
        extParams: "",
        mediaScene: "video",
        neoInfos: [{
          creativeId: cid,
          extInfo: "",
          llsid: llsid,
          requestSceneType: taskCfg.requestSceneType,
          taskType: taskCfg.taskType,
          watchExpId: "",
          watchStage: 0
        }],
        pageId: taskCfg.pageId,
        posId: taskCfg.posId,
        reportType: 0,
        sessionId: "",
        startTime: this.startTime,
        subPageId: taskCfg.subPageId
      });

      const post = "bizStr=" + encodeURIComponent(bizJson) + "&cs=false&client_key=3c2cd3f3&kuaishou.api_st=" + this.kuaishouApiSt;
      const qsTotal = this.queryParams + "&" + post;

      const sig = await this.getNsSig(this.taskReportPath, qsTotal, this.salt);
      if (!sig) return null;

      return {
        sig: sig.sig,
        sig3: sig.__NS_sig3,
        sigtoken: sig.__NStokensig,
        xfalcon: sig.__NS_xfalcon,
        postData: post
      };
    } catch (e) {
      console.log(`❌ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} 生成报告签名异常: ${e.message}`);
      return null;
    }
  }

  async submitReport(sig, sig3, sigToken, xfalcon, postData, taskKey, taskCfg) {
    try {
      const qs = this.queryParams +
        "&sig=" + sig +
        "&__NS_sig3=" + sig3 +
        "&__NS_xfalcon=" + (xfalcon || "") +
        "&__NStokensig=" + sigToken;

      const url = "https://api.e.kuaishou.com" + this.taskReportPath + "?" + qs;

      const { body } = await requestWrapper({
        method: "POST",
        url,
        headers: {
          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.nickname}] 提交任务`);

      if (!body) return { success: false, reward: 0 };
      if (body.result === 1) {
        const reward = body.data?.neoAmount || 0;

        // 获取当前总金币
        const currentTotalCoin = await this.getCurrentTotalCoin();
        const totalCoinDisplay = currentTotalCoin !== null ? ` | 当前总金币: ${currentTotalCoin}` : "";

        console.log(`💰 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} ${taskCfg.name} 获得 ${reward} 金币${totalCoinDisplay}`);

        // 累计奖励用于养号判断
        this.totalRewardThisRun += reward;

        // 低奖励触发养号（低于阈值直接触发养号，不刷金币）
        if (FARM_CONFIG.ENABLE_FARM && reward < FARM_CONFIG.LOW_REWARD_FARM_THRESHOLD && this.farmCountToday < FARM_CONFIG.FARM_DAILY_LIMIT) {
            console.log(`⚠️ 账号[${this.nickname}] 奖励 ${reward} 金币低于阈值 ${FARM_CONFIG.LOW_REWARD_FARM_THRESHOLD}，触发养号（跳过本次刷金币）`);
            this.farmCountToday++;
            await doFarming(this.nickname, `低奖励(${reward}金币)`);

            // 养号后重新获取总金币显示
            const afterFarmCoin = await this.getCurrentTotalCoin();
            if (afterFarmCoin !== null) {
              console.log(`📊 账号[${this.nickname}] 养号后总金币: ${afterFarmCoin}`);
            }

            // 养号后停止当前任务，返回成功但标记为已处理
            return { success: true, reward, farmed: true };
        }

        if (reward <= this.lowRewardThreshold) {
          this.lowRewardStreak++;
          if (ENABLE_DID_CHANGE) {
            this.did = generateAndroidDID();
            console.log(`⚠️ 账号[${this.nickname}] 奖励过低，已更换DID，连续低奖励：${this.lowRewardStreak}/${this.lowRewardLimit}`);
          } else {
            console.log(`⚠️ 账号[${this.nickname}] 奖励过低，连续低奖励：${this.lowRewardStreak}/${this.lowRewardLimit}`);
          }

          if (this.lowRewardStreak >= this.lowRewardLimit) {
            console.log(`🏁 账号[${this.nickname}] 连续低奖励超限，停止全部任务`);
            this.stopAllTasks = true;
            return { success: true, reward };
          }
          const waitMs = Math.floor(Math.random() * 10000) + 583000;
          console.log(`🔍 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} ==> 等待 ${Math.round(waitMs / 1000)}s`);
          await new Promise(r => setTimeout(r, waitMs));
        } else {
          this.lowRewardStreak = 0;
        }
        return { success: true, reward };
      }

      if ([20107, 20108, 1003, 415].includes(body.result)) {
        console.log(`⚠️ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} ${taskCfg.name} 已达上限`);
        this.taskLimitReached[taskKey] = true;
        return { success: false, reward: 0 };
      }

      console.log(`❌ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} ${taskCfg.name} 失败 result=${body.result}`);
      return { success: false, reward: 0 };
    } catch (e) {
      console.log(`❌ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} 提交任务异常: ${e.message}`);
      return { success: false, reward: 0 };
    }
  }

  async runSingleTask(taskKey) {
    const cfg = this.taskDef[taskKey];
    if (!cfg) return false;
    if (this.taskLimitReached[taskKey] || this.stopAllTasks) return false;

    try {
      const adInfo = await this.retry(() => this.getAdInfo(cfg), "获取广告 " + cfg.name, 3);
      if (!adInfo) {
        this.taskStats[taskKey].failed++;
        return false;
      }

      // 广告转化：点击广告进入页面模拟真人浏览
      if (adInfo.title) {
        console.log(`📢 账号[${this.nickname}] 广告标题: ${adInfo.title.substring(0, 100)}`);
        // 根据广告标题判断类型并执行转化
        let adType = "browse";
        if (adInfo.title.includes("小说") || adInfo.title.includes("阅读") || adInfo.title.includes("故事")) {
            adType = "novel";
            await simulateNovelReading(this.nickname);
        } else if (adInfo.title.includes("下载") || adInfo.title.includes("游戏") || adInfo.title.includes("APP") || adInfo.title.includes("应用")) {
            adType = "app";
            await simulateAppPlay(this.nickname, "推荐应用");
        } else if (adInfo.title.includes("直播")) {
            adType = "live";
            // 直播广告观看5-10分钟
            const shortWatchTime = Math.floor(Math.random() * 300000) + 300000;
            await randomDelay(shortWatchTime, shortWatchTime + 60000);
            console.log(`🎥 [${this.nickname}] 观看直播广告 ${Math.round(shortWatchTime/60000)}分钟`);
        } else {
            const browseTime = Math.floor(Math.random() * 30000) + 30000;
            console.log(`📄 [${this.nickname}] 浏览广告内容 ${Math.round(browseTime/1000)}秒...`);
            await randomDelay(browseTime, browseTime + 5000);
        }
      }

      const waitMs = Math.floor(Math.random() * 10000) + 38000;
      console.log(`🔍 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} ==> ${cfg.name} ${randomAdStatus()} ${Math.round(waitMs / 1000)}s`);
      await new Promise(r => setTimeout(r, waitMs));

      const sign = await this.retry(() => this.makeReportSign(adInfo.cid, adInfo.llsid, taskKey, cfg), "生成报告签名", 3);
      if (!sign) {
        this.taskStats[taskKey].failed++;
        return false;
      }

      const result = await this.retry(() => this.submitReport(sign.sig, sign.sig3, sign.sigtoken, sign.xfalcon, sign.postData, taskKey, cfg), "提交报告", 3);
      if (result?.success) {
        this.taskStats[taskKey].success++;
        this.taskStats[taskKey].totalReward += result.reward || 0;
        return true;
      }

      this.taskStats[taskKey].failed++;
      return false;
    } catch (e) {
      console.log(`❌ 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} 任务异常(${taskKey}): ${e.message}`);
      this.taskStats[taskKey].failed++;
      return false;
    }
  }

  async runAllTasks() {
    const results = {};
    for (const t of this.tasksToExecute) {
      if (this.stopAllTasks) break;
      if (!this.taskDef[t]) continue;

      console.log(`🚀 账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} 开始任务：${this.taskDef[t].name}`);
      results[t] = await this.runSingleTask(t);

      if (this.stopAllTasks) break;
      if (t !== this.tasksToExecute.at(-1)) {
        const wait = Math.floor(Math.random() * 8000) + 7000;
        console.log(`⏱ 账号[${this.nickname}] 任务间隔等待 ${Math.round(wait / 1000)}s`);
        await new Promise(r => setTimeout(r, wait));
      }
    }
    return results;
  }

  printStats() {
    console.log(`\n账号[${this.nickname}]${this.remark ? "（" + this.remark + "）" : ""} 任务统计:`);
    for (const [k, stat] of Object.entries(this.taskStats)) {
      const name = this.taskDef[k].name;
      console.log(`  ${name}: 成功${stat.success}次, 失败${stat.failed}次, 总奖励${stat.totalReward}金币`);
    }
    console.log(`🌾 养号统计: 今日已养号 ${this.farmCountToday}/${FARM_CONFIG.FARM_DAILY_LIMIT} 次`);
    console.log(`💰 本轮总奖励: ${this.totalRewardThisRun} 金币`);
  }

  getStats() {
    return this.taskStats;
  }
}

// 解析单行账号字符串（remark#cookie#salt#proxy 或简化格式）
function parseAccountLine(line) {
  const parts = String(line || "").trim().split("#");
  if (parts.length < 2) return null;

  let remark = "";
  let cookie = "";
  let salt = "";
  let proxy = null;

  if (parts.length === 2) {
    cookie = parts[0];
    salt = parts[1];
  } else if (parts.length === 3) {
    if (/socks5:\/\//i.test(parts[2])) {
      cookie = parts[0];
      salt = parts[1];
      proxy = parts[2];
    } else {
      remark = parts[0];
      cookie = parts[1];
      salt = parts[2];
    }
  } else if (parts.length >= 4) {
    remark = parts[0];
    cookie = parts[1];
    salt = parts.slice(2, -1).join("#");
    proxy = parts.at(-1);
  }

  cookie = cookie.replace("kpn=NEBULA", "kpn=KUAISHOU");

  if (proxy) {
    if (proxy.includes("|")) {
      const [host, port, user, pwd] = proxy.split("|");
      proxy = `socks5://${user}:${pwd}@${host}:${port}`;
    } else if (!/^socks5:\/\//i.test(proxy)) {
      console.log("⚠️ 代理非socks5，忽略：" + proxy);
      proxy = null;
    }
  }

  return { remark, salt, cookie, proxyUrl: proxy };
}

// 加载所有有效账号
function loadAllAccounts() {
  const lines = parseAllAccounts();
  const list = [];
  for (const line of lines) {
    const acc = parseAccountLine(line);
    if (acc) list.push(acc);
    else console.log("账号格式错误：" + line);
  }
  list.forEach((acc, i) => acc.index = i + 1);
  return list;
}

// 并发调度器
async function concurrentRun(items, concurrency, taskFn) {
  const results = new Array(items.length);
  let index = 0;

  const worker = async () => {
    while (true) {
      const i = index++;
      if (i >= items.length) return;
      try {
        results[i] = await taskFn(items[i], i);
      } catch (e) {
        console.log(`并发异常（账号${i + 1}）：${e.message}`);
        results[i] = null;
      }
    }
  };

  const workers = Array.from({ length: Math.min(concurrency, items.length) }, worker);
  await Promise.all(workers);
  return results;
}

// 单个账号完整执行流程
async function runAccount(account) {
  if (account.proxyUrl) {
    console.log(`账号[${account.index}]${account.remark ? "（" + account.remark + "）" : ""} 🔌 测试代理...`);
    const proxyCheck = await checkProxyConnect(account.proxyUrl, `账号[${account.index}]`);
    console.log("  - " + proxyCheck.msg);
    if (proxyCheck.ok && proxyCheck.ip && proxyCheck.ip !== "localhost") {
      if (usedIPSet.has(proxyCheck.ip)) {
        console.log("\n⚠️ 相同IP重复，退出防止风控：" + proxyCheck.ip);
        process.exit(1);
      }
      usedIPSet.add(proxyCheck.ip);
    }
  } else {
    console.log(`账号[${account.index}]${account.remark ? "（" + account.remark + "）" : ""} 直连模式`);
  }

  console.log(`账号[${account.index}]${account.remark ? "（" + account.remark + "）" : ""} 🔍 获取账号信息...`);
  const infoBefore = await getAccountBasic(account.cookie, account.proxyUrl, account.index);
  const nickname = infoBefore?.nickname || "账号" + account.index;

  if (infoBefore) {
    const coin = infoBefore.totalCoin ?? "未知";
    const cash = infoBefore.allCash ?? "未知";
    console.log(`账号[${nickname}]${account.remark ? "（" + account.remark + "）" : ""} ✅ 登录成功 | 金币: ${coin} | 余额: ${cash}`);
  } else {
    console.log(`账号[${nickname}]${account.remark ? "（" + account.remark + "）" : ""} ❌ 信息获取失败，继续执行`);
  }

  const runner = new AccountRunner({
    ...account,
    nickname,
    tasksToExecute: TASKS_TO_RUN
  });

  await runner.checkCoinIsOverLimit();
  if (runner.coinExceeded) {
    console.log(`账号[${nickname}] 金币已超限，不执行任务`);
    const infoAfter = await getAccountBasic(account.cookie, account.proxyUrl, account.index);
    return {
      index: account.index,
      remark: account.remark || "无备注",
      nickname,
      initialCoin: infoBefore?.totalCoin || 0,
      finalCoin: infoAfter?.totalCoin || 0,
      coinChange: (infoAfter?.totalCoin || 0) - (infoBefore?.totalCoin || 0),
      initialCash: infoBefore?.allCash || 0,
      finalCash: infoAfter?.allCash || 0,
      cashChange: (infoAfter?.allCash || 0) - (infoBefore?.allCash || 0),
      stats: runner.getStats(),
      coinLimitExceeded: true
    };
  }

  // 先执行一次初始养号
  if (FARM_CONFIG.ENABLE_FARM && runner.farmCountToday < FARM_CONFIG.FARM_DAILY_LIMIT) {
    console.log(`🌾 [${nickname}] 开始初始养号...`);
    runner.farmCountToday++;
    await doFarming(nickname, "初始养号");
    runner.hasDoneInitialFarm = true;
  }

  // 开始刷金币任务
  for (let round = 0; round < TOTAL_ROUNDS; round++) {
    // 检查是否已触发养号且达到上限
    if (runner.stopAllTasks) {
      console.log(`账号[${nickname}] 🏁 停止条件触发，退出循环`);
      break;
    }

    const wait = Math.floor(Math.random() * 8000) + 8000;
    const now = new Date();
    console.log(`账号[${nickname}] ⌛ 第${round + 1}轮，等待 ${Math.round(wait / 1000)}s=====>${now.toLocaleString()}`);
    await new Promise(r => setTimeout(r, wait));
    console.log(`账号[${nickname}] 🚀 第${round + 1}轮任务开始`);
    await runner.runAllTasks();

    if (runner.stopAllTasks) {
      console.log(`账号[${nickname}] 🏁 停止条件触发，退出循环`);
      break;
    }

    if (round < TOTAL_ROUNDS - 1) {
      const interval = Math.floor(Math.random() * 10000) + 100000;
      console.log(`账号[${nickname}] ⌛ 轮间等待 ${Math.round(interval / 1000)}s`);
      await new Promise(r => setTimeout(r, interval));
    }
  }

  const infoAfter = await getAccountBasic(account.cookie, account.proxyUrl, account.index);
  const coinBefore = infoBefore?.totalCoin || 0;
  const coinAfter = infoAfter?.totalCoin || 0;
  const cashBefore = infoBefore?.allCash || 0;
  const cashAfter = infoAfter?.allCash || 0;

  runner.printStats();

  return {
    index: account.index,
    remark: account.remark || "无备注",
    nickname,
    initialCoin: coinBefore,
    finalCoin: coinAfter,
    coinChange: coinAfter - coinBefore,
    initialCash: cashBefore,
    finalCash: cashAfter,
    cashChange: cashAfter - cashBefore,
    stats: runner.getStats(),
    coinLimitExceeded: runner.coinExceeded,
    farmCount: runner.farmCountToday
  };
}

// 结果汇总表格
function printSummary(results) {
  if (!results.length) {
    console.log("\n无结果可展示");
    return;
  }

  const totalInitCoin = results.reduce((sum, r) => sum + (Number(r.initialCoin) || 0), 0);
  const totalFinalCoin = results.reduce((sum, r) => sum + (Number(r.finalCoin) || 0), 0);
  const totalCoinDelta = totalFinalCoin - totalInitCoin;
  const totalInitCash = results.reduce((sum, r) => sum + (Number(r.initialCash) || 0), 0);
  const totalFinalCash = results.reduce((sum, r) => sum + (Number(r.finalCash) || 0), 0);
  const totalCashDelta = totalFinalCash - totalInitCash;
  const totalFarmCount = results.reduce((sum, r) => sum + (r.farmCount || 0), 0);

  let totalTask = 0, totalSucc = 0, totalReward = 0;
  results.forEach(r => {
    if (!r.stats) return;
    Object.values(r.stats).forEach(s => {
      totalTask += s.success + s.failed;
      totalSucc += s.success;
      totalReward += s.totalReward || 0;
    });
  });

  const succRate = totalTask > 0 ? ((totalSucc / totalTask) * 100).toFixed(1) : "0.0";
  const limitAccounts = results.filter(r => r.coinLimitExceeded).length;

  console.log("\n" + "=".repeat(80));
  console.log("|" + padCenter(" 快手任务执行结果汇总 ", 78) + "|");
  console.log("=".repeat(80));
  console.log(`| 总账号: ${results.length} | 超限账号: ${limitAccounts} | 总任务: ${totalTask} | 成功率: ${succRate}% |`);
  console.log(`| 金币变化: ${totalCoinDelta} | 总奖励: ${totalReward} | 余额变化: ${totalCashDelta.toFixed(2)} |`);
  console.log(`| 总养号次数: ${totalFarmCount} |`);
  console.log("-".repeat(80));

  const heads = ["序号", "备注", "昵称", "初始金币", "最终金币", "金币变化", "初始余额", "最终余额", "余额变化", "养号次数"];
  const widths = [6, 16, 16, 12, 12, 12, 12, 12, 12, 10];
  let headLine = "|";
  heads.forEach((h, i) => headLine += padCenter(h, widths[i]) + "|");
  console.log(headLine);

  let sepLine = "|";
  widths.forEach(w => sepLine += "-".repeat(w) + "|");
  console.log(sepLine);

  results.forEach(r => {
    const lineParts = [
      r.index,
      r.remark,
      (r.nickname || "-") + (r.coinLimitExceeded ? " ⚠️" : ""),
      r.initialCoin,
      r.finalCoin,
      r.coinChange >= 0 ? "+" + r.coinChange : r.coinChange,
      r.initialCash,
      r.finalCash,
      r.cashChange >= 0 ? "+" + r.cashChange.toFixed(2) : r.cashChange.toFixed(2),
      r.farmCount || 0
    ];

    let line = "|";
    lineParts.forEach((p, i) => line += padCenter(p, widths[i]) + "|");
    console.log(line);
  });

  console.log("=".repeat(80));
  console.log("|" + padCenter(" 执行完成 ", 78) + "|");
  console.log("=".repeat(80));
}

// 主入口
(async () => {
  const accounts = loadAllAccounts();
  console.log("有效账号数：" + accounts.length);
  if (accounts.length === 0) process.exit(1);

  const finalResults = [];
  await concurrentRun(accounts, CONCURRENCY, async acc => {
    console.log(`\n—— 🚀 开始账号[${acc.index}]${acc.remark ? "（" + acc.remark + "）" : ""} ——`);
    try {
      const res = await runAccount(acc);
      finalResults.push(res);
    } catch (e) {
      console.log(`账号[${acc.index}] 执行异常：${e.message}`);
      finalResults.push({
        index: acc.index,
        remark: acc.remark || "无备注",
        nickname: "账号" + acc.index,
        initialCoin: 0, finalCoin: 0, coinChange: 0,
        initialCash: 0, finalCash: 0, cashChange: 0,
        error: e.message,
        farmCount: 0
      });
    }
  });

  finalResults.sort((a, b) => a.index - b.index);
  console.log("\n✅ 全部任务执行完成");
  console.log("\n------------------------------------ 最终汇总 ------------------------------------");
  printSummary(finalResults);
})();

const finalEncryptTag = "jsjiami.com.v7";