package xmlres import ( "encoding/json" "encoding/xml" "fmt" "io" "net/http" "strconv" "strings" "time" ) func ParseSideEffectArgs(argsStr string) []int { if argsStr == "" { return []int{} } parts := strings.Fields(argsStr) args := make([]int, 0, len(parts)) for _, part := range parts { if num, err := strconv.Atoi(part); err == nil { args = append(args, num) } } return args } // MovesTbl 定义 XML 根元素 type MovesTbl struct { XMLName xml.Name `xml:"MovesTbl"` Moves []Move `xml:"Moves>Move"` EFF []SideEffect `xml:"SideEffects>SideEffect"` } type MovesJSON struct { MovesTbl MovesJSONRoot `json:"MovesTbl"` } type MovesJSONRoot struct { Moves struct { Move []Move `json:"Move"` } `json:"Moves"` SideEffects struct { SideEffect []SideEffect `json:"SideEffect"` } `json:"SideEffects"` } type MovesMap struct { XMLName xml.Name `xml:"MovesTbl"` Moves map[int]Move EFF []SideEffect `xml:"SideEffects>SideEffect"` } type rawFlexibleString string func (s *rawFlexibleString) UnmarshalJSON(data []byte) error { text := strings.TrimSpace(string(data)) if text == "" || text == "null" { *s = "" return nil } if len(text) >= 2 && text[0] == '"' && text[len(text)-1] == '"' { var decoded string if err := json.Unmarshal(data, &decoded); err != nil { return err } *s = rawFlexibleString(decoded) return nil } *s = rawFlexibleString(text) return nil } // Move 定义单个技能的结构 type Move struct { ID int `xml:"ID,attr" json:"ID"` Name string `xml:"Name,attr" json:"Name"` Category int `xml:"Category,attr" json:"Category"` //属性 Type int `xml:"Type,attr" json:"Type"` //类型 Power int `xml:"Power,attr" json:"Power"` //威力 MaxPP int `xml:"MaxPP,attr" json:"MaxPP"` //最大PP Accuracy int `xml:"Accuracy,attr" json:"Accuracy"` //命中率 CritRate int `xml:"CritRate,attr,omitempty" json:"CritRate,omitempty"` //暴击率 Priority int `xml:"Priority,attr,omitempty" json:"Priority,omitempty"` //优先级 MustHit int `xml:"MustHit,attr,omitempty" json:"MustHit,omitempty"` //是否必中 SwapElemType int `xml:"SwapElemType,attr,omitempty" json:"SwapElemType,omitempty"` //技能交换属性 CopyElemType int `xml:"CopyElemType,attr,omitempty" json:"CopyElemType,omitempty"` // 技能复制属性 CritAtkFirst int `xml:"CritAtkFirst,attr,omitempty" json:"CritAtkFirst,omitempty"` // 先出手时必定致命一击 CritAtkSecond int `xml:"CritAtkSecond,attr,omitempty" json:"CritAtkSecond,omitempty"` //后出手时必定致命一击 CritSelfHalfHp int `xml:"CritSelfHalfHp,attr,omitempty" json:"CritSelfHalfHp,omitempty"` //自身体力低于一半时必定致命一击 CritFoeHalfHp int `xml:"CritFoeHalfHp,attr,omitempty" json:"CritFoeHalfHp,omitempty"` //对方体力低于一半时必定致命一击 DmgBindLv int `xml:"DmgBindLv,attr,omitempty" json:"DmgBindLv,omitempty"` //使对方受到的伤害值等于自身的等级 PwrBindDv int `xml:"PwrBindDv,attr,omitempty" json:"PwrBindDv,omitempty"` //威力(power)取决于自身的潜力(个体值) PwrDouble int `xml:"PwrDouble,attr,omitempty" json:"PwrDouble,omitempty"` //攻击时,若对方处于异常状态, 则威力翻倍; DmgBindHpDv int `xml:"DmgBindHpDv,attr,omitempty" json:"DmgBindHpDv,omitempty"` //使对方受到的伤害值等于自身的体力值 SideEffect string `xml:"SideEffect,attr,omitempty" json:"SideEffect,omitempty"` SideEffectArg string `xml:"SideEffectArg,attr,omitempty" json:"SideEffectArg,omitempty"` SideEffectS []int SideEffectArgS []int AtkNum int `xml:"AtkNum,attr,omitempty" json:"AtkNum,omitempty"` AtkType int `xml:"AtkType,attr,omitempty" json:"AtkType,omitempty"` // 0:所有人 1:仅己方 2:仅对方 3:仅自己 Url string `xml:"Url,attr,omitempty" json:"Url,omitempty"` Info string `xml:"info,attr,omitempty" json:"info,omitempty"` CD *int `xml:"CD,attr" json:"CD"` } func (m *Move) UnmarshalJSON(data []byte) error { type moveAlias struct { ID int `json:"ID"` Name string `json:"Name"` Category int `json:"Category"` Type int `json:"Type"` Power int `json:"Power"` MaxPP int `json:"MaxPP"` Accuracy int `json:"Accuracy"` CritRate int `json:"CritRate,omitempty"` Priority int `json:"Priority,omitempty"` MustHit int `json:"MustHit,omitempty"` SwapElemType int `json:"SwapElemType,omitempty"` CopyElemType int `json:"CopyElemType,omitempty"` CritAtkFirst int `json:"CritAtkFirst,omitempty"` CritAtkSecond int `json:"CritAtkSecond,omitempty"` CritSelfHalfHp int `json:"CritSelfHalfHp,omitempty"` CritFoeHalfHp int `json:"CritFoeHalfHp,omitempty"` DmgBindLv int `json:"DmgBindLv,omitempty"` PwrBindDv int `json:"PwrBindDv,omitempty"` PwrDouble int `json:"PwrDouble,omitempty"` DmgBindHpDv int `json:"DmgBindHpDv,omitempty"` SideEffect rawFlexibleString `json:"SideEffect,omitempty"` SideEffectArg rawFlexibleString `json:"SideEffectArg,omitempty"` AtkNum int `json:"AtkNum,omitempty"` AtkType int `json:"AtkType,omitempty"` Url string `json:"Url,omitempty"` Info string `json:"info,omitempty"` CD *int `json:"CD"` } var aux moveAlias if err := json.Unmarshal(data, &aux); err != nil { return err } *m = Move{ ID: aux.ID, Name: aux.Name, Category: aux.Category, Type: aux.Type, Power: aux.Power, MaxPP: aux.MaxPP, Accuracy: aux.Accuracy, CritRate: aux.CritRate, Priority: aux.Priority, MustHit: aux.MustHit, SwapElemType: aux.SwapElemType, CopyElemType: aux.CopyElemType, CritAtkFirst: aux.CritAtkFirst, CritAtkSecond: aux.CritAtkSecond, CritSelfHalfHp: aux.CritSelfHalfHp, CritFoeHalfHp: aux.CritFoeHalfHp, DmgBindLv: aux.DmgBindLv, PwrBindDv: aux.PwrBindDv, PwrDouble: aux.PwrDouble, DmgBindHpDv: aux.DmgBindHpDv, SideEffect: string(aux.SideEffect), SideEffectArg: string(aux.SideEffectArg), AtkNum: aux.AtkNum, AtkType: aux.AtkType, Url: aux.Url, Info: aux.Info, CD: aux.CD, } return nil } type SideEffect struct { ID int `xml:"ID,attr" json:"ID"` Help string `xml:"help,attr" json:"help"` Des string `xml:"des,attr" json:"des"` } // ReadHTTPFile 通过HTTP GET请求获取远程文件内容 // url: 远程文件的URL地址 // 返回文件内容字节流和可能的错误 func ReadHTTPFile(url string) ([]byte, error) { // 创建HTTP客户端并设置超时时间(避免无限等待) client := &http.Client{ Timeout: 30 * time.Second, // 30秒超时 } // 发送GET请求 resp, err := client.Get(url) if err != nil { return nil, fmt.Errorf("请求失败: %w", err) } defer resp.Body.Close() // 确保响应体被关闭 // 检查响应状态码 if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("请求返回非成功状态码: %d", resp.StatusCode) } // 读取响应体内容 content, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("读取内容失败: %w", err) } return content, nil }