{"record":{"id":"d9d3e8204d948d03","repo":"babalae/better-genshin-impact","slug":"n-levelandminoraffixlines","errorCode":null,"errorMessage":"未找到等级对应的行：\\n{levelAndMinorAffixLines}","messagePattern":"未找到等级对应的行：\\\\n(.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTask.cs","lineNumber":732,"sourceCode":"            }\n            minorAffixes.Add(new ArtifactAffix(artifactAffixType, affixValue, isUnactivated));\n        }\n        #endregion\n\n        #region 等级\n        string levelLine = levelAndMinorAffixLines.Select(l =>\n        {\n            string pattern = @\"^\\+(\\d*)$\";\n            Match match = Regex.Match(l, pattern);\n            if (match.Success)\n            {\n                return match.Groups[1].Value;\n            }\n            else\n            {\n                return null;\n            }\n        }).Where(l => l != null).Cast<string>().SingleOrDefault() ?? throw new Exception($\"未找到等级对应的行：\\n{levelAndMinorAffixLines}\");\n        if (!int.TryParse(levelLine, out int level) || level < 0 || level > 20)\n        {\n            throw new Exception($\"未识别的等级：{levelLine}\");\n        }\n        #endregion\n\n        return new ArtifactStat(name, mainAffix, minorAffixes.ToArray(), level);\n    }\n\n    public static ArtifactStatus GetArtifactStatus(Mat src)\n    {\n        using Mat upperLine = new Mat(src, new Rect(0, 0, src.Width, (int)(src.Height * 0.19)));\n        //using Mat hsvMat = upperLine.CvtColor(ColorConversionCodes.BGR2HSV_FULL);\n        //var pixel_hsv_pink = hsvMat.At<Vec3b>(17, 12);    // 注意是（Y，X）\n        //var pixel_hsv_grren = hsvMat.At<Vec3b>(8, 105);   // 注意是（Y，X）\n\n        // 粉色锁\n        Scalar pinkhsv = OpenCvCommonHelper.CommonHSV2OpenCVHSVFull(new Scalar(9, 0.54, 1.00));","sourceCodeStart":714,"sourceCodeEnd":750,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/AutoArtifactSalvage/AutoArtifactSalvageTask.cs#L714-L750","documentation":"Thrown in the level-parsing region when no line in levelAndMinorAffixLines matches '^\\+(\\d*)$'. The artifact's enhancement level (shown as '+N') could not be located. SingleOrDefault returns null when zero lines match.","triggerScenarios":"OCR did not capture the '+N' level text; the level line uses a different format (e.g. 'Lv. N' after a UI change); the level region crop shifted; the artifact is level 0 and shows no '+' (then no line matches).","commonSituations":"UI scale/layout change moving the level out of levelAndMinorAffixRoi; game version changing the level display format; OCR weakness on the small '+' glyph; a level-0 artifact with no visible plus.","solutions":["Inspect levelAndMinorAffixLines to see what was captured.","Handle the level-0 case (no '+') by defaulting to 0 instead of throwing.","Update the regex if the level format changed.","Verify the ROI crop percentages match the current card layout."],"exampleFix":"// before\nstring levelLine = ...SingleOrDefault() ?? throw new Exception($\"未找到等级对应的行：\\n{levelAndMinorAffixLines}\");\n// after - tolerate level 0 (no +N shown)\nstring? levelLine = ...SingleOrDefault();\nint level = 0;\nif (levelLine != null && (!int.TryParse(levelLine, out level) || level < 0 || level > 20))\n    throw new Exception($\"未识别的等级：{levelLine}\");","handlingStrategy":"validation","validationCode":"static string? FindLevelLine(IEnumerable<string> lines) =>\n    lines.Select(l => Regex.Match(l, @\"^\\+(\\d*)$\")).Where(m => m.Success).Select(m => m.Groups[1].Value).SingleOrDefault();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat a missing level line as level 0 rather than throwing.","Update the regex if the level display format changes.","Verify levelAndMinorAffixRoi crop percentages match the current card.","Use RecognitionFailurePolicy.Skip to tolerate occasional misses."],"tags":["game-task","ocr","artifact","recognition","regex"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}