{"record":{"id":"268862ad53439217","repo":"babalae/better-genshin-impact","slug":"condensedresincount","errorCode":null,"errorMessage":"识别浓缩树脂数量失败: {condensedResinCount}","messagePattern":"识别浓缩树脂数量失败: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/GameTask/Common/Job/GoToCraftingBenchTask.cs","lineNumber":129,"sourceCode":"                //浓缩纠缠重试\n                var condensed =await NewRetry.WaitForAction(() =>\n                {\n                    var condensedResinCountRa = ra.Find(ElementRecognition.Get(\"CondensedResinCount\", ra));\n                    if (!condensedResinCountRa.IsEmpty())\n                    {\n                        // 图像右侧就是浓缩树脂数量\n                        var countArea = ra.DeriveCrop(condensedResinCountRa.X + condensedResinCountRa.Width,\n                            condensedResinCountRa.Y, condensedResinCountRa.Width*5/3, condensedResinCountRa.Height);\n                        var count = OcrFactory.Paddle.OcrWithoutDetector(countArea.CacheGreyMat);\n                        condensedResinCount = StringUtils.TryParseInt(count);\n                    }\n                    return condensedResinCount >= 0 && condensedResinCount <=5;\n                },ct,3,200); \n                if (!condensed)\n                {\n                    Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_ESCAPE);\n                    await new ReturnMainUiTask().Start(ct);\n                    throw new Exception($\"识别浓缩树脂数量失败: {condensedResinCount}\");\n                }\n                \n                // 每次合成消耗的数量\n                const int resinConsumedPerCraft = 60;\n                // 需要保留的最小数量\n                 int minResinToKeep = SelectedConfig.MinResinToKeep;\n                // 可以用来合成的树脂数量\n                int resinAvailableForCrafting = fragileResinCount - minResinToKeep;\n                // 最大可合成次数\n                int maxCraftsPossible = 5 - condensedResinCount;\n                // 计算需要合成的次数\n                int craftsNeeded = resinAvailableForCrafting / resinConsumedPerCraft;\n                if (craftsNeeded < 0)\n                {\n                    craftsNeeded = 0;\n                }\n                // 计算最大合成次数\n                craftsNeeded = Math.Min(maxCraftsPossible, craftsNeeded);","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/GameTask/Common/Job/GoToCraftingBenchTask.cs#L111-L147","documentation":"Thrown by GoToCraftingBenchTask.GoCraftResinOnce when a 3-attempt NewRetry.WaitForAction cannot OCR the condensed-resin count into the valid 0-5 range. The retry crops the area to the right of the CondensedResinCount template and runs Paddle OcrWithoutDetector, storing into condensedResinCount.","triggerScenarios":"WaitForAction predicate (condensedResinCount >= 0 && <= 5) is false for all 3 attempts at 200ms. The cropped OCR region yields a number outside 0-5 (often a misread like 50 or a parse of nearby UI digits), or StringUtils.TryParseInt keeps returning a value > 5.","commonSituations":"The condensed-resin count region (right of the CondensedResinCount template) shifted and now includes adjacent digits; the OCR reads a stale/garbage value; the template match for CondensedResinCount anchored the crop incorrectly at the current scale; condensed-resin display shows '/5' and OCR captured the denominator.","solutions":["Tighten the OCR crop width (Width*5/3) so it covers only the count digit, not adjacent '/5'.","Add a regex to extract only the leading digit(s) before any '/' before the range check.","Re-verify the CondensedResinCount template still matches at the current resolution/scale.","Increase retry attempts/delay and log the raw OCR string each attempt."],"exampleFix":"// before\nvar count = OcrFactory.Paddle.OcrWithoutDetector(countArea.CacheGreyMat);\ncondensedResinCount = StringUtils.TryParseInt(count);\n...\nreturn condensedResinCount >= 0 && condensedResinCount <=5;\n\n// after: strip '/N' before parsing\nvar count = OcrFactory.Paddle.OcrWithoutDetector(countArea.CacheGreyMat);\nvar digitMatch = System.Text.RegularExpressions.Regex.Match(count, @\"^\\s*(\\d+)\");\ncondensedResinCount = digitMatch.Success ? StringUtils.TryParseInt(digitMatch.Groups[1].Value) : 0;\nreturn condensedResinCount >= 0 && condensedResinCount <= 5;","handlingStrategy":"fallback","validationCode":"// Pre-check the condensed-resin template anchors a valid region\nvar anchor = ra.Find(ElementRecognition.Get(\"CondensedResinCount\", ra));\nif (anchor.IsEmpty())\n    Logger.LogWarning(\"浓缩树脂计数锚点未找到，OCR 可能失败\");","typeGuard":"static bool IsValidCondensedCount(int n) => n is >= 0 and <= 5;","tryCatchPattern":"try { await GoCraftResinOnce(country, ct); }\ncatch (Exception e) when (e.Message.Contains(\"识别浓缩树脂数量失败\"))\n{ /* fall back to a conservative craft count (e.g. 0) and continue */ }","preventionTips":["Strip trailing '/5' from OCR output before parsing.","Tighten the OCR crop to the count digit only.","Log the raw OCR string each attempt to detect region drift."],"tags":["ocr","crafting","resin","genshin-ui"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}