斗鱼鱼塘商城自动兑换工具 (注意手动设置个人用户ID以及房间号)
// ==UserScript== // @name 斗鱼鱼塘商城兑换工具 // @namespace YourNamespaceHere // @version 1.3 // @description 斗鱼鱼塘商城自动兑换工具 (注意手动设置个人用户ID以及房间号) // @match https://www.douyu.com/pages/fish-act/mine* // @grant GM_addStyle // @grant GM_xmlhttpRequest // @license MIT // ==/UserScript== (function() { 'use strict'; // ---------- 重要 ----------// let previousAcfCcnValue = null; let ctnid = '123'; ///用户ID 在发送请求的时候会自动在Cookies获取最新的ID const roomid = '123'; //房间ID 不支持靓号 (某些奖品需要粉丝牌等级才能兑) // 用于判断页面是否加载完成的标志变量 let pageLoaded = false; // 监听页面加载状态改变事件 window.addEventListener('load', function () { pageLoaded = true; initScript(); }); // 初始化脚本的函数,在页面加载完成后执行具体操作 function initScript() { // 添加悬浮窗样式 GM_addStyle(` #overlay { position: fixed; top: 26%; left: 50%; transform: translate(-50%, -50%); background-color: rgba(255, 255, 255, 0.9); padding: 20px; border-radius: 10px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); display: none; z-index: 9999; } button { margin: 5px; padding: 10px 20px; font-size: 16px; cursor: pointer; border: none; border-radius: 5px; } button.controlExchange { background-color: red; color: white; margin: 5px; padding: 10px 20px; font-size: 16px; cursor: pointer; border: none; border-radius: 5px; } button.autoExchange { background-color: red; color: white; margin: 5px; padding: 10px 20px; font-size: 16px; cursor: pointer; border: none; border-radius: 5px; } select { margin: 5px; padding: 10px; font-size: 16px; border: 1px solid #ccc; border-radius: 5px; } `); // 创建悬浮窗元素及按钮 const overlay = document.createElement('div'); overlay.id = 'overlay'; // 创建控制兑换的按钮(集成启动和停止功能) const controlExchangeButton = document.createElement('button'); controlExchangeButton.textContent = '启动兑换 ✔'; controlExchangeButton.className = 'controlExchange'; // 创建自动兑换按钮 const autoExchangeButton = document.createElement('button'); autoExchangeButton.textContent = '自动兑换 ✖'; autoExchangeButton.className = 'autoExchange'; // 创建下拉菜单元素 const selectMenu = document.createElement('select'); // 我只换了每种类型的第一个 再根据斗鱼的尿性推算的后面几个数字 const items = [ { value: 'hahahahha', text: '请选择需要兑换的奖品' }, { value: 'PROP_1', text: '3级粉丝牌 初级水手' }, { value: 'PROP_2', text: '3级粉丝牌 精英士官' }, { value: 'PROP_3', text: '6级粉丝牌 心动卡' }, { value: 'FREE_PROP_1', text: '10 陪伴印章' }, { value: 'FREE_PROP_2', text: '30 陪伴印章' }, { value: 'FREE_PROP_3', text: '50 陪伴印章' }, { value: 'YC_TY_1', text: '0.1 鱼翅' }, { value: 'YC_TY_2', text: '0.5 鱼翅' }, { value: 'YC_TY_3', text: '1 鱼翅' }, { value: 'YW_1', text: '100 鱼丸' }, { value: 'YW_2', text: '200 鱼丸' }, { value: 'YW_3', text: '500 鱼丸' }, { value: 'YC_CHIP_1', text: '2 鱼翅碎片' }, { value: 'YC_CHIP_2', text: '5 鱼翅碎片' } ]; // 循环创建下拉菜单选项 items.forEach(item => { const option = document.createElement('option'); option.value = item.value; option.textContent = item.text; selectMenu.appendChild(option); }); overlay.appendChild(controlExchangeButton); overlay.appendChild(autoExchangeButton); overlay.appendChild(selectMenu); document.body.appendChild(overlay); // 用于记录鼠标按下时的坐标以及悬浮窗初始坐标 let startX, startY, offsetX, offsetY; // 为悬浮窗添加鼠标按下事件监听器 overlay.addEventListener('mousedown', function (e) { startX = e.pageX; startY = e.pageY; offsetX = overlay.offsetLeft; offsetY = overlay.offsetTop; document.addEventListener('mousemove', drag); document.addEventListener('mouseup', stopDrag); }); // 拖动时的处理函数 function drag(e) { overlay.style.left = offsetX + e.pageX - startX + 'px'; overlay.style.top = offsetY + e.pageY - startY + 'px'; } // 停止拖动的处理函数 function stopDrag() { document.removeEventListener('mousemove', drag); document.removeEventListener('mouseup', stopDrag); } // 用于存储当前选择的index值的变量 默认无 避免出Bug的时候花光光 let selectedIndexValue = 'hahahahha'; // 监听下拉菜单选项改变事件,更新选中的index值 selectMenu.addEventListener('change', function () { selectedIndexValue = this.value; console.log(`目前选择 ${this.options[this.selectedIndex].textContent} - ${this.value}`); //检查切换功能 }); // 用于控制兑换代码是否执行的标志变量,初始设为false表示未运行 let isRunning = false; // 用于标记自动兑换功能是否开启,初始设为false let autoExchangeEnabled = false; // 显示悬浮窗 function showOverlay() { overlay.style.display = 'block'; } // 隐藏悬浮窗 function hideOverlay() { overlay.style.display = 'none'; } // // 点击启动按钮的处理函数 // startButton.addEventListener('click', function () { // isRunning = true; // runExchangeLoop(); // }); // // 点击停止按钮的处理函数 // stopButton.addEventListener('click', function () { // isRunning = false; // }); // 点击控制兑换按钮的处理函数 controlExchangeButton.addEventListener('click', function () { if (isRunning) { isRunning = false; this.textContent = '启动兑换 ✔'; this.style.backgroundColor ='red'; console.log(`停止兑换 ${isRunning}`); } else { isRunning = true; this.textContent = '停止兑换 ✖'; this.style.backgroundColor = 'green'; console.log(`开始兑换 ${isRunning}`); runExchangeLoop(); } }); // 点击自动兑换按钮的处理函数 autoExchangeButton.addEventListener('click', function () { autoExchangeEnabled =!autoExchangeEnabled; if (autoExchangeEnabled) { this.textContent = '自动兑换中 ✔'; this.style.backgroundColor = 'green'; startAutoExchange(); } else { this.textContent = '自动兑换 ✖'; this.style.backgroundColor = 'red'; stopAutoExchange(); } }); // 获取当前时间的分钟和秒数 function getCurrentTime() { const now = new Date(); const minutes = now.getMinutes(); const seconds = now.getSeconds(); return { minutes, seconds }; } // 模拟兑换代码执行的函数(这里简化了之前的fetch请求,实际要替换成完整准确的) async function exchange() { try { const cookies = document.cookie; const acf_ccn = cookies.split('; ').find(cookie => cookie.startsWith('acf_ccn=')); if (acf_ccn) { let acf_ccnValue = acf_ccn.split('=')[1]; if (previousAcfCcnValue!== acf_ccnValue) { console.log(`CtnID 已经刷新 \n 旧ID:${ctnid} \n 新ID:${acf_ccnValue}`); previousAcfCcnValue = acf_ccnValue; ctnid = acf_ccnValue; } } console.log(`兑换请求属性设置 ctn=${ctnid}&rid=${roomid}&index=${selectedIndexValue}`); await fetch("https://www.douyu.com/japi/revenuenc/web/actfans/convert/convertOpt", { "headers": { "accept": "application/json, text/plain, */*", "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7", "content-type": "application/x-www-form-urlencoded", "priority": "u=1, i", "sec-ch-ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"Windows\"", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-origin" }, "referrer": "https://www.douyu.com/pages/fish-act/shop", "referrerPolicy": "strict-origin-when-cross-origin", "body": `ctn=${ctnid}&rid=${roomid}&index=${selectedIndexValue}`, "method": "POST", "mode": "cors", "credentials": "include" }); // await GM_xmlhttpRequest({ // method: 'POST', // url: "https://www.douyu.com/japi/revenuenc/web/actfans/convert/convertOpt", // headers: { // "accept": "application/json, text/plain, */*", // "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7", // "content-type": "application/x-www-form-urlencoded", // "priority": "u=1, i", // "sec-ch-ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"", // "sec-ch-ua-mobile": "?0", // "sec-ch-ua-platform": "\"Windows\"", // "sec-fetch-dest": "empty", // "sec-fetch-mode": "cors", // "sec-fetch-site": "same-origin" // }, // referrer: "https://www.douyu.com/pages/fish-act/shop", // referrerPolicy: "strict-origin-when-cross-origin", // data: `ctn=${ctnid}&rid=${roomid}&index=${selectedIndexValue}`, // onload: function (response) { // console.log('兑换请求响应:', response); // }, // onerror: function (error) { // console.error('兑换出现错误:', error); // } // }); } catch (error) { console.error('兑换出现错误:', error); } await sleep(100); //0.1 秒运行一次 避免CPU占用过高崩溃 } // 循环执行兑换代码的函数(根据标志变量控制) async function runExchangeLoop() { let count = 1; let targetCount = 200 //0,1秒运行一次 10次=1秒 100次=10秒 默认200次= 20秒 建议在 59分50秒点击启动, 会在大约00分10~13秒结束 while (isRunning) { await exchange(); console.log(`目前兑换请求发送次数 ${count}`); count++; updateControlExchangeButton(isRunning,targetCount-count); if (count-1 >= targetCount) { isRunning = false; updateControlExchangeButton(isRunning,targetCount-count); } } } // 独立的自动兑换循环执行函数 async function autoExchangeLoop() { console.log('启动自动兑换功能'); let autoExchangeCount = 0; while (autoExchangeEnabled) { const currentTime = getCurrentTime(); if (isInTimeRange()) { autoExchangeCount = 0; console.log(`目前时间 ${currentTime.minutes}分${currentTime.seconds}秒 发送兑换请求`); await exchange(); console.log(`目前时间 ${currentTime.minutes}分${currentTime.seconds}秒 发送兑换请求结束`); } else { await sleep(1000); // 不在时间区间内,等待1秒后再次检查时间 autoExchangeCount++; if(autoExchangeCount % 60 === 0){ console.log(`自动兑换运行中 每分钟提示一次 ${autoExchangeCount/60} 目前时间 ${currentTime.minutes}分${currentTime.seconds}秒`); } } } } // 启动自动兑换循环 function startAutoExchange() { autoExchangeLoop(); console.log(`开始自动兑换${autoExchangeEnabled}`); } // 停止自动兑换循环 function stopAutoExchange() { autoExchangeEnabled = false; console.log(`停止自动兑换${autoExchangeEnabled}`); } // 判断当前时间是否在指定时间区间内(59分58秒 - 00分05秒) function isInTimeRange() { const currentTime = getCurrentTime(); return (currentTime.minutes === 59 && currentTime.seconds >= 58) || (currentTime.minutes === 0 && currentTime.seconds <= 5); } // 简单的异步等待函数(以毫秒为单位) function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function updateControlExchangeButton(isRunning,countLeft) { if (isRunning) { controlExchangeButton.textContent = `停止兑换 ✖ 剩余请求 ${countLeft}`; controlExchangeButton.style.backgroundColor = 'green'; } else { controlExchangeButton.textContent = '启动兑换 ✔'; controlExchangeButton.style.backgroundColor ='red'; } } // 页面加载完成后显示悬浮窗 showOverlay(); } })();