mirror of
https://github.com/babalae/bettergi-scripts-list.git
synced 2026-03-25 04:59:52 +08:00
feat(义父立本): 添加UID识别和防重复执行功能 (#2633)
* feat(义父立本): 添加UID识别和防重复执行功能 - 集成OCR UID识别功能,自动获取当前游戏UID - 添加execute.json文件记录执行状态,防止同一天重复执行 - 实现日期检查逻辑,已执行的UID当天不再运行 - 新增utils/uid.js工具模块,包含完整的UID识别和验证功能 - 升级版本号从1.0到1.1 - 添加云端客作为贡献者 - 优化代码格式和错误处理机制 * refactor(date): 调整日期获取逻辑以支持时区偏移 - 将 getCurrentDate 函数重命名为 getAdjustedDate - 实现4小时时区偏移调整功能(立本4点更新) - 使用手动格式化替代 toLocaleDateString 方法 - 更新函数调用以使用新的日期调整逻辑
This commit is contained in:
BIN
repo/js/义父立本/assets/RecognitionObject/paimon_menu.png
Normal file
BIN
repo/js/义父立本/assets/RecognitionObject/paimon_menu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
7
repo/js/义父立本/execute.json
Normal file
7
repo/js/义父立本/execute.json
Normal file
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"uid": 0,
|
||||
"success": false,
|
||||
"date": ""
|
||||
}
|
||||
]
|
||||
@@ -1,5 +1,35 @@
|
||||
eval(file.readTextSync(`utils/uid.js`));
|
||||
let checkInterval = +settings.checkInterval || 50;
|
||||
let waitTime = 40;
|
||||
|
||||
function getAdjustedDate() {
|
||||
const now = new Date();
|
||||
// 减去4小时(4 * 60 * 60 * 1000 毫秒)
|
||||
now.setHours(now.getHours() - 4);
|
||||
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
|
||||
|
||||
// 更新json文件
|
||||
async function updateFile(settingsArray, path) {
|
||||
let json = JSON.stringify(settingsArray, null, 2)
|
||||
.replaceAll(']"', ']')
|
||||
.replaceAll('"[', '[')
|
||||
.replaceAll('\\"', '"')
|
||||
.replaceAll('\\\\n', '\\n')
|
||||
// warn("settings==>"+json, true)
|
||||
// 写入更新后的设置
|
||||
const success = file.writeTextSync(path, json);
|
||||
if (!success) {
|
||||
throw new Error("写入设置文件失败");
|
||||
}
|
||||
}
|
||||
|
||||
(async function () {
|
||||
//启用自动剧情
|
||||
//dispatcher.addTimer(new RealtimeTimer("AutoSkip"));
|
||||
@@ -9,6 +39,18 @@ let waitTime = 40;
|
||||
log.warn("游戏窗口非 1920×1080,可能导致图像识别失败,如果执意使用可能造成异常,后果自负");
|
||||
await sleep(5000);
|
||||
}
|
||||
|
||||
let executeJson = "execute.json"
|
||||
let execute = JSON.parse(file.readTextSync(executeJson));
|
||||
let uid = await uidUtil.ocrUID();
|
||||
let currentDate = getAdjustedDate();
|
||||
for (const uidElement of execute) {
|
||||
if (uidElement.uid === uid && uidElement.date === currentDate) {
|
||||
log.info("UID:{uid} 今天已经立本过了", uid);
|
||||
return
|
||||
}
|
||||
}
|
||||
let executeList = execute ? execute : new Array()
|
||||
while (attempts < 3) {
|
||||
attempts++;
|
||||
await pathingScript.runFile(`assets/前往立本.json`);
|
||||
@@ -36,6 +78,13 @@ let waitTime = 40;
|
||||
}
|
||||
}
|
||||
|
||||
executeList.push({
|
||||
uid: uid,
|
||||
success: success,//冗余
|
||||
date: currentDate
|
||||
})
|
||||
await updateFile(executeList, executeJson)
|
||||
|
||||
if (!success) {
|
||||
log.error("3次重试均失败");
|
||||
}
|
||||
@@ -62,8 +111,16 @@ async function findAndClick(target, doClick = true, maxAttempts = 60) {
|
||||
const rg = captureGameRegion();
|
||||
try {
|
||||
const res = rg.find(target);
|
||||
if (res.isExist()) { await sleep(checkInterval * 2 + 50); if (doClick) { res.click(); } return true; }
|
||||
} finally { rg.dispose(); }
|
||||
if (res.isExist()) {
|
||||
await sleep(checkInterval * 2 + 50);
|
||||
if (doClick) {
|
||||
res.click();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} finally {
|
||||
rg.dispose();
|
||||
}
|
||||
if (i < maxAttempts - 1) await sleep(checkInterval);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"name": "义父立本",
|
||||
"version": "1.0",
|
||||
"version": "1.1",
|
||||
"bgi_version": "0.44.8",
|
||||
"description": "谢谢老板",
|
||||
"saved_files": [],
|
||||
@@ -9,6 +9,10 @@
|
||||
{
|
||||
"name": "mno",
|
||||
"links": "https://github.com/Bedrockx"
|
||||
},
|
||||
{
|
||||
"name": "云端客",
|
||||
"links": "https://github.com/Kirito520Asuna"
|
||||
}
|
||||
],
|
||||
"settings_ui": "settings.json",
|
||||
|
||||
145
repo/js/义父立本/utils/uid.js
Normal file
145
repo/js/义父立本/utils/uid.js
Normal file
@@ -0,0 +1,145 @@
|
||||
const commonPath = 'assets/RecognitionObject/'
|
||||
const commonMap = new Map([
|
||||
['main_ui', {
|
||||
path: `${commonPath}`,
|
||||
name: 'paimon_menu',
|
||||
type: '.png',
|
||||
}],
|
||||
])
|
||||
const genshinJson = {
|
||||
width: 1920,//genshin.width,
|
||||
height: 1080,//genshin.height,
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据键值获取JSON路径
|
||||
* @param {string} key - 要查找的键值
|
||||
* @returns {any} 返回与键值对应的JSON路径值
|
||||
*/
|
||||
function getJsonPath(key) {
|
||||
return commonMap.get(key); // 通过commonMap的get方法获取指定键对应的值
|
||||
}
|
||||
|
||||
function saveOnlyNumber(str) {
|
||||
str = str ? str : '';
|
||||
// 使用正则表达式匹配字符串中的所有数字
|
||||
// \d+ 匹配一个或多个数字
|
||||
// .join('') 将匹配到的数字数组连接成一个字符串
|
||||
// parseInt 将连接后的字符串转换为整数
|
||||
return parseInt(str.match(/\d+/g).join(''));
|
||||
}
|
||||
|
||||
async function ocrUID() {
|
||||
let uid_json = {
|
||||
x: 1683,
|
||||
y: 1051,
|
||||
width: 234,
|
||||
height: 28,
|
||||
}
|
||||
let recognitionObjectOcr = RecognitionObject.Ocr(uid_json.x, uid_json.y, uid_json.width, uid_json.height);
|
||||
let region3 = captureGameRegion()
|
||||
try {
|
||||
let res = region3.find(recognitionObjectOcr);
|
||||
log.debug(`[OCR识别UID]识别结果: ${res.text}, 原始坐标: x=${res.x}, y=${res.y},width:${res.width},height:${res.height}`);
|
||||
//只保留数字
|
||||
let uid
|
||||
try {
|
||||
uid = saveOnlyNumber(res.text)
|
||||
} catch (e) {
|
||||
log.debug(`UID未识别`)
|
||||
uid = 0
|
||||
}
|
||||
log.debug(`[OCR识别UID]识别结果: {uid}`, uid);
|
||||
return uid
|
||||
}finally {
|
||||
region3.dispose()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 判断是否在主界面的函数
|
||||
const isInMainUI = () => {
|
||||
// let name = '主界面'
|
||||
let main_ui = getJsonPath('main_ui');
|
||||
// 定义识别对象
|
||||
let paimonMenuRo = RecognitionObject.TemplateMatch(
|
||||
file.ReadImageMatSync(`${main_ui.path}${main_ui.name}${main_ui.type}`),
|
||||
0,
|
||||
0,
|
||||
genshinJson.width / 3.0,
|
||||
genshinJson.width / 5.0
|
||||
);
|
||||
let captureRegion = captureGameRegion();
|
||||
let res = captureRegion.find(paimonMenuRo);
|
||||
captureRegion.Dispose()
|
||||
return !res.isEmpty();
|
||||
};
|
||||
|
||||
async function toMainUi() {
|
||||
let ms = 1000
|
||||
let index = 1
|
||||
await sleep(ms);
|
||||
while (!isInMainUI()) {
|
||||
await sleep(ms);
|
||||
await genshin.returnMainUi(); // 如果未启用,则返回游戏主界面
|
||||
await sleep(ms);
|
||||
if (index > 3) {
|
||||
throw new Error(`多次尝试返回主界面失败`);
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function compareUid(UID = settings.uid) {
|
||||
let uid = await ocrUID()
|
||||
let setUid = 0
|
||||
try {
|
||||
setUid = saveOnlyNumber(UID)
|
||||
} catch (e) {
|
||||
// log.warn(`UID未设置`)
|
||||
}
|
||||
let compare = uid === setUid
|
||||
if (compare) {
|
||||
log.info(`[OCR识别UID]识别结果: {uid} 与设置UID相同`, uid);
|
||||
}
|
||||
return compare
|
||||
}
|
||||
|
||||
async function checkUid() {
|
||||
let reJson = {
|
||||
inMainUI: false,
|
||||
isUid: false
|
||||
}
|
||||
if (isInMainUI()) {
|
||||
reJson.isUid = await compareUid()
|
||||
}
|
||||
return reJson
|
||||
}
|
||||
|
||||
async function check() {
|
||||
let check = false
|
||||
if (settings.uid) {
|
||||
try {
|
||||
await toMainUi();
|
||||
} catch (e) {
|
||||
log.warn("多次尝试返回主界面失败")
|
||||
}
|
||||
let checkJson = await checkUid()
|
||||
if ((!checkJson.inMainUI) && (!checkJson.isUid)) {
|
||||
//尝试直接识别
|
||||
checkJson.isUid = await compareUid()
|
||||
}
|
||||
check = checkJson.isUid
|
||||
}
|
||||
return check
|
||||
}
|
||||
|
||||
this.uidUtil = {
|
||||
toMainUi,
|
||||
isInMainUI,
|
||||
checkUid,
|
||||
ocrUID,
|
||||
check,
|
||||
compareUid,
|
||||
}
|
||||
Reference in New Issue
Block a user