Files
huya-go/internal/sniper/category.go
T
yml2213 43b3cb351e feat(sniper): 增加1.5s快速超时熔断,重构角色未绑定分类解绑会话失效
- 兑换请求增加独立的 RequestTimeout 上下文超时熔断(默认 1500ms),防止微服务卡死吃掉 5 秒
- 剥离 CategoryRoleUnbound(角色未绑定/抖动),不再计入 sessionStreak 判死阈值,杜绝误杀有效账号
- 将 CategoryRoleUnbound 与 CategoryTooFrequent 纳入 sessionAliveCategory,正常回包可重置会话计数
- 补充单测 TestRunTargetsRoleUnboundDoesNotStopAccount 与 TestExchangeTargetFastTimeout
2026-10-18 21:23:49 +08:00

90 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package sniper
import (
"fmt"
"strconv"
"strings"
)
// TargetSummary 把目标列表渲染成「13437(冠军之刃)」这样的单行摘要,供启动日志使用。
//
// 2026-10-16 的复盘正卡在「日志里没有目标 pid」:三台机器都只记了 sid 与 targets=1,
// 看不出各自打的是哪个奖品,也就无法解释为什么一台售罄、另一台库存完好。
func TargetSummary(targets []Target) string {
parts := make([]string, 0, len(targets))
for _, target := range targets {
name := strings.TrimSpace(target.Name)
switch {
case target.PID > 0 && name != "":
parts = append(parts, fmt.Sprintf("%d(%s)", target.PID, name))
case target.PID > 0:
parts = append(parts, strconv.FormatInt(int64(target.PID), 10))
case name != "":
parts = append(parts, name)
case target.Auto:
parts = append(parts, "自动选择")
}
}
if len(parts) == 0 {
return "未指定"
}
return strings.Join(parts, ",")
}
// CategoryLabel 返回结局分类的中文短标签,供任务结束时的结局日志使用。
func CategoryLabel(category string) string {
switch category {
case CategorySuccess:
return "已抢到"
case CategorySoldOut:
return "售罄"
case CategoryTooFrequent:
return "被限流"
case CategoryNotOpen:
return "未开放"
case CategoryNotEnough:
return "积分不足"
case CategoryAlreadyDone:
return "已兑换过"
case CategoryOffShelf:
return "已下架"
case CategorySessionLost:
return "会话失效"
case CategoryRoleUnbound:
return "角色未绑定/抖动"
case CategoryProtocol:
return "协议异常"
case CategoryCondition:
return "条件未达成"
case CategoryNotFound:
return "未匹配到奖品"
case CategoryError:
return "请求异常"
default:
return "失败"
}
}
// CategoryText 把类目限制渲染成日志文案(空串表示不限类目)。
func CategoryText(category string) string {
key := strings.TrimSpace(category)
if key == "" {
return "不限"
}
return key
}
// LogLevelForCategory 把结果分类映射成日志等级,供界面按等级高亮与筛选。
func LogLevelForCategory(category string) string {
switch category {
case CategorySuccess:
return "success"
case CategoryError, CategoryProtocol:
return "error"
case CategoryFailed, CategoryTooFrequent, CategoryCondition, CategoryRoleUnbound, CategorySessionLost:
return "warn"
default:
return "info"
}
}