@@ -350,6 +350,45 @@ async function naturalMove(initX, initY, targetX, targetY, duration, wiggle = 30
350350 moveMouseTo ( targetX , targetY ) ;
351351}
352352
353+ // 定义一个独立的函数用于在指定区域进行 OCR 识别并输出识别内容
354+ async function recognizeTextInRegion ( captureRegion , ocrRegion , timeout = 5000 ) {
355+ let startTime = Date . now ( ) ;
356+ let retryCount = 0 ; // 重试计数
357+ while ( Date . now ( ) - startTime < timeout ) {
358+ try {
359+ // 在指定区域进行 OCR 识别
360+ let ocrResult = captureRegion . find ( RecognitionObject . ocr ( ocrRegion . x , ocrRegion . y , ocrRegion . width , ocrRegion . height ) ) ;
361+ if ( ocrResult ) {
362+ // 后处理:根据替换映射表检查和替换错误识别的字符
363+ let correctedText = ocrResult . text ;
364+ return correctedText ; // 返回识别到的内容
365+ } else {
366+ log . warn ( `OCR 识别区域未找到内容` ) ;
367+ return null ; // 如果 OCR 未识别到内容,返回 null
368+ }
369+ } catch ( error ) {
370+ retryCount ++ ; // 增加重试计数
371+ log . warn ( `OCR 摩拉数识别失败,正在进行第 ${ retryCount } 次重试...` ) ;
372+ }
373+ await sleep ( 500 ) ; // 短暂延迟,避免过快循环
374+ }
375+ log . warn ( `经过多次尝试,仍然无法在指定区域识别到文字` ) ;
376+ return null ; // 如果未识别到文字,返回 null
377+ }
378+ async function getMora ( captureRegion ) {
379+ let ocrRegionMora = { x : 1606 , y : 28 , width : 164 , height : 40 } ; // 设置对应的识别区域
380+ let recognizedText = await recognizeTextInRegion ( captureRegion , ocrRegionMora ) ;
381+ log . debug ( `成功识别到摩拉数值: ${ recognizedText } ` ) ;
382+ try {
383+ recognizedText = recognizedText . replace ( / [ , , ] / g, '' ) ; // 移除逗号
384+ recognizedText = parseInt ( recognizedText , 10 ) ; // 转换为整数
385+ return recognizedText ;
386+ } catch ( error ) {
387+ log . warn ( `解析摩拉数值时发生错误: ${ error . message } ` ) ;
388+ }
389+ return null ;
390+ }
391+
353392// 切换下一页商品
354393async function nextGoodsPage ( ) {
355394 //设置脚本环境的游戏分辨率和DPI缩放
@@ -448,13 +487,43 @@ async function spikChat(npcName) {
448487 await sleep ( 1000 ) ;
449488}
450489
451- // 购买逻辑
490+ let initialMora = null ;
491+ let maxMora = null ;
492+ if ( settings . _maxMora && settings . _maxMora . trim ( ) !== "" ) {
493+ try {
494+ maxMora = parseInt ( settings . _maxMora ) ;
495+ if ( isNaN ( maxMora ) ) {
496+ throw "最大摩拉数值必须是数字或留空" ;
497+ }
498+ } catch ( error ) {
499+ log . warn ( `解析最大摩拉数值时发生错误: ${ error . message } ` ) ;
500+ throw `解析最大摩拉数值时发生错误: ${ error . message } ` ;
501+ }
502+ log . info ( "设置最大使用摩拉数值: {maxMora}" , maxMora ) ;
503+ } else {
504+ log . info ( "未设置最大使用摩拉数值,购买时不做限制" ) ;
505+ }
506+
507+
508+ // 购买逻辑,返回true时停止购买
452509async function buyGoods ( npcName ) {
453510 // 设置脚本环境的游戏分辨率和DPI缩放
454511 setGameMetrics ( 3840 , 2160 , 1.5 ) ;
455512
456513 let tempGoods = [ ...npcData [ npcName ] . enableGoods ] ;
457-
514+ if ( maxMora !== null ) {
515+ // 需要识别初始摩拉数值
516+ if ( initialMora === null ) {
517+ log . info ( "正在识别初始摩拉数值" ) ;
518+ let captureRegion = captureGameRegion ( ) ;
519+ initialMora = await getMora ( captureRegion ) ;
520+ if ( initialMora === null ) {
521+ log . info ( "无法识别当前摩拉数值,本次购买时不做限制" ) ;
522+ } else {
523+ log . info ( "识别到初始摩拉数值: {initialMora}" , initialMora ) ;
524+ }
525+ }
526+ }
458527 // 多页购买
459528 for ( let i = 0 ; i < npcData [ npcName ] . page ; i ++ ) {
460529 log . info ( "购买列表: {goods}" , [ ...tempGoods ] . join ( ", " ) ) ;
@@ -479,6 +548,23 @@ async function buyGoods(npcName) {
479548 await sleep ( 500 ) ;
480549 // 重新截图
481550 captureRegion = captureGameRegion ( ) ;
551+
552+ if ( maxMora !== null && initialMora !== null ) {
553+ // 识别当前摩拉数值
554+ let mora = await getMora ( captureRegion ) ;
555+ if ( mora === null ) {
556+ log . info ( "无法识别摩拉数值,继续购买下一件商品" ) ;
557+ }
558+ let currentSpent = initialMora - mora ;
559+ log . info ( `当前摩拉已花费: ${ currentSpent } ,剩余预算: ${ maxMora - currentSpent } ` ) ;
560+ if ( currentSpent >= maxMora ) {
561+ log . info ( "已达到最大使用摩拉数值,停止购买" ) ;
562+ return true ;
563+ }
564+ } else {
565+ log . info ( "未设置最大摩拉数值,继续购买下一件商品" ) ;
566+ }
567+
482568 }
483569 else {
484570 log . info ( "购买失败: {item}, 背包已经满或商品已售罄" , goodsData [ item ] . name ) ;
@@ -501,6 +587,7 @@ async function buyGoods(npcName) {
501587 await sleep ( 500 ) ;
502588 }
503589 }
590+ return false ;
504591 }
505592}
506593
@@ -575,10 +662,14 @@ async function initRo() {
575662 }
576663 await autoPath ( npc . path ) ;
577664 await spikChat ( npc . name ) ;
578- await buyGoods ( key ) ;
665+ const needStop = await buyGoods ( key ) ;
579666 // 返回主界面
580667 await genshin . returnMainUi ( ) ;
581668 log . info ( "完成购买NPC: {npcName}" , npc . name ) ;
669+ if ( needStop ) {
670+ log . info ( "达到最大使用摩拉数值,停止后续购买" ) ;
671+ break ;
672+ }
582673 }
583674 else {
584675 log . info ( "跳过未启用的NPC: {npcName}" , npc . name ) ;
0 commit comments