207 lines
4.2 KiB
Go
207 lines
4.2 KiB
Go
package parser
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"equipment-analyzer/internal/model"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
type HexParser struct{}
|
|
|
|
func NewHexParser() *HexParser {
|
|
return &HexParser{}
|
|
}
|
|
|
|
func (hp *HexParser) ParseHexData(hexDataList []string) (*model.CaptureResult, error) {
|
|
result := &model.CaptureResult{
|
|
Data: make([]model.Equipment, 0),
|
|
Units: make([]interface{}, 0),
|
|
}
|
|
|
|
for _, hexData := range hexDataList {
|
|
equipment, err := hp.parseSingleEquipment(hexData)
|
|
if err != nil {
|
|
continue // 跳过解析失败的数据
|
|
}
|
|
result.Data = append(result.Data, *equipment)
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (hp *HexParser) parseSingleEquipment(hexData string) (*model.Equipment, error) {
|
|
// 将十六进制字符串转换为字节数组
|
|
bytes, err := hex.DecodeString(hexData)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid hex string: %v", err)
|
|
}
|
|
|
|
if len(bytes) < 47 { // 最小长度检查
|
|
return nil, fmt.Errorf("data too short")
|
|
}
|
|
|
|
equipment := &model.Equipment{
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
// 解析各个字段(基于之前的分析逻辑)
|
|
equipment.Code = hp.extractCode(bytes)
|
|
equipment.Ct = hp.extractTimestamp(bytes)
|
|
equipment.E = hp.extractExperience(bytes)
|
|
equipment.G = hp.extractGrade(bytes)
|
|
//equipment.ID = hp.extractID(bytes)
|
|
equipment.L = hp.extractLocked(bytes)
|
|
equipment.Mg = hp.extractMagic(bytes)
|
|
equipment.Op = hp.extractOperations(bytes)
|
|
equipment.P = hp.extractPower(bytes)
|
|
equipment.S = hp.extractString(bytes)
|
|
equipment.Sk = hp.extractSkill(bytes)
|
|
|
|
return equipment, nil
|
|
}
|
|
|
|
func (hp *HexParser) extractCode(bytes []byte) string {
|
|
if len(bytes) < 4 {
|
|
return "efm00"
|
|
}
|
|
codeValue := hp.readInt(bytes, 0)
|
|
return fmt.Sprintf("efm%02d", codeValue%100)
|
|
}
|
|
|
|
func (hp *HexParser) extractTimestamp(bytes []byte) time.Time {
|
|
if len(bytes) < 8 {
|
|
return time.Now()
|
|
}
|
|
timestamp := hp.readInt(bytes, 4)
|
|
return time.Unix(int64(timestamp), 0)
|
|
}
|
|
|
|
func (hp *HexParser) extractExperience(bytes []byte) int {
|
|
if len(bytes) < 12 {
|
|
return 0
|
|
}
|
|
return hp.readInt(bytes, 8)
|
|
}
|
|
|
|
func (hp *HexParser) extractGrade(bytes []byte) int {
|
|
if len(bytes) < 13 {
|
|
return 0
|
|
}
|
|
return int(bytes[12])
|
|
}
|
|
|
|
func (hp *HexParser) extractID(bytes []byte) int {
|
|
if len(bytes) < 17 {
|
|
return 0
|
|
}
|
|
return hp.readInt(bytes, 13)
|
|
}
|
|
|
|
func (hp *HexParser) extractLocked(bytes []byte) bool {
|
|
if len(bytes) < 18 {
|
|
return false
|
|
}
|
|
return (bytes[17] & 0x01) != 0
|
|
}
|
|
|
|
func (hp *HexParser) extractMagic(bytes []byte) int {
|
|
if len(bytes) < 20 {
|
|
return 0
|
|
}
|
|
return hp.readShort(bytes, 18)
|
|
}
|
|
|
|
func (hp *HexParser) extractOperations(bytes []byte) []model.Operation {
|
|
operations := make([]model.Operation, 0)
|
|
|
|
if len(bytes) < 21 {
|
|
return operations
|
|
}
|
|
|
|
offset := 20
|
|
opCount := int(bytes[offset])
|
|
offset++
|
|
|
|
for i := 0; i < opCount && offset+3 < len(bytes); i++ {
|
|
attrType := int(bytes[offset])
|
|
offset++
|
|
|
|
attrValue := hp.readShort(bytes, offset)
|
|
offset += 2
|
|
|
|
attrName := hp.getAttributeName(attrType)
|
|
|
|
op := model.Operation{
|
|
Type: attrName,
|
|
Value: attrValue,
|
|
}
|
|
operations = append(operations, op)
|
|
}
|
|
|
|
return operations
|
|
}
|
|
|
|
func (hp *HexParser) extractPower(bytes []byte) int {
|
|
if len(bytes) < 44 {
|
|
return 0
|
|
}
|
|
return hp.readInt(bytes, 40)
|
|
}
|
|
|
|
func (hp *HexParser) extractString(bytes []byte) string {
|
|
if len(bytes) < 46 {
|
|
return "0000"
|
|
}
|
|
stringValue := hp.readShort(bytes, 44)
|
|
return fmt.Sprintf("%04x", stringValue)
|
|
}
|
|
|
|
func (hp *HexParser) extractSkill(bytes []byte) int {
|
|
if len(bytes) < 47 {
|
|
return 0
|
|
}
|
|
return int(bytes[46])
|
|
}
|
|
|
|
func (hp *HexParser) readInt(bytes []byte, offset int) int {
|
|
if offset+3 >= len(bytes) {
|
|
return 0
|
|
}
|
|
return int(bytes[offset])<<24 | int(bytes[offset+1])<<16 |
|
|
int(bytes[offset+2])<<8 | int(bytes[offset+3])
|
|
}
|
|
|
|
func (hp *HexParser) readShort(bytes []byte, offset int) int {
|
|
if offset+1 >= len(bytes) {
|
|
return 0
|
|
}
|
|
return int(bytes[offset])<<8 | int(bytes[offset+1])
|
|
}
|
|
|
|
func (hp *HexParser) getAttributeName(attrType int) string {
|
|
switch attrType {
|
|
case 1:
|
|
return "att"
|
|
case 2:
|
|
return "def"
|
|
case 3:
|
|
return "hp"
|
|
case 4:
|
|
return "max_hp"
|
|
case 5:
|
|
return "speed"
|
|
case 6:
|
|
return "crit"
|
|
case 7:
|
|
return "crit_dmg"
|
|
case 8:
|
|
return "effectiveness"
|
|
case 9:
|
|
return "effect_resistance"
|
|
default:
|
|
return fmt.Sprintf("unknown_%d", attrType)
|
|
}
|
|
}
|