// ==UserScript==
// @name 金庸群侠•大乱斗额外按钮
// @namespace http://tampermonkey.net/
// @version 0.6.161
// @description 金庸群侠•大乱斗便利性按钮插件:1.战斗中修改主角目标选择策略按钮;2.残卷使用数量+30按钮。
// @author Ymmzy
// @match https://zhouxiaobo1990.gitee.io/jyf/0.*
// @icon https://www.google.com/s2/favicons?sz=64&domain=gitee.io
// @grant none
// @run-at document-end
// @license MIT
// ==/UserScript==
const ELEMENT = {
navigator: {
selector: "#navigator"
},
dialogTitle: {
selector: "#actionDialog > div > div.mdc-dialog__container > div.mdc-dialog__surface > h2"
},
dialogConfirm: {
selector: "#actionDialog > div > div.mdc-dialog__container > div.mdc-dialog__surface > div.mdc-dialog__actions > button.acceptButton",
condition: ele => !document.querySelector("#actionDialog > div > div.mdc-dialog__container > div.mdc-dialog__surface > div.mdc-dialog__actions").classList.contains("hidden")
},
battleButtonContainer: {
selector: "#battleUiPage > div.pixiContainer > div.bottomLeftBar"
},
battleSetting: {
selector: "#battleUiPage > div.pixiContainer > div.topRightBar > button.settingsButton"
},
battleSettingTarget: {
selector: "#actionDialog > div > div.mdc-dialog__container > div.mdc-dialog__surface > div.mdc-dialog__content > div > div > button",
text: "目标选择策略"
},
battleSettingBack: {
selector: "#actionDialog > div > div.mdc-dialog__container > div.mdc-dialog__surface > div.mdc-dialog__content > div > div > button",
text: "返回"
},
battleTargetItem: {
selector: "#actionDialog > div > div.mdc-dialog__container > div.mdc-dialog__surface > div.mdc-dialog__content > div > div:nth-child(1) > div > div > div.mdc-select__menu > ul > li"
},
itemTitle: {
selector: "#inspectItemsPage > main > div > div.jyfPageTemplate.mainContent > div.description > div.name"
},
itemNumberLabel: {
selector: "#actionDialog > div > div.mdc-dialog__container > div.mdc-dialog__surface > div.mdc-dialog__content > div > div > div > label"
},
itemNumberInput: {
selector: "#actionDialog > div > div.mdc-dialog__container > div.mdc-dialog__surface > div.mdc-dialog__content > div > div > div > label > input"
}
};
function getEle({selector, text, condition}) {
const eles = document.querySelectorAll(selector);
for (const ele of eles) {
if (ele && ele.style.display !== 'none' && (!text || ele.textContent.includes(text)) && (!condition || condition(ele))) return ele;
}
return null;
}
async function waitEle({selector, text, condition}) {
let ele = null;
let time = 100;
await new Promise(resolve => {
const timer = setInterval(() => {
if ((ele = getEle({selector, text, condition}))) {
clearInterval(timer);
resolve();
}
if (!time--) {
console.warn("Timeout:", {selector, text, condition});
resolve();
}
}, 10);
});
return ele;
}
async function clickEle({selector, text, condition}) {
let ele = await waitEle({selector, text, condition});
ele && ele.click();
}
function createEle(parent, type, classes, text) {
const ele = document.createElement(type);
if (classes && classes.length > 0) ele.classList.add(...classes);
if (text) ele.innerText = text;
if (parent) parent.appendChild(ele);
return ele;
}
//残卷+30按钮
function initAddThirtyButton() {
const dialogTitle = getEle(ELEMENT.dialogTitle);
const config = {
childList: true,
subtree: true
};
const mutationObserver = new MutationObserver(async (mutationsList, observer) => {
for (const mutation of mutationsList) {
if (mutation.type === 'childList' && mutation.target === dialogTitle && mutation.addedNodes.length > 0) {
const addedNode = mutation.addedNodes[0];
if (addedNode.nodeType === Node.TEXT_NODE && addedNode.textContent.match(/使用.+残卷/)) {
observer.disconnect();
const label = await waitEle(ELEMENT.itemNumberLabel);
const btn = createEle(label, "button", ["maxValueButton", "mdc-icon-button"], "+30");
btn.style.alignSelf = "center";
btn.style.display = "flex";
btn.style.justifyContent = "center";
btn.style.alignItems = "center";
btn.style.fontSize = "18px";
btn.onclick = () => {
//获取持有数量
const item = getEle(ELEMENT.itemTitle);
const match = item.innerText.match(/剩余:([\d]+)/);
if (match) {
const max = Number(match[1]);
const input = getEle(ELEMENT.itemNumberInput);
input.value = Math.min(max, (Math.floor(input.value / 30) + 1) * 30);
}
};
observer.observe(dialogTitle, config);
}
}
}
});
mutationObserver.observe(dialogTitle, config);
}
//战斗目标策略按钮
function initBattleControlButton() {
const battleButtonContainer = getEle(ELEMENT.battleButtonContainer);
let lock = false;
const createBattleControlButton = (text, act, x, y) => {
const btn = createEle(battleButtonContainer, "button", ["mdc-icon-button", "battle-control-button"], text);
btn.onclick = async () => {
if (lock) return;
lock = true;
await clickEle(ELEMENT.battleSetting);
const battleTarget = await waitEle(ELEMENT.battleSettingTarget);
//目标策略按钮是否可见
if (!battleTarget.parentElement.classList.contains("hidden")) {
battleTarget.click();
await clickEle({...ELEMENT.battleTargetItem, text: act});
await clickEle(ELEMENT.dialogConfirm);
} else await clickEle(ELEMENT.battleSettingBack);
lock = false;
};
const biasX = 52 * x;
const biasY = 52 * y;
btn.style.left = biasX + "px";
btn.style.bottom = biasY + "px";
btn.style.position = "absolute";
btn.style.fontSize = "18px";
};
createBattleControlButton("北", "向北移动", 1, 2);
createBattleControlButton("南", "向南移动", 1, 0);
createBattleControlButton("西", "向西移动", 0, 1);
createBattleControlButton("东", "向东移动", 2, 1);
createBattleControlButton("近", "最近的敌人", 1, 1);
}
(async function () {
'use strict';
await waitEle(ELEMENT.navigator);
initAddThirtyButton();
initBattleControlButton();
console.log("===== extra buttons =====");
})();