refactor(socket): 重构 ClientData 结构体并优化相关逻辑

- 简化 ClientData 结构体,移除不必要的方法
- 优化 Player 结构体,调整 Conn 类型
- 更新 wscodec.go 中的 Conn 结构体
- 删除未使用的 XML 相关文件和代码
- 调整 ServerEvent 和 controller 中的相关逻辑
This commit is contained in:
2025-08-30 00:36:08 +08:00
parent 1f835c1197
commit 7b5ec208fc
31 changed files with 472 additions and 602 deletions

View File

@@ -1,9 +1,5 @@
package socket
import (
"sync"
)
func ConutPlayer() int {
count := 0
@@ -15,46 +11,19 @@ func ConutPlayer() int {
}
type ClientData struct {
isCrossDomain bool //是否跨域过
player *Player //客户实体
IsCrossDomain bool //是否跨域过
Player *Player //客户实体
//UserID uint32
m sync.Mutex
wsmsg WsCodec
}
func (cd *ClientData) SetPlayer(player *Player) {
cd.m.Lock()
defer cd.m.Unlock()
cd.player = player
}
func (cd *ClientData) GetPlayer() *Player {
cd.m.Lock()
defer cd.m.Unlock()
return cd.player
}
func (cd *ClientData) Getwsmsg() *WsCodec {
cd.m.Lock()
defer cd.m.Unlock()
return &cd.wsmsg
}
func (cd *ClientData) SetCrossDomain(isCrossDomain bool) {
cd.m.Lock()
defer cd.m.Unlock()
cd.isCrossDomain = isCrossDomain
}
func (cd *ClientData) GetIsCrossDomain() bool {
cd.m.Lock()
defer cd.m.Unlock()
return cd.isCrossDomain
Wsmsg *WsCodec
}
func NewClientData() *ClientData {
cd := ClientData{
isCrossDomain: false,
player: nil,
m: sync.Mutex{},
wsmsg: WsCodec{},
IsCrossDomain: false,
Player: nil,
Wsmsg: &WsCodec{},
}
return &cd

View File

@@ -20,7 +20,7 @@ var Mainplayer = &utils.SyncMap[uint32, *Player]{} //玩家数据
func (c *Conn) SendPack(bytes []byte) error {
if t, ok := c.MainConn.Context().(*ClientData); ok {
if t.Getwsmsg().Upgraded {
if t.Wsmsg.Upgraded {
// This is the echo server
err := wsutil.WriteServerMessage(c.MainConn, ws.OpBinary, bytes)
if err != nil {
@@ -41,7 +41,7 @@ func (c *Conn) SendPack(bytes []byte) error {
}
type Player struct {
MainConn Conn
MainConn *Conn
IsLogin bool //是否登录
mu sync.Mutex
@@ -58,7 +58,7 @@ type Player struct {
// PlayerOption 定义配置 Player 的函数类型
type PlayerOption func(*Player)
func WithConn(c Conn) PlayerOption {
func WithConn(c *Conn) PlayerOption {
return func(p *Player) {
p.MainConn = c
}
@@ -76,7 +76,7 @@ func NewPlayer(opts ...PlayerOption) *Player {
}
func (p *Player) SendPack(b []byte) error {
fmt.Println("发送数据包", len(b))
// fmt.Println("发送数据包", len(b))
err := p.MainConn.SendPack(b)
return err
}

View File

@@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"io"
"sync"
"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
@@ -13,6 +14,7 @@ import (
type Conn struct {
MainConn gnet.Conn `struc:"[0]pad"` //TODO 不序列化,,序列化下面的作为blob存数据库
Mu sync.Mutex
}
func NewConn(c gnet.Conn) *Conn {

View File

@@ -1,20 +0,0 @@
package xml
import (
"fmt"
"testing"
"github.com/ECUST-XX/xml"
)
func Test_main(t *testing.T) {
// 解析XML到结构体
var maps Items
t1, _ := getItemsXML()
xml.Unmarshal(t1, &maps)
//tf, _ := xml.MarshalIndentShortForm(tt, " ", " ")
fmt.Println(maps)
}

View File

@@ -1,106 +0,0 @@
package xml
import (
"fmt"
"io"
"log"
"net/http"
"time"
"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"` // 攻击加成
}
// 复用HTTP文件读取函数
func ReadHTTPFile(url string) ([]byte, error) {
client := &http.Client{
Timeout: 30 * time.Second,
}
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
}
// 获取物品XML内容
func getItemsXML() ([]byte, error) {
// 替换为实际的Items XML文件URL
content, err := ReadHTTPFile("http://127.0.0.1:8080/assets/43.xml")
if err != nil {
log.Fatalf("无法读取物品文件: %v", err)
}
return content, nil
}
// 解析XML到结构体
func getItems() Items {
var items Items
content, _ := getItemsXML()
if err := xml.Unmarshal(content, &items); err != nil {
log.Fatalf("物品XML解析失败: %v", err)
}
return items
}
// 全局物品配置变量
var ItemsConfig = getItems()

View File

@@ -1,20 +0,0 @@
package skill
import (
"fmt"
"testing"
"github.com/ECUST-XX/xml"
)
func Test_main(t *testing.T) {
// 解析XML到结构体
var maps MovesTbl
t1, _ := getxml()
xml.Unmarshal(t1, &maps)
//tf, _ := xml.MarshalIndentShortForm(tt, " ", " ")
fmt.Println(maps.Moves[4].SideEffect)
fmt.Println(maps.Moves[4].SideEffectArg)
}

View File

@@ -1,20 +0,0 @@
package xml
import (
"fmt"
"testing"
"github.com/ECUST-XX/xml"
)
func Test_main(t *testing.T) {
// 解析XML到结构体
var maps TalkCount
t1, _ := getxml()
xml.Unmarshal(t1, &maps)
//tf, _ := xml.MarshalIndentShortForm(tt, " ", " ")
fmt.Println(maps)
}

View File

@@ -1,89 +0,0 @@
package xml
import (
"fmt"
"io"
"log"
"net/http"
"time"
"github.com/ECUST-XX/xml" // 注意需确保该xml库与示例中使用的一致
)
func getxml() ([]byte, error) {
// 读取整个文件内容,返回字节切片和错误
content, err := ReadHTTPFile("http://127.0.0.1:8080/assets/talk_count.xml")
if err != nil {
// 处理错误(文件不存在、权限问题等)
log.Fatalf("无法读取文件: %v", err)
}
return content, nil
}
// TalkCount 根节点,对应<talk_count>标签
// 注意xml.Name需指定命名空间与XML中的xmlns保持一致
type TalkCount struct {
XMLName xml.Name `xml:"nieo.seer.org.talk-count talk_count"`
Entries []Entry `xml:"entry"` // 包含所有entry节点
}
// Entry 单个条目配置,对应<entry>标签
type Entry 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
}
// 复用示例中的ReadHTTPFile函数读取远程文件
func ReadHTTPFile(url string) ([]byte, error) {
client := &http.Client{
Timeout: 30 * time.Second,
}
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
}
// 获取XML内容可根据实际URL修改
func getTalkCountXML() ([]byte, error) {
// 注意此处URL需替换为实际的talk_count.xml文件地址
content, err := ReadHTTPFile("http://127.0.0.1:8080/assets/talk_count.xml")
if err != nil {
log.Fatalf("无法读取文件: %v", err)
}
return content, nil
}
// 解析XML到结构体
func getTalkCount() TalkCount {
var talkCount TalkCount
content, _ := getTalkCountXML()
// 解析XML时需注意命名空间匹配
if err := xml.Unmarshal(content, &talkCount); err != nil {
log.Fatalf("XML解析失败: %v", err)
}
return talkCount
}
// 全局配置变量,用于存储解析后的结果
var TalkCountConfig = getTalkCount()

View 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 {}
}
}()
}

View 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"` // 攻击加成
}

View File

@@ -1,12 +1,6 @@
package xml
package xmlres
import (
"fmt"
"io"
"log"
"net/http"
"time"
"github.com/ECUST-XX/xml"
)
@@ -68,56 +62,3 @@ type Component struct {
Des string `xml:"des,attr,omitempty"` // 鼠标提示文本(可选)
IsStop int `xml:"isStop,attr,omitempty"` // 鼠标悬停是否跳帧0/1可选
}
// 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/210.xml")
if err != nil {
// 处理错误(文件不存在、权限问题等)
log.Fatalf("无法读取文件: %v", err)
}
return content, nil
}
func getMaps() Maps {
// 解析XML到结构体
var maps Maps
t1, _ := getxml()
xml.Unmarshal(t1, &maps)
return maps
}
// 全局函数配置
var MapConfig = getMaps()

122
common/data/xmlres/mon.go Normal file
View 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"` // 版本描述
}

View File

@@ -1,4 +1,4 @@
package skill
package xmlres
import (
"encoding/xml"

View 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
}

View File

@@ -1,4 +1,4 @@
package xml
package xmlres
import (
"fmt"
@@ -49,13 +49,7 @@ var s = `
func Test_main(t *testing.T) {
// 解析XML到结构体
var maps Maps
t1, _ := getxml()
xml.Unmarshal(t1, &maps)
//tf, _ := xml.MarshalIndentShortForm(tt, " ", " ")
fmt.Println(maps)
initfile()
}

View File

@@ -46,13 +46,13 @@ func (s *Server) OnClose(c gnet.Conn, _ error) (action gnet.Action) {
return
}
t := v.GetPlayer()
if v != nil {
glog.Debug(context.Background(), t, "断开连接")
t.IsLogin = false
socket.Mainplayer.Delete(t.Info.UserID)
share.ShareManager.DeleteUserOnline(t.Info.UserID) //设置用户登录服务器
t.Save() //保存玩家数据
if v.Player != nil {
glog.Debug(context.Background(), v.Player.Info.UserID, "断开连接")
v.Player.IsLogin = false
socket.Mainplayer.Delete(v.Player.Info.UserID)
share.ShareManager.DeleteUserOnline(v.Player.Info.UserID) //设置用户登录服务器
v.Player.Save() //保存玩家数据
}
//}
@@ -86,7 +86,7 @@ func (s *Server) OnTraffic(c gnet.Conn) (action gnet.Action) {
return gnet.Close
}
ws := c.Context().(*socket.ClientData).Getwsmsg()
ws := c.Context().(*socket.ClientData).Wsmsg
tt, len1 := ws.ReadBufferBytes(c)
if tt == gnet.Close {
@@ -166,7 +166,7 @@ const TEXT = "<policy-file-request/>\x00"
func handle(c gnet.Conn) {
clientdata := c.Context().(*socket.ClientData)
if clientdata.GetIsCrossDomain() {
if clientdata.IsCrossDomain {
return
}
@@ -183,7 +183,7 @@ func handle(c gnet.Conn) {
c.Write([]byte(CROSS_DOMAIN))
c.Discard(len(TEXT))
clientdata.SetCrossDomain(true) //= true //TODO 待修复未成功切换bug
clientdata.IsCrossDomain = true
return
}