// ==UserScript== // @name BIN文件上传提取Token工具 // @namespace http://tampermonkey.net/ // @version 0.5 // @description 上传BIN文件提取RoleToken并生成WSS链接 // @author 豆包编程助手 // @match *://*/* // @grant GM_xmlhttpRequest // @grant GM_setClipboard // ==/UserScript== (function() { 'use strict'; // 界面状态变量 let toolContainer = null; let isToolVisible = false; // 创建工具界面 function createToolUI() { // 检查是否已存在界面 if (document.getElementById('bin-token-extractor')) { toolContainer = document.getElementById('bin-token-extractor'); return toolContainer; } // 创建容器(固定宽度380px) const container = document.createElement('div'); container.id = 'bin-token-extractor'; container.style.cssText = ` position: fixed; top: 50%; right: 20px; transform: translateY(-50%); background: linear-gradient(180deg, #ffffff 0%, #f9fbfd 100%); border-radius: 16px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12); width: 380px; max-height: 80vh; overflow-y: auto; padding: 25px; z-index: 99999; display: none; /* 默认隐藏 */ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); `; // 优化后的HTML结构 container.innerHTML = `

BIN文件Token提取工具

上传文件,提取RoleToken并生成WSS链接

📂

点击或拖放BIN文件

仅支持 .bin 格式文件

`; document.body.appendChild(container); toolContainer = container; return container; } // 切换工具显示/隐藏状态 function toggleTool() { if (!toolContainer) { createToolUI(); } isToolVisible = !isToolVisible; if (isToolVisible) { // 显示工具并添加淡入动画 toolContainer.style.display = 'block'; setTimeout(() => { toolContainer.style.opacity = '1'; toolContainer.style.transform = 'translateY(-50%) scale(1)'; }, 10); // 初始化工具功能 initToolFunctions(); } else { // 添加淡出动画后隐藏 toolContainer.style.opacity = '0'; toolContainer.style.transform = 'translateY(-50%) scale(0.95)'; setTimeout(() => { toolContainer.style.display = 'none'; }, 300); } } // 初始化工具功能 function initToolFunctions() { if (!toolContainer) return; // 获取DOM元素 const uploadArea = toolContainer.querySelector('#uploadArea'); const fileInput = toolContainer.querySelector('#fileInput'); const fileInfo = toolContainer.querySelector('#fileInfo'); const uploadBtn = toolContainer.querySelector('#uploadBtn'); const progressContainer = toolContainer.querySelector('#progressContainer'); const progressBar = toolContainer.querySelector('#progressBar'); const progressText = toolContainer.querySelector('#progressText'); const statusMessage = toolContainer.querySelector('#statusMessage'); const resultContainer = toolContainer.querySelector('#resultContainer'); const wssLinkDisplay = toolContainer.querySelector('#wssLinkDisplay'); const copyWssLinkBtn = toolContainer.querySelector('#copyWssLinkBtn'); let selectedFile = null; let extractedToken = null; // 点击上传区域触发文件选择 uploadArea.addEventListener('click', function(e) { if (e.target !== fileInput) { fileInput.click(); } }); // 拖放功能 ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { uploadArea.addEventListener(eventName, preventDefaults, false); }); function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } ['dragenter', 'dragover'].forEach(eventName => { uploadArea.addEventListener(eventName, highlight, false); }); ['dragleave', 'drop'].forEach(eventName => { uploadArea.addEventListener(eventName, unhighlight, false); }); function highlight() { uploadArea.style.borderColor = '#3b82f6'; uploadArea.style.backgroundColor = 'rgba(59, 130, 246, 0.05)'; uploadArea.style.transform = 'scale(1.02)'; } function unhighlight() { uploadArea.style.borderColor = '#d1d9e6'; uploadArea.style.backgroundColor = '#f8fafc'; uploadArea.style.transform = 'scale(1)'; } // 文件拖放处理 uploadArea.addEventListener('drop', handleDrop, false); function handleDrop(e) { const dt = e.dataTransfer; const files = dt.files; if (files.length) { handleFiles(files); } } // 文件选择处理 fileInput.addEventListener('change', function() { if (this.files.length) { handleFiles(this.files); } }); function handleFiles(files) { const file = files[0]; // 检查文件类型 if (!file.name.toLowerCase().endsWith('.bin')) { showStatus('请选择.bin格式的文件', 'error'); return; } selectedFile = file; updateFileInfo(file); uploadBtn.disabled = false; uploadBtn.style.opacity = '1'; uploadBtn.style.transform = 'translateY(0)'; } function updateFileInfo(file) { fileInfo.textContent = `已选择: ${file.name} (${formatFileSize(file.size)})`; fileInfo.style.display = 'block'; // 添加淡入动画 fileInfo.style.opacity = '0'; setTimeout(() => { fileInfo.style.opacity = '1'; }, 10); } function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } // 上传按钮点击事件 uploadBtn.addEventListener('click', function() { if (!selectedFile) { showStatus('请先选择文件', 'error'); return; } // 禁用上传按钮,防止重复点击 uploadBtn.disabled = true; uploadBtn.style.opacity = '0.7'; uploadBtn.style.transform = 'translateY(2px)'; // 隐藏之前的结果 resultContainer.style.display = 'none'; // 显示进度条 progressContainer.style.display = 'block'; progressBar.style.width = '0%'; progressText.textContent = '0%'; // 直接上传文件 uploadFile(selectedFile); }); function uploadFile(file) { showStatus('正在上传文件...', ''); // 读取文件内容 const reader = new FileReader(); reader.onload = function(e) { const arrayBuffer = e.target.result; // 配置请求 GM_xmlhttpRequest({ method: 'POST', url: 'https://xxz-xyzw.hortorgames.com/login/authuser?_seq=1', data: arrayBuffer, headers: { 'Content-Type': 'application/octet-stream' }, responseType: 'arraybuffer', onprogress: function(e) { if (e.lengthComputable) { const percentComplete = (e.loaded / e.total) * 100; progressBar.style.width = percentComplete + '%'; progressText.textContent = Math.round(percentComplete) + '%'; } }, onload: function(response) { if (response.status >= 200 && response.status < 300) { try { // 处理二进制响应 const arrayBuffer = response.response; if (arrayBuffer) { // 提取RoleToken extractRoleToken(arrayBuffer); showStatus('Token提取成功!', 'success'); } else { showStatus('上传成功,但响应为空', 'error'); } } catch (e) { showStatus('处理响应时出错: ' + e.message, 'error'); } } else { showStatus('上传失败: ' + response.statusText, 'error'); } // 重新启用上传按钮 uploadBtn.disabled = false; uploadBtn.style.opacity = '1'; uploadBtn.style.transform = 'translateY(0)'; }, onerror: function() { showStatus('上传过程中发生错误', 'error'); uploadBtn.disabled = false; uploadBtn.style.opacity = '1'; uploadBtn.style.transform = 'translateY(0)'; } }); }; reader.onerror = function() { showStatus('读取文件失败', 'error'); uploadBtn.disabled = false; uploadBtn.style.opacity = '1'; uploadBtn.style.transform = 'translateY(0)'; }; reader.readAsArrayBuffer(file); } function extractRoleToken(arrayBuffer) { try { // 将ArrayBuffer转换为Uint8Array以便处理 const bytes = new Uint8Array(arrayBuffer); // 转换为ASCII字符串以便搜索 let asciiString = ''; for (let i = 0; i < bytes.length; i++) { // 只转换可打印的ASCII字符(32-126) if (bytes[i] >= 32 && bytes[i] <= 126) { asciiString += String.fromCharCode(bytes[i]); } else { asciiString += '.'; // 用点号表示不可打印字符 } } // 搜索Token的位置 - 查找 "Token" 字符串 const tokenIndex = asciiString.indexOf('Token'); if (tokenIndex !== -1) { // 找到Token标记,提取Token值 let tokenStart = tokenIndex + 5; // "Token"长度为5 // 跳过可能的非Base64字符,直到找到Base64字符 while (tokenStart < asciiString.length) { const char = asciiString[tokenStart]; if (isBase64Char(char)) { break; } tokenStart++; } // 提取Base64 Token let tokenEnd = tokenStart; while (tokenEnd < asciiString.length && isBase64Char(asciiString[tokenEnd])) { tokenEnd++; } const tokenValue = asciiString.substring(tokenStart, tokenEnd); if (tokenValue.length > 0) { extractedToken = tokenValue; resultContainer.style.display = 'block'; // 触发动画 setTimeout(() => { resultContainer.style.transform = 'translateY(0)'; resultContainer.style.opacity = '1'; }, 10); // 生成并显示完整的WSS链接 generateAndDisplayWssLink(extractedToken); // 平滑滚动到结果区域 resultContainer.scrollIntoView({ behavior: 'smooth' }); } else { showStatus('找到Token标记但未找到Token值', 'error'); } } else { showStatus('在响应中未找到Token标记', 'error'); } } catch (error) { showStatus('提取Token时发生错误: ' + error.message, 'error'); } } function isBase64Char(char) { // Base64字符集: A-Z, a-z, 0-9, +, /, = return /[A-Za-z0-9+/=]/.test(char); } function showStatus(message, type) { statusMessage.textContent = message; statusMessage.className = ''; statusMessage.style.backgroundColor = ''; statusMessage.style.color = ''; statusMessage.style.boxShadow = 'none'; if (type === 'success') { statusMessage.style.backgroundColor = 'rgba(16, 185, 129, 0.1)'; statusMessage.style.color = '#059669'; statusMessage.style.borderLeft = '3px solid #10b981'; } else if (type === 'error') { statusMessage.style.backgroundColor = 'rgba(239, 68, 68, 0.1)'; statusMessage.style.color = '#dc2626'; statusMessage.style.borderLeft = '3px solid #ef4444'; } else { statusMessage.style.backgroundColor = 'rgba(59, 130, 246, 0.1)'; statusMessage.style.color = '#2563eb'; statusMessage.style.borderLeft = '3px solid #3b82f6'; } statusMessage.style.display = 'block'; statusMessage.style.opacity = '0'; statusMessage.style.transform = 'translateY(10px)'; // 触发淡入动画 setTimeout(() => { statusMessage.style.opacity = '1'; statusMessage.style.transform = 'translateY(0)'; }, 10); // 3秒后自动隐藏非错误状态 if (type !== 'error') { setTimeout(() => { statusMessage.style.opacity = '0'; statusMessage.style.transform = 'translateY(10px)'; setTimeout(() => { statusMessage.style.display = 'none'; }, 300); }, 3000); } } // 复制完整WSS链接按钮事件 copyWssLinkBtn.addEventListener('click', function() { const wssLink = wssLinkDisplay.textContent; if (!wssLink) return; GM_setClipboard(wssLink); // 按钮点击反馈 this.style.backgroundColor = '#059669'; setTimeout(() => { this.style.backgroundColor = '#10b981'; }, 200); showStatus('WSS链接已复制', 'success'); }); // 生成并显示完整的WSS链接 function generateAndDisplayWssLink(token) { // 生成随机的会话ID和连接ID const currentTime = Date.now(); const sessId = currentTime * 100 + Math.floor(Math.random() * 100); const connId = currentTime + Math.floor(Math.random() * 10); // 构建WebSocket参数 const wssParams = `{"roleToken":"${token}","sessId":${sessId},"connId":${connId},"isRestore":0}`; // 显示完整的WSS链接参数 wssLinkDisplay.textContent = wssParams; } } // 创建切换按钮(兼具显示和关闭功能) function createToggleButton() { // 创建按钮 const toggleBtn = document.createElement('button'); toggleBtn.innerHTML = `🔑BIN Token提取`; toggleBtn.style.cssText = ` position: fixed; bottom: 20px; right: 20px; background: linear-gradient(90deg, #3b82f6 0%, #60a5fa 100%); color: white; border: none; padding: 10px 18px; border-radius: 50px; font-size: 13px; font-weight: 600; cursor: pointer; box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3); white-space: nowrap; z-index: 99998; transition: all 0.3s; `; // 添加悬停效果 toggleBtn.addEventListener('mouseenter', () => { toggleBtn.style.transform = 'translateY(-2px)'; toggleBtn.style.boxShadow = '0 6px 20px rgba(59, 130, 246, 0.4)'; }); toggleBtn.addEventListener('mouseleave', () => { toggleBtn.style.transform = 'translateY(0)'; toggleBtn.style.boxShadow = '0 4px 15px rgba(59, 130, 246, 0.3)'; }); // 添加点击事件 - 切换显示/隐藏 toggleBtn.addEventListener('click', toggleTool); document.body.appendChild(toggleBtn); } // 页面加载完成后创建切换按钮 window.addEventListener('load', createToggleButton); })();