2025-08-30 00:36:08 +08:00
|
|
|
|
package xmlres
|
2025-08-25 04:23:32 +08:00
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"encoding/xml"
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
"io"
|
|
|
|
|
|
"net/http"
|
|
|
|
|
|
"time"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// MovesTbl 定义 XML 根元素
|
|
|
|
|
|
type MovesTbl struct {
|
|
|
|
|
|
XMLName xml.Name `xml:"MovesTbl"`
|
|
|
|
|
|
Moves []Move `xml:"Moves>Move"`
|
|
|
|
|
|
EFF []SideEffect `xml:"SideEffects>SideEffect"`
|
|
|
|
|
|
}
|
|
|
|
|
|
type MovesMap struct {
|
|
|
|
|
|
XMLName xml.Name `xml:"MovesTbl"`
|
2025-08-25 16:26:56 +08:00
|
|
|
|
Moves map[int]Move
|
2025-08-25 04:23:32 +08:00
|
|
|
|
EFF []SideEffect `xml:"SideEffects>SideEffect"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Move 定义单个技能的结构
|
|
|
|
|
|
type Move struct {
|
2025-09-03 00:37:05 +08:00
|
|
|
|
ID int `xml:"ID,attr"`
|
|
|
|
|
|
Name string `xml:"Name,attr"`
|
|
|
|
|
|
|
|
|
|
|
|
Category int `xml:"Category,attr"` //属性
|
|
|
|
|
|
Type int `xml:"Type,attr"` //类型
|
|
|
|
|
|
Power int `xml:"Power,attr"` //威力
|
|
|
|
|
|
MaxPP int `xml:"MaxPP,attr"` //最大PP
|
|
|
|
|
|
Accuracy int `xml:"Accuracy,attr"` //命中率
|
|
|
|
|
|
CritRate int `xml:"CritRate,attr,omitempty"` //暴击率
|
|
|
|
|
|
Priority int `xml:"Priority,attr,omitempty"` //优先级
|
|
|
|
|
|
MustHit int `xml:"MustHit,attr,omitempty"` //是否必中
|
|
|
|
|
|
SwapElemType int `xml:"SwapElemType,attr,omitempty"` //技能交换属性
|
|
|
|
|
|
CopyElemType int `xml:"CopyElemType,attr,omitempty"` // 技能复制属性
|
|
|
|
|
|
CritAtkFirst int `xml:"CritAtkFirst,attr,omitempty"` // 先出手时必定致命一击
|
|
|
|
|
|
CritAtkSecond int `xml:"CritAtkSecond,attr,omitempty"` //后出手时必定致命一击
|
|
|
|
|
|
CritSelfHalfHp int `xml:"CritSelfHalfHp,attr,omitempty"` //自身体力低于一半时必定致命一击
|
|
|
|
|
|
CritFoeHalfHp int `xml:"CritFoeHalfHp,attr,omitempty"` //对方体力低于一半时必定致命一击
|
|
|
|
|
|
DmgBindLv int `xml:"DmgBindLv,attr,omitempty"` //使对方受到的伤害值等于自身的等级
|
|
|
|
|
|
PwrBindDv int `xml:"PwrBindDv,attr,omitempty"` //威力(power)取决于自身的潜力(个体值)
|
|
|
|
|
|
PwrDouble int `xml:"PwrDouble,attr,omitempty"` //攻击时,若对方处于异常状态, 则威力翻倍;
|
2025-08-25 04:23:32 +08:00
|
|
|
|
|
|
|
|
|
|
SideEffect string `xml:"SideEffect,attr,omitempty"`
|
|
|
|
|
|
SideEffectArg string `xml:"SideEffectArg,attr,omitempty"`
|
|
|
|
|
|
AtkNum int `xml:"AtkNum,attr,omitempty"`
|
|
|
|
|
|
Url string `xml:"Url,attr,omitempty"`
|
|
|
|
|
|
|
|
|
|
|
|
Info string `xml:"info,attr,omitempty"`
|
|
|
|
|
|
|
|
|
|
|
|
CD int `xml:"CD,attr"`
|
|
|
|
|
|
}
|
|
|
|
|
|
type SideEffect struct {
|
|
|
|
|
|
ID int `xml:"ID,attr"`
|
|
|
|
|
|
Help string `xml:"help,attr"`
|
|
|
|
|
|
Des string `xml:"des,attr"`
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
}
|