机器人控制中心
打开机器人实例
机器人BotId:
Url
打开数量:
(当前还可打开:5 个)
打开机器人
当前运行的机器人实例(共 0 个)
暂无运行中的机器人实例
插件管理
插件代码:
// 页面URL信息提取工具 // 配置参数 const FETCH_INTERVAL = 5000; // 执行间隔时间(毫秒) const PAGE_REFRESH_INTERVAL = 15 * 60 * 1000; // 页面刷新间隔时间(毫秒)- 15分钟 // 系统配置读取接口 const PHP_SAVE_URL = "http://127.0.0.1/Extens/Six/config_api.php"; const PHP_GET_DATA_URL = "http://127.0.0.1/Extens/Six/get_data.php"; const PHP_UPDATE_BET_STATUS_URL = "http://127.0.0.1/Extens/Six/update_bet_status.php"; const account = 'Six003'; /** * 解析URL参数 * @returns {Object} 解析后的URL参数对象 */ function getUrlParams() { const params = {}; const queryString = window.location.search.substring(1); const pairs = queryString.split('&'); for (let i = 0; i < pairs.length; i++) { const pair = pairs[i].split('='); const key = decodeURIComponent(pair[0]); const value = decodeURIComponent(pair[1] || ''); params[key] = value; } return params; } /** * 获取页面中的期数值 * 支持从iframe和直接DOM中查找 * @returns {string|null} 找到的期数值或null */ function getDrawNumber() { console.log('=== 尝试获取期数值 ==='); // 确保我们使用正确的document对象 console.log(`当前document是否可用: ${!!document}`); console.log(`document readyState: ${document.readyState}`); let foundDrawNumber = null; // 尝试从iframe中获取期数元素 try { console.log('尝试从iframe中获取期数元素...'); const iframeElement = document.getElementById('frame') || document.getElementsByName('frame')[0]; if (iframeElement) { console.log('找到iframe元素'); // 检查iframe是否已加载完成 if (iframeElement.contentDocument && iframeElement.contentDocument.readyState === 'complete') { console.log('iframe内容已加载完成'); // 尝试在iframe的document中查找drawNumber元素 const iframeDocument = iframeElement.contentDocument || iframeElement.contentWindow.document; const drawNumberElement = iframeDocument.getElementById('drawNumber'); if (drawNumberElement) { const drawNumber = drawNumberElement.textContent.trim(); console.log(`从iframe中获取到期数值: ${drawNumber}`); foundDrawNumber = drawNumber; } else { console.log('在iframe中未找到drawNumber元素,尝试查找lottery_info容器...'); // 尝试在iframe中查找lottery_info容器 const lotteryInfoElement = iframeDocument.getElementById('lottery_info'); if (lotteryInfoElement) { console.log('在iframe中找到lottery_info容器'); // 尝试在父容器中查找可能的期数元素 const possibleDrawElements = lotteryInfoElement.querySelectorAll('span'); console.log(`在lottery_info中找到${possibleDrawElements.length}个span元素`); // 遍历可能的元素,寻找包含期数的元素 possibleDrawElements.forEach((element, index) => { const text = element.textContent.trim(); if (text && text.includes('期')) { console.log(`可能的期数元素 ${index}: ${text}`); // 提取数字部分 const numbers = text.match(/\d+/g); if (numbers && numbers.length > 0) { console.log(`提取到期数值: ${numbers[0]}`); if (!foundDrawNumber) { foundDrawNumber = numbers[0]; } } } }); } else { console.log('在iframe中未找到lottery_info容器'); console.log('iframe标题:', iframeDocument.title); } } } else { console.log('iframe内容尚未加载完成,等待下一次执行...'); } } else { console.log('未找到ID或name为frame的iframe元素'); // 输出页面中的iframe信息用于调试 const allIframes = document.querySelectorAll('iframe'); console.log(`页面中共有${allIframes.length}个iframe元素`); allIframes.forEach((iframe, index) => { console.log(`iframe ${index}: ID=${iframe.id}, name=${iframe.name}`); }); } } catch (error) { console.error('从iframe获取元素时发生错误:', error.message); } // 同时保留原有的直接查找逻辑作为备选 const directDrawNumberElement = document.getElementById('drawNumber'); if (directDrawNumberElement) { const drawNumber = directDrawNumberElement.textContent.trim(); console.log(`直接获取到期数值: ${drawNumber}`); if (!foundDrawNumber) { foundDrawNumber = drawNumber; } } return foundDrawNumber; } /** * 加载系统配置 * @returns {Promise<Array|null>} 配置对象数组或null */ async function loadSystemConfig() { console.log('=== 开始加载系统配置 ==='); try { const response = await fetch(PHP_SAVE_URL); if (!response.ok) { throw new Error(`HTTP错误,状态码: ${response.status}`); } const data = await response.json(); console.log('配置加载结果:', data); // 判断返回的数据是否为数组 if (data.success && Array.isArray(data.data)) { console.log(`=== 系统配置详情 ===`); console.log(`共获取到 ${data.data.length} 条配置记录`); // 打印每条配置的详情 data.data.forEach((config, index) => { console.log(`配置 ${index + 1}:`); console.log(` 固定金额参数: ${config.fixed_amount}`); console.log(` 倍数参数: ${config.multiplier}`); console.log(` 是否单条投注: ${config.is_single_bet ? '是' : '否'}`); console.log(` 所属账号: ${config.account || '未知'}`); console.log(` 彩种类型: ${config.title || '未知'}`); console.log(` 投注类型: ${config.wtype || '未知'}`); console.log(` 彩种类型: ${config.lotteryType || '未知'}`); console.log(` 配置状态: ${config.status || '未知'}`); }); return data.data; } else if (data.success && data.data) { // 如果返回的不是数组但是有数据,将其包装成数组返回 console.log('注意:系统配置返回的不是数组,将其包装成数组'); return [data.data]; } else { console.log(`未获取到配置数据: ${data.message || '未知错误'}`); return null; } } catch (error) { console.error('加载系统配置时发生错误:', error.message); return null; } } /** * 获取投注数据 * @param {Object} params 查询参数对象,可选包含wtype、round、title * @returns {Promise<Array|null>} 投注数据数组或null */ async function getBettingData(params = {}) { console.log('=== 开始获取投注数据 ==='); try { // 构建查询参数 const queryParams = new URLSearchParams(); if (params.wtype) queryParams.append('wtype', params.wtype); if (params.round) queryParams.append('round', params.round); if (params.title) queryParams.append('title', params.title); if (params.account) queryParams.append('account', params.account); // 构建完整URL const url = `${PHP_GET_DATA_URL}${queryParams.toString() ? '?' + queryParams.toString() : ''}`; console.log(`请求URL: ${url}`); const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP错误,状态码: ${response.status}`); } const data = await response.json(); console.log('投注数据获取结果:', data); if (data.success && Array.isArray(data.data)) { console.log(`=== 投注数据详情 ===`); console.log(`共获取 ${data.data.length} 条投注记录`); // 打印前几条数据作为示例 if (data.data.length > 0) { console.log('前3条投注记录示例:'); const sampleData = data.data; sampleData.forEach((record, index) => { console.log(`记录 ${index + 1}:`); console.log(` 号码: ${record.numbers}`); console.log(` 金额: ${record.amount}`); console.log(` 类型: ${record.wtype || '未知'}`); console.log(` 期数: ${record.round || '未知'}`); }); } return data; } else { console.log(`未获取到投注数据: ${data.message || '未知错误'}`); return null; } } catch (error) { console.error('获取投注数据时发生错误:', error.message); return null; } } /** * 主函数:页面加载完成后执行 */ async function main() { console.log('=== 页面加载完成,开始执行 ==='); console.log(`当前域名: ${window.location.hostname}`); console.log(`当前完整URL: ${window.location.href}`); console.log(`URL协议: ${window.location.protocol}`); console.log(`端口: ${window.location.port || '默认'}`); console.log(`路径: ${window.location.pathname}`); console.log(`哈希值: ${window.location.hash}`); // 解析当前页面URL参数 const urlParams = getUrlParams(); console.log('=== URL参数解析结果 ==='); if (Object.keys(urlParams).length > 0) { console.log('获取到的URL参数:'); for (const [key, value] of Object.entries(urlParams)) { console.log(` ${key}: ${value}`); } } else { console.log('未找到任何URL参数'); } // 调用函数获取期数值 console.log('=== 页面元素数据 ==='); const drawNumber = getDrawNumber(); if (drawNumber) { console.log(`最终获取到期数值: ${drawNumber}`); // 读取到期数后,加载系统配置 console.log('期数获取成功,开始加载系统配置...'); const systemConfig = await loadSystemConfig(); if (systemConfig) { console.log('系统配置加载成功!'); // 遍历每一条配置参数 for (const [index, config] of systemConfig.entries()) { try { console.log(`\n=== 处理第 ${index + 1} 条配置参数 ===`); // 检查配置状态,只有status为1时才执行后续操作 if (Number(config.status) !== 1) { console.log(`配置 ${index + 1} 的状态不是1(当前状态: ${config.status || '未设置'}),跳过处理`); continue; } if (!config.account || config.account !== account) { console.log(`配置 ${index + 1} 的账号不是 ${account}(当前账号: ${config.account || '未设置'}),跳过处理`); continue; } console.log(`配置 ${index + 1} 的状态为1,继续处理`); // 根据配置参数构建查询条件 const queryParams = { round: drawNumber, // 期数 title: config.title || undefined, // 彩种类型 account: config.account || undefined, // 所属账号 wtype: config.wtype || undefined // 投注类型 }; console.log('开始获取准备投注的数据...'); console.log(`使用的查询参数: round=${queryParams.round}, title=${queryParams.title || '未设置'}, wtype=${queryParams.wtype || '未设置'}`); // 使用当前配置参数获取投注数据 const bettingData = await getBettingData(queryParams); if (bettingData) { console.log(`配置 ${index + 1} 的投注数据获取成功!`); // 执行投注操作 if (bettingData && bettingData.data && bettingData.data.length > 0) { console.log('开始准备投注...'); await submitBetting(bettingData, config); } } else { console.log(`配置 ${index + 1} 的投注数据获取失败或无数据`); } } catch (error) { console.error(`处理配置 ${index + 1} 时发生异常:`, error.message); console.log(`跳过当前配置,继续处理下一条配置...`); // 跳出当前循环,继续下一次循环 continue; } } } else { console.log('系统配置加载失败或无配置数据'); } } else { console.log('未能获取到期数值,跳过配置加载'); } } // 标志变量,用于跟踪是否正在执行主函数 let isExecuting = false; // 递归执行函数,确保每次执行完成后再等待指定时间执行下一次 async function executeWithDelay() { // 检查是否正在执行 if (isExecuting) { console.log('上次执行尚未完成,等待下次执行机会...'); // 设置定时器继续下一次执行 setTimeout(executeWithDelay, 10000); // 等待10秒后再次尝试 return; } try { // 设置执行标志为true isExecuting = true; // 执行主函数,并处理可能的异常 try { await main(); console.log(`执行完成,等待 ${FETCH_INTERVAL/1000} 秒后进行下一次执行...`); } catch (mainError) { console.error('主函数执行过程中发生错误:', mainError.message); console.log('准备重新开始执行...'); } // 无论main函数是否成功执行,都设置定时器继续下一次执行 setTimeout(executeWithDelay, FETCH_INTERVAL); } catch (error) { console.error('executeWithDelay函数发生严重错误:', error.message); // 即使发生严重错误,也要确保下一次执行能正常进行 setTimeout(executeWithDelay, FETCH_INTERVAL); } finally { // 重置执行标志为false isExecuting = false; } } // 设置页面定时刷新函数 function setupPageRefresh() { console.log(`设置页面定时刷新,间隔时间:${PAGE_REFRESH_INTERVAL/1000}秒`); // 使用setInterval设置定时刷新 const refreshTimer = setInterval(() => { console.log('执行页面刷新操作...'); window.location.reload(); }, PAGE_REFRESH_INTERVAL); return refreshTimer; } // 监听页面加载完成事件 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { // 首次执行主函数 executeWithDelay(); // 设置页面定时刷新 setupPageRefresh(); }); } else { // 页面已经加载完成,立即执行主函数 executeWithDelay(); // 设置页面定时刷新 setupPageRefresh(); } /** * 提交投注数据 * @param {Object} bettingData - 投注数据对象,包含numbers和amount * @param {Object} config - 配置对象 */ async function submitBetting(bettingData, config) { try { // 创建FormData对象 const formData = new FormData(); // 设置lotteryType formData.append('lotteryType', config.lotteryType); // 生成类似101761121617237格式的betNum值 function generateBetNum() { const now = new Date(); // 获取年份后两位 const year = now.getFullYear().toString().slice(2); // 获取月份(0-11),加1并补零 const month = String(now.getMonth() + 1).padStart(2, '0'); // 获取日期,补零 const date = String(now.getDate()).padStart(2, '0'); // 获取小时,补零 const hour = String(now.getHours()).padStart(2, '0'); // 获取分钟,补零 const minute = String(now.getMinutes()).padStart(2, '0'); // 获取秒,补零 const second = String(now.getSeconds()).padStart(2, '0'); // 获取毫秒的前三位 const millisecond = String(now.getMilliseconds()).padStart(3, '0').slice(0, 3); // 组合成类似格式:10 + 年份后两位 + 月份 + 日期 + 小时 + 分钟 + 秒 + 毫秒前两位 // 例如:101761121617237 对应的是 2017年6月11日21时6分17秒237毫秒 return '10' + year + month + date + hour + minute + second + millisecond.slice(0, 2); } const betNum = generateBetNum(); formData.append('betNum', betNum); // 设置prompt和gt参数 formData.append('prompt', 'true'); formData.append('gt', 'B'); // 处理投注数据,根据新的数据格式从data数组中提取每个投注项 if (bettingData && bettingData.data && Array.isArray(bettingData.data) && bettingData.data.length > 0) { bettingData.data.forEach((item, index) => { // 从item中提取numbers、amount和rate // 格式化数字:01-09 转换为 1-9,保留其他数字格式 let number = item.numbers; // numbers是字符串格式 // 检查是否为01-09格式的字符串 if (/^0[1-9]$/.test(number)) { number = number.substring(1); // 移除前导0 } let amount = parseFloat(item.amount); // 转换为数字 const odds = parseFloat(item.rate); // 使用rate作为赔率 // KeyCode格式为TMA+数字 let keyCode = `TMA${number}`; if(parseFloat(config.fixed_amount)>0){ amount = parseFloat(config.fixed_amount); } if(parseFloat(config.multiplier)>0){ amount = parseFloat(config.multiplier) * amount; } formData.append(`betdata[${index}][Amount]`, amount.toString()); formData.append(`betdata[${index}][KeyCode]`, keyCode); formData.append(`betdata[${index}][Odds]`, odds.toString()); if(config.wtype==='特码B' || config.wtype==='特B' || config.toWtype==='特码B'){ formData.append(`betdata[${index}][isTmb]`, '1'); } console.log(`添加投注项 ${index + 1}: KeyCode=${keyCode}, Amount=${amount}, Odds=${odds}`); }); } console.log('投注数据准备完成,开始提交投注请求...'); console.log(`投注编号: ${betNum}`); console.log(`投注类型: ${config.lotteryType}`); // 显示投注号码列表 const betNumbers = bettingData.ids; console.log(`投注号码: ${betNumbers}`); // 计算总投注金额 const totalAmount = bettingData.data.reduce((sum, item) => sum + parseFloat(item.amount), 0); console.log(`总投注金额: ${totalAmount.toFixed(3)}`); console.log(`投注项数量: ${bettingData.data.length}`); // 发送投注请求 const response = await fetch(`/PlaceBet/Confirmbet?lotteryType=${config.lotteryType}`, { method: 'POST', body: formData, credentials: 'include' // 包含cookies等凭证 }); if (!response.ok) { throw new Error(`投注请求失败: ${response.status} ${response.statusText}`); } const result = await response.json(); console.log('投注请求成功,响应结果:', result); // 可以根据实际情况添加成功后的处理逻辑 if (result.succeed===1) { console.log(result.msg); // 投注成功,更新投注状态为1 updateBetStatus(bettingData.ids, 1); } else { console.warn('投注失败:', result.msg || '未知错误'); // 投注失败,更新投注状态为2 updateBetStatus(bettingData.ids, 2); } } catch (error) { console.error('投注过程中发生错误:', error); // 发生错误时,将投注状态设置为2 if (bettingData && bettingData.ids) { updateBetStatus(bettingData.ids, 2); } // 可以根据实际情况添加错误处理逻辑 } } /** * 更新投注状态 * @param {string} ids - 投注编号,可能是多个id用逗号分隔的字符串 * @param {number} betStatus - 投注状态,1表示成功,2表示失败 */ async function updateBetStatus(ids, betStatus) { try { console.log(`开始更新投注状态,ids: ${ids}, betStatus: ${betStatus}`); // 创建FormData对象 const formData = new FormData(); formData.append('ids', ids); formData.append('betStatus', betStatus.toString()); // 发送状态更新请求 const response = await fetch(PHP_UPDATE_BET_STATUS_URL, { method: 'POST', body: formData }); if (!response.ok) { throw new Error(`状态更新请求失败: ${response.status} ${response.statusText}`); } const result = await response.json(); console.log('投注状态更新结果:', result); if (result.success) { console.log(`投注状态更新成功,影响条数: ${result.affectedRows || 0}`); } else { console.warn('投注状态更新失败:', result.message || '未知错误'); } } catch (error) { console.error('更新投注状态过程中发生错误:', error); } }
更新并重新加载插件
操作日志