babalae/better-genshin-impact · error · FormatException
原粹树脂上限 OCR 失败:{countText}
Error message
原粹树脂上限 OCR 失败:{countText} What it means
RecognizeOriginalResinLimit 用 OcrWithoutDetector 读取 '当前/上限' 文本,剥离非数字后要求至少 3 位数字(用于取最后三位作为上限)。位数不足 3 说明 OCR 根本没读到完整的 'NNN/LLL' 结构,无法可靠得到上限,抛 FormatException。
Source
Thrown at BetterGenshinImpact/GameTask/AutoBoss/AutoBossTask.cs:348
}
var originalResin = resinLimit - missingResin;
_logger.LogInformation("{Name}:剩余树脂 {Count}", Name, originalResin);
return new OriginalResinInfo(originalResin, resinLimit);
}
/// <summary>
/// 按原右上角 OCR 区域读取当前/上限文本,并取数字串最后三位作为树脂上限。
/// </summary>
private int RecognizeOriginalResinLimit(ImageRegion capture, int resinIconRight)
{
var countRect = new Rect(resinIconRight + ScaleX(25), ScaleY(37), ScaleX(120), ScaleY(24));
using var countRegion = capture.DeriveCrop(countRect);
var countText = OcrFactory.Paddle.OcrWithoutDetector(countRegion.SrcMat);
var digits = Regex.Replace(StringUtils.ConvertFullWidthNumToHalfWidth(countText), @"\D", "");
if (digits.Length < 3)
{
throw new FormatException($"原粹树脂上限 OCR 失败:{countText}");
}
var limitText = digits[^3..];
if (!int.TryParse(limitText, NumberStyles.None, CultureInfo.InvariantCulture, out var resinLimit) || resinLimit <= 0)
{
throw new FormatException($"原粹树脂上限解析失败:{countText}");
}
_logger.LogDebug("{Name}:原粹树脂上限 OCR:{Text} -> {Limit}", Name, countText, resinLimit);
return resinLimit;
}
/// <summary>
/// 读取树脂详情弹窗中的全部恢复时间;已完全恢复时返回零时长。
/// </summary>
private TimeSpan RecognizeFullRecoveryTime(ImageRegion capture, int resinIconLeft, int resinIconBottom)
{
// 该偏移来自截图实际像素,不随 AssetScale 缩放。View on GitHub (pinned to a7cb36712d)
Solutions
- 确认点击 resinIconRegion 后 Delay(500) 足够让弹窗稳定,必要时加大等待或轮询弹窗出现。
- 校准 countRect 相对 iconRight 的偏移与尺寸,确保覆盖整段 '当前/上限'。
- 检查 AssetScale / 截图分辨率(log debug 的 OCR 文本),调整区域或改用 OcrResult 多区域拼接。
- 在外层 catch(行 282)兜底,将 OCR 失败降级为预检跳过而非任务中止。
Example fix
// before
var countText = OcrFactory.Paddle.OcrWithoutDetector(countRegion.SrcMat);
var digits = Regex.Replace(StringUtils.ConvertFullWidthNumToHalfWidth(countText), @"\D", "");
if (digits.Length < 3)
{
throw new FormatException($"原粹树脂上限 OCR 失败:{countText}");
}
// after
var countText = OcrFactory.Paddle.OcrWithoutDetector(countRegion.SrcMat);
_logger.LogDebug("{Name}:上限 OCR 原文:{Text}", Name, countText);
var digits = Regex.Replace(StringUtils.ConvertFullWidthNumToHalfWidth(countText), @"\D", "");
if (digits.Length < 3)
{
throw new FormatException($"原粹树脂上限 OCR 失败:{countText}");
} Defensive patterns
Strategy: retry
Validate before calling
// 调用 RecognizeOriginalResinLimit 前,可先确认弹窗已出现
// (无直接 API,建议在 RecognizeOriginalResinInfoFromBigMap 内重试截图)
for (int i = 0; i < 3; i++)
{
using var c = CaptureToRectArea();
try { return RecognizeOriginalResinLimit(c, iconRight); }
catch (FormatException) when (i < 2) { await Delay(300, _ct); }
} Try / catch
try { var limit = RecognizeOriginalResinLimit(capture, iconRight); }
catch (FormatException ex) { _logger.LogWarning("{Name}:上限 OCR 失败:{Msg}", Name, ex.Message); throw; } Prevention
- 点击树脂图标后等待弹窗动画完成再截图,必要时轮询。
- 记录 OCR 原文 debug 日志,快速定位区域偏移。
- 对关键 OCR 步骤加 1-2 次重试,吸收动画/卡顿抖动。
When it happens
Trigger: countRect 区域(resinIconRight+ScaleX(25), ScaleY(37), ScaleX(120)×ScaleY(24))落在空白或只有当前值的区域;OCR 返回空串、单字符或全角符号;图标定位 iconRight 偏移导致裁剪框错位。
Common situations: 树脂详情弹窗未弹出或被遮挡;游戏分辨率/缩放与 AssetScale 不匹配使 ScaleX/ScaleY 偏移;PaddleOCR 模型在该小字号下识别失败;图标模板匹配漂移。
Related errors
- 计算缺失树脂 {missingResin} 超过树脂上限 {resinLimit}
- 原粹树脂上限解析失败:{countText}
- 未识别到全部恢复时间:{text}
- 树脂恢复时间格式无效:{timeText}
- 关闭补充原粹树脂提示超时
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/6e392947e1b9f13a.
Report an issue: GitHub.