init
This commit is contained in:
206
internal/parser/hex_parser.go
Normal file
206
internal/parser/hex_parser.go
Normal file
@@ -0,0 +1,206 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user