mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-03-15 07:43:20 +08:00
fix auto genius invokation
This commit is contained in:
@@ -18,7 +18,7 @@ public partial class AutoGeniusInvokationConfig : ObservableObject
|
||||
|
||||
[ObservableProperty] private int _sleepDelay = 0;
|
||||
|
||||
public List<Rect> DefaultCharacterCardRects { get; set; } = new List<Rect>()
|
||||
public List<Rect> DefaultCharacterCardRects { get;} = new List<Rect>()
|
||||
{
|
||||
new(667, 632, 165, 282),
|
||||
new(877, 632, 165, 282),
|
||||
@@ -29,26 +29,25 @@ public partial class AutoGeniusInvokationConfig : ObservableObject
|
||||
/// <summary>
|
||||
/// 骰子数量文字识别区域
|
||||
/// </summary>
|
||||
public Rect MyDiceCountRect { get; set; } = new(58, 632, 45, 47); // 42,47
|
||||
public Rect MyDiceCountRect { get; } = new(58, 632, 45, 47); // 42,47
|
||||
|
||||
/// <summary>
|
||||
/// 角色卡牌区域向左扩展距离,包含HP区域
|
||||
/// </summary>
|
||||
public int CharacterCardLeftExtend { get; set; } = 20;
|
||||
public int CharacterCardLeftExtend { get; } = 20;
|
||||
|
||||
/// <summary>
|
||||
/// 角色卡牌区域向右扩展距离,包含充能区域
|
||||
/// </summary>
|
||||
public int CharacterCardRightExtend { get; set; } = 14;
|
||||
public int CharacterCardRightExtend { get; } = 14;
|
||||
|
||||
/// <summary>
|
||||
/// 出战角色卡牌区域向上或者向下的距离差
|
||||
/// </summary>
|
||||
public int ActiveCharacterCardSpace { get; set; } = 41;
|
||||
public int ActiveCharacterCardSpace { get; } = 41;
|
||||
|
||||
/// <summary>
|
||||
/// HP区域 在 角色卡牌区域 的相对位置
|
||||
/// </summary>
|
||||
|
||||
public Rect CharacterCardExtendHpRect { get; set; } = new(-20, 0, 60, 55);
|
||||
public Rect CharacterCardExtendHpRect { get; } = new(-20, 0, 60, 55);
|
||||
}
|
||||
@@ -511,8 +511,8 @@ public class GeniusInvokationControl
|
||||
// 鼠标移动到中心
|
||||
ClickGameWindowCenter();
|
||||
|
||||
_logger.LogInformation("等待10s对方重投");
|
||||
Sleep(10000);
|
||||
_logger.LogInformation("等待5s对方重投");
|
||||
Sleep(5000);
|
||||
}
|
||||
|
||||
public Point MakeOffset(Point p)
|
||||
@@ -995,12 +995,10 @@ public class GeniusInvokationControl
|
||||
Sleep(2000); // 切人动画
|
||||
}
|
||||
|
||||
public void AppendCharacterStatus(Character character, Mat srcMat, int hp = -1)
|
||||
public void AppendCharacterStatus(Character character, Mat greyMat, int hp = -2)
|
||||
{
|
||||
using var gray = new Mat();
|
||||
Cv2.CvtColor(srcMat, gray, ColorConversionCodes.BGR2GRAY);
|
||||
// 截取出战角色区域扩展
|
||||
using var characterMat = new Mat(gray, new Rect(character.Area.X,
|
||||
using var characterMat = new Mat(greyMat, new Rect(character.Area.X,
|
||||
character.Area.Y,
|
||||
character.Area.Width + 40,
|
||||
character.Area.Height + 10));
|
||||
@@ -1029,7 +1027,6 @@ public class GeniusInvokationControl
|
||||
public Character WhichCharacterActiveWithRetry(Duel duel)
|
||||
{
|
||||
// 检查角色是否被击败 // 这里又检查一次是因为最后一个角色存活的情况下,会自动出战
|
||||
// TODO 这个击败识别有问题,需要优化
|
||||
var defeatedArray = WhatCharacterDefeated(duel.CharacterCardRects);
|
||||
for (var i = defeatedArray.Length - 1; i >= 0; i--)
|
||||
{
|
||||
@@ -1084,7 +1081,9 @@ public class GeniusInvokationControl
|
||||
{
|
||||
// 首个相交矩形就是出战角色
|
||||
duel.CurrentCharacter = duel.Characters[i + 1];
|
||||
AppendCharacterStatus(duel.CurrentCharacter, srcMat);
|
||||
var grayMat = new Mat();
|
||||
Cv2.CvtColor(srcMat, grayMat, ColorConversionCodes.BGR2GRAY);
|
||||
AppendCharacterStatus(duel.CurrentCharacter, grayMat);
|
||||
|
||||
Cv2.Rectangle(srcMat, rect1, Scalar.Yellow);
|
||||
Cv2.Rectangle(srcMat, duel.CharacterCardRects[i], Scalar.Blue, 2);
|
||||
@@ -1119,27 +1118,47 @@ public class GeniusInvokationControl
|
||||
var hpArray = new int[3]; // 1 代表未出战 2 代表出战
|
||||
for (var i = 0; i < duel.CharacterCardRects.Count; i++)
|
||||
{
|
||||
if (duel.Characters[i + 1].IsDefeated)
|
||||
{
|
||||
// 已经被击败的角色肯定未出战
|
||||
hpArray[i] = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
var cardRect = duel.CharacterCardRects[i];
|
||||
// 未出战角色的hp区域
|
||||
var hpMat = new Mat(srcMat, new Rect(cardRect.X + _config.CharacterCardExtendHpRect.X,
|
||||
cardRect.Y + _config.CharacterCardExtendHpRect.Y,
|
||||
_config.CharacterCardExtendHpRect.Width, _config.CharacterCardExtendHpRect.Height));
|
||||
var text = OcrFactory.Paddle.Ocr(hpMat);
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
Cv2.ImWrite($"log\\hp_n_{i}.jpg", hpMat);
|
||||
Debug.WriteLine($"角色{i}未出战HP位置识别结果{text}");
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
// 说明这个角色未出战
|
||||
hpArray[i] = 1;
|
||||
}
|
||||
|
||||
hpMat = new Mat(srcMat, new Rect(cardRect.X + _config.CharacterCardExtendHpRect.X,
|
||||
cardRect.Y + _config.CharacterCardExtendHpRect.Y - _config.ActiveCharacterCardSpace,
|
||||
_config.CharacterCardExtendHpRect.Width, _config.CharacterCardExtendHpRect.Height));
|
||||
text = OcrFactory.Paddle.Ocr(hpMat);
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
else
|
||||
{
|
||||
hpArray[i] = 2;
|
||||
duel.CurrentCharacter = duel.Characters[i + 1];
|
||||
AppendCharacterStatus(duel.CurrentCharacter, srcMat);
|
||||
return duel.CurrentCharacter;
|
||||
hpMat = new Mat(srcMat, new Rect(cardRect.X + _config.CharacterCardExtendHpRect.X,
|
||||
cardRect.Y + _config.CharacterCardExtendHpRect.Y - _config.ActiveCharacterCardSpace,
|
||||
_config.CharacterCardExtendHpRect.Width, _config.CharacterCardExtendHpRect.Height));
|
||||
text = OcrFactory.Paddle.Ocr(hpMat);
|
||||
Cv2.ImWrite($"log\\hp_active_{i}.jpg", hpMat);
|
||||
Debug.WriteLine($"角色{i}出战HP位置识别结果{text}");
|
||||
if (!string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
var hp = -2;
|
||||
if (Regex.IsMatch(text, @"^[0-9]+$"))
|
||||
{
|
||||
hp = int.Parse(text);
|
||||
}
|
||||
|
||||
hpArray[i] = 2;
|
||||
duel.CurrentCharacter = duel.Characters[i + 1];
|
||||
AppendCharacterStatus(duel.CurrentCharacter, srcMat, hp);
|
||||
return duel.CurrentCharacter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1147,7 +1166,8 @@ public class GeniusInvokationControl
|
||||
{
|
||||
// 找到并不等1的
|
||||
var index = hpArray.ToList().FindIndex(x => x != 1);
|
||||
duel.CurrentCharacter = duel.Characters[index];
|
||||
Debug.WriteLine($"通过OCR HP的方式没有识别到出战角色,但是通过排除法确认角色{index + 1}处于出战状态!");
|
||||
duel.CurrentCharacter = duel.Characters[index + 1];
|
||||
AppendCharacterStatus(duel.CurrentCharacter, srcMat);
|
||||
return duel.CurrentCharacter;
|
||||
}
|
||||
@@ -1181,15 +1201,17 @@ public class GeniusInvokationControl
|
||||
/// <summary>
|
||||
/// 通过OCR识别当前骰子数量
|
||||
/// </summary>
|
||||
/// <param name="duel"></param>
|
||||
/// <returns></returns>
|
||||
public int GetDiceCountByOcr()
|
||||
{
|
||||
var srcMat = CaptureGameGreyMat();
|
||||
var diceCountMap = new Mat(srcMat, _config.MyDiceCountRect);
|
||||
var text = OcrFactory.Paddle.Ocr(diceCountMap);
|
||||
text = text.Replace(" ", "");
|
||||
_logger.LogInformation("通过OCR识别当前骰子数量: {Text}", text);
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
Cv2.ImWrite("log\\dice_count_empty.jpg", diceCountMap);
|
||||
return -10;
|
||||
}
|
||||
else if (Regex.IsMatch(text, @"^[0-9]+$"))
|
||||
@@ -1198,6 +1220,7 @@ public class GeniusInvokationControl
|
||||
}
|
||||
else
|
||||
{
|
||||
Cv2.ImWrite("log\\dice_count_error.jpg", diceCountMap);
|
||||
return -10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace BetterGenshinImpact.GameTask.AutoGeniusInvokation.Model
|
||||
sb.Append($"角色{Index},");
|
||||
if (Hp != -2)
|
||||
{
|
||||
sb.Append($"Hp={Hp},");
|
||||
sb.Append($"HP={Hp},");
|
||||
}
|
||||
sb.Append($"充能={EnergyByRecognition},");
|
||||
if (StatusList?.Count > 0)
|
||||
|
||||
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging;
|
||||
using OpenCvSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -145,17 +146,20 @@ public class Duel
|
||||
|
||||
// 行动前重新确认骰子数量
|
||||
var diceCountFromOcr = GeniusInvokationControl.GetInstance().GetDiceCountByOcr();
|
||||
var diceDiff = Math.Abs(CurrentDiceCount - diceCountFromOcr);
|
||||
if (diceDiff is > 0 and <= 2)
|
||||
if (diceCountFromOcr != -10)
|
||||
{
|
||||
_logger.LogInformation("可能存在场地牌影响了骰子数[{CurrentDiceCount}] -> [{DiceCountFromOcr}]", CurrentDiceCount, diceCountFromOcr);
|
||||
CurrentDiceCount = diceCountFromOcr;
|
||||
}
|
||||
else if (diceDiff > 2)
|
||||
{
|
||||
_logger.LogWarning(" OCR识别到的骰子数[{DiceCountFromOcr}]和计算得出的骰子数[{CurrentDiceCount}]差距较大,舍弃结果", diceCountFromOcr, CurrentDiceCount);
|
||||
}
|
||||
var diceDiff = Math.Abs(CurrentDiceCount - diceCountFromOcr);
|
||||
if (diceDiff is > 0 and <= 2)
|
||||
{
|
||||
_logger.LogInformation("可能存在场地牌影响了骰子数[{CurrentDiceCount}] -> [{DiceCountFromOcr}]", CurrentDiceCount, diceCountFromOcr);
|
||||
CurrentDiceCount = diceCountFromOcr;
|
||||
}
|
||||
else if (diceDiff > 2)
|
||||
{
|
||||
_logger.LogWarning(" OCR识别到的骰子数[{DiceCountFromOcr}]和计算得出的骰子数[{CurrentDiceCount}]差距较大,舍弃结果", diceCountFromOcr, CurrentDiceCount);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var alreadyExecutedActionIndex = new List<int>();
|
||||
var alreadyExecutedActionCommand = new List<ActionCommand>();
|
||||
@@ -286,6 +290,7 @@ public class Duel
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
Debug.WriteLine(ex.StackTrace);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user