Last active
February 4, 2026 06:12
-
-
Save Ansen/04af8cc1465388cc56b5597228e37cd0 to your computer and use it in GitHub Desktop.
文字传奇界面调整(优化版)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name web传奇快速TP + 房间锁定助手 + 挂机配置 | |
| // @namespace http://tampermonkey.net/ | |
| // @version 2.1 | |
| // @description 快速TP + 房间锁定 + 挂机配置 | |
| // @author abcd | |
| // @match *://cq.071717.xyz/* | |
| // @match *://cq.333398.xyz/* | |
| // @match https://chuanqi.makifx.com/ | |
| // @grant unsafeWindow | |
| // ==/UserScript== | |
| (function () { | |
| 'use strict'; | |
| // 核心工具函数模块 | |
| const CoreUtils = { | |
| executeInPage(code) { | |
| const script = document.createElement('script'); | |
| script.textContent = code; | |
| document.documentElement.appendChild(script); | |
| script.remove(); | |
| }, | |
| teleport(roomId, isManual = false) { | |
| // 仅在手动传送时解除房间锁定 | |
| if (isManual && AutoConfig.autoLockRoomEnabled && RoomLocker.lockEnabled) { | |
| RoomLocker.unlockRoom(); | |
| } | |
| // 执行传送 | |
| this.executeInPage(`socket.emit('cmd', { text: "goto_room ${roomId}" });`); | |
| // 传送完成后延迟一段时间再锁定房间(等待状态更新) | |
| setTimeout(() => { | |
| if (AutoConfig.autoLockRoomEnabled) { | |
| RoomLocker.lockRoom(); | |
| } | |
| }, 1000); // 延迟 1 秒确保房间状态已更新 | |
| } | |
| }; | |
| // 状态管理模块 | |
| const StateManager = { | |
| getState() { | |
| return unsafeWindow.__LOCK_HELPER_STATE__ || null; | |
| }, | |
| getRoom() { | |
| const state = this.getState(); | |
| return state ? state.room : null; | |
| }, | |
| hasMobs() { | |
| const state = this.getState(); | |
| return state && Array.isArray(state.mobs) && state.mobs.length > 0; | |
| }, | |
| getPlayerHpPercent() { | |
| const hpEl = gameElements.uiHp(); | |
| if (hpEl) { | |
| const [current, max] = hpEl.textContent.split('/').map(Number); | |
| if (max > 0) { | |
| return Math.floor((current / max) * 100); | |
| } | |
| } | |
| return 100; | |
| } | |
| }; | |
| // 房间锁定模块 | |
| const RoomLocker = { | |
| lockedRoom: null, | |
| lockEnabled: false, | |
| lockRoom() { | |
| const room = StateManager.getRoom(); | |
| if (!room) return; | |
| this.lockedRoom = { | |
| zoneId: room.zoneId, | |
| roomId: room.roomId, | |
| zone: room.zone, | |
| name: room.name | |
| }; | |
| this.lockEnabled = true; | |
| this.updateLockStatus(); | |
| }, | |
| unlockRoom() { | |
| this.lockEnabled = false; | |
| this.lockedRoom = null; | |
| this.updateLockStatus(); | |
| }, | |
| outOfLock() { | |
| if (!this.lockEnabled || !this.lockedRoom) return false; | |
| const room = StateManager.getRoom(); | |
| if (!room) return false; | |
| return room.zoneId !== this.lockedRoom.zoneId || room.roomId !== this.lockedRoom.roomId; | |
| }, | |
| returnLockRoom() { | |
| if (!this.lockedRoom) return; | |
| CoreUtils.teleport(`${this.lockedRoom.zoneId}:${this.lockedRoom.roomId}`); | |
| }, | |
| updateLockStatus() { | |
| const statusBox = document.querySelector('#lock-status'); | |
| if (!statusBox) return; | |
| const room = StateManager.getRoom(); | |
| statusBox.innerHTML = `<div style="font-size:12px;">📍 位置:${room ? room.zone + '·' + room.name : '--'}</div> | |
| <div style="font-size:12px;">👿 怪物:${StateManager.hasMobs() ? '有' : '无'}</div> | |
| <div style="font-size:12px;">🔒 状态:${this.lockEnabled ? '已锁定' : '未锁定'}</div> | |
| `; | |
| } | |
| }; | |
| // 挂机配置模块 | |
| const AutoConfig = { | |
| autoHealEnabled: true, // 默认开启自动治愈 | |
| healThreshold: 90, // 默认血量阈值为90% | |
| autoFrostEnabled: true, // 默认开启自动雪霜 | |
| frostThreshold: 90, // 默认血量阈值为90% | |
| autoLockRoomEnabled: true, // 默认开启自动锁定房间 | |
| checkAndAct() { | |
| const hpPercent = StateManager.getPlayerHpPercent(); | |
| // 自动治愈 | |
| if (this.autoHealEnabled && hpPercent <= this.healThreshold) { | |
| socket.emit('cmd', {text: `cast heal`}); | |
| } | |
| // 自动雪霜 | |
| if (this.autoFrostEnabled && hpPercent <= this.frostThreshold) { | |
| socket.emit('cmd', {text: `use snow_frost`}); | |
| } | |
| }, | |
| updateConfigUI() { | |
| const configBox = document.querySelector('#auto-config'); | |
| if (!configBox) return; | |
| configBox.innerHTML = `<div style="font-size:12px;"> | |
| <label><input type="checkbox" id="auto-heal-toggle" ${this.autoHealEnabled ? 'checked' : ''}> 自动治愈</label> | |
| <br> | |
| <label>血量%:<input type="number" id="heal-threshold" value="${this.healThreshold}" min="1" max="100" style="width: 50px; height: 20px; appearance: none; -moz-appearance: textfield;"></label> | |
| <br> | |
| <label><input type="checkbox" id="auto-frost-toggle" ${this.autoFrostEnabled ? 'checked' : ''}> 自动雪霜</label> | |
| <br> | |
| <label>血量%:<input type="number" id="frost-threshold" value="${this.frostThreshold}" min="1" max="100" style="width: 50px; height: 20px; appearance: none; -moz-appearance: textfield;"></label> | |
| <br> | |
| <label><input type="checkbox" id="auto-lock-room-toggle" ${this.autoLockRoomEnabled ? 'checked' : ''}> 自动锁定房间</label> | |
| </div> | |
| `; | |
| // 绑定事件 | |
| document.getElementById('auto-heal-toggle').onchange = (e) => { | |
| this.autoHealEnabled = e.target.checked; | |
| }; | |
| document.getElementById('heal-threshold').oninput = (e) => { | |
| this.healThreshold = parseInt(e.target.value); | |
| }; | |
| document.getElementById('auto-frost-toggle').onchange = (e) => { | |
| this.autoFrostEnabled = e.target.checked; | |
| }; | |
| document.getElementById('frost-threshold').oninput = (e) => { | |
| this.frostThreshold = parseInt(e.target.value); | |
| }; | |
| document.getElementById('auto-lock-room-toggle').onchange = (e) => { | |
| this.autoLockRoomEnabled = e.target.checked; | |
| }; | |
| } | |
| }; | |
| // 游戏元素映射 | |
| const gameElements = { | |
| uiHp: () => document.getElementById('ui-hp') | |
| }; | |
| // 经验房按钮生成函数 | |
| function createExpButtons(container) { | |
| const grid = document.createElement('div'); | |
| grid.style = "display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; padding:5px;"; | |
| for (let i = 1; i <= 11; i++) { | |
| const btn = document.createElement('button'); | |
| const suffix = i === 1 ? "" : i - 1; | |
| btn.innerText = i; | |
| btn.style = "padding:5px 0; background:#1a1a1a; color:#00ff00; border:1px solid #444; cursor:pointer; font-size:11px; border-radius:3px;"; | |
| btn.onmouseover = () => btn.style.borderColor = "#00ff00"; | |
| btn.onmouseout = () => btn.style.borderColor = "#444"; | |
| btn.onclick = () => CoreUtils.teleport(`molong:gate${suffix}`, true); // 手动传送标记为 true | |
| grid.appendChild(btn); | |
| } | |
| container.appendChild(grid); | |
| } | |
| // GUI构建函数 | |
| function buildGUI(config) { | |
| const panel = document.createElement('div'); | |
| panel.id = "tp-helper-panel-always-on"; | |
| panel.style = ` | |
| position: fixed; | |
| right: 10px; | |
| top: 100px; | |
| width: 160px; | |
| background: rgba(0, 0, 0, 0.85); | |
| border: 2px solid #d4af37; | |
| border-radius: 8px; | |
| color: #fff; | |
| z-index: 999999; | |
| padding: 8px; | |
| font-family: "Microsoft YaHei", sans-serif; | |
| box-shadow: 0 0 15px rgba(0,0,0,0.8); | |
| user-select: none; | |
| cursor: move; /* 添加拖动光标 */ | |
| `; | |
| // 添加拖动功能 | |
| let isDragging = false; | |
| let offsetX = 0, offsetY = 0; | |
| panel.addEventListener('mousedown', (e) => { | |
| isDragging = true; | |
| offsetX = e.clientX - panel.getBoundingClientRect().left; | |
| offsetY = e.clientY - panel.getBoundingClientRect().top; | |
| panel.style.cursor = 'grabbing'; | |
| }); | |
| document.addEventListener('mousemove', (e) => { | |
| if (isDragging) { | |
| panel.style.left = `${e.clientX - offsetX}px`; | |
| panel.style.top = `${e.clientY - offsetY}px`; | |
| panel.style.right = 'auto'; // 取消right属性以允许自由定位 | |
| } | |
| }); | |
| document.addEventListener('mouseup', () => { | |
| isDragging = false; | |
| panel.style.cursor = 'move'; | |
| }); | |
| panel.innerHTML += `<div style="text-align:center;color:#d4af37;margin-bottom:8px;font-weight:bold;border-bottom:1px solid #555;padding-bottom:5px;font-size:14px;">🚀 快速空降</div>`; | |
| const scrollBox = document.createElement('div'); | |
| scrollBox.style = "max-height: 80vh; overflow-y: auto; scrollbar-width: none;"; | |
| config.forEach(group => { | |
| const dropdown = document.createElement('div'); | |
| dropdown.style = "margin-bottom: 10px;"; | |
| const label = document.createElement('div'); | |
| label.innerText = group.g; | |
| label.style = "font-size:12px; color:#d4af37; padding:5px; background:#2a2a2a; border:1px solid #444; cursor:pointer; border-radius:4px;"; | |
| label.onclick = () => { | |
| const content = dropdown.querySelector('.dropdown-content'); | |
| content.style.display = content.style.display === 'block' ? 'none' : 'block'; | |
| }; | |
| const content = document.createElement('div'); | |
| content.className = 'dropdown-content'; | |
| content.style = "display:none; background:#1a1a1a; border:1px solid #444; border-top:none; border-radius:0 0 4px 4px;"; | |
| if (group.g === "⭐ 经验房 (1-11)") { | |
| createExpButtons(content); | |
| } else if (group.g === "🔒 房间锁定") { | |
| content.innerHTML = ` | |
| <div id="lock-status" style="line-height:1.5;border-bottom:1px solid #444;padding-bottom:6px;margin-bottom:6px;"> | |
| <div style="font-size:12px;">📍 位置:--</div> | |
| <div style="font-size:12px;">👿 怪物:--</div> | |
| <div style="font-size:12px;">🔒 状态:未锁定</div> | |
| </div> | |
| `; | |
| const lockBtn = document.createElement('button'); | |
| lockBtn.innerText = '🔒 锁定当前房间'; | |
| lockBtn.style = "width:100%;margin-bottom:4px;font-size:12px;padding:4px 8px;border-radius:4px;background:#2a2a2a;color:#eee;border:1px solid #444;cursor:pointer;"; | |
| lockBtn.onmouseover = () => { | |
| lockBtn.style.background = "#d4af37"; | |
| lockBtn.style.color = "#000"; | |
| }; | |
| lockBtn.onmouseout = () => { | |
| lockBtn.style.background = "#2a2a2a"; | |
| lockBtn.style.color = "#eee"; | |
| }; | |
| lockBtn.onclick = () => RoomLocker.lockRoom(); | |
| const unlockBtn = document.createElement('button'); | |
| unlockBtn.innerText = '🔗 解除锁定'; | |
| unlockBtn.style = "width:100%;font-size:12px;padding:4px 8px;border-radius:4px;background:#2a2a2a;color:#eee;border:1px solid #444;cursor:pointer;"; | |
| unlockBtn.onmouseover = () => { | |
| unlockBtn.style.background = "#d4af37"; | |
| unlockBtn.style.color = "#000"; | |
| }; | |
| unlockBtn.onmouseout = () => { | |
| unlockBtn.style.background = "#2a2a2a"; | |
| unlockBtn.style.color = "#eee"; | |
| }; | |
| unlockBtn.onclick = () => RoomLocker.unlockRoom(); | |
| content.appendChild(lockBtn); | |
| content.appendChild(unlockBtn); | |
| } else if (group.g === "🎮 挂机配置") { | |
| content.innerHTML = `<div id="auto-config"></div>`; | |
| setTimeout(() => { | |
| AutoConfig.updateConfigUI(); // 延迟执行以确保 DOM 加载完成 | |
| }, 0); | |
| } else { | |
| group.items.forEach(([name, id]) => { | |
| const btn = document.createElement('button'); | |
| btn.innerText = name; | |
| btn.style = "width:100%; margin:2px 0; padding:6px; background:#2a2a2a; color:#eee; border:1px solid #444; cursor:pointer; font-size:12px; text-align:left; border-radius:4px; transition: 0.1s;"; | |
| btn.onmouseover = () => { | |
| btn.style.background = "#d4af37"; | |
| btn.style.color = "#000"; | |
| btn.style.fontWeight = "bold"; | |
| }; | |
| btn.onmouseout = () => { | |
| btn.style.background = "#2a2a2a"; | |
| btn.style.color = "#eee"; | |
| btn.style.fontWeight = "normal"; | |
| }; | |
| btn.onclick = () => CoreUtils.teleport(id, true); // 手动传送标记为 true | |
| content.appendChild(btn); | |
| }); | |
| } | |
| dropdown.appendChild(label); | |
| dropdown.appendChild(content); | |
| scrollBox.appendChild(dropdown); | |
| }); | |
| panel.appendChild(scrollBox); | |
| document.body.appendChild(panel); | |
| } | |
| // 初始化劫持 console.log | |
| CoreUtils.executeInPage(` | |
| (function () { | |
| const raw = console.log; | |
| console.log = function (...args) { | |
| try { | |
| if ( | |
| args.length === 2 && | |
| args[0] === 'Received state payload:' && | |
| typeof args[1] === 'object' | |
| ) { | |
| window.__LOCK_HELPER_STATE__ = args[1]; | |
| } | |
| } catch (e) {} | |
| raw.apply(console, args); | |
| }; | |
| })(); | |
| `); | |
| // 构建 GUI | |
| const config = [ | |
| {g: "🏘️ 买药", items: [["土城集市", "mg_town:mg_market"], ["比奇城门", "bq_town:gate"]]}, | |
| { | |
| g: "👿 小boss", | |
| items: [["虹魔教主", "fm:deep"], ["千年树妖", "brm:jungle"], ["沃玛教主", "wms:deep"], ["祖玛教主", "zm:throne"], ["赤月恶魔", "cr:demon"], ["触龙神", "wgc:deep5"], ["黄泉教主", "bone:deep"], ["牛魔教主", "nm_temple:deep"]] | |
| }, | |
| { | |
| g: "🎖️ 大boss", | |
| items: [["魔龙教主", "molong:deep"],["炎龙", "wb:lair"], ["玄武", "sb_guild:sanctum"], ["暗之沃玛", "dark_bosses:dark_woma_lair"], ["暗之祖玛", "dark_bosses:dark_zuma_lair"], ["暗之虹魔", "dark_bosses:dark_hongmo_lair"], ["暗之黄泉", "dark_bosses:dark_huangquan_lair"], ["暗之血魔", "dark_bosses:dark_doublehead_lair"], ["暗之骷髅", "dark_bosses:dark_skeleton_lair"]] | |
| }, | |
| {g: "⭐ 经验房 (1-11)", items: []}, | |
| {g: "🔒 房间锁定", items: []}, | |
| {g: "🎮 挂机配置", items: []} | |
| ]; | |
| buildGUI(config); | |
| // 启动定时器 | |
| setInterval(() => { | |
| RoomLocker.updateLockStatus(); | |
| if (RoomLocker.lockEnabled && RoomLocker.outOfLock()) { | |
| RoomLocker.returnLockRoom(); | |
| } | |
| AutoConfig.checkAndAct(); // 检查并执行挂机逻辑 | |
| }, 500); | |
| console.log("快速空降助手 + 房间锁定助手 + 挂机配置已启动 (常开模式)"); | |
| })(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name 文字传奇界面调整(优化版) | |
| // @version 2026-01-27 | |
| // @description 调整界面文字传奇布局(更稳健、更易维护) | |
| // @author reginfos,langge | |
| // @match https://chuanqi.makifx.com/ | |
| // @grant GM_addStyle | |
| // ==/UserScript== | |
| (function () { | |
| 'use strict'; | |
| /******************** | |
| * 样式统一管理 | |
| ********************/ | |
| GM_addStyle(` | |
| #stats-inventory { | |
| max-height: 200px !important; | |
| overflow-y: auto !important; | |
| overflow-x: hidden !important; | |
| } | |
| .hidden { | |
| display: none !important; | |
| } | |
| .status-card, .side { | |
| height: 600px; /* 你自己调 */ | |
| max-height: 600px; | |
| overflow-y: auto; | |
| overflow-x: hidden; | |
| } | |
| `); | |
| /******************** | |
| * 工具函数 | |
| ********************/ | |
| const $ = (sel) => document.querySelector(sel); | |
| const $$ = (sel) => Array.from(document.querySelectorAll(sel)); | |
| function safeAppend(parent, child) { | |
| if (parent && child) { | |
| parent.appendChild(child); | |
| } | |
| } | |
| function safeRemove(el) { | |
| if (el) { | |
| el.remove(); | |
| } | |
| } | |
| function swapDivs(parentSelector, index1, index2) { | |
| const parent = $(parentSelector); | |
| if (!parent) return; | |
| const children = Array.from(parent.children); | |
| if ( | |
| index1 < 0 || index2 < 0 || | |
| index1 >= children.length || | |
| index2 >= children.length || | |
| index1 === index2 | |
| ) return; | |
| const el1 = children[index1]; | |
| const el2 = children[index2]; | |
| const next = el2.nextSibling === el1 ? el2 : el2.nextSibling; | |
| parent.insertBefore(el1, el2); | |
| parent.insertBefore(el2, next); | |
| } | |
| /******************** | |
| * 主逻辑(等待 DOM 就绪) | |
| ********************/ | |
| function init() { | |
| const statusCards = $$('.status-card'); | |
| const actionGroups = $$('.action-group'); | |
| const sideActionGroups = $$('.side .action-group'); | |
| // 将目标放到【行动面板】 | |
| //safeAppend(statusCards[1], actionGroups[3]); | |
| // 将技能框放到【常用操作】 | |
| safeAppend(statusCards[2],sideActionGroups[1]); | |
| // 将召唤框放到【属性框】 | |
| safeAppend(statusCards[0],sideActionGroups[3]); | |
| // 将物品放到【属性框】 | |
| safeAppend(statusCards[1], actionGroups[4]); | |
| // 将移动面板移动到上面 | |
| const statusGrid = $('.status-grid'); | |
| const sidePanel = $('.side'); | |
| safeAppend(statusGrid, sidePanel); | |
| // 去掉头部文字 | |
| safeRemove($('header')); | |
| // 页面整体样式调整 | |
| const app = $('#app'); | |
| if (app) { | |
| app.style.padding = '0'; | |
| app.style.maxWidth = 'none'; | |
| } | |
| // 上方人物信息:4 列 | |
| if (statusGrid) { | |
| statusGrid.style.setProperty( | |
| 'grid-template-columns', | |
| 'repeat(4, minmax(0, 1fr))' | |
| ); | |
| } | |
| // 聊天区域调整 | |
| const gameGrid = $('.game-grid'); | |
| if (gameGrid) { | |
| gameGrid.style.setProperty('grid-template-columns', '2fr 2fr'); | |
| } | |
| // 怪物目标框高度 | |
| if (actionGroups[3]) { | |
| actionGroups[3].style.height = '150px'; | |
| } | |
| // 隐藏修炼框 | |
| if (actionGroups[7]) { | |
| actionGroups[7].classList.add('hidden'); | |
| } | |
| // 系统日志移动到和聊天框平级 | |
| const logWrap = $('.log-wrap'); | |
| safeAppend(gameGrid, logWrap); | |
| // 交换聊天框和系统日志位置 | |
| swapDivs('.game-grid', 0, 1); | |
| // 日志高度调整 | |
| const log = $('#log'); | |
| if (log) { | |
| log.style.minHeight = 'auto'; | |
| log.style.height = '320px'; | |
| } | |
| } | |
| /******************** | |
| * DOM Ready | |
| ********************/ | |
| if (document.readyState === 'loading') { | |
| document.addEventListener('DOMContentLoaded', init); | |
| } else { | |
| init(); | |
| } | |
| })(); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
使用方法
安装 Tampermonkey 插件,然后 点击 我安装
更新内容
20260126