Script Archived
This script has been archived by the author. The script may be no longer functional, and the author no longer maintains it. You cannot provide feedback for this script.
// ==UserScript==
// @name 宝可梦点击(Poke Clicker)辅助脚本 脚本核心模块
// @namespace PokeClickerHelper
// @version 0.1.5
// @description 核心模块作为基础依赖框架/库提供大量公共方法供其他功能模块调用,【必须安装】,否则功能模块无法生效。
// @author DreamNya、苍猫
// @match https://www.pokeclicker.com
// @match https://g8hh.github.io/pokeclicker/
// @match https://pokeclicker.g8hh.com
// @match https://yx.g8hh.com/pokeclicker/
// @match https://dreamnya.github.io/pokeclicker/
// @icon data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/319hf99fYX/fX2F/319hf8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////////99fYX/fX2F/319hf8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////////wAAAP8AAAD/fX2F/319hf99fYX/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////8AAAD/AAAA/wAAAP99fYX/fX2F/wAAAP8AAAD/AAAA/319hf8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/HBT//xwU//8AAAD//////319hf8AAAD/Dgim/w4Ipv8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAD/HBT//xwU//8cFP//HBT//wAAAP8AAAD/Dgim/w4Ipv8OCKb/Dgim/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/xwU//8cFP//HBT//xwU/44cFP//HBT//xwU//8cFP//Dgim/w4Ipv8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/HBT//xwU/47/////HBT/jhwU//8cFP//HBT//w4Ipv8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/xwU//8cFP//HBT/jhwU//8OCKb/Dgim/w4Ipv8OCKb/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/xwU//8OCKb/Dgim/w4Ipv8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAPw/AADwDwAA4AcAAOAHAADAAwAAwAMAAMADAADAAwAA4AcAAOAHAADwDwAA/D8AAP//AAD//wAA//8AAA==
// @grant none
// @license MIT
// @run-at document-body
// ==/UserScript==
/* eslint-env jquery */
/* global Preload,NotificationConstants */
/* eslint no-implicit-globals:0, no-eval:0*/
const { scriptHandler, version } = GM_info;
const [V, v] = version.split('.');
if (scriptHandler == "Tampermonkey") {
if (V < 4 || (V == 4 && v < 16)) alert(`Tampermonkey版本过低 可能无法正常运行脚本\n建议更新至4.16+版本\n当前版本:${scriptHandler} ${version}`)
}
////////////////////
// 脚本公共Object //
////////////////////
//所有方法均挂载在PokeClickerHelper对象下便于调用(简写PCH)
let PokeClickerHelper = {};
let PCH = PokeClickerHelper;
window.PCH = PokeClickerHelper;
window.PokeClickerHelper = PokeClickerHelper;
//存储或读取变量至localStorage 自动补全前缀PokeClickerHelper_,防止命名冲突
PokeClickerHelper.get = function (key, defaultValue) {
let value = JSON.parse(localStorage.getItem('PokeClickerHelper_' + key))
return value ?? defaultValue
}
PokeClickerHelper.set = function (key, value) {
localStorage.setItem('PokeClickerHelper_' + key, JSON.stringify(value))
}
//通知函数
//默认设置 标题:'宝可梦点击(Poke Clicker)辅助脚本';样式:Danger;持续:10秒;默认不进行浏览器通知
PokeClickerHelper.Notify = function ({ title = '宝可梦点击(Poke Clicker)辅助脚本', message, timeout = 10000, type = NotificationConstants.NotificationOption.danger, ...args }, alert = false) {
//节流 相同通知10秒内最多通知一次
const now = Date.now()
if (now - PokeClickerHelper.NotifyThrottle[message] < 10000) return
PokeClickerHelper.NotifyThrottle[message] = now
//桌面通知
alert && new Notification(message)
//游戏内通知
window.Notifier.notify({ title, message, timeout, type, ...args })
}
PokeClickerHelper.NotifyThrottle = {}
//委托初始化前函数:PokeClickerHelper.initBeforeList.add(fuc)
//{fuc}自定义函数
PokeClickerHelper.initBeforeList = new Set()
//读取存档前初始化函数
initBefore()
function initBefore() {
initHook()
initGameTickHook()
PokeClickerHelper.addHook('Game', forceWebWorker)
initWebWorker()
initUI()
//PokeClickerHelper.hookGameTickList.add(() => console.log('tick测试'))
initAfterHook()
PokeClickerHelper.initBeforeList.forEach(i => i())
PokeClickerHelper.Notify({ title: '宝可梦点击(Poke Clicker)辅助脚本', message: "加载成功" });
PokeClickerHelper.addHook('Game', initAfterStartHook)
}
//委托初始化后函数:PokeClickerHelper.initAfterList.add(fuc)
//{fuc}自定义函数
PokeClickerHelper.initAfterList = new Set()
//读取存档后初始化函数
function initAfter() {
appendUI()
PokeClickerHelper.initAfterList.forEach(i => i())
}
function initAfterHook() {
const realHideSplashScreen = Preload.hideSplashScreen
Preload.hideSplashScreen = function (fast = false) {
initAfter()
realHideSplashScreen(fast)
}
}
//强制游戏使用Web Worker计时器,减少延迟
//暂不支持自定义 TODO:Script Setting
function forceWebWorker(Game) {
const replacement = [["let pageHidden = document.hidden;", "/*let pageHidden = document.hidden;"],
["// Try start our webworker so we can process stuff while the page isn't focused", "*/"],
["let pageHidden = false;\n self.onmessage = function(e) {\n if (e.data.pageHidden != undefined) {\n pageHidden = e.data.pageHidden;\n }\n };", ""],
["if (!pageHidden) return;", ""],
["Settings.getSetting('useWebWorkerForGameTicks').value ? this.gameTick() : null", "this.gameTick()"],
["document.addEventListener('visibilitychange', () => {", "/*document.addEventListener('visibilitychange', () => {"],
["this.worker.postMessage({ 'pageHidden': pageHidden });\n if (this.worker) {", "this.worker.postMessage({ 'pageHidden': pageHidden });*/\n if (this.worker) {"]];
PokeClickerHelper.HookFuc(Game, 'start', replacement, '');
}
PokeClickerHelper.initAfterStartList = new Set()
//游戏完全加载后初始化函数
function initAfterStartHook(Game) {
const realStart = Game.start.bind(Game)
Game.start = function () {
realStart()
PokeClickerHelper.initAfterStartList.forEach(i => i())
}
}
//////////////////
// 劫持对象方法 //
//////////////////
//通过function.toString().replace劫持替换原有函数
//会自动在hook object对象下挂载3个属性{real_prop}原生函数、{hook_prop}劫持函数、{hookStorage}存储prop名方便还原或再次劫持
//调用后直接劫持并应用,如只想劫持不应用,需要额外调用PokeClickerHelper.restoreHook({obj})
//注:暂不支持多模块同时劫持同一个对象并分别还原
//(目前理念是各模块功能明确,互不干涉,暂不存在多模块需要劫持同一个对象情况)
//调用方法
//劫持对象属性 PokeClickerHelper.HookFuc({object}, {prop}, {replacement}, {argName})
//{object}劫持对象 {prop}劫持属性 {replacement}替换函数体内容(二维数组) {argName}替换函数传入参数名(字符串 以,分隔)
//
//还原已劫持对象所有劫持函数 PokeClickerHelper.restoreHook({object})
//{object}已劫持对象
//
//重新劫持已还原劫持对象所有劫持函数 PokeClickerHelper.applyHook({object})
//{object}已还原劫持对象
//
//额外功能:(通常用于脚本内自定义函数格式化,其结果通常用于与网页劫持函数拼接)
//不劫持只返回格式化函数体 PokeClickerHelper.HookFucBody({fucntion})
//{fucntion}需要格式化的函数
PokeClickerHelper.HookFuc = function (obj, prop, replacement, arg) {
const fuc = obj[prop]
let text = fuc.toString()
text = text.slice(text.indexOf('{') + 1, -1)
for (let item of replacement) {
if (typeof item[0] == 'string') { //string则includes;RegExp则test
if (!text.includes(item[0])) { //先检测是否存在 不存在代表脚本过时 停止注入
alert('替换失败 脚本可能需要更新' + item[0])
return false
}
} else {
if (!item[0].test(text)) {
alert('替换失败 脚本可能需要更新' + item[0])
return false
}
}
text = text.replace(item[0], item[1])
}
const newFuc = new Function(arg, text)
obj['real_' + prop] = obj[prop]
obj[prop] = newFuc
obj['hook_' + prop] = newFuc
obj.hookStorage = obj.hookStorage || []
obj.hookStorage.push(prop)
}
//还原替换hook函数
//prop为指定还原,无prop则为全部还原
PokeClickerHelper.restoreHook = function (obj, prop) {
if (prop != void 0) {
if (!obj['real_' + prop]) return
obj[prop] = obj['real_' + prop]
} else {
Object.values(obj.hookStorage).forEach(i => {
obj[i] = obj['real_' + i]
})
}
}
//重新劫持hook函数
//prop为指定劫持,无prop则为全部劫持
PokeClickerHelper.applyHook = function (obj, prop) {
if (prop != void 0) {
if (!obj['hook_' + prop]) return
obj[prop] = obj['hook_' + prop]
} else {
Object.values(obj.hookStorage).forEach(i => {
obj[i] = obj['hook_' + i]
})
}
}
//格式化函数体
PokeClickerHelper.HookFucBody = function (fuc) {
let text = fuc.toString()
return text.slice(text.indexOf('{') + 1, -1)
}
////////////////////
// 委托Web Worker //
////////////////////
//Web Worker 用于执行tick间隔低于100ms函数
//每种tick各生成一个Web Worker,相同tick函数共用同一Web Worker
//不建议生成过多Web Worker影响效率
//(暂不支持传参,如要传参可以改为读写全局变量/对象上的属性)
//调用方法
//创建一个setInterval循环线程 PokeClickerHelper.Worker.setInterval(callback,delay)
//创建一个setTimeout循环线程 PokeClickerHelper.Worker.setTimeout(callback,delay)
//注:setTimeout循环线程同样不断循环执行,并非只执行一次,循环方法不同(setInterval为执行函数前计算间隔;setTimeout为执行函数后计算间隔)
//
//删除一个setInterval循环线程 PokeClickerHelper.Worker.clearInterval(callback,delay)
//删除一个setTimeout循环线程 PokeClickerHelper.Worker.claerTimeout(callback,delay)
//注:删除循环线程需要传入创建时传入的{callback}函数及{delay}间隔
//
//{callback}需要不断执行的tick函数
//{delay}间隔毫秒
function initWebWorker() {
PokeClickerHelper.Worker = {}
PokeClickerHelper.Worker.setInterval = function (callback, delay) {
let callbackList = this['intervalList' + delay]
if (callbackList == void 0) {
callbackList = new Set()
let workerURL = URL.createObjectURL(new Blob([`setInterval(()=>{postMessage('')},${delay})`]))
this.intervalWorker = new Worker(workerURL)
this.intervalWorker.onmessage = () => {
callbackList.forEach(i => i())
}
URL.revokeObjectURL(workerURL) //垃圾回收
this['intervalList' + delay] = callbackList
}
callbackList.add(callback)
}
PokeClickerHelper.Worker.setTimeout = function (callback, delay) {
let callbackList = this['timeoutList' + delay]
if (callbackList == void 0) {
callbackList = new Set()
let workerURL = URL.createObjectURL(new Blob([`(function Timeout(){postMessage('');setTimeout(Timeout,${delay})})()`]))
this.timeoutWorker = new Worker(workerURL)
this.timeoutWorker.onmessage = () => {
callbackList.forEach(i => i())
}
URL.revokeObjectURL(workerURL) //垃圾回收
this['timeoutList' + delay] = callbackList
}
callbackList.add(callback)
}
PokeClickerHelper.Worker.clearInterval = function (callback, delay) {
let callbackList = this['intervalList' + delay]
if (!callbackList) return
callbackList.delete(callback)
if (callbackList.size == 0) {
this.intervalWorker.terminate()
this['intervalList' + delay] = void 0
}
}
PokeClickerHelper.Worker.clearTimeout = function (callback, delay) {
let callbackList = this['timeoutList' + delay]
if (!callbackList) return
callbackList.delete(callback)
if (callbackList.size == 0) {
this.intervalWorker.terminate()
this['timeoutList' + delay] = void 0
}
}
}
///////////////////////
// 委托劫持class函数 //
///////////////////////
//委托劫持class,只委托脚本运行后无法直接访问需要额外new的class,不委托已经new过可直接访问的class,如:Battle、MapHelper
//调用方法:
//初始化委托劫持class函数:PokeClickerHelper.addHook({className},{fuction(new hookClass)}})
//{className} 委托劫持class函数名称
//{fuction(new hookClass)} 委托劫持的class函数对应的劫持方法,传参:劫持后的new hookClass
function initHook() {
PokeClickerHelper.hookLists = new Set()
PokeClickerHelper.addHook = function (className, hookFuc) {
if (PokeClickerHelper.hookLists.has(className)) {
PokeClickerHelper['hook' + className + 'List'].add(hookFuc)
} else {
PokeClickerHelper.hookLists.add(className)
PokeClickerHelper['hook' + className + 'List'] = new Set([hookFuc])
//eval may not harmful but useful(=_=!)
PokeClickerHelper['real' + className] = eval(className)
eval(className + '=' + function (...args) {
const hookedFuc = new PokeClickerHelper['real' + className](...args) //劫持class
PokeClickerHelper['hook' + className] = hookedFuc
PokeClickerHelper['hook' + className + 'List'].forEach(i => i(hookedFuc)) //调用委托劫持函数 传入劫持后的class
return hookedFuc
})
}
}
}
///////////////////////////////
// 委托劫持Game.gameTick函数 //
///////////////////////////////
//利用游戏原生Game.gameTick函数运行脚本定时代码
//(游戏默认100ms执行一次Game.gameTick函数 支持Web Worker较精确定时器)
//调用方法:
//委托增加gameTick执行函数:PokeClickerHelper.hookGameTickList.add({fuction})
//委托删除gameTick执行函数:PokeClickerHelper.hookGameTickList.delete({fuction})
//{function}委托gameTick执行函数
function initGameTickHook() {
PokeClickerHelper.hookGameTickList = new Set()
const gameTickHook = function (Game) {
Game.realGameTick = Game.gameTick
Game.gameTick = function () {
PokeClickerHelper.hookGameTickList.forEach(i => i()) //调用委托劫持Game.gameTick函数
Game.realGameTick()
}
}
//初始化劫持Game 并将委托劫持Game.gameTick函数加入到Game class劫持
PokeClickerHelper.addHook('Game', gameTickHook)
}
////////////////
// 可视化界面 //
////////////////
//同时机不同模块UI加载顺序根据油猴等脚本管理器加载顺序决定
//
//以油猴为例,
//核心模块运行时机为// @run-at document-start
//其余所有功能模块运行时机均应为// @run-at document-body
//无论脚本管理器中脚本序号,核心模块必定优先于功能模块加载
//而功能模块加载时机相同,因此功能模块UI加载顺序根据脚本管理器中功能模块脚本序号决定,序号越小加载越早
//
//若核心模块脚本序号为10,孵蛋模块脚本序号为1,自动地牢/道馆脚本序号为5,
// 加载顺序:核心模块→孵蛋模块→自动地牢/道馆模块。面板UI显示顺序:孵蛋模块→自动地牢/道馆模块
//若核心模块脚本序号为10,孵蛋模块脚本序号为4,自动地牢/道馆脚本序号为2,
// 加载顺序:核心模块→自动地牢/道馆模块→孵蛋模块。面板UI显示顺序:自动地牢/道馆模块→孵蛋模块
//调用方法:
//增加css样式:PokeClickerHelper.UIstyle({styleText})
//{styleText}仅style内css样式文字(不含<style>节点)
//
//增加#PokeClickerHelperBody内DOM元素:PokeClickerHelper.UIDOM({DOMText})
//{DOMText} DOM元素文字(需含子元素节点<div>等)
//
//增加 开始菜单=>设置=>Script标签页内DOM元素:PokeClickerHelper.UIScript({DOMText})
//{DOMText} DOM元素文字(需含子元素节点<tr>等)
//
//增加DOM元素监听事件:PokeClickerHelper.UIlistener.push({DOMlistener})
//{DOMlistener} DOM监听事件函数
//
//如果上述静态方法均无法满足需求,可尝试以下动态自定义方法
//增加动态自定义UI函数:PokeClickerHelper.UICustomFuc.push({UICustomFun})
//{UICustomFun} 自定义UI函数
//
//增加非#PokeClickerHelperBody UI面板:PokeClickerHelper.UIContainerID.push({UIContainerID})
//{UIContainerID} 自定义UI面板ID(增加后与#PokeClickerHelperBody适用相同方法)
function initUI() {
PokeClickerHelper.UIstyle = []
PokeClickerHelper.UIDOM = []
PokeClickerHelper.UIScript = [] //Author:猫猫
PokeClickerHelper.UIlistener = []
PokeClickerHelper.UICustomFuc = []
PokeClickerHelper.UIContainerID = ['#PokeClickerHelperContainer']
//TODO 先这样凑合用吧 摆烂 看着CSS就头疼
const style = `
#PokeClickerHelperContainer{z-index:1;font-family:"Open Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";position:absolute;top:38px;right:0;width:375px;background-color:white;opacity:.9;padding:10px;font-size:12px}
#PokeClickerHelperContainer button{margin-left:5px}
#PokeClickerHelperContainer .custom-row{margin-top:10px;display:flex}
#PokeClickerHelperContainer .form-group{margin-bottom:5px}
.labelContainer{width:93px;display:inline-block}
.contentContainer{flex:1;padding-left:0px;padding-right:0px}
.opacity-25{opacity: 0.25}
#PokeClickerHelperContainer input[type=checkbox]{position: absolute;margin-top: 0.24rem;margin-left: -1rem;}
`
PokeClickerHelper.UIcontainer = `
<div id="PokeClickerHelperContainer" class="shadow bg-white border border-primary" style="width: 375px; top: 50px; right: 10px;">
<div>
<div class="d-inline">
<label>完全隐藏(Shift+F12):</label>
</div>
<button id="PokeClickerHelperToggle" class="btn btn-sm btn-primary">隐藏</button>
</div>
<div class="mt-2 mb-1 border-top border-secondary"></div>
<div id="PokeClickerHelperBody">
</div>
</div>
`
//Author:猫猫
PokeClickerHelper.UIScriptTab = `<li class="nav-item"><a class="nav-link" href="#PokeClickerHelperSettings-Script" data-toggle="tab">Script</a></li>`
PokeClickerHelper.UIScriptTbody = `
<div class="tab-pane" id = "PokeClickerHelperSettings-Script">
<table class="table table-striped table-hover m-0">
<tbody id="PokeClickerHelperSettingsTbody">
</tbody>
</table>
</div>
`
const listener = function () {
//DOM元素监听事件 触发监听事件后自动存储DOM.value(button、input、select均以value存储)
const DOMlistener = function () {
if (this.dataset.save == 'false') return
if (this.nodeName == 'INPUT' && this.type == 'checkbox') this.value = this.checked
PokeClickerHelper.set(PokeClickerHelper.formatId(this), this.value)
}
PokeClickerHelper.UIContainerID.forEach(i => {
$(`${i} button`).on('click', DOMlistener)
$(`${i} input,${i} select`).on('change', DOMlistener)
})
$('#PokeClickerHelperToggle').on('click', function () {
if (this.value == '隐藏') {
$('#PokeClickerHelperContainer *:not(#PokeClickerHelperToggle):not(:has(#PokeClickerHelperToggle))').addClass('d-none')
$('#PokeClickerHelperToggle').text(this.value = '显示')
$('#PokeClickerHelperContainer').css('width', '75px')
} else {
$('#PokeClickerHelperContainer *:not(#PokeClickerHelperToggle):not(:has(#PokeClickerHelperToggle))').removeClass('d-none')
$('#PokeClickerHelperToggle').text(this.value = '隐藏')
$('#PokeClickerHelperContainer').css('width', '375px')
}
})
//拖拽 多重解构语法糖
document.querySelector("#PokeClickerHelperContainer").addEventListener('mousedown', function ({ x: Gx, y: Gy, which, target: { nodeName } }) {
if (which != 1 || nodeName == 'BUTTON' || nodeName == 'INPUT' || nodeName == 'SELECT') return
const that = this
const top = that.style.top.replace('px', '') * 1 - Gy
const right = that.style.right.replace('px', '') * 1 + Gx
const mousemove = function ({ x, y }) {
that.style.top = top + y + 'px'
that.style.right = right - x + 'px'
}
const mouseup = function ({ x, y }) {
this.removeEventListener('mousemove', mousemove)
this.removeEventListener('mouseup', mouseup)
x != Gx && PokeClickerHelper.set('top', that.style.top)
y != Gy && PokeClickerHelper.set('right', that.style.right)
}
document.addEventListener('mousemove', mousemove)
document.addEventListener('mouseup', mouseup)
})
//Shift+F12隐藏
document.addEventListener('keydown', ({ key, shiftKey }) => {
if (key == 'F12' && shiftKey) $("#PokeClickerHelperContainer").toggleClass('d-none')
})
}
PokeClickerHelper.UIstyle.push(style)
PokeClickerHelper.UIlistener.push(listener)
}
//读取DOM.value(button、input、select均以value存储)
PokeClickerHelper.UIsettings = function () {
const clickEvent = new Event('click')
const changeEvent = new Event('change')
PokeClickerHelper.UIContainerID.forEach(i => {
$(`${i} button,${i} input,${i} select`).each(UIsettings)
})
$("#PokeClickerHelperContainer").css({ 'top': PokeClickerHelper.set('top', '50px'), 'right': PokeClickerHelper.get('right', '10px') })
function UIsettings() {
let value = PokeClickerHelper.get(PokeClickerHelper.formatId(this))
if (value == void 0) return
this.value = value
switch (this.nodeName) {
case 'BUTTON': this.dispatchEvent(clickEvent); break
case "INPUT": {
if (this.type == "checkbox") {
this.checked = JSON.parse(value);
}
break
}
case 'SELECT': this.dispatchEvent(changeEvent); break
default: alert('UIsettings Error')
}
}
}
//去除DOM元素ID前缀(DOM元素ID应以PokeClickerHelper开头)
PokeClickerHelper.formatId = function (e) {
let id = e.id
if (!id.startsWith('PokeClickerHelper')) {
console.log(e, 'id规则错误,应以PokeClickerHelper开头\nlocalStorage读写失败')
alert(e.nodeName + ' id规则错误,应以PokeClickerHelper开头,详见控制台。\nlocalStorage读写失败')
throw new Error('id规则错误,应以PokeClickerHelper开头\nlocalStorage读写失败')
}
return id.replace(/^PokeClickerHelper/, '')
}
//加载UI
function appendUI() {
$('body').append('<style>' + PokeClickerHelper.UIstyle.join('\n') + '</style>' + PokeClickerHelper.UIcontainer)
$('#settingsModal .nav.nav-tabs').append(PokeClickerHelper.UIScriptTab) //Author:猫猫
$('#settingsModal .tab-content').eq(0).append(PokeClickerHelper.UIScriptTbody) //Author:猫猫
PokeClickerHelper.UIDOM.forEach(i => $('#PokeClickerHelperBody').append(i))
PokeClickerHelper.UIScript.forEach(i => $('#PokeClickerHelperSettingsTbody').append(i)) //Author:猫猫
PokeClickerHelper.UICustomFuc.forEach(i => i())
PokeClickerHelper.UIlistener.forEach(i => i())
PokeClickerHelper.UIsettings() //读取主面板UI DOM元素存储并设置、触发监听事件
}