From 7b5ec208fcd9791431cad4e4653571abedc1fbd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <1@72wo.cn> Date: Sat, 30 Aug 2025 00:36:08 +0800 Subject: [PATCH] =?UTF-8?q?refactor(socket):=20=E9=87=8D=E6=9E=84=20Client?= =?UTF-8?q?Data=20=E7=BB=93=E6=9E=84=E4=BD=93=E5=B9=B6=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 简化 ClientData 结构体,移除不必要的方法 - 优化 Player 结构体,调整 Conn 类型 - 更新 wscodec.go 中的 Conn 结构体 - 删除未使用的 XML 相关文件和代码 - 调整 ServerEvent 和 controller 中的相关逻辑 --- .vscode/launch.json | 7 +- common/data/socket/Client.go | 45 +------ common/data/socket/player.go | 8 +- common/data/socket/wscodec.go | 2 + common/data/xml/item/1_test.go | 20 --- common/data/xml/item/item.go | 106 --------------- common/data/xml/skill/monster_refresh_test.go | 20 --- common/data/xml/talk/monster_refresh_test.go | 20 --- common/data/xml/talk/talk.go | 89 ------------- common/data/xmlres/file.go | 84 ++++++++++++ common/data/xmlres/item.go | 53 ++++++++ common/data/{xml/map => xmlres}/map.go | 61 +-------- common/data/xmlres/mon.go | 122 ++++++++++++++++++ common/data/{xml/skill => xmlres}/skill.go | 2 +- common/data/xmlres/talk.go | 23 ++++ .../xml_test.go} | 10 +- common/socket/ServerEvent.go | 20 +-- logic/controller/controller.go | 11 +- logic/controller/login.go | 18 +-- logic/controller/map.go | 10 +- logic/controller/task.go | 103 ++++++--------- logic/controller/walk.go | 14 +- logic/service/fight/info/BattleSkillEntity.go | 6 +- logic/service/maps/Map_Ogre.go | 2 +- logic/service/maps/mapin.go | 60 ++++++--- logic/service/service.go | 42 +++--- logic/service/space/hot.go | 6 +- logic/service/space/space.go | 6 +- modules/blazing/model/task.go | 9 +- modules/blazing/model/task_Daily.go | 48 ------- modules/blazing/service/task.go | 47 +++---- 31 files changed, 472 insertions(+), 602 deletions(-) delete mode 100644 common/data/xml/item/1_test.go delete mode 100644 common/data/xml/item/item.go delete mode 100644 common/data/xml/skill/monster_refresh_test.go delete mode 100644 common/data/xml/talk/monster_refresh_test.go delete mode 100644 common/data/xml/talk/talk.go create mode 100644 common/data/xmlres/file.go create mode 100644 common/data/xmlres/item.go rename common/data/{xml/map => xmlres}/map.go (70%) create mode 100644 common/data/xmlres/mon.go rename common/data/{xml/skill => xmlres}/skill.go (99%) create mode 100644 common/data/xmlres/talk.go rename common/data/{xml/map/monster_refresh_test.go => xmlres/xml_test.go} (96%) delete mode 100644 modules/blazing/model/task_Daily.go diff --git a/.vscode/launch.json b/.vscode/launch.json index 956fa82b9..e3a7fcce1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,7 +13,7 @@ "mode": "auto", "cwd": "${workspaceFolder}", "program": "${workspaceFolder}/login", - "console": "integratedTerminal" + }, { @@ -24,7 +24,7 @@ "cwd": "${workspaceFolder}", "args": ["-port=1"], "program": "${workspaceFolder}/logic", - "console": "integratedTerminal" + }, { "name": "Launch logic2", "type": "go", @@ -32,6 +32,7 @@ "mode": "auto", "cwd": "${workspaceFolder}", "args": ["-port=2"], + "program": "${workspaceFolder}/logic", "console": "integratedTerminal" }, { @@ -41,7 +42,7 @@ "mode": "auto", "cwd": "${workspaceFolder}", "args": ["-port=0"], - "program": "${workspaceFolder}/logic", "console": "integratedTerminal" + "program": "${workspaceFolder}/logic", } ] diff --git a/common/data/socket/Client.go b/common/data/socket/Client.go index 08a77cf79..7ede19f20 100644 --- a/common/data/socket/Client.go +++ b/common/data/socket/Client.go @@ -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 diff --git a/common/data/socket/player.go b/common/data/socket/player.go index abdf2105e..f59c92917 100644 --- a/common/data/socket/player.go +++ b/common/data/socket/player.go @@ -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 } diff --git a/common/data/socket/wscodec.go b/common/data/socket/wscodec.go index 61c4aff48..d8dd965f0 100644 --- a/common/data/socket/wscodec.go +++ b/common/data/socket/wscodec.go @@ -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 { diff --git a/common/data/xml/item/1_test.go b/common/data/xml/item/1_test.go deleted file mode 100644 index 575a15328..000000000 --- a/common/data/xml/item/1_test.go +++ /dev/null @@ -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) - -} diff --git a/common/data/xml/item/item.go b/common/data/xml/item/item.go deleted file mode 100644 index f91b7f393..000000000 --- a/common/data/xml/item/item.go +++ /dev/null @@ -1,106 +0,0 @@ -package xml - -import ( - "fmt" - "io" - "log" - "net/http" - "time" - - "github.com/ECUST-XX/xml" // 保持与之前一致的XML库 -) - -// Items 根节点,对应标签 -type Items struct { - XMLName xml.Name `xml:"Items"` - Items []Item `xml:"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 精灵属性子节点,对应标签 -// 注:根据实际需求补充字段,这里以常见属性为例 -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 要塞保卫战子节点,对应标签 -// 注:根据实际需求补充字段,这里以常见属性为例 -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() diff --git a/common/data/xml/skill/monster_refresh_test.go b/common/data/xml/skill/monster_refresh_test.go deleted file mode 100644 index f7709cdc8..000000000 --- a/common/data/xml/skill/monster_refresh_test.go +++ /dev/null @@ -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) -} diff --git a/common/data/xml/talk/monster_refresh_test.go b/common/data/xml/talk/monster_refresh_test.go deleted file mode 100644 index 6d0f5340a..000000000 --- a/common/data/xml/talk/monster_refresh_test.go +++ /dev/null @@ -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) - -} diff --git a/common/data/xml/talk/talk.go b/common/data/xml/talk/talk.go deleted file mode 100644 index 725ac1942..000000000 --- a/common/data/xml/talk/talk.go +++ /dev/null @@ -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 根节点,对应标签 -// 注意:xml.Name需指定命名空间,与XML中的xmlns保持一致 -type TalkCount struct { - XMLName xml.Name `xml:"nieo.seer.org.talk-count talk_count"` - Entries []Entry `xml:"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() diff --git a/common/data/xmlres/file.go b/common/data/xmlres/file.go new file mode 100644 index 000000000..05455816c --- /dev/null +++ b/common/data/xmlres/file.go @@ -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 {} + } + }() + +} diff --git a/common/data/xmlres/item.go b/common/data/xmlres/item.go new file mode 100644 index 000000000..eddd11f77 --- /dev/null +++ b/common/data/xmlres/item.go @@ -0,0 +1,53 @@ +package xmlres + +import ( + "github.com/ECUST-XX/xml" // 保持与之前一致的XML库 +) + +// Items 根节点,对应标签 +type Items struct { + XMLName xml.Name `xml:"Items"` + Items []Item `xml:"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 精灵属性子节点,对应标签 +// 注:根据实际需求补充字段,这里以常见属性为例 +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 要塞保卫战子节点,对应标签 +// 注:根据实际需求补充字段,这里以常见属性为例 +type TeamPK struct { + FortBonus int `xml:"fortBonus,attr,omitempty"` // 要塞加成 + DefenseBonus int `xml:"defenseBonus,attr,omitempty"` // 防御加成 + AttackBonus int `xml:"attackBonus,attr,omitempty"` // 攻击加成 +} diff --git a/common/data/xml/map/map.go b/common/data/xmlres/map.go similarity index 70% rename from common/data/xml/map/map.go rename to common/data/xmlres/map.go index 145757bf7..22082b4ef 100644 --- a/common/data/xml/map/map.go +++ b/common/data/xmlres/map.go @@ -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() diff --git a/common/data/xmlres/mon.go b/common/data/xmlres/mon.go new file mode 100644 index 000000000..88195a9ab --- /dev/null +++ b/common/data/xmlres/mon.go @@ -0,0 +1,122 @@ +package xmlres + +import ( + "encoding/xml" +) + +// 根结构体:对应 节点 +type MonsterRoot struct { + XMLName xml.Name `xml:"Maps"` + WorldWildMons WorldWildMons `xml:"WorldWildMons"` // 世界野怪配置 + Maps []TMapConfig `xml:"Map"` // 所有地图配置(多个) + DefaultMaps DefaultMaps `xml:"DefaultMaps"` // 默认登录场景 + VersionNumber VersionNumber `xml:"VersionNumber"` // 版本信息 +} + +// 世界野怪容器:对应 +type WorldWildMons struct { + WorldWildMonsters []WorldWildMonster `xml:"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(可能多个,空格分隔) +} + +// 单张地图配置:对应 +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配置(下的) +} + +// ########################### 关键新增:MonstersConfig(对应 ) ########################### +// 野怪配置容器:包含野怪奖励概率和多只野怪 +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(对应 ) ########################### +// 单只野怪配置:ID可能是多个值(空格分隔),Lv是等级范围(空格分隔) +type Monster1 struct { + ID string `xml:"ID,attr"` // 野怪ID(如"164 0 0..."或"10") + Lv string `xml:"Lv,attr"` // 等级范围(如"1 2"表示1-2级) +} + +// 游戏触发点组:对应 +type GameTriggerGrp struct { + GameID string `xml:"GameID,attr"` // 游戏ID + TriggerPts []TriggerPt `xml:"TriggerPt"` // 触发点(多个) +} + +// 触发点:对应 +type TriggerPt struct { + ID int `xml:"ID,attr"` // 触发点ID + Name string `xml:"Name,attr"` // 触发点名称(可选) +} + +// 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精灵配置:对应 +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"` // 速度(可选) +} + +// 默认登录场景容器:对应 +type DefaultMaps struct { + DefaultMaps []DefaultMap `xml:"DefaultMap"` // 多个默认场景 +} + +// 默认登录场景:对应 +type DefaultMap struct { + ID int `xml:"ID,attr"` // 场景ID + RandMaps string `xml:"RandMaps,attr"` // 随机场景列表(逗号分隔) + Desc string `xml:"Desc,attr"` // 场景描述 +} + +// 版本信息容器:对应 +type VersionNumber struct { + Version Version `xml:"Version"` // 版本详情 +} + +// 版本详情:对应 +type Version struct { + ID string `xml:"ID,attr"` // 版本号(如"20190614") + Desc string `xml:"Desc,attr"` // 版本描述 +} diff --git a/common/data/xml/skill/skill.go b/common/data/xmlres/skill.go similarity index 99% rename from common/data/xml/skill/skill.go rename to common/data/xmlres/skill.go index 46924334e..96fd16fab 100644 --- a/common/data/xml/skill/skill.go +++ b/common/data/xmlres/skill.go @@ -1,4 +1,4 @@ -package skill +package xmlres import ( "encoding/xml" diff --git a/common/data/xmlres/talk.go b/common/data/xmlres/talk.go new file mode 100644 index 000000000..1652d44d0 --- /dev/null +++ b/common/data/xmlres/talk.go @@ -0,0 +1,23 @@ +package xmlres + +import ( + "github.com/ECUST-XX/xml" // 注意:需确保该xml库与示例中使用的一致 +) + +// TalkCount 根节点,对应标签 +// 注意:xml.Name需指定命名空间,与XML中的xmlns保持一致 +type TalkCount struct { + XMLName xml.Name `xml:"nieo.seer.org.talk-count talk_count"` + Entries []TalkEntry `xml:"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) +} diff --git a/common/data/xml/map/monster_refresh_test.go b/common/data/xmlres/xml_test.go similarity index 96% rename from common/data/xml/map/monster_refresh_test.go rename to common/data/xmlres/xml_test.go index f37f367be..8eaaf2f4f 100644 --- a/common/data/xml/map/monster_refresh_test.go +++ b/common/data/xmlres/xml_test.go @@ -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() } diff --git a/common/socket/ServerEvent.go b/common/socket/ServerEvent.go index c9b469c17..067f67d81 100644 --- a/common/socket/ServerEvent.go +++ b/common/socket/ServerEvent.go @@ -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 = "\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 } diff --git a/logic/controller/controller.go b/logic/controller/controller.go index 7a2aed98c..52e6f32e1 100644 --- a/logic/controller/controller.go +++ b/logic/controller/controller.go @@ -88,7 +88,7 @@ func init() { //默认初始化扫描 method := typ.Method(i) methodValue := value.MethodByName(method.Name) - fmt.Println("找到注册方法", method.Name) + //fmt.Println("找到注册方法", method.Name) methodValue.Type().NumIn() for _, func_cmd := range getcmd(methodValue.Type().In(0)) { @@ -190,13 +190,14 @@ func Recv(c *socket.Conn, data handler.TomeeHeader) { nameField.Set(reflect.ValueOf(data)) } if cmdlister.Type().In(1) == reflect.TypeOf(&socket.Player{}) { - c1 := service.GetPlayer(c, data.UserID) - err := c1.WaitForLoginWithCtx(context.Background()) + t := service.GetPlayer(c, data.UserID) + // fmt.Println(data.CMD, "接收 变量的地址 ", &t.Info, t.Info.UserID) + err := t.WaitForLoginWithCtx(context.Background()) if err != nil { fmt.Println("登录失败") } - params = append(params, ptrValue1, reflect.ValueOf(c1)) + params = append(params, ptrValue1, reflect.ValueOf(t)) } else { params = append(params, ptrValue1, reflect.ValueOf(c)) @@ -225,7 +226,7 @@ func Recv(c *socket.Conn, data handler.TomeeHeader) { } data.Version = "7" - glog.Debug(context.Background(), data.CMD, "回复数据") + //glog.Debug(context.Background(), data.CMD, "回复数据") c.SendPack(data.Pack(ret[0].Interface())) } diff --git a/logic/controller/login.go b/logic/controller/login.go index 98164da5a..1ffbbca64 100644 --- a/logic/controller/login.go +++ b/logic/controller/login.go @@ -14,7 +14,6 @@ import ( "time" "github.com/gogf/gf/v2/os/glog" - "github.com/jinzhu/copier" ) // 处理命令: 1001 @@ -22,22 +21,23 @@ func (h *Controller) Login(data *login.InInfo, c *socket.Conn) (result *login.Ou if tt := data.CheakSession(); tt { //说明sid正确 h.RPCClient.Kick(data.Head.UserID) //先踢人 - playerinfo := blservice.NewUserService(data.Head.UserID).Person() - t := service.SetPlayer(c, playerinfo) + + t := service.GetPlayer(c, data.Head.UserID) + t.Info = blservice.NewUserService(data.Head.UserID).Person() + t.Info.UserID = data.Head.UserID t.Onlinetime = uint32(time.Now().Unix()) //保存时间戳 - copier.Copy(playerinfo, t) //先复制给内存信息 share.ShareManager.SetUserOnline(data.Head.UserID, h.Port) //设置用户登录服务器 t.CompleteLogin() //通知客户端登录成功 glog.Debug(context.Background(), "登录成功,初始地图 人数:", space.GetSpace(t.Info.MapID).Len()) result = login.NewOutInfo() //设置登录消息 - copier.Copy(playerinfo, result) - + result.PlayerInfo = *t.Info + tt := maps.NewOutInfo() + //copier.Copy(t.Info, tt) + t1 := handler.NewTomeeHeader(2001, t.Info.UserID) defer space.GetSpace(t.Info.MapID).Set(t.Info.UserID, t).Range(func(playerID uint32, player *socket.Player) bool { - tt := maps.NewOutInfo() - copier.Copy(playerinfo, tt) - t1 := handler.NewTomeeHeader(2001, t.Info.UserID) + player.SendPack(t1.Pack(&tt)) return true }) diff --git a/logic/controller/map.go b/logic/controller/map.go index 21a8066e0..394493fe2 100644 --- a/logic/controller/map.go +++ b/logic/controller/map.go @@ -6,7 +6,6 @@ import ( "blazing/logic/service/maphot" "blazing/logic/service/maps" "blazing/logic/service/space" - mservice "blazing/modules/blazing/service" "time" "github.com/jinzhu/copier" @@ -18,15 +17,11 @@ func (h *Controller) MapEnter(data *maps.InInfo, c *socket.Player) (result *maps space.GetSpace(c.Info.MapID).Set(c.Info.UserID, c) //添加玩家 result = maps.NewOutInfo() c.Info.Pos = data.Point - copier.Copy(c.Info, result) + copier.Copy(result, c.Info) data.Broadcast(c.Info.MapID, *result) //同步广播 // 如果是无怪地图,直接返回 - if mservice.NewMonsterService().GetId(c.Info.MapID) == nil { - return nil, -1 - } - // 创建新的停止通道 c.StopChan = make(chan struct{}) @@ -70,6 +65,7 @@ func (h Controller) MapHot(data *maphot.InInfo, c *socket.Player) (result *mapho } func (h *Controller) MapLeave(data *maps.LeaveMapInboundInfo, c *socket.Player) (result *maps.LeaveMapOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的 //result = &maps.LeaveMapOutboundInfo{UserID: c.GetUserID()} + data.Broadcast(c.Info.MapID, maps.LeaveMapOutboundInfo{UserID: c.Info.UserID}) //同步广播 space.GetSpace(c.Info.MapID).Delete(c.Info.UserID) // 如果有正在运行的刷怪协程,发送停止信号 @@ -87,7 +83,7 @@ func (h *Controller) MapList(data *maps.ListMapPlayerInboundInfo, c *socket.Play space.GetSpace(c.Info.MapID).Range(func(userID uint32, player *socket.Player) bool { result1 := maps.NewOutInfo() - copier.Copy(player.Info, result1) + copier.Copy(result1, player.Info) result.Player = append(result.Player, *result1) return true }) diff --git a/logic/controller/task.go b/logic/controller/task.go index 08ed37edf..2ee38e1ae 100644 --- a/logic/controller/task.go +++ b/logic/controller/task.go @@ -12,47 +12,28 @@ import ( * 接受任务 */ func (h Controller) AcceptTask(data *task.AcceptTaskInboundInfo, c *socket.Player) (result *task.AcceptTaskOutboundInfo, err errorcode.ErrorCode) { - - if data.Head.CMD == 2201 { //判断不是每日任务 - service.NewUserService(c.Info.UserID).TaskExec(func(ttt map[uint32]model.TaskInfo) bool { - ft, ok := ttt[data.TaskId] - if ok { //如果找到任务 - if ft.Status == 0 { //可以接受 - ft.Status = 1 //接受 - return true - } else { - return false - } - } else { - ttt[data.TaskId] = model.TaskInfo{ - Status: 1, - } - - } - - return false - }) - } else { - service.NewUserService(c.Info.UserID).DailyTaskExec(func(ttt map[uint32]model.DailyTaskInfo) bool { - ft, ok := ttt[data.TaskId] - if ok { //如果找到任务 - if ft.Status == 0 { //可以接受 - ft.Status = 1 //接受 - return true - } else { - return false - } - } else { - ttt[data.TaskId] = model.DailyTaskInfo{ - Status: 1, - } - - } - - return false - }) + isdaliy := false + if data.Head.CMD != 2201 { //判断是每日任务 + isdaliy = true } + service.NewUserService(c.Info.UserID).TaskExec(func(ttt map[uint32]model.TaskInfo) bool { + ft, ok := ttt[data.TaskId] + if ok { //如果找到任务 + if ft.Status == 0 { //可以接受 + ft.Status = 1 //接受 + return true + } else { + return false + } + } else { + ttt[data.TaskId] = model.TaskInfo{ + Status: 1, + } + } + + return false + }, isdaliy) result = &task.AcceptTaskOutboundInfo{} result.TaskId = data.TaskId return result, 0 @@ -62,29 +43,19 @@ func (h Controller) AcceptTask(data *task.AcceptTaskInboundInfo, c *socket.Playe * 更新任务步骤 */ func (h Controller) AddTaskBuf(data *task.AddTaskBufInboundInfo, c *socket.Player) (result *task.AddTaskBufOutboundInfo, err errorcode.ErrorCode) { - - if data.Head.CMD == 2204 { //判断不是每日任务 - service.NewUserService(c.Info.UserID).TaskExec(func(ttt map[uint32]model.TaskInfo) bool { - if conditions, ok := ttt[data.TaskId]; ok { - conditions.TaskInfo = data.TaskList - ttt[data.TaskId] = conditions - return true - } - - return false - }) - } else { - service.NewUserService(c.Info.UserID).DailyTaskExec(func(ttt map[uint32]model.DailyTaskInfo) bool { - if conditions, ok := ttt[data.TaskId]; ok { - conditions.DailyTaskInfo = data.TaskList - ttt[data.TaskId] = conditions - return true - } - - return false - }) - + isdaliy := false + if data.Head.CMD != 2204 { //判断是每日任务 + isdaliy = true } + service.NewUserService(c.Info.UserID).TaskExec(func(ttt map[uint32]model.TaskInfo) bool { + if conditions, ok := ttt[data.TaskId]; ok { + conditions.TaskInfo = data.TaskList + ttt[data.TaskId] = conditions + return true + } + + return false + }, isdaliy) return &task.AddTaskBufOutboundInfo{}, 0 } @@ -107,12 +78,10 @@ func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *socket. * 获取任务状态 */ func (h Controller) Get_Task_Buf(data *task.GetTaskBufInboundInfo, c *socket.Player) (result *task.GetTaskBufOutboundInfo, err errorcode.ErrorCode) { - - if data.Head.CMD == 2203 { //判断不是每日任务 - - } else { - - } + // isdaliy := false + // if data.Head.CMD != 2203 { //判断是每日任务 + // isdaliy = true + // } return &task.GetTaskBufOutboundInfo{}, 0 } diff --git a/logic/controller/walk.go b/logic/controller/walk.go index 0ab7a72b5..081a77524 100644 --- a/logic/controller/walk.go +++ b/logic/controller/walk.go @@ -4,14 +4,18 @@ import ( "blazing/common/data/socket" "blazing/common/socket/errorcode" "blazing/logic/service/space" + "context" + + "github.com/gogf/gf/v2/os/glog" + "github.com/jinzhu/copier" ) func (h Controller) Walk(data *space.InInfo, c *socket.Player) (result *space.OutInfo, err errorcode.ErrorCode) { - - data.Broadcast(c.Info.UserID, space.OutInfo{Flag: data.Flag, - UserID: c.Info.UserID, - Reserve2: data.Reverse2, - Point: data.Point}) //走路的广播 + result = &space.OutInfo{} + err1 := copier.Copy(result, data) + result.UserID = data.Head.UserID + glog.Debug(context.Background(), err1) + data.Broadcast(c.Info.MapID, *result) //走路的广播 return nil, -1 } diff --git a/logic/service/fight/info/BattleSkillEntity.go b/logic/service/fight/info/BattleSkillEntity.go index d7c7b4e1f..95b58c0fe 100644 --- a/logic/service/fight/info/BattleSkillEntity.go +++ b/logic/service/fight/info/BattleSkillEntity.go @@ -2,7 +2,7 @@ package info import ( element "blazing/common/data/Element" - "blazing/common/data/xml/skill" + "blazing/common/data/xmlres" "blazing/common/utils/random" "context" @@ -35,7 +35,7 @@ var Category = enum.New[struct { // 实现了战斗中技能的所有属性和行为,包括PP管理、技能使用、属性获取等 // 战斗中可以修改技能实体值,比如是否暴击,是否必中等 type BattleSkillEntity struct { - skill.Move + xmlres.Move ctx context.Context SideEffects []int SideEffectArgs []int @@ -61,7 +61,7 @@ func CreateBattleSkillWithInfinity(id int, pp int) *BattleSkillEntity { } // 从资源仓库获取技能数据 - move, ok := skill.MovesConfig.Moves[id] + move, ok := xmlres.MovesConfig.Moves[id] if !ok { glog.Error(context.Background(), "技能ID无效", "id", id) } diff --git a/logic/service/maps/Map_Ogre.go b/logic/service/maps/Map_Ogre.go index f937c5b8f..e2e145d5c 100644 --- a/logic/service/maps/Map_Ogre.go +++ b/logic/service/maps/Map_Ogre.go @@ -7,5 +7,5 @@ type OgreInfo struct { type OgrePetInfo struct { Id uint32 Shiny uint32 + Lv uint32 `struc:"skip"` //等级 } - diff --git a/logic/service/maps/mapin.go b/logic/service/maps/mapin.go index e89fba7c6..3d06e40e2 100644 --- a/logic/service/maps/mapin.go +++ b/logic/service/maps/mapin.go @@ -2,13 +2,16 @@ package maps import ( "blazing/common/data/socket" + "blazing/common/data/xmlres" "blazing/common/socket/handler" "blazing/logic/service/space" "blazing/modules/blazing/model" "math/rand" + "strings" "time" "github.com/creasty/defaults" + "github.com/gogf/gf/v2/util/gconv" ) type InInfo struct { @@ -38,9 +41,9 @@ func (t *InInfo) Broadcast(mapid uint32, o OutInfo) { func (t *InInfo) SpawnMonsters(c *socket.Player, isfrist bool) { // 获取当前地图的怪物配置 - // if c == nil || mservice.NewMonsterService().GetId(c.MapId) == 0 { //用户离线 - // return - // } + if c == nil || c.Info.MapID == 0 { //用户离线 + return + } if !c.IsLogin { defer func() { @@ -60,27 +63,54 @@ func (t *InInfo) SpawnMonsters(c *socket.Player, isfrist bool) { t.monsters, _, _ = replaceOneNumber(t.monsters) } - t1 := t.genMonster(c.Info.UserID) + t1 := t.genMonster(c.Info.MapID) + if t1 != nil { + t1 := tt.Pack(t1) + c.SendPack(t1) + } - c.SendPack(tt.Pack(&t1)) +} + +// 2. 从 string 类型 slice 随机选一个元素 +func RandomStringFromSlice(s []string) string { + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + randomIdx := r.Intn(len(s)) + return s[randomIdx] } // 应该根据怪物信息决定后端生成 -func (t *InInfo) genMonster(mapid uint32) OgreInfo { +func (t *InInfo) genMonster(mapid uint32) *OgreInfo { // 设置怪物信息 t1 := OgreInfo{} + for _, tc := range xmlres.Monster.Maps { + if tc.ID == gconv.Int(mapid) && tc.Monsters != nil { + + for i, m := range tc.Monsters.Monsters { //这里是9个 + id := strings.Split(m.ID, " ") + lv := strings.Split(m.Lv, " ") + ttt := OgrePetInfo{ + Id: gconv.Uint32(RandomStringFromSlice(id)), + } + if ttt.Id != 0 { + ttt.Shiny = 0 //待确认是否刷新异色 + ttt.Lv = gconv.Uint32(RandomStringFromSlice(lv)) + } + t1.Data[i] = ttt + + } + break + } + + } + t2 := OgreInfo{} for i := 0; i < 3; i++ { - ttt := OgrePetInfo{} - // ttt.Id = mservice.NewMonsterService().GetId(mapid) //待修改成xml获取 - - ttt.Shiny = uint32(i + 1) //异色概率,待实现自定义 - //t1.Data[i] = mservice.NewMonsterService().GetId(c.MapId) - t1.Data[t.monsters[i]] = ttt + t2.Data[t.monsters[i]] = t1.Data[t.monsters[i]] } - return t1 + return &t2 } // 计算整数的二进制1的个数(Integer.bitCount) @@ -101,7 +131,7 @@ func generateThreeUniqueNumbers() [3]int { index := 0 for index < 3 { - num := rand.Intn(10) + num := rand.Intn(9) if !selected[num] { selected[num] = true result[index] = num @@ -124,7 +154,7 @@ func replaceOneNumber(original [3]int) ([3]int, int, int) { originalMap[num] = true } - for i := 0; i < 10; i++ { + for i := 0; i < 8; i++ { if !originalMap[i] { candidates = append(candidates, i) } diff --git a/logic/service/service.go b/logic/service/service.go index cf1edc23d..8a24040a8 100644 --- a/logic/service/service.go +++ b/logic/service/service.go @@ -4,24 +4,30 @@ import ( "blazing/common/data/socket" "blazing/common/socket/errorcode" "blazing/common/socket/handler" - "blazing/modules/blazing/model" ) func GetPlayer(c *socket.Conn, userid uint32) *socket.Player { //TODO 这里待优化,可能存在内存泄漏问题 - + c.Mu.Lock() + defer c.Mu.Unlock() //检查player初始化,是否为conn初始后取map,防止二次连接后存在两个player clientdata := c.MainConn.Context().(*socket.ClientData) - if clientdata.GetPlayer() != nil { - return clientdata.GetPlayer() - } - var player *socket.Player - if player1, ok := socket.Mainplayer.Load((userid)); ok { - - clientdata.SetPlayer(player1) + if clientdata.Player != nil { + return clientdata.Player } - return player + clientdata.Player = socket.NewPlayer( + + socket.WithConn(c), //注入conn + ) + + // gff := socket.NewClientData() + + // gff.Player = clientdata.Player + // c.MainConn.SetContext(gff) + socket.Mainplayer.Store(userid, clientdata.Player) + + return clientdata.Player // return nil } func KickPlayer(userid uint32) { //踢出玩家 @@ -40,19 +46,3 @@ func KickPlayer(userid uint32) { //踢出玩家 //return player // return nil } -func SetPlayer(c *socket.Conn, user *model.PlayerInfo) *socket.Player { //TODO 这里待优化, - - clientdata := c.MainConn.Context().(*socket.ClientData) - - player := socket.NewPlayer( - - - socket.WithConn(*c), //注入conn - ) - socket.Mainplayer.Store(user.UserID, player) - - clientdata.SetPlayer(player) //= player - - return player - // return nil -} diff --git a/logic/service/space/hot.go b/logic/service/space/hot.go index 39aee604f..f429ede5d 100644 --- a/logic/service/space/hot.go +++ b/logic/service/space/hot.go @@ -1,7 +1,7 @@ package space import ( - xml "blazing/common/data/xml/map" + "blazing/common/data/xmlres" "golang.org/x/sync/singleflight" ) @@ -19,7 +19,7 @@ func GetMapHot() []MapHotInfo { tt := make(map[uint32]uint32) - for _, v := range xml.MapConfig.Maps { + for _, v := range xmlres.MapConfig.Maps { t1, ok := tt[uint32(v.Super)] if ok { @@ -41,5 +41,5 @@ func GetMapHot() []MapHotInfo { } return result, nil }) -return result1.([]MapHotInfo) + return result1.([]MapHotInfo) } diff --git a/logic/service/space/space.go b/logic/service/space/space.go index 56a4f6ca4..63e1f7ae6 100644 --- a/logic/service/space/space.go +++ b/logic/service/space/space.go @@ -2,7 +2,7 @@ package space import ( "blazing/common/data/socket" - xml "blazing/common/data/xml/map" + "blazing/common/data/xmlres" "blazing/common/utils" "blazing/modules/blazing/model" "sync" @@ -37,7 +37,7 @@ func (m *Space) Get(playerID uint32) (*socket.Player, bool) { // Set 存储玩家实例(按ID) // 写操作使用Lock,独占锁保证数据一致性 -func (m *Space) Set(playerID uint32, player *socket.Player)*Space { +func (m *Space) Set(playerID uint32, player *socket.Player) *Space { m.mu.Lock() defer m.mu.Unlock() m.data[playerID] = player @@ -90,7 +90,7 @@ func GetSpace(id uint32) *Space { } //如果不ok,说明星球未创建,那就新建星球 - for _, v := range xml.MapConfig.Maps { + for _, v := range xmlres.MapConfig.Maps { if v.ID == int(id) { //找到这个地图 t := NewSpace() t.DefaultPos = model.Pos{X: uint32(v.X), Y: uint32(v.Y)} diff --git a/modules/blazing/model/task.go b/modules/blazing/model/task.go index 9c4a74193..e8b467488 100644 --- a/modules/blazing/model/task.go +++ b/modules/blazing/model/task.go @@ -1,6 +1,9 @@ package model -import "blazing/cool" +import ( + "blazing/cool" + "time" +) const TableNameTask = "task" @@ -15,7 +18,9 @@ type Task struct { type TaskInfo struct { // TaskInfo 任务步骤信息,对应Java的@ArraySerialize(FIXED_LENGTH=20)注解 // struc:"[20]byte" 确保二进制序列化时固定20字节长度,json标签指定JSON字段名 - TaskInfo []uint32 `struc:"[20]byte" json:"task_info"` + TaskType uint32 `json:"task_type"` //区分是每日任务还是常规任务,常规为0,每日为1 + TaskInfo []uint32 `struc:"[20]byte" json:"task_info"` + LastResetTime time.Time `gorm:"not null;comment:'上次重置时间(UTC)'" json:"last_reset_time"` //这里是每天重置 // Status 任务整体状态:0-未接受,1-已接受,2-已完成未领取,3-已完成已领取 // json标签指定JSON字段名,与业务状态说明保持一致 Status byte `json:"status"` diff --git a/modules/blazing/model/task_Daily.go b/modules/blazing/model/task_Daily.go deleted file mode 100644 index a6891c728..000000000 --- a/modules/blazing/model/task_Daily.go +++ /dev/null @@ -1,48 +0,0 @@ -package model - -import ( - "blazing/cool" - "time" -) - -const TableNameDailyTask = "DailyTask" - -// DailyTask mapped from table -type DailyTask struct { - *cool.Model - PlayerID uint64 `gorm:"not null;index:idx_DailyTask_by_player_id;comment:'所属玩家ID'" json:"player_id"` - Data string `gorm:"type:text;not null;comment:'全部数据'" json:"data"` -} - -// DailyTaskInfo 单个任务的详细信息,包含任务步骤状态和整体状态 -type DailyTaskInfo struct { - // DailyTaskInfo 任务步骤信息,对应Java的@ArraySerialize(FIXED_LENGTH=20)注解 - // struc:"[20]byte" 确保二进制序列化时固定20字节长度,json标签指定JSON字段名 - DailyTaskInfo []uint32 `struc:"[20]byte" json:"DailyTask_info"` - LastResetTime time.Time `gorm:"not null;comment:'上次重置时间(UTC)'" json:"last_reset_time"` //这里是每天重置 - // Status 任务整体状态:0-未接受,1-已接受,2-已完成未领取,3-已完成已领取 - // json标签指定JSON字段名,与业务状态说明保持一致 - Status byte `json:"status"` -} - -// TableName PlayerInfo's table name -func (*DailyTask) TableName() string { - return TableNamePlayerInfo -} - -// GroupName PlayerInfo's table group -func (*DailyTask) GroupName() string { - return "default" -} - -// NewPlayerInfo create a new PlayerInfo -func NewDailyTask() *DailyTask { - return &DailyTask{ - Model: cool.NewModel(), - } -} - -// init 创建表 -func init() { - cool.CreateTable(&DailyTask{}) -} diff --git a/modules/blazing/service/task.go b/modules/blazing/service/task.go index d8df1e9d0..134d0d018 100644 --- a/modules/blazing/service/task.go +++ b/modules/blazing/service/task.go @@ -33,7 +33,24 @@ func Exec[T, F any](userid uint32, s *cool.Service, processFunc func(F) bool) bo m1.Save(player) return false } -func (s *UserService) TaskExec(t func(map[uint32]model.TaskInfo) bool) (ret bool) { +func (s *UserService) TaskExec(t func(map[uint32]model.TaskInfo) bool, isdaliy bool) (ret bool) { + + if isdaliy { + Exec[model.Task](s.userid, s.task, func(tt map[uint32]model.TaskInfo) bool { + + //先重置每日 + for _, v := range tt { + if v.TaskType == 1 && !IsToday(v.LastResetTime) { + + v.Status = 0 //重置+自动接受每日任务 + v.LastResetTime = time.Now().UTC() + } + + } + + return true + }) + } return Exec[model.Task](s.userid, s.task, t) // m := cool.DBM(s.task.Model).Where("player_id", s.userid) // var tt model.Task @@ -57,34 +74,6 @@ func IsToday(t time.Time) bool { t.Month() == now.Month() && t.Day() == now.Day() } -func (s *UserService) DailyTaskExec(t func(map[uint32]model.DailyTaskInfo) bool) (ret bool) { - Exec[model.DailyTask](s.userid, s.task, func(tt map[uint32]model.DailyTaskInfo) bool { - - //先重置每日 - for _, v := range tt { - if !IsToday(v.LastResetTime) { - - v.Status = 0 //重置+自动接受每日任务 - v.LastResetTime = time.Now().UTC() - } - - } - - return true - }) - - return Exec[model.DailyTask](s.userid, s.task, t) - // m := cool.DBM(s.task.Model).Where("player_id", s.userid) - // var tt model.Task - // m.Scan(&tt) - // var ttt map[uint32]model.TaskInfo - // json.Unmarshal([]byte(tt.Data), &ttt) - // ret = t(ttt) - // t1, _ := json.Marshal(&ttt) - // tt.Data = string(t1) - // m.Save(&tt) //退出时保存 - // return -} // /** // * 完成任务