refactor(socket): 重构 ClientData 结构体并优化相关逻辑
- 简化 ClientData 结构体,移除不必要的方法 - 优化 Player 结构体,调整 Conn 类型 - 更新 wscodec.go 中的 Conn 结构体 - 删除未使用的 XML 相关文件和代码 - 调整 ServerEvent 和 controller 中的相关逻辑
This commit is contained in:
84
common/data/xmlres/file.go
Normal file
84
common/data/xmlres/file.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package xmlres
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/ECUST-XX/xml"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gfsnotify"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
)
|
||||
|
||||
var path string
|
||||
|
||||
func getXml[T any](path string) T {
|
||||
|
||||
// 解析XML到结构体
|
||||
var xmls T
|
||||
t1 := gfile.GetBytes(path)
|
||||
xml.Unmarshal(t1, &xmls)
|
||||
|
||||
return xmls
|
||||
}
|
||||
|
||||
var (
|
||||
MapConfig Maps //地图配置
|
||||
ItemsConfig Items //物品配置
|
||||
TalkConfig TalkCount //任务配置
|
||||
Monster MonsterRoot //野怪配置
|
||||
Skill MovesTbl //技能配置
|
||||
)
|
||||
|
||||
func initfile() {
|
||||
path1, _ := os.Getwd()
|
||||
path = path1 + "/public/assets/"
|
||||
MapConfig = getXml[Maps](path + "210.xml")
|
||||
ItemsConfig = getXml[Items](path + "43.xml")
|
||||
TalkConfig = getXml[TalkCount](path + "talk.xml")
|
||||
Monster = getXml[MonsterRoot](path + "地图配置野怪.xml")
|
||||
Skill = getXml[MovesTbl](path + "227.xml")
|
||||
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
initfile() //先初始化一次
|
||||
|
||||
go func() {
|
||||
|
||||
if !gfile.Exists(path) {
|
||||
fileHandle, _ := gfile.Create(path)
|
||||
fileHandle.Close()
|
||||
}
|
||||
|
||||
//updatersares()
|
||||
ctx := gctx.New()
|
||||
_, err := gfsnotify.Add(path, func(event *gfsnotify.Event) {
|
||||
if event.IsCreate() {
|
||||
glog.Debug(ctx, "创建文件 : ", event.Path)
|
||||
}
|
||||
if event.IsWrite() {
|
||||
glog.Debug(ctx, "写入文件 : ", event.Path)
|
||||
initfile() //先初始化一次
|
||||
}
|
||||
if event.IsRemove() {
|
||||
glog.Debug(ctx, "删除文件 : ", event.Path)
|
||||
}
|
||||
if event.IsRename() {
|
||||
glog.Debug(ctx, "重命名文件 : ", event.Path)
|
||||
}
|
||||
if event.IsChmod() {
|
||||
glog.Debug(ctx, "修改权限 : ", event.Path)
|
||||
}
|
||||
glog.Debug(ctx, event)
|
||||
}, true)
|
||||
|
||||
if err != nil {
|
||||
glog.Fatal(ctx, err)
|
||||
} else {
|
||||
select {}
|
||||
}
|
||||
}()
|
||||
|
||||
}
|
||||
53
common/data/xmlres/item.go
Normal file
53
common/data/xmlres/item.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package xmlres
|
||||
|
||||
import (
|
||||
"github.com/ECUST-XX/xml" // 保持与之前一致的XML库
|
||||
)
|
||||
|
||||
// Items 根节点,对应<Items>标签
|
||||
type Items struct {
|
||||
XMLName xml.Name `xml:"Items"`
|
||||
Items []Item `xml:"Item"` // 包含所有物品配置
|
||||
}
|
||||
|
||||
// Item 单个物品配置,对应<Item>标签
|
||||
type Item struct {
|
||||
ID int `xml:"ID,attr"` // 物品ID(与items.xml一致)
|
||||
Name string `xml:"Name,attr"` // 物品名称
|
||||
Rarity int `xml:"Rarity,attr,omitempty"` // 稀有度(可选)
|
||||
Price int `xml:"Price,attr"` // 价格
|
||||
Tradability int `xml:"Tradability,attr"` // 可交易性(0/1)
|
||||
VipTradability int `xml:"VipTradability,attr"` // VIP可交易性(0/1)
|
||||
DailyKey int `xml:"DailyKey,attr,omitempty"` // 每日限制键值(可选)
|
||||
DailyOutMax int `xml:"DailyOutMax,attr,omitempty"` // 每日最大产出(可选)
|
||||
Wd int `xml:"wd,attr"` // 未知属性(根据原XML保留)
|
||||
UseMax int `xml:"UseMax,attr"` // 最大使用次数
|
||||
LifeTime int `xml:"LifeTime,attr"` // 生命周期(0为永久)
|
||||
Purpose int `xml:"purpose,attr"` // 用途标识
|
||||
Bean int `xml:"Bean,attr,omitempty"` // 豆子数量(可选)
|
||||
Hide int `xml:"Hide,attr"` // 是否隐藏(0/1)
|
||||
Sort int `xml:"Sort,attr,omitempty"` // 排序序号(可选)
|
||||
Des string `xml:"des,attr"` // 物品用途(根据说明补充)
|
||||
Color string `xml:"color,attr,omitempty"` // 装备名字颜色(可选)
|
||||
Level int `xml:"level,attr,omitempty"` // 装备等级(星星,可选)
|
||||
|
||||
Pet *Pet `xml:"pet,omitempty"` // 精灵属性子节点(可选)
|
||||
TeamPK *TeamPK `xml:"teamPK,omitempty"` // 要塞保卫战子节点(可选)
|
||||
}
|
||||
|
||||
// Pet 精灵属性子节点,对应<pet>标签
|
||||
// 注:根据实际需求补充字段,这里以常见属性为例
|
||||
type Pet struct {
|
||||
Attack int `xml:"attack,attr,omitempty"` // 攻击加成
|
||||
Defense int `xml:"defense,attr,omitempty"` // 防御加成
|
||||
HP int `xml:"hp,attr,omitempty"` // 生命值加成
|
||||
Speed int `xml:"speed,attr,omitempty"` // 速度加成
|
||||
}
|
||||
|
||||
// TeamPK 要塞保卫战子节点,对应<teamPK>标签
|
||||
// 注:根据实际需求补充字段,这里以常见属性为例
|
||||
type TeamPK struct {
|
||||
FortBonus int `xml:"fortBonus,attr,omitempty"` // 要塞加成
|
||||
DefenseBonus int `xml:"defenseBonus,attr,omitempty"` // 防御加成
|
||||
AttackBonus int `xml:"attackBonus,attr,omitempty"` // 攻击加成
|
||||
}
|
||||
64
common/data/xmlres/map.go
Normal file
64
common/data/xmlres/map.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package xmlres
|
||||
|
||||
import (
|
||||
"github.com/ECUST-XX/xml"
|
||||
)
|
||||
|
||||
// Maps 根节点,对应<Maps>标签
|
||||
type Maps struct {
|
||||
XMLName xml.Name `xml:"Maps"`
|
||||
Maps []Map `xml:"map"` // 包含所有地图配置
|
||||
}
|
||||
|
||||
// Map 单张地图配置,对应<map>标签
|
||||
type Map struct {
|
||||
ID int `xml:"id,attr"` // 地图ID
|
||||
Name string `xml:"name,attr"` // 地图名称
|
||||
X int `xml:"x,attr"` // 地图X坐标
|
||||
Y int `xml:"y,attr"` // 地图Y坐标
|
||||
Des string `xml:"des,attr,omitempty"` // 地图描述(可选)
|
||||
Super int `xml:"super,attr,omitempty"` // 上级地图ID(可选)
|
||||
IsFB int `xml:"isFB,attr,omitempty"` // 是否为副本(0/1,可选)
|
||||
IsLocal int `xml:"isLocal,attr,omitempty"` // 是否为本地地图(0/1,可选)
|
||||
Sound string `xml:"sound,attr,omitempty"` // 背景音乐(可选)
|
||||
ReplaceMapID int `xml:"replaceMapId,attr,omitempty"` // 替换地图ID(可选)
|
||||
FX int `xml:"fx,attr,omitempty"` // 道具地面X坐标(可选)
|
||||
FY int `xml:"fy,attr,omitempty"` // 道具地面Y坐标(可选)
|
||||
WX int `xml:"wx,attr,omitempty"` // 道具墙面X坐标(可选)
|
||||
WY int `xml:"wy,attr,omitempty"` // 道具墙面Y坐标(可选)
|
||||
HX int `xml:"hx,attr,omitempty"` // 总部主电脑X坐标(可选)
|
||||
HY int `xml:"hy,attr,omitempty"` // 总部主电脑Y坐标(可选)
|
||||
|
||||
Entries Entries `xml:"Entries,omitempty"` // 进入点配置(可选)
|
||||
ChangeMapComp ComponentList `xml:"changeMapComp,omitempty"` // 场景切换组件(可选)
|
||||
FunComp ComponentList `xml:"funComp,omitempty"` // 点击触发组件(可选)
|
||||
AutoComp ComponentList `xml:"autoComp,omitempty"` // 自动触发组件(可选)
|
||||
}
|
||||
|
||||
// Entries 进入点集合,对应<Entries>标签
|
||||
type Entries struct {
|
||||
Entries []Entry `xml:"Entry"` // 多个进入点
|
||||
}
|
||||
|
||||
// Entry 单个进入点配置,对应<Entry>标签
|
||||
type Entry struct {
|
||||
FromMap int `xml:"FromMap,attr"` // 来源地图ID
|
||||
PosX int `xml:"PosX,attr"` // 进入后X坐标
|
||||
PosY int `xml:"PosY,attr"` // 进入后Y坐标
|
||||
}
|
||||
|
||||
// ComponentList 组件集合(用于统一管理不同类型的组件列表)
|
||||
type ComponentList struct {
|
||||
Components []Component `xml:"component"` // 多个组件
|
||||
}
|
||||
|
||||
// Component 单个功能组件配置,对应<component>标签
|
||||
type Component struct {
|
||||
Name string `xml:"name,attr,omitempty"` // 组件名称(可选)
|
||||
Hit string `xml:"hit,attr,omitempty"` // 碰撞区域标识(可选)
|
||||
TargetID int `xml:"targetID,attr,omitempty"` // 目标地图ID(可选)
|
||||
Dir int `xml:"dir,attr,omitempty"` // 滚动方向(1-4,可选)
|
||||
Fun string `xml:"fun,attr,omitempty"` // 触发函数名(可选)
|
||||
Des string `xml:"des,attr,omitempty"` // 鼠标提示文本(可选)
|
||||
IsStop int `xml:"isStop,attr,omitempty"` // 鼠标悬停是否跳帧(0/1,可选)
|
||||
}
|
||||
122
common/data/xmlres/mon.go
Normal file
122
common/data/xmlres/mon.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package xmlres
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
)
|
||||
|
||||
// 根结构体:对应 <Maps> 节点
|
||||
type MonsterRoot struct {
|
||||
XMLName xml.Name `xml:"Maps"`
|
||||
WorldWildMons WorldWildMons `xml:"WorldWildMons"` // 世界野怪配置
|
||||
Maps []TMapConfig `xml:"Map"` // 所有地图配置(多个<Map>)
|
||||
DefaultMaps DefaultMaps `xml:"DefaultMaps"` // 默认登录场景
|
||||
VersionNumber VersionNumber `xml:"VersionNumber"` // 版本信息
|
||||
}
|
||||
|
||||
// 世界野怪容器:对应 <WorldWildMons>
|
||||
type WorldWildMons struct {
|
||||
WorldWildMonsters []WorldWildMonster `xml:"WorldWildMonster"` // 多个<WorldWildMonster>
|
||||
}
|
||||
|
||||
// 世界野怪配置:对应 <WorldWildMonster>
|
||||
type WorldWildMonster struct {
|
||||
WorldWildProb int `xml:"WorldWildProb,attr"` // 变身概率(分子)
|
||||
WorldWildMonId int `xml:"WorldWildMonId,attr"` // 野怪ID
|
||||
WorldWildMonLv int `xml:"WorldWildMonLv,attr"` // 野怪等级
|
||||
WorldWildStart int `xml:"WorldWildStart,attr"` // 出现起始时间(0-23)
|
||||
WorldWildEnd int `xml:"WorldWildEnd,attr"` // 出现结束时间(0-23)
|
||||
NewSeIdxs string `xml:"NewSeIdxs,attr"` // 特效ID(可能多个,空格分隔)
|
||||
}
|
||||
|
||||
// 单张地图配置:对应 <Map>
|
||||
type TMapConfig struct {
|
||||
ID int `xml:"ID,attr"` // 地图ID
|
||||
Name string `xml:"Name,attr"` // 地图名称
|
||||
InitX int `xml:"InitX,attr"` // 玩家初始X坐标
|
||||
InitY int `xml:"InitY,attr"` // 玩家初始Y坐标
|
||||
GameTriggerGrps []GameTriggerGrp `xml:"GameTriggerGrp"` // 触发点组(多个)
|
||||
Monsters *MonstersC `xml:"Monsters"` // 新增:野怪配置(可选,用指针处理“无该节点”的情况)
|
||||
Bosses []BossConfig `xml:"Bosses>Boss"` // BOSS配置(<Bosses>下的<Boss>)
|
||||
}
|
||||
|
||||
// ########################### 关键新增:MonstersConfig(对应 <Monsters>) ###########################
|
||||
// 野怪配置容器:包含野怪奖励概率和多只野怪
|
||||
type MonstersC struct {
|
||||
WildBonusProb int `xml:"WildBonusProb,attr"` // 打赢野怪给奖励的概率(分子,如300)
|
||||
WildBonusTotalProb int `xml:"WildBonusTotalProb,attr"` // 打赢野怪给奖励的概率(分母,如1000)
|
||||
BonusID int `xml:"BonusID,attr"` // 奖励ID(如5239)
|
||||
ItemBonusID int `xml:"ItemBonusID,attr"` // 物品奖励ID(如1)
|
||||
Monsters []Monster1 `xml:"Monster"` // 多只野怪(<Monster>子节点)
|
||||
}
|
||||
|
||||
// ########################### 关键新增:Monster(对应 <Monster>) ###########################
|
||||
// 单只野怪配置:ID可能是多个值(空格分隔),Lv是等级范围(空格分隔)
|
||||
type Monster1 struct {
|
||||
ID string `xml:"ID,attr"` // 野怪ID(如"164 0 0..."或"10")
|
||||
Lv string `xml:"Lv,attr"` // 等级范围(如"1 2"表示1-2级)
|
||||
}
|
||||
|
||||
// 游戏触发点组:对应 <GameTriggerGrp>
|
||||
type GameTriggerGrp struct {
|
||||
GameID string `xml:"GameID,attr"` // 游戏ID
|
||||
TriggerPts []TriggerPt `xml:"TriggerPt"` // 触发点(多个)
|
||||
}
|
||||
|
||||
// 触发点:对应 <TriggerPt>
|
||||
type TriggerPt struct {
|
||||
ID int `xml:"ID,attr"` // 触发点ID
|
||||
Name string `xml:"Name,attr"` // 触发点名称(可选)
|
||||
}
|
||||
|
||||
// BOSS配置:对应 <Boss>
|
||||
type BossConfig struct {
|
||||
Id *int `xml:"Id,attr"` // BOSSID(可选,用指针处理空值)
|
||||
BossCatchable int `xml:"BossCatchable,attr"` // 是否可捕捉(0/1,默认0)
|
||||
AppearTime string `xml:"AppearTime,attr"` // 出现时间(如"0 23")
|
||||
BossVisible int `xml:"BossVisible,attr"` // 是否可见(0/1,默认0)
|
||||
Name string `xml:"Name,attr"` // BOSS名称(可选)
|
||||
DailyKey *string `xml:"DailyKey,attr"` // 每日挑战次数Key(可选)
|
||||
MaxTimes *int `xml:"MaxTimes,attr"` // 非VIP每日挑战上限(可选)
|
||||
VipMaxTimes *int `xml:"VipMaxTimes,attr"` // VIP每日挑战上限(可选)
|
||||
WinBonusId *string `xml:"WinBonusId,attr"` // 胜利奖励ID(可选)
|
||||
WinOutId *int `xml:"WinOutId,attr"` // 胜利输出ID(可选)
|
||||
FailBonusId *string `xml:"FailBonusId,attr"` // 失败奖励ID(可选)
|
||||
FailOutId *int `xml:"FailOutId,attr"` // 失败输出ID(可选)
|
||||
BossMon []BossMon `xml:"BossMon"` // BOSS对应的精灵(多个)
|
||||
}
|
||||
|
||||
// BOSS精灵配置:对应 <BossMon>
|
||||
type BossMon struct {
|
||||
MonID string `xml:"MonID,attr"` // 精灵ID(可能多个,空格分隔)
|
||||
Hp int `xml:"Hp,attr"` // 生命值
|
||||
Lv int `xml:"Lv,attr"` // 等级
|
||||
NewSeIdxs string `xml:"NewSeIdxs,attr"` // 特效ID(可选,空格分隔)
|
||||
Atk *int `xml:"Atk,attr"` // 攻击(可选)
|
||||
Def *int `xml:"Def,attr"` // 防御(可选)
|
||||
Spatk *int `xml:"Spatk,attr"` // 特攻(可选)
|
||||
Spdef *int `xml:"Spdef,attr"` // 特防(可选)
|
||||
Spd *int `xml:"Spd,attr"` // 速度(可选)
|
||||
}
|
||||
|
||||
// 默认登录场景容器:对应 <DefaultMaps>
|
||||
type DefaultMaps struct {
|
||||
DefaultMaps []DefaultMap `xml:"DefaultMap"` // 多个默认场景
|
||||
}
|
||||
|
||||
// 默认登录场景:对应 <DefaultMap>
|
||||
type DefaultMap struct {
|
||||
ID int `xml:"ID,attr"` // 场景ID
|
||||
RandMaps string `xml:"RandMaps,attr"` // 随机场景列表(逗号分隔)
|
||||
Desc string `xml:"Desc,attr"` // 场景描述
|
||||
}
|
||||
|
||||
// 版本信息容器:对应 <VersionNumber>
|
||||
type VersionNumber struct {
|
||||
Version Version `xml:"Version"` // 版本详情
|
||||
}
|
||||
|
||||
// 版本详情:对应 <Version>
|
||||
type Version struct {
|
||||
ID string `xml:"ID,attr"` // 版本号(如"20190614")
|
||||
Desc string `xml:"Desc,attr"` // 版本描述
|
||||
}
|
||||
117
common/data/xmlres/skill.go
Normal file
117
common/data/xmlres/skill.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package xmlres
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"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"`
|
||||
Moves map[int]Move
|
||||
EFF []SideEffect `xml:"SideEffects>SideEffect"`
|
||||
}
|
||||
|
||||
// Move 定义单个技能的结构
|
||||
type Move struct {
|
||||
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"`
|
||||
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"`
|
||||
PwrDouble int `xml:"PwrDouble,attr,omitempty"`
|
||||
|
||||
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
|
||||
}
|
||||
func getxml() ([]byte, error) {
|
||||
|
||||
// 读取整个文件内容,返回字节切片和错误
|
||||
content, err := ReadHTTPFile("http://127.0.0.1:8080/assets/227.xml")
|
||||
if err != nil {
|
||||
// 处理错误(文件不存在、权限问题等)
|
||||
log.Fatalf("无法读取文件: %v", err)
|
||||
}
|
||||
return content, nil
|
||||
|
||||
}
|
||||
func getMoves() MovesMap {
|
||||
|
||||
// 解析XML到结构体
|
||||
var maps MovesTbl
|
||||
t1, _ := getxml()
|
||||
xml.Unmarshal(t1, &maps)
|
||||
var mapss MovesMap
|
||||
mapss.Moves = make(map[int]Move, 0)
|
||||
for _, v := range maps.Moves {
|
||||
mapss.Moves[int(v.ID)] = v
|
||||
}
|
||||
|
||||
return mapss
|
||||
}
|
||||
|
||||
// 全局函数配置
|
||||
var MovesConfig = getMoves()
|
||||
23
common/data/xmlres/talk.go
Normal file
23
common/data/xmlres/talk.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package xmlres
|
||||
|
||||
import (
|
||||
"github.com/ECUST-XX/xml" // 注意:需确保该xml库与示例中使用的一致
|
||||
)
|
||||
|
||||
// TalkCount 根节点,对应<talk_count>标签
|
||||
// 注意:xml.Name需指定命名空间,与XML中的xmlns保持一致
|
||||
type TalkCount struct {
|
||||
XMLName xml.Name `xml:"nieo.seer.org.talk-count talk_count"`
|
||||
Entries []TalkEntry `xml:"entry"` // 包含所有entry节点
|
||||
}
|
||||
|
||||
// Entry 单个条目配置,对应<entry>标签
|
||||
type TalkEntry struct {
|
||||
ID int `xml:"id,attr"` // 条目ID
|
||||
ItemID int `xml:"item_id,attr"` // 物品ID
|
||||
ItemMinCount int `xml:"item_min_count,attr"` // 物品最小数量
|
||||
ItemMaxCount int `xml:"item_max_count,attr"` // 物品最大数量
|
||||
Desc string `xml:"desc,attr"` // 描述信息
|
||||
Count int `xml:"count,attr"` // 计数
|
||||
Policy string `xml:"policy,attr,omitempty"` // 策略(可选,如week)
|
||||
}
|
||||
142
common/data/xmlres/xml_test.go
Normal file
142
common/data/xmlres/xml_test.go
Normal file
@@ -0,0 +1,142 @@
|
||||
package xmlres
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ECUST-XX/xml"
|
||||
"github.com/antchfx/xmlquery"
|
||||
)
|
||||
|
||||
var s = `
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
多个地图ID归属于一个星球
|
||||
此XML表主要配置一些各个星球有可能需要用到的共用信息, 比如目前在世界地图上显示玩家所在位置
|
||||
-->
|
||||
<superMaps>
|
||||
<maps id="1" name="传送舱" x="" y=""/>
|
||||
<maps id="4" name="船长室" x="" y=""/>
|
||||
<maps id="5" name="实验室" x="" y=""/>
|
||||
<maps id="6" name="动力室" x="" y=""/>
|
||||
<maps id="7" name="瞭望舱" x="" y=""/>
|
||||
<maps id="8" name="机械室" x="" y=""/>
|
||||
<maps id="9" name="资料室" x="" y=""/>
|
||||
<maps id="19" name="太空站" x="" y=""/>
|
||||
<maps id="101" name="教官办公室" x="" y=""/>
|
||||
<maps id="103" name="瞭望露台" x="" y=""/>
|
||||
<maps id="107" name="发明室" x="" y=""/>
|
||||
<!--星球-->
|
||||
<maps id="10 11 12 13" name="克洛斯星" galaxy="1" x="358" y="46"/>
|
||||
<maps id="15 16 17" name="火山星" galaxy="1" x="533" y="46"/>
|
||||
<maps id="20 21 22" name="海洋星" galaxy="1" x="190" y="11"/>
|
||||
<maps id="25 26 27" name="云霄星" galaxy="1" x="652" y="24"/>
|
||||
<maps id="30 31 32 33 34 35 36" name="赫尔卡星" galaxy="1" x="45" y="34"/>
|
||||
<maps id="40 41 42 43" name="塞西利亚星" galaxy="1" x="1012" y="30"/>
|
||||
<maps id="17" name="双子阿尔法星" galaxy="1" x="822" y="96"/>
|
||||
<maps id="47 49" name="双子贝塔星" galaxy="1" x="883" y="63"/>
|
||||
<maps id="51 52 53" name="斯诺星" galaxy="1" x="1290" y="15"/>
|
||||
<maps id="54 55 56" name="露西欧星" galaxy="1" x="1405" y="120"/>
|
||||
<maps id="57 58 59" name="尼古尔星" galaxy="2" x="30" y="50"/>
|
||||
<maps id="60 61 62 63 64" name="塔克星" galaxy="2" x="135" y="44"/>
|
||||
<maps id="325 326 327" name="艾迪星" galaxy="2" x="250" y="30"/>
|
||||
<maps id="328" name="斯科尔星" galaxy="2" x="375" y="40"/>
|
||||
<maps id="333 334" name="普雷空间站" galaxy="2" x="500" y="50"/>
|
||||
<maps id="338 339" name="哈默星" galaxy="2" x="590" y="70"/>
|
||||
<maps id="314" name="拜伦号" galaxy="1" x="1160" y="55"/>
|
||||
</superMaps>`
|
||||
|
||||
func Test_main(t *testing.T) {
|
||||
|
||||
initfile()
|
||||
|
||||
}
|
||||
|
||||
func main1() {
|
||||
s := `
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
多个地图ID归属于一个星球
|
||||
此XML表主要配置一些各个星球有可能需要用到的共用信息, 比如目前在世界地图上显示玩家所在位置
|
||||
-->
|
||||
<superMaps>
|
||||
<maps id="1" name="传送舱" x="" y=""/>
|
||||
<maps id="4" name="船长室" x="" y=""/>
|
||||
<maps id="5" name="实验室" x="" y=""/>
|
||||
<maps id="6" name="动力室" x="" y=""/>
|
||||
<maps id="7" name="瞭望舱" x="" y=""/>
|
||||
<maps id="8" name="机械室" x="" y=""/>
|
||||
<maps id="9" name="资料室" x="" y=""/>
|
||||
<maps id="19" name="太空站" x="" y=""/>
|
||||
<maps id="101" name="教官办公室" x="" y=""/>
|
||||
<maps id="103" name="瞭望露台" x="" y=""/>
|
||||
<maps id="107" name="发明室" x="" y=""/>
|
||||
<!--星球-->
|
||||
<maps id="10 11 12 13" name="克洛斯星" galaxy="1" x="358" y="46"/>
|
||||
<maps id="15 16 17" name="火山星" galaxy="1" x="533" y="46"/>
|
||||
<maps id="20 21 22" name="海洋星" galaxy="1" x="190" y="11"/>
|
||||
<maps id="25 26 27" name="云霄星" galaxy="1" x="652" y="24"/>
|
||||
<maps id="30 31 32 33 34 35 36" name="赫尔卡星" galaxy="1" x="45" y="34"/>
|
||||
<maps id="40 41 42 43" name="塞西利亚星" galaxy="1" x="1012" y="30"/>
|
||||
<maps id="17" name="双子阿尔法星" galaxy="1" x="822" y="96"/>
|
||||
<maps id="47 49" name="双子贝塔星" galaxy="1" x="883" y="63"/>
|
||||
<maps id="51 52 53" name="斯诺星" galaxy="1" x="1290" y="15"/>
|
||||
<maps id="54 55 56" name="露西欧星" galaxy="1" x="1405" y="120"/>
|
||||
<maps id="57 58 59" name="尼古尔星" galaxy="2" x="30" y="50"/>
|
||||
<maps id="60 61 62 63 64" name="塔克星" galaxy="2" x="135" y="44"/>
|
||||
<maps id="325 326 327" name="艾迪星" galaxy="2" x="250" y="30"/>
|
||||
<maps id="328" name="斯科尔星" galaxy="2" x="375" y="40"/>
|
||||
<maps id="333 334" name="普雷空间站" galaxy="2" x="500" y="50"/>
|
||||
<maps id="338 339" name="哈默星" galaxy="2" x="590" y="70"/>
|
||||
<maps id="314" name="拜伦号" galaxy="1" x="1160" y="55"/>
|
||||
</superMaps>`
|
||||
|
||||
doc, err := xmlquery.Parse(strings.NewReader(s))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
//channel := xmlquery.FindOne(doc, "//superMaps")
|
||||
// if n := channel.SelectElement("maps"); n != nil {
|
||||
// fmt.Printf("title: %s\n", n.InnerText())
|
||||
// }
|
||||
if l := xmlquery.Find(doc, "//maps[@id='9']"); l != nil {
|
||||
t := l[0].Attr
|
||||
fmt.Printf("%v", t[1])
|
||||
}
|
||||
// for i, n := range xmlquery.Find(doc, "//maps/@id") {
|
||||
// fmt.Printf("#%d %s\n", i, n.InnerText())
|
||||
// }
|
||||
}
|
||||
|
||||
func TestMMMs(t *testing.T) {
|
||||
|
||||
decoder := xml.NewDecoder(strings.NewReader(s))
|
||||
var rootComments []string
|
||||
rootFound := false
|
||||
|
||||
for {
|
||||
token, err := decoder.Token()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
switch t := token.(type) {
|
||||
case xml.StartElement:
|
||||
// 遇到根元素开始标签后停止收集注释
|
||||
rootFound = true
|
||||
fmt.Printf("找到根元素: %s\n", t.Name.Local)
|
||||
case xml.Comment:
|
||||
if !rootFound {
|
||||
// 保存根元素前的注释
|
||||
rootComments = append(rootComments, string(t))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 输出捕获的根注释
|
||||
fmt.Println("\n根注释内容:")
|
||||
for _, comment := range rootComments {
|
||||
fmt.Println(strings.TrimSpace(comment))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user