This commit is contained in:
yml2213
2026-07-23 13:03:47 +08:00
commit 2a67d074a4
12 changed files with 999 additions and 0 deletions
+214
View File
@@ -0,0 +1,214 @@
package hfb
import (
"fmt"
"regexp"
"strconv"
"strings"
)
var numberPattern = regexp.MustCompile(`[-+]?\d+(?:\.\d+)?`)
func ParseUploadText(text string) (ParsedUpload, error) {
values := make(map[string]string)
for lineNo, line := range strings.Split(text, "\n") {
line = strings.TrimSpace(line)
if line == "" {
continue
}
key, value, ok := splitKeyValue(line)
if !ok {
return ParsedUpload{}, fmt.Errorf("第 %d 行格式不正确,应为“字段:值”", lineNo+1)
}
key = normalizeKey(key)
if key == "" {
continue
}
values[key] = strings.TrimSpace(value)
}
account := ExternalAccountData{}
var err error
account.LoginMethod = firstValue(values, "上号方式", "登录方式")
account.Rank = firstValue(values, "段位")
account.Level, err = parseRequiredInt(values, "等级")
if err != nil {
return ParsedUpload{}, err
}
account.SafeSlots, err = parseRequiredInt(values, "保险格数", "保险箱格数")
if err != nil {
return ParsedUpload{}, err
}
account.DailyLossM, err = parseRequiredFloat(values, "每日消耗")
if err != nil {
return ParsedUpload{}, err
}
account.SecretKD, err = parseRequiredFloat(values, "绝密KD", "绝密kd")
if err != nil {
return ParsedUpload{}, err
}
account.Deposit, err = parseRequiredFloat(values, "押金")
if err != nil {
return ParsedUpload{}, err
}
account.BanRecord = optionalDefault(firstValue(values, "封禁记录"), "无")
account.CommonRegion = firstValue(values, "常用地区", "常用区域")
account.ContactPhone = firstValue(values, "联系电话", "手机号", "电话")
account.OwnerOnlineTime = firstValue(values, "号主在线时间", "在线时间")
account.Currency.HafuCoin, err = parseRequiredFloat(values, "哈夫币纯币", "哈夫币")
if err != nil {
return ParsedUpload{}, err
}
account.Currency.RecycleRatio, err = parseRequiredRatio(values, "回收比例")
if err != nil {
return ParsedUpload{}, err
}
account.Currency.RecycleRent, err = parseRequiredFloat(values, "回收租金")
if err != nil {
return ParsedUpload{}, err
}
account.DailyConsumption.Stamina, err = parseRequiredInt(values, "体力")
if err != nil {
return ParsedUpload{}, err
}
account.DailyConsumption.Weight, err = parseRequiredInt(values, "负重")
if err != nil {
return ParsedUpload{}, err
}
account.Inventory.AWMBullets, err = parseOptionalInt(values, "AWM子弹数量", "AWM子弹")
if err != nil {
return ParsedUpload{}, err
}
account.Inventory.Level6Helmets, err = parseOptionalInt(values, "6头数量", "六头数量", "6头")
if err != nil {
return ParsedUpload{}, err
}
account.Inventory.Level6Armor, err = parseOptionalInt(values, "6甲数量", "六甲数量", "6甲")
if err != nil {
return ParsedUpload{}, err
}
account.Inventory.Skins = parseSkins(firstValue(values, "皮肤"))
if strings.TrimSpace(account.LoginMethod) == "" {
return ParsedUpload{}, fmt.Errorf("缺少必填字段:上号方式")
}
if strings.TrimSpace(account.Rank) == "" {
return ParsedUpload{}, fmt.Errorf("缺少必填字段:段位")
}
return ParsedUpload{
UploaderName: firstValue(values, "上传人", "上传者", "上传账号", "上传管理员"),
Account: account,
}, nil
}
func splitKeyValue(line string) (string, string, bool) {
if idx := strings.Index(line, ""); idx >= 0 {
return line[:idx], line[idx+len(""):], true
}
if idx := strings.Index(line, ":"); idx >= 0 {
return line[:idx], line[idx+1:], true
}
return "", "", false
}
func normalizeKey(key string) string {
return strings.ToUpper(strings.ReplaceAll(strings.TrimSpace(key), " ", ""))
}
func firstValue(values map[string]string, labels ...string) string {
for _, label := range labels {
if value, ok := values[normalizeKey(label)]; ok {
return strings.TrimSpace(value)
}
}
return ""
}
func optionalDefault(value, fallback string) string {
if strings.TrimSpace(value) == "" {
return fallback
}
return strings.TrimSpace(value)
}
func parseRequiredInt(values map[string]string, labels ...string) (int, error) {
value := firstValue(values, labels...)
if value == "" {
return 0, fmt.Errorf("缺少必填字段:%s", labels[0])
}
return parseIntLabel(labels[0], value)
}
func parseOptionalInt(values map[string]string, labels ...string) (int, error) {
value := firstValue(values, labels...)
if value == "" {
return 0, nil
}
return parseIntLabel(labels[0], value)
}
func parseIntLabel(label, value string) (int, error) {
number, err := parseFloatText(value, false)
if err != nil {
return 0, fmt.Errorf("%s 数字格式不正确:%s", label, value)
}
return int(number), nil
}
func parseRequiredFloat(values map[string]string, labels ...string) (float64, error) {
value := firstValue(values, labels...)
if value == "" {
return 0, fmt.Errorf("缺少必填字段:%s", labels[0])
}
number, err := parseFloatText(value, false)
if err != nil {
return 0, fmt.Errorf("%s 数字格式不正确:%s", labels[0], value)
}
return number, nil
}
func parseRequiredRatio(values map[string]string, labels ...string) (float64, error) {
value := firstValue(values, labels...)
if value == "" {
return 0, fmt.Errorf("缺少必填字段:%s", labels[0])
}
number, err := parseFloatText(value, true)
if err != nil {
return 0, fmt.Errorf("%s 数字格式不正确:%s", labels[0], value)
}
return number, nil
}
func parseFloatText(value string, preferLast bool) (float64, error) {
value = strings.TrimSpace(strings.ReplaceAll(value, ",", ""))
matches := numberPattern.FindAllString(value, -1)
if len(matches) == 0 {
return 0, strconv.ErrSyntax
}
pick := matches[0]
if preferLast {
pick = matches[len(matches)-1]
}
return strconv.ParseFloat(pick, 64)
}
func parseSkins(value string) []string {
value = strings.TrimSpace(value)
if value == "" || value == "无" || strings.EqualFold(value, "none") {
return nil
}
parts := strings.FieldsFunc(value, func(r rune) bool {
return r == ',' || r == '' || r == '、' || r == ';' || r == ''
})
skins := make([]string, 0, len(parts))
for _, part := range parts {
part = strings.TrimSpace(part)
if part != "" && part != "无" {
skins = append(skins, part)
}
}
return skins
}