feat(xmlres): 添加磁盘配置文件回退机制并支持JSON格式配置 - 新增readConfigContent函数,优先从资源包读取配置,失败时回退到磁盘文件 - 添加diskConfigPath变量存储本地配置路径 - 支持从磁盘读取JSON格式配置文件,增强配置灵活性 - 修改getJson函数增加错误处理和调试日志输出 - 将技能配置从XML格式改为JSON格式,提升数据解析效率 - 初始化时设置默认磁盘配置路径为public/config目录 ```
This commit is contained in:
@@ -5,7 +5,10 @@ import (
|
|||||||
|
|
||||||
_ "blazing/common/data/xmlres/packed"
|
_ "blazing/common/data/xmlres/packed"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/ECUST-XX/xml"
|
"github.com/ECUST-XX/xml"
|
||||||
"github.com/gogf/gf/v2/os/gres"
|
"github.com/gogf/gf/v2/os/gres"
|
||||||
@@ -13,23 +16,55 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var path string
|
var path string
|
||||||
|
var diskConfigPath string
|
||||||
|
|
||||||
|
func readConfigContent(path string) []byte {
|
||||||
|
content := gres.GetContent(path)
|
||||||
|
if len(content) > 0 {
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
if diskConfigPath == "" {
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
diskPath := filepath.Join(diskConfigPath, strings.TrimPrefix(path, "config/"))
|
||||||
|
data, err := os.ReadFile(diskPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("[xmlres] readConfigContent fallback failed: path=%s disk=%s err=%v\n", path, diskPath, err)
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("[xmlres] readConfigContent fallback hit: path=%s disk=%s len=%d\n", path, diskPath, len(data))
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
func getXml[T any](path string) T {
|
func getXml[T any](path string) T {
|
||||||
|
|
||||||
// 解析XML到结构体
|
// 解析XML到结构体
|
||||||
var xmls T
|
var xmls T
|
||||||
|
|
||||||
t1 := gres.GetContent(path)
|
t1 := readConfigContent(path)
|
||||||
xml.Unmarshal(t1, &xmls)
|
xml.Unmarshal(t1, &xmls)
|
||||||
|
|
||||||
return xmls
|
return xmls
|
||||||
}
|
}
|
||||||
func getJson[T any](path string) T {
|
func getJson[T any](path string) T {
|
||||||
|
|
||||||
// 解析XML到结构体
|
// 解析JSON到结构体
|
||||||
var xmls T
|
var xmls T
|
||||||
t1 := gres.GetContent(path)
|
t1 := readConfigContent(path)
|
||||||
json.Unmarshal(t1, &xmls)
|
if len(t1) == 0 {
|
||||||
|
fmt.Printf("[xmlres] getJson empty content: path=%s\n", path)
|
||||||
|
return xmls
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(t1, &xmls); err != nil {
|
||||||
|
head := string(t1)
|
||||||
|
if len(head) > 300 {
|
||||||
|
head = head[:300]
|
||||||
|
}
|
||||||
|
fmt.Printf("[xmlres] getJson unmarshal failed: path=%s len=%d err=%v head=%q\n", path, len(t1), err, head)
|
||||||
|
}
|
||||||
|
|
||||||
return xmls
|
return xmls
|
||||||
}
|
}
|
||||||
@@ -59,6 +94,7 @@ var (
|
|||||||
func Initfile() {
|
func Initfile() {
|
||||||
//gres.Dump()
|
//gres.Dump()
|
||||||
path1, _ := os.Getwd()
|
path1, _ := os.Getwd()
|
||||||
|
diskConfigPath = filepath.Join(path1, "public", "config")
|
||||||
path = path1 + "/public/config/"
|
path = path1 + "/public/config/"
|
||||||
path = "config/"
|
path = "config/"
|
||||||
MapConfig = getXml[Maps](path + "210.xml")
|
MapConfig = getXml[Maps](path + "210.xml")
|
||||||
@@ -87,10 +123,10 @@ func Initfile() {
|
|||||||
return gconv.Int(m.ProductID)
|
return gconv.Int(m.ProductID)
|
||||||
|
|
||||||
})
|
})
|
||||||
Skill := getXml[MovesTbl](path + "227.xml")
|
skillConfig := getJson[MovesJSON](path + "moves_flash.json")
|
||||||
|
|
||||||
SkillMap = make(map[int]Move, len(Skill.Moves))
|
SkillMap = make(map[int]Move, len(skillConfig.MovesTbl.Moves.Move))
|
||||||
for _, v := range Skill.Moves {
|
for _, v := range skillConfig.MovesTbl.Moves.Move {
|
||||||
v.SideEffectS = ParseSideEffectArgs(v.SideEffect)
|
v.SideEffectS = ParseSideEffectArgs(v.SideEffect)
|
||||||
v.SideEffectArgS = ParseSideEffectArgs(v.SideEffectArg)
|
v.SideEffectArgS = ParseSideEffectArgs(v.SideEffectArg)
|
||||||
SkillMap[v.ID] = v
|
SkillMap[v.ID] = v
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,7 @@
|
|||||||
package xmlres
|
package xmlres
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -33,52 +34,156 @@ type MovesTbl struct {
|
|||||||
Moves []Move `xml:"Moves>Move"`
|
Moves []Move `xml:"Moves>Move"`
|
||||||
EFF []SideEffect `xml:"SideEffects>SideEffect"`
|
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 {
|
type MovesMap struct {
|
||||||
XMLName xml.Name `xml:"MovesTbl"`
|
XMLName xml.Name `xml:"MovesTbl"`
|
||||||
Moves map[int]Move
|
Moves map[int]Move
|
||||||
EFF []SideEffect `xml:"SideEffects>SideEffect"`
|
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 定义单个技能的结构
|
// Move 定义单个技能的结构
|
||||||
type Move struct {
|
type Move struct {
|
||||||
ID int `xml:"ID,attr"`
|
ID int `xml:"ID,attr" json:"ID"`
|
||||||
Name string `xml:"Name,attr"`
|
Name string `xml:"Name,attr" json:"Name"`
|
||||||
|
|
||||||
Category int `xml:"Category,attr"` //属性
|
Category int `xml:"Category,attr" json:"Category"` //属性
|
||||||
Type int `xml:"Type,attr"` //类型
|
Type int `xml:"Type,attr" json:"Type"` //类型
|
||||||
Power int `xml:"Power,attr"` //威力
|
Power int `xml:"Power,attr" json:"Power"` //威力
|
||||||
MaxPP int `xml:"MaxPP,attr"` //最大PP
|
MaxPP int `xml:"MaxPP,attr" json:"MaxPP"` //最大PP
|
||||||
Accuracy int `xml:"Accuracy,attr"` //命中率
|
Accuracy int `xml:"Accuracy,attr" json:"Accuracy"` //命中率
|
||||||
CritRate int `xml:"CritRate,attr,omitempty"` //暴击率
|
CritRate int `xml:"CritRate,attr,omitempty" json:"CritRate,omitempty"` //暴击率
|
||||||
Priority int `xml:"Priority,attr,omitempty"` //优先级
|
Priority int `xml:"Priority,attr,omitempty" json:"Priority,omitempty"` //优先级
|
||||||
MustHit int `xml:"MustHit,attr,omitempty"` //是否必中
|
MustHit int `xml:"MustHit,attr,omitempty" json:"MustHit,omitempty"` //是否必中
|
||||||
SwapElemType int `xml:"SwapElemType,attr,omitempty"` //技能交换属性
|
SwapElemType int `xml:"SwapElemType,attr,omitempty" json:"SwapElemType,omitempty"` //技能交换属性
|
||||||
CopyElemType int `xml:"CopyElemType,attr,omitempty"` // 技能复制属性
|
CopyElemType int `xml:"CopyElemType,attr,omitempty" json:"CopyElemType,omitempty"` // 技能复制属性
|
||||||
CritAtkFirst int `xml:"CritAtkFirst,attr,omitempty"` // 先出手时必定致命一击
|
CritAtkFirst int `xml:"CritAtkFirst,attr,omitempty" json:"CritAtkFirst,omitempty"` // 先出手时必定致命一击
|
||||||
CritAtkSecond int `xml:"CritAtkSecond,attr,omitempty"` //后出手时必定致命一击
|
CritAtkSecond int `xml:"CritAtkSecond,attr,omitempty" json:"CritAtkSecond,omitempty"` //后出手时必定致命一击
|
||||||
CritSelfHalfHp int `xml:"CritSelfHalfHp,attr,omitempty"` //自身体力低于一半时必定致命一击
|
CritSelfHalfHp int `xml:"CritSelfHalfHp,attr,omitempty" json:"CritSelfHalfHp,omitempty"` //自身体力低于一半时必定致命一击
|
||||||
CritFoeHalfHp int `xml:"CritFoeHalfHp,attr,omitempty"` //对方体力低于一半时必定致命一击
|
CritFoeHalfHp int `xml:"CritFoeHalfHp,attr,omitempty" json:"CritFoeHalfHp,omitempty"` //对方体力低于一半时必定致命一击
|
||||||
DmgBindLv int `xml:"DmgBindLv,attr,omitempty"` //使对方受到的伤害值等于自身的等级
|
DmgBindLv int `xml:"DmgBindLv,attr,omitempty" json:"DmgBindLv,omitempty"` //使对方受到的伤害值等于自身的等级
|
||||||
PwrBindDv int `xml:"PwrBindDv,attr,omitempty"` //威力(power)取决于自身的潜力(个体值)
|
PwrBindDv int `xml:"PwrBindDv,attr,omitempty" json:"PwrBindDv,omitempty"` //威力(power)取决于自身的潜力(个体值)
|
||||||
PwrDouble int `xml:"PwrDouble,attr,omitempty"` //攻击时,若对方处于异常状态, 则威力翻倍;
|
PwrDouble int `xml:"PwrDouble,attr,omitempty" json:"PwrDouble,omitempty"` //攻击时,若对方处于异常状态, 则威力翻倍;
|
||||||
DmgBindHpDv int `xml:"DmgBindHpDv,attr,omitempty"` //使对方受到的伤害值等于自身的体力值
|
DmgBindHpDv int `xml:"DmgBindHpDv,attr,omitempty" json:"DmgBindHpDv,omitempty"` //使对方受到的伤害值等于自身的体力值
|
||||||
SideEffect string `xml:"SideEffect,attr,omitempty"`
|
SideEffect string `xml:"SideEffect,attr,omitempty" json:"SideEffect,omitempty"`
|
||||||
SideEffectArg string `xml:"SideEffectArg,attr,omitempty"`
|
SideEffectArg string `xml:"SideEffectArg,attr,omitempty" json:"SideEffectArg,omitempty"`
|
||||||
SideEffectS []int
|
SideEffectS []int
|
||||||
SideEffectArgS []int
|
SideEffectArgS []int
|
||||||
AtkNum int `xml:"AtkNum,attr,omitempty"`
|
AtkNum int `xml:"AtkNum,attr,omitempty" json:"AtkNum,omitempty"`
|
||||||
AtkType int `xml:"AtkType,attr,omitempty"` // 0:所有人 1:仅己方 2:仅对方 3:仅自己
|
AtkType int `xml:"AtkType,attr,omitempty" json:"AtkType,omitempty"` // 0:所有人 1:仅己方 2:仅对方 3:仅自己
|
||||||
Url string `xml:"Url,attr,omitempty"`
|
Url string `xml:"Url,attr,omitempty" json:"Url,omitempty"`
|
||||||
|
|
||||||
Info string `xml:"info,attr,omitempty"`
|
Info string `xml:"info,attr,omitempty" json:"info,omitempty"`
|
||||||
|
|
||||||
CD *int `xml:"CD,attr"`
|
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 {
|
type SideEffect struct {
|
||||||
ID int `xml:"ID,attr"`
|
ID int `xml:"ID,attr" json:"ID"`
|
||||||
Help string `xml:"help,attr"`
|
Help string `xml:"help,attr" json:"help"`
|
||||||
Des string `xml:"des,attr"`
|
Des string `xml:"des,attr" json:"des"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadHTTPFile 通过HTTP GET请求获取远程文件内容
|
// ReadHTTPFile 通过HTTP GET请求获取远程文件内容
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
E:/newcode/sun/public/assets/227.xml
|
|
||||||
347076
public/config/moves.json
347076
public/config/moves.json
File diff suppressed because it is too large
Load Diff
1
public/config/moves_flash.json
Symbolic link
1
public/config/moves_flash.json
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
E:/newcode/flash/out/resource/json/moves_flash.json
|
||||||
Reference in New Issue
Block a user