// ==UserScript== // @name PokeBonk 辅助 // @namespace https://pokebonk.com/ // @version 1.0.0 // @description PokéBonk 一键辅助:无敌模式、一击清怪、伤害倍率(1x-100x)、一键清屏,面板内含各功能效果说明 // @match https://pokebonk.com/* // @grant none // @run-at document-idle // @noframes // ==/UserScript== /* * PokéBonk 辅助 v1.0 * ============================================================ * 四大功能(均带面板内效果说明): * ① 无敌模式:给 player.hp 装读写拦截器(accessor),任何把血量打到 ≤0 的 * 伤害都会被拦下并回满,从写入点根除死亡,不依赖受伤方法名。 * ② 一击清怪:每帧把存活敌人的 hp 压到 1,玩家随便一次攻击即触发游戏自带的 * 「血量≤0→击杀」逻辑,等于全场秒杀。 * ③ 伤害倍率(1x/5x/20x/100x):包装「对敌人扣血」的最终汇聚方法,玩家的 * 普攻/技能/道具/灼烧中毒等一切对敌伤害统一 ×N,且只放大敌人实际掉血, * 不影响吸血、计量等旁路数值。 * ④ 一键清屏:立刻把当前存活敌人 hp 压到 1(配合自动攻击瞬间清场)。 */ (() => { 'use strict'; if (window.__PB_ASSIST__) { window.__PB_ASSIST__.togglePanel?.(); return; } const S = { god: true, oneShot: false, mult: 1, dmg: null }; // dmg: null 未检测 / true 已挂接 / false 未适配 const tried = new WeakSet(); const log = (...a) => console.log('%c[PokéBonk辅助]', 'color:#e94756;font-weight:bold', ...a); // ---- 1. 发现游戏入口模块(自动适配构建号变化) -------------------------- async function findGameEntry() { const home = await fetch('/', { cache: 'no-store' }).then(r => r.text()); const outer = home.match(/assets\/(main-[\w-]+\.js)/)?.[1]; if (!outer) throw new Error('未找到外层入口'); const outerJs = await fetch('/assets/' + outer).then(r => r.text()); const inner = [...new Set(outerJs.match(/main-[\w-]+\.js/g) || [])].find(n => n !== outer); if (!inner) throw new Error('未找到游戏模块'); return new URL('./assets/' + inner, location.origin).href; } // ---- 2. 无敌:给 player.hp 装读写拦截器 -------------------------------- function installGod(player) { if (player.__pbGod) return; let cur = player.hp; try { Object.defineProperty(player, 'hp', { configurable: true, enumerable: true, get() { return cur; }, set(v) { if (!S.god) { cur = v; return; } // 关闭无敌时正常写入 // 无敌开启:任何会导致死亡(≤0/非法)的写入都回满;正常掉血保留观感 if (typeof v !== 'number' || !isFinite(v) || v <= 0) cur = this.maxHp; else cur = Math.min(v, this.maxHp); } }); player.__pbGod = true; } catch (e) { /* 若属性不可配置则跳过,不影响游戏 */ } } // ---- 3. 伤害倍率:运行时特征匹配核心扣血方法(抗改名) ------------------ function patchDamage(combat) { const proto = Object.getPrototypeOf(combat); if (!proto) return false; if (proto.__pbDmg) return true; // 本次页面已挂接过 for (const k of Object.getOwnPropertyNames(proto)) { let fn; try { fn = Object.getOwnPropertyDescriptor(proto, k)?.value; } catch (e) { continue; } if (typeof fn !== 'function') continue; let src; try { src = Function.prototype.toString.call(fn); } catch (e) { continue; } // 特征:恰两参小方法、开头取出 run.enemies、体内有 hp 数组扣减 if (src.length > 900) continue; if (!/^[\w$]{1,30}\(\w{1,3},\w{1,3}\)\{let \w+=this\.run\.enemies/.test(src)) continue; if (!/\.hp\[\w+\]/.test(src) || !/-=/.test(src)) continue; const orig = fn; try { proto[k] = function (e, t) { if (S.mult > 1 && typeof t === 'number' && isFinite(t)) t *= S.mult; return orig.call(this, e, t); }; proto.__pbDmg = k; } catch (err) { return false; } log('伤害倍率已挂接核心扣血方法:', k); return true; } log('伤害倍率:未匹配到核心扣血方法(游戏可能已更新),该功能暂不可用,其余功能不受影响'); return false; } // ---- 4. 每帧:装无敌 + 挂倍率 + 一击清怪 -------------------------------- function frameAssist(app) { const run = app.run; if (!run) return; if (run.player) installGod(run.player); const cb = run.combat; if (cb && !tried.has(cb)) { tried.add(cb); try { S.dmg = patchDamage(cb); } catch (e) { S.dmg = false; } } if (S.oneShot) { const en = run.enemies; if (en && typeof en.n === 'number') { for (let i = 0; i < en.n; i++) { if (en.alive ? en.alive[i] : true) en.hp[i] = 1; // 压到 1,等玩家攻击触发击杀 } } } } // ---- 5. 一键清屏 -------------------------------------------------------- function wipeScreen() { const run = window.__pbApp__?.run; const en = run?.enemies; if (!en || typeof en.n !== 'number') return; let c = 0; for (let i = 0; i < en.n; i++) { if (en.alive ? en.alive[i] : true) { en.hp[i] = 1; c++; } } toast(`已清场(${c})`); } // ---- 6. 悬浮面板(每个功能带效果说明) ---------------------------------- function buildPanel() { const host = document.createElement('div'); host.id = 'pb-assist-host'; const root = host.attachShadow({ mode: 'open' }); root.innerHTML = `