您需要先安装一款用户样式管理器扩展(如 Stylus)后才能安装此样式。
您需要先安装一款用户样式管理器扩展(如 Stylus)后才能安装此样式。
您需要先安装一款用户样式管理器扩展(如 Stylus)后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
(我已经安装了用户样式管理器,让我安装!)
// ==UserScript==
// @name Theresmore自动点击工具
// @namespace Theresmore自动点击工具
// @match https://theresmoregame.g8hh.com/
// @grant none
// @version 1.1
// @author zty
// @description 解放你的双手自动自动点击工具
// @license MIT
// ==/UserScript==
; (function () {
const timeout = 1000 * 10 // 10秒点一次
const minFood = 2 // 食物最小值
let blackList = initBlackList() // 部分只能建造一个的建筑需要跳过
const houseList = ['房屋', '市政厅', '宅邸', '住宅区', '发展部', '定居点大厅'] // 会减少食物的建筑
function initBlackList() {
return ['雕像', '心灵神殿', '战争神殿', '月明之夜', '光荣退休']
}
var css = `
#auto_update_btn {
position: fixed;
right: 0;
bottom: 64px;
background: #1d1e20;
border-radius: 50%;
height: 32px;
width: 32px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-size: 14px;
border: 2px solid white;
z-index: 100;
color: white;
cursor: pointer;
}
`
/*添加样式*/
function addStyle(css) {
if (!css) return
var head = document.querySelector('head')
var style = document.createElement('style')
style.type = 'text/css'
style.innerHTML = css
head.appendChild(style)
}
/*生成自动升级建筑的按钮*/
function createBtn() {
var btn = document.createElement('div')
btn.title = '开'
var span = document.createElement('span')
span.innerText = '开'
btn.appendChild(span)
btn.id = 'auto_update_btn'
document.body.appendChild(btn)
/*初始化事件*/
// 点击按钮启动定时器
btn.addEventListener('click', function () {
toggleBtnStatus()
toggleBtnText()
})
}
// 切换文字
function toggleBtnText() {
const node = document.querySelector('#auto_update_btn')
const text = node.innerText
node.innerText = text === '开' ? '关' : '开'
}
// 自动升级建筑
function autoBuild() {
const tabListNode = document
.querySelector('#main-tabs')
.querySelector(`div[role=tablist]`)
const tabNode = tabListNode.childNodes[0]
const flag = tabNode && tabNode.getAttribute('aria-selected') === 'true'
if (!flag) {
console.log('没找到容器,即将切换到“建造”页')
// 自动切换到建造tab页
tabNode && tabNode.click()
} else {
const id = tabNode.getAttribute('aria-controls')
const containerNode = document.getElementById(id)
const list = containerNode.querySelectorAll(`button.btn`)
const subTabNodes = containerNode.querySelector(`div[role=tablist]`)
let isAllUpdatedInThisTab = false
// judgeFood() // 食物小于${minFood}时不建造房屋
for (const [i, node] of list.entries()) {
let hasClick = false
if (
!node.classList.value.includes('btn-off') &&
!blackList.some((word) => node.textContent.includes(word))
) {
console.log(`${new Date().toLocaleString()}建造:`, node.textContent)
node.click()
hasClick = true
return true
}
isAllUpdatedInThisTab = i === list.length - 1 && !hasClick
}
return false
// console.log('当前页是否全部升级:', isAllUpdatedInThisTab)
// if (isAllUpdatedInThisTab && subTabNodes) {
// // 如果当前页全部升级了,切换到另一个建筑页,按顺序往后切换,如果当前是最后一个tab,则切换回第一个tab
// const currentSubTab = subTabNodes.querySelector(
// `button[aria-selected=true]`
// ) // 当前选中的子tab页
// const nextTab = currentSubTab.nextElementSibling
// if (nextTab) {
// console.log(`切换到${nextTab.textContent}`)
// nextTab.click()
// } else {
// const target = subTabNodes.childNodes[0]
// console.log(`切换到${target.textContent}`)
// target.click()
// }
// }
}
}
// 自动研究
function autoResearch() {
const tabListNode = document
.querySelector('#main-tabs')
.querySelector(`div[role=tablist]`)
const tabNode = tabListNode.childNodes[1]
const flag = tabNode && tabNode.getAttribute('aria-selected') === 'true'
if (!flag) {
console.log('没找到容器,即将切换到“研究”页')
tabNode && tabNode.click()
} else {
const id = tabNode.getAttribute('aria-controls')
const containerNode = document.getElementById(id)
const list = containerNode.querySelectorAll(`button.btn`)
const subTabNodes = containerNode.querySelector(`div[role=tablist]`)
let isAllUpdatedInThisTab = false
for (const [i, node] of list.entries()) {
let hasClick = false
if (
!node.classList.value.includes('btn-off') &&
!blackList.some((word) => node.textContent.includes(word))
) {
console.log(`${new Date().toLocaleString()}研究:`, node.textContent)
node.click()
hasClick = true
return true
}
isAllUpdatedInThisTab = i === list.length - 1 && !hasClick
}
}
return false
}
// 自动调整工人
function autoTuneWorker() {
const tabListNode = document
.querySelector('#main-tabs')
.querySelector(`div[role=tablist]`)
const tabNode = tabListNode.childNodes[2]
var list = document.querySelector('table').querySelectorAll('tr')
var rscRatioMap = new Map();
for (var node of list) {
var name = node.childNodes[0].innerText
var dataStrs = node.childNodes[1].innerText.split('/')
var cur = Number(dataStrs[0].replace(',', ''))
var cap = Number(dataStrs[1].replace(',', ''))
var ratio = cur / cap
rscRatioMap.set(name, ratio)
// console.log('资源情况:', name, ratio)
}
// avoid humen resource occupied by professor.
rscRatioMap.set('研究点', 1)
const id = tabNode.getAttribute('aria-controls')
const containerNode = document.getElementById(id)
list = containerNode.querySelectorAll(`div.sub-container div.p-4`)
var maxIdx = 0
var maxVal = 0
var minIdx = 0
var minVal = 1
for (const [i, node] of list.entries()) {
var div1 = node.querySelector('div.flex-1')
name = div1.querySelector('h5').innerText
var rscNameTds = div1.querySelectorAll('td.text-left')
var rscSpeedTds = div1.querySelectorAll('td.text-right')
var minRatio = 1
for (let index = 0; index < rscNameTds.length; index++) {
var rscName = rscNameTds[index].innerText
var rscSpeed = rscSpeedTds[index].innerText
if (rscSpeed.includes('-')) {
continue
}
var ratio = rscRatioMap.get(rscName) || 0
if (ratio < minRatio) {
minRatio = ratio
}
}
dataStrs = node.querySelector('div.relative input').getAttribute('value').split('/')
cur = Number(dataStrs[0].trim())
cap = Number(dataStrs[1].trim())
var maxPermit = name == '农民' ? judgeFood() : true
// var minPermit = name == '农民' ? !judgeFood() : true
if (minRatio > maxVal && cur > 0 && maxPermit) {
maxIdx = i
maxVal = minRatio
}
if (minRatio < minVal && cur < cap) {
minIdx = i
minVal = minRatio
}
}
// ensure food wont run out.
if (rscRatioMap.get('食物') < 0.2) {
minIdx = 0
}
node = list[maxIdx]
name = node.querySelector('div.flex-1').querySelector('h5').innerText
var lessBtn = node.querySelector('div.relative').querySelectorAll('button.rounded-none')[0]
lessBtn.click()
console.log('减少人力:', name)
node = list[minIdx]
name = node.querySelector('div.flex-1').querySelector('h5').innerText
var moreBtn = node.querySelector('div.relative').querySelectorAll('button.rounded-none')[1]
setTimeout(() => {
console.log('增加人力1:', name)
moreBtn.click()
}, 500)
setTimeout(() => {
console.log('增加人力2:', name)
moreBtn.click()
}, 1000)
return true
}
// 自动祈祷
function autoMagic() {
const tabListNode = document
.querySelector('#main-tabs')
.querySelector(`div[role=tablist]`)
const tabNode = tabListNode.childNodes[3]
var flag = tabNode && tabNode.getAttribute('aria-selected') === 'true'
if (!flag) {
console.log('没找到容器,即将切换到“魔法”页')
tabNode && tabNode.click()
} else {
const id = tabNode.getAttribute('aria-controls')
const containerNode = document.getElementById(id)
const subTabNodes = containerNode.querySelector(`div[role=tablist]`)
const prayNode = subTabNodes.childNodes[1]
flag = prayNode && prayNode.getAttribute('aria-selected') === 'true'
if (!flag) {
prayNode && prayNode.click()
return
}
const list = containerNode.querySelectorAll(`button.btn`)
let isAllUpdatedInThisTab = false
for (const [i, node] of list.entries()) {
let hasClick = false
if (
!node.classList.value.includes('btn-off') &&
!blackList.some((word) => node.textContent.includes(word))
) {
console.log(`${new Date().toLocaleString()}祈祷:`, node.textContent)
node.click()
hasClick = true
return true
}
isAllUpdatedInThisTab = i === list.length - 1 && !hasClick
}
}
return false
}
let buildingInterval = null
let mode = 0
let maxMode = 3
let checkTime = 0
function checkTab() {
const tabListNode = document
.querySelector('#main-tabs')
.querySelector(`div[role=tablist]`)
if (tabListNode.childNodes.length <= mode) {
mode = 0
return false
}
if (maxMode == 3 && tabListNode.childNodes.length >= 6) {
// open autoMagic
maxMode = 4
}
const tabNode = tabListNode.childNodes[mode]
const flag = tabNode && tabNode.getAttribute('aria-selected') === 'true'
if (!flag && checkTime < 12) {
console.log('需要切换到tab:' + mode)
checkTime += 1
return true
}
checkTime = 0
return false
}
function switchTab() {
const tabListNode = document
.querySelector('#main-tabs')
.querySelector(`div[role=tablist]`)
if (tabListNode.childNodes.length <= mode) {
mode = 0
return false
}
const tabNode = tabListNode.childNodes[mode]
const flag = tabNode && tabNode.getAttribute('aria-selected') === 'true'
if (!flag) {
console.log('切换到tab:' + mode)
tabNode && tabNode.click()
}
}
let modeMaxSkipTimes = new Map()
let modeSkipTimes = new Map()
function autoHelpler() {
closeDialog()
if (checkTab()) return
let rst = false
switch (mode) {
case 0:
rst = autoBuild()
break;
case 1:
rst = autoResearch()
break;
case 2:
rst = autoTuneWorker()
break;
case 3:
rst = autoMagic()
break;
default:
break;
}
var maxSkipTime = modeMaxSkipTimes.get(mode) || 0
if (rst) {
modeMaxSkipTimes.set(mode, Math.max(0, maxSkipTime - 1))
} else {
modeMaxSkipTimes.set(mode, Math.min(10, maxSkipTime + 1))
console.log('设置模式跳过', mode, modeMaxSkipTimes.get(mode))
}
setTimeout(() => {
if (checkTab()) return
while (true) {
mode += 1
mode %= maxMode
var maxSkipTime = modeMaxSkipTimes.get(mode) || 0
var skipTime = modeSkipTimes.get(mode) || 0
if (skipTime < maxSkipTime) {
modeSkipTimes.set(mode, skipTime + 1)
} else {
modeSkipTimes.set(mode, 0)
break
}
}
switchTab()
}, timeout / 2);
}
// 开启自动升级建筑定时器
function handleAutoUpdateStart() {
buildingInterval = setInterval(autoHelpler, timeout)
}
// 清除自动升级建筑定时器
function handleAutoUpdateClear() {
buildingInterval = clearInterval(buildingInterval)
}
// 切换自动升级建筑定时器状态
function toggleBtnStatus() {
if (buildingInterval) {
console.log('~~~~关闭定时器~~~~')
handleAutoUpdateClear()
} else {
console.log('~~~~开启定时器~~~~')
handleAutoUpdateStart()
}
}
// 判断食物数量
// function judgeFood() {
// var list = document.querySelector('table').querySelectorAll('tr')
// for (var node of list) {
// if (!node.innerText.includes('食物')) continue
// // 获取食物速度
// var val = Number(node.childNodes[2].innerText.split('/')[0])
// if (val < minFood) {
// blackList.push(...houseList)
// } else {
// blackList = initBlackList()
// }
// }
// }
function judgeFood() {
var list = document.querySelector('table').querySelectorAll('tr')
for (var node of list) {
if (!node.innerText.includes('食物')) continue
// 获取食物速度
var val = Number(node.childNodes[2].innerText.split('/')[0])
return val > minFood
}
}
// 关闭dialog
function closeDialog() {
const dialogNode = document.querySelector('#headlessui-portal-root')
dialogNode && dialogNode.querySelector('.sr-only').parentNode.click()
}
createBtn()
addStyle(css)
})()