babalae/better-genshin-impact · error · FormatException

树脂恢复时间格式无效:{timeText}

Error message

树脂恢复时间格式无效:{timeText}

What it means

ParseRecoveryTime 校验 H:MM:SS 三段:必须三段、均可解析、minutes/seconds 在 0..59。由于上游正则已要求 \d{2},hours 段 \d{1,3} 总能解析;该异常实际触发于 minutes 或 seconds ≥ 60(例如 OCR 把 '05' 读成 '95'),即 OCR 数值越界。

Source

Thrown at BetterGenshinImpact/GameTask/AutoBoss/AutoBossTask.cs:429

            throw new FormatException($"未识别到全部恢复时间:{text}");
        }

        return ParseRecoveryTime(timeMatches[timeMatches.Count - 1].Value);
    }

    private static TimeSpan ParseRecoveryTime(string timeText)
    {
        var parts = timeText.Split(':');
        if (parts.Length != 3
            || !int.TryParse(parts[0], NumberStyles.None, CultureInfo.InvariantCulture, out var hours)
            || !int.TryParse(parts[1], NumberStyles.None, CultureInfo.InvariantCulture, out var minutes)
            || !int.TryParse(parts[2], NumberStyles.None, CultureInfo.InvariantCulture, out var seconds)
            || minutes < 0
            || minutes > 59
            || seconds < 0
            || seconds > 59)
        {
            throw new FormatException($"树脂恢复时间格式无效:{timeText}");
        }

        return new TimeSpan(hours, minutes, seconds);
    }

    private static string FormatRecoveryTime(TimeSpan time)
    {
        return $"{(int)time.TotalHours:D2}:{time.Minutes:D2}:{time.Seconds:D2}";
    }

    /// <summary>
    /// 当前处于大地图树脂详情弹窗时,尝试使用须臾或脆弱树脂补充原粹树脂。
    /// </summary>
    private async Task<bool> TryUseSupplementalResinBeforeRound(OriginalResinInfo originalResin)
    {
        var page = new BvPage(_ct);
        var currentResin = originalResin;
        var unavailableResins = new HashSet<string>(StringComparer.Ordinal);

View on GitHub (pinned to a7cb36712d)

Solutions

  1. 记录 timeText 原文确认哪段越界。
  2. 对越界值做钳制(clamp minutes/seconds 到 0..59)后重试,而非直接失败。
  3. 改进 OCR 前处理(二值化/放大)提升冒号识别率。
  4. 在外层兜底降级。

Example fix

// before
if (minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59)
{
    throw new FormatException($"树脂恢复时间格式无效:{timeText}");
}

// after
if (minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59)
{
    throw new FormatException($"树脂恢复时间格式无效(分秒越界):{timeText}");
}
Defensive patterns

Strategy: validation

Validate before calling

// ParseRecoveryTime 内:越界值钳制而非抛出(仅当确信 OCR 单字符错误时)
// 谨慎使用:钳制会改变结果。建议优先抛出并重试 OCR。

Try / catch

try { return ParseRecoveryTime(value); }
catch (FormatException ex) { _logger.LogWarning("恢复时间解析失败 [{Value}]:{Msg}", value, ex.Message); throw; }

Prevention

When it happens

Trigger: OCR 把时间某段读成 ≥60 的值('12:95:00');冒号被识别为数字导致段数错位后又被正则误匹配;分割后某段含非数字(理论上正则已排除)。

Common situations: 小字号 OCR 把 ':' 误读为数字或把相邻数字粘连;detailRect 区域噪声多;模型对游戏字体识别不稳。

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/1cf912e77be9601d. Report an issue: GitHub.