diff --git a/cool/config.go b/common/cool/config.go
similarity index 100%
rename from cool/config.go
rename to common/cool/config.go
diff --git a/cool/const.go b/common/cool/const.go
similarity index 100%
rename from cool/const.go
rename to common/cool/const.go
diff --git a/cool/controller-simple.go b/common/cool/controller-simple.go
similarity index 100%
rename from cool/controller-simple.go
rename to common/cool/controller-simple.go
diff --git a/cool/controller.go b/common/cool/controller.go
similarity index 100%
rename from cool/controller.go
rename to common/cool/controller.go
diff --git a/cool/cool.go b/common/cool/cool.go
similarity index 100%
rename from cool/cool.go
rename to common/cool/cool.go
diff --git a/cool/coolconfig/config.go b/common/cool/coolconfig/config.go
similarity index 100%
rename from cool/coolconfig/config.go
rename to common/cool/coolconfig/config.go
diff --git a/cool/cooldb/cooldb.go b/common/cool/cooldb/cooldb.go
similarity index 100%
rename from cool/cooldb/cooldb.go
rename to common/cool/cooldb/cooldb.go
diff --git a/cool/coolfile/coolfile.go b/common/cool/coolfile/coolfile.go
similarity index 100%
rename from cool/coolfile/coolfile.go
rename to common/cool/coolfile/coolfile.go
diff --git a/cool/ctx.go b/common/cool/ctx.go
similarity index 100%
rename from cool/ctx.go
rename to common/cool/ctx.go
diff --git a/cool/db.go b/common/cool/db.go
similarity index 100%
rename from cool/db.go
rename to common/cool/db.go
diff --git a/cool/file.go b/common/cool/file.go
similarity index 100%
rename from cool/file.go
rename to common/cool/file.go
diff --git a/cool/func.go b/common/cool/func.go
similarity index 100%
rename from cool/func.go
rename to common/cool/func.go
diff --git a/cool/go.mod b/common/cool/go.mod
similarity index 100%
rename from cool/go.mod
rename to common/cool/go.mod
diff --git a/cool/go.sum b/common/cool/go.sum
similarity index 100%
rename from cool/go.sum
rename to common/cool/go.sum
diff --git a/cool/initdb.go b/common/cool/initdb.go
similarity index 100%
rename from cool/initdb.go
rename to common/cool/initdb.go
diff --git a/cool/middleware.go b/common/cool/middleware.go
similarity index 100%
rename from cool/middleware.go
rename to common/cool/middleware.go
diff --git a/cool/middleware_handler_response.go b/common/cool/middleware_handler_response.go
similarity index 100%
rename from cool/middleware_handler_response.go
rename to common/cool/middleware_handler_response.go
diff --git a/cool/model.go b/common/cool/model.go
similarity index 100%
rename from cool/model.go
rename to common/cool/model.go
diff --git a/cool/service.go b/common/cool/service.go
similarity index 100%
rename from cool/service.go
rename to common/cool/service.go
diff --git a/common/core/info/LoginUserInfo.go b/common/core/info/LoginUserInfo.go
new file mode 100644
index 000000000..05a4d223c
--- /dev/null
+++ b/common/core/info/LoginUserInfo.go
@@ -0,0 +1,217 @@
+package info
+
+// Point 表示坐标结构
+type Point struct {
+ X uint32
+ Y uint32
+}
+
+// TeamInfo 战队信息
+type TeamInfo struct {
+ // 此处应包含TeamInfo的具体字段,原Java代码中未给出详细定义
+ // 请根据实际需求补充
+}
+
+// TeamPKInfo 战队PK信息
+type TeamPKInfo struct {
+ // 此处应包含TeamPKInfo的具体字段,原Java代码中未给出详细定义
+ // 请根据实际需求补充
+}
+
+// PeopleItemInfo 人物物品信息
+type PeopleItemInfo struct {
+ // 此处应包含PeopleItemInfo的具体字段,原Java代码中未给出详细定义
+ // 请根据实际需求补充
+}
+
+// PetInfo 精灵信息
+type PetInfo struct {
+ // 此处应包含PetInfo的具体字段,原Java代码中未给出详细定义
+ // 请根据实际需求补充
+}
+
+// LoginUserInfo 登录用户信息结构体
+type LoginUserInfo struct {
+ // 米米号 通过sid拿到
+ UserId uint64
+ // 注册时间(按秒的时间戳)
+ RegisterTime uint64
+ // 16字节昵称
+ Nick [16]byte `array_serialize:"fixed_length,16"`
+ // 暂时不明建议先给固定值0
+ Vip uint16 `ushort:"true"`
+ // 暂时不明建议先给固定值15
+ Viped uint16 `ushort:"true"`
+ // 暂时不明建议先给固定值0
+ DsFlag uint64
+ // 机器人人物颜色 00 rgb
+ Color uint64
+ // 暂时不明建议先给固定值0
+ Texture uint64
+ // 暂时不明建议先给固定值3000
+ Energy uint64 `default:"3000"`
+ // 赛尔豆
+ Coins uint64
+ // 暂时不明建议先给固定值0
+ FightBadge uint64
+ // 上线的地图id
+ MapID uint64
+ // 上线的坐标 2个uint
+ Pos Point `array_serialize:"fixed_length,8"`
+ // 已经消耗掉的时间(秒为单位)
+ TimeToday uint64
+ // 总电池限制(秒为单位)
+ TimeLimit uint64
+ // 暂时不明感觉是某种活动建议先给固定值0(只能0或1)
+ IsClothHalfDay byte
+ // 暂时不明感觉是某种活动建议先给固定值0(只能0或1)
+ IsRoomHalfDay byte
+ // 暂时不明感觉是某种活动建议先给固定值0(只能0或1)
+ IFortressHalfDay byte
+ // 暂时不明感觉是某种活动建议先给固定值0(只能0或1)
+ IsHQHalfDay byte
+ // 暂时不明建议先给固定值0
+ LoginCount uint64
+ // 邀请活动建议先给固定值0
+ Inviter uint64
+ // 邀请活动建议先给固定值0
+ NewInviteeCount uint64
+ // 超no等级建议固定8
+ VipLevel uint64 `default:"8"`
+ // 超no的vip值建议固定80000
+ VipValue uint64 `default:"80000"`
+ // 超no的外形等级建议固定1(暂定)
+ VipStage uint64 `default:"1"`
+ // nono是否自动充电 建议固定1
+ AutoCharge uint64 `default:"1"`
+ // 超no的结束时间建议尽可能大
+ VipEndTime uint64 `default:"4294967295"`
+ // 邀请活动建议先给固定值0
+ FreshManBonus uint64
+ // 超no芯片列表*(80字节)
+ NonoChipList [80]byte `array_serialize:"fixed_length,80"`
+ // 50字节,默认值为3
+ DailyResArr [50]byte `array_serialize:"fixed_length,50"`
+ // 教官id
+ TeacherID uint64
+ // 学员id
+ StudentID uint64
+ // 毕业人数
+ GraduationCount uint64
+ // 默认值为0
+ MaxPuniLv uint64 `default:"0"`
+ // 精灵的最高等级
+ PetMaxLevel uint64
+ // 所有的精灵的数量
+ AllPetNumber uint64
+ // 精灵王之战胜场
+ MonKingWin uint64
+ // 勇者之塔当前到达的层数
+ CurrentStage uint64
+ // 试炼之塔最大胜利的层数
+ MaxStage uint64
+ // 试炼之塔当前到达的层数
+ CurrentFreshStage uint64
+ // 试炼之塔最大胜利的层数
+ MaxFreshStage uint64
+ // 星际擂台连胜
+ MaxArenaWins uint64
+ // 未知默认0
+ TwoTimes uint64 `default:"0"`
+ // 未知默认0
+ ThreeTimes uint64 `default:"0"`
+ // 是否自动战斗(未知默认值0)
+ AutoFight uint64 `default:"0"`
+ // 自动战斗剩余的场次(未知默认值0)
+ AutoFightTime uint64 `default:"0"`
+ // 能量吸收仪剩余次数(未知待定默认值0)
+ EnergyTime uint64 `default:"0"`
+ // 学习力吸收仪剩余次数(未知待定默认值0)
+ LearnTimes uint64 `default:"0"`
+ // 未知默认0
+ MonBattleMedal uint64 `default:"0"`
+ // 未知默认0
+ RecordCount uint64 `default:"0"`
+ // 未知默认0
+ ObtainTm uint64 `default:"0"`
+ // 当前在孵化的元神珠id
+ SoulBeadItemID uint64
+ // 未知默认0
+ ExpireTm uint64 `default:"0"`
+ // 未知默认0
+ FuseTimes uint64 `default:"0"`
+ // 玩家有没有nono
+ HasNono uint64 `default:"1"`
+ // 玩家有没有超能nono
+ SuperNono uint64 `default:"1"`
+ // 默认值-1
+ NonoState uint64 `default:"4294967295"`
+ // nono的颜色
+ NonoColor uint64
+ // nono的名字 必须要补齐到16位
+ NonoNick [16]byte `array_serialize:"fixed_length,16"`
+ // 猜测为战队信息24字节
+ TeamInfo TeamInfo `array_serialize:"fixed_length,24"`
+ // 8字节
+ TeamPkInfo TeamPKInfo `array_serialize:"fixed_length,8"`
+ // 1字节 无内容
+ Reserved byte
+ // 默认值为0
+ Badge uint64 `default:"0"`
+ // 未知(27字节,默认值为3)
+ Reserved1 [27]byte `array_serialize:"fixed_length,27"`
+ // 任务状态数组(500字节,3为已经完成,建议默认值为3)
+ TaskList [500]byte `array_serialize:"fixed_length,500"`
+ // 精灵背包内的信息由于特性精灵的存在精灵背包不定长 如果有特性占199字节 如果没特性 一个精灵占175字节
+ PetList []PetInfo
+ // 穿戴装备 8字节
+ Clothes []PeopleItemInfo
+}
+
+// NewLoginUserInfo 创建新的登录用户信息实例,设置默认值
+func NewLoginUserInfo() *LoginUserInfo {
+ info := &LoginUserInfo{
+ Vip: 0,
+ Viped: 15,
+ Energy: 3000,
+ VipLevel: 8,
+ VipValue: 80000,
+ VipStage: 1,
+ AutoCharge: 1,
+ VipEndTime: uint64(^uint32(0)),
+ TwoTimes: 0,
+ ThreeTimes: 0,
+ AutoFight: 0,
+ AutoFightTime: 0,
+ EnergyTime: 0,
+ LearnTimes: 0,
+ MonBattleMedal: 0,
+ RecordCount: 0,
+ ObtainTm: 0,
+ ExpireTm: 0,
+ FuseTimes: 0,
+ HasNono: 1,
+ SuperNono: 1,
+ NonoState: uint64(^uint32(0)),
+ Badge: 0,
+ }
+
+ // 初始化固定长度数组
+ for i := range info.NonoChipList {
+ info.NonoChipList[i] = 0
+ }
+ for i := range info.DailyResArr {
+ info.DailyResArr[i] = 3
+ }
+ for i := range info.Reserved1 {
+ info.Reserved1[i] = 3
+ }
+ for i := range info.TaskList {
+ info.TaskList[i] = 3
+ }
+
+ // 初始化nono昵称
+ copy(info.NonoNick[:], "nono")
+
+ return info
+}
diff --git a/common/core/info/ServerInfo.go b/common/core/info/ServerInfo.go
new file mode 100644
index 000000000..5639e12c1
--- /dev/null
+++ b/common/core/info/ServerInfo.go
@@ -0,0 +1,41 @@
+package info
+
+// ServerInfo 服务器信息结构体
+type ServerInfo struct {
+ // 连接ID, 即服务器序号
+ OnlineID uint32
+ // 当前服务器玩家在线数量, 供SWF显示
+ UserCnt uint32
+ // 服务器IP, 16字节UTF-8, 不足16补齐到16
+ IP []byte `v:"FIXED_LENGTH|length:16"`
+ // 端口
+ Port uint16
+ // 好友在线的个数
+ Friends uint32
+}
+
+// NewServerInfo 创建新的服务器信息实例
+func NewServerInfo() *ServerInfo {
+ return &ServerInfo{
+ OnlineID: 0,
+ UserCnt: 0,
+ IP: []byte{},
+ Port: 0,
+ Friends: 0,
+ }
+}
+
+// // SetIP 设置IP地址并自动填充到16字节
+// func (s *ServerInfo) SetIP(ip string) {
+// copy(s.IP[:], ip)
+// if len(ip) < 16 {
+// for i := len(ip); i < 16; i++ {
+// s.IP[i] = 0 // 用0填充剩余字节
+// }
+// }
+// }
+
+// // GetIP 获取IP地址(去除填充的0)
+// func (s *ServerInfo) GetIP() string {
+// return strings.TrimRight(string(s.IP[:]), "\x00")
+// }
diff --git a/common/go.mod b/common/go.mod
index 0ce39b06a..393060b42 100644
--- a/common/go.mod
+++ b/common/go.mod
@@ -7,6 +7,7 @@ require github.com/panjf2000/gnet v1.6.7
require (
github.com/panjf2000/ants/v2 v2.11.3 // indirect
github.com/panjf2000/gnet/v2 v2.5.0 // indirect
+ github.com/tnnmigga/enum v1.0.2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
diff --git a/common/go.sum b/common/go.sum
index 7b73e262f..aee57ed50 100644
--- a/common/go.sum
+++ b/common/go.sum
@@ -23,6 +23,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/tnnmigga/enum v1.0.2 h1:Yvchx0Esc01X5HiphW78sKzH/RXKttdFsfPO1ARiOa4=
+github.com/tnnmigga/enum v1.0.2/go.mod h1:QaBFBwGJi/2GAM34b2pz6UL2NRtl2TRZ8lXp4vGwqhA=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
diff --git a/common/player/Server.go b/common/player/Server.go
deleted file mode 100644
index a18b5b289..000000000
--- a/common/player/Server.go
+++ /dev/null
@@ -1,360 +0,0 @@
-package socket
-
-import (
- "context"
- "database/sql"
- "errors"
- "fmt"
- "log"
- "sync"
- "time"
-
-)
-
-// Server 游戏服务器核心类,管理玩家、星球和游戏逻辑
-type Server struct {
- players map[int64]*entity.Player
- planets map[int64]*planet.Planet
- mutex sync.RWMutex
- gameRepo repo.GameResourceRepo
- serverRepo repo.ServerRepo
- accountRepo repo.AccountRepo
- playerInfoRepo repo.PlayerInfoRepo
- playerItemRepo repo.PlayerItemInfoRepo
- petRepo repo.PetRepo
-}
-
-// NewServer 创建新的游戏服务器实例
-func NewServer(
- gameRepo repo.GameResourceRepo,
- serverRepo repo.ServerRepo,
- accountRepo repo.AccountRepo,
- playerInfoRepo repo.PlayerInfoRepo,
- playerItemRepo repo.PlayerItemInfoRepo,
- petRepo repo.PetRepo,
-) *Server {
- s := &Server{
- players: make(map[int64]*entity.Player),
- planets: make(map[int64]*planet.Planet),
- gameRepo: gameRepo,
- serverRepo: serverRepo,
- accountRepo: accountRepo,
- playerInfoRepo: playerInfoRepo,
- playerItemRepo: playerItemRepo,
- petRepo: petRepo,
- }
- s.initializePlanets()
- return s
-}
-
-// initializePlanets 初始化所有星球
-func (s *Server) initializePlanets() {
- maps := s.gameRepo.GetAllMaps()
- for _, config := range maps {
- planet := s.generatePlanet(config)
- s.planets[planet.GetId()] = planet
- }
-}
-
-// generatePlanet 根据地图配置生成星球
-func (s *Server) generatePlanet(config *mapInfo.MapXmlModel) *planet.Planet {
- entries := config.GetEntries()
- positions := make(map[int64]structs.Point)
-
- if len(entries) == 0 {
- positions = make(map[int64]structs.Point)
- } else {
- for _, entry := range entries {
- positions[entry.GetFromMap()] = s.generatePoint(entry)
- }
- }
-
- return planet.NewPlanet(
- s,
- int64(config.GetId()),
- config.GetName(),
- structs.Point{X: config.GetX(), Y: config.GetY()},
- positions,
- s.gameRepo.CanMapRefresh(config.GetId()),
- )
-}
-
-// generatePoint 从入口配置生成点坐标
-func (s *Server) generatePoint(xml *mapInfo.EntryXmlModel) structs.Point {
- return structs.Point{X: xml.GetPosX(), Y: xml.GetPosY()}
-}
-
-// GetPlayer 获取玩家信息
-func (s *Server) GetPlayer(accountID int64) (*entity.Player, error) {
- s.mutex.RLock()
- defer s.mutex.RUnlock()
-
- player, exists := s.players[accountID]
- if !exists {
- return nil, errors.New("玩家不存在")
- }
- return player, nil
-}
-
-// GetPlanet 获取星球信息
-func (s *Server) GetPlanet(planetID int64) (*planet.Planet, error) {
- s.mutex.RLock()
- defer s.mutex.RUnlock()
-
- planet, exists := s.planets[planetID]
- if !exists {
- return nil, errors.New("星球不存在")
- }
- return planet, nil
-}
-
-// GetDefaultPlanet 获取默认星球
-func (s *Server) GetDefaultPlanet() (*planet.Planet, error) {
- s.mutex.RLock()
- defer s.mutex.RUnlock()
-
- planet, exists := s.planets[1] // 假设1是默认星球ID
- if !exists {
- return nil, errors.New("未找到默认星球")
- }
- return planet, nil
-}
-
-// PlayerEnter 玩家加入服务器
-func (s *Server) PlayerEnter(player *entity.Player) {
- s.mutex.Lock()
- defer s.mutex.Unlock()
-
- s.players[player.GetAccountID()] = player
-}
-
-// PlayerOffline 玩家离线处理
-func (s *Server) PlayerOffline(player *entity.Player) {
- s.mutex.Lock()
- defer s.mutex.Unlock()
-
- // 清理缓存会话数据
- if err := s.accountRepo.RemoveSessionID(player.GetSessionID()); err != nil {
- log.Printf("清除会话ID失败: %v", err)
- }
-
- // 清理登录绑定服务器
- if err := s.serverRepo.CancelRecordAccount(player.GetAccountID()); err != nil {
- log.Printf("取消账号绑定失败: %v", err)
- }
-
- // 从玩家列表中移除
- delete(s.players, player.GetAccountID())
-}
-
-// BroadcastMessage 广播消息给所有在线玩家
-func (s *Server) BroadcastMessage(message *net.OutboundMessage) {
- s.mutex.RLock()
- defer s.mutex.RUnlock()
-
- for _, player := range s.players {
- if player.IsOnline() {
- player.SendMessage(message)
- }
- }
-}
-
-// BroadcastMessageWithFilter 按条件广播消息给在线玩家
-func (s *Server) BroadcastMessageWithFilter(message *net.OutboundMessage, filter func(*entity.Player) bool) {
- s.mutex.RLock()
- defer s.mutex.RUnlock()
-
- for _, player := range s.players {
- if player.IsOnline() && filter(player) {
- player.SendMessage(message)
- }
- }
-}
-
-// GeneratePetEntity 生成宠物实体
-func (s *Server) GeneratePetEntity(
- playerID int64,
- petTypeID int,
- individualValue int16,
- nature int,
- abilityTypeEnum int,
- isShiny bool,
- level int,
-) (*pet.PetEntity, error) {
- if level < 1 || level > 100 {
- return nil, fmt.Errorf("精灵等级必须在1到100之间, level: %d", level)
- }
-
- petInfo, err := s.gameRepo.GetMonsterByID(petTypeID)
- if err != nil {
- return nil, fmt.Errorf("无效的精灵ID, pet_id: %d, 错误: %v", petTypeID, err)
- }
-
- firstSkillInfo, err := s.gameRepo.GetPetFirstSkillID(petTypeID, level)
- if err != nil {
- return nil, fmt.Errorf("精灵没有初始技能, pet_id: %d, 错误: %v", petTypeID, err)
- }
-
- zero := int16(0)
-
- pet := pet.NewPetEntityBuilder()
- .WithAsset(petInfo)
- .WithLevelToExp(s.gameRepo.GetLevelToExp())
- .WithPlayerID(playerID)
- .WithCapturePlayerID(playerID)
- .WithCaptureTime(time.Now().Unix())
- .WithCaptureMap(0) // 假设0是默认地图ID
- .WithCaptureRect(0) // 假设0是默认区域
- .WithCaptureLevel(level)
- .WithIndividualValue(individualValue)
- .WithNature(nature)
- .WithAbilityTypeEnum(abilityTypeEnum)
- .WithIsShiny(isShiny)
- .WithLevel(level)
- .WithCurrentExp(0)
- .WithEvHp(zero)
- .WithEvAttack(zero)
- .WithEvDefense(zero)
- .WithEvSpecialAttack(zero)
- .WithEvSpecialDefense(zero)
- .WithEvSpeed(zero)
- .WithSkill1ID(firstSkillInfo[0].GetId())
- .WithSkill1Pp(firstSkillInfo[0].GetMaxPp())
- .WithSkill2ID(firstSkillInfo[1].GetId())
- .WithSkill2Pp(firstSkillInfo[1].GetMaxPp())
- .WithSkill3ID(firstSkillInfo[2].GetId())
- .WithSkill3Pp(firstSkillInfo[2].GetMaxPp())
- .WithSkill4ID(firstSkillInfo[3].GetId())
- .WithSkill4Pp(firstSkillInfo[3].GetMaxPp())
- .WithIndividualGuarantee(0)
- .WithNatureGuarantee(0)
- .Build()
-
- if err := s.CalculatePetPanel(pet); err != nil {
- return nil, err
- }
-
- return pet, nil
-}
-
-// CalculatePetPanel 计算宠物面板属性
-func (s *Server) CalculatePetPanel(petEntity *pet.PetEntity) error {
- natureInfo, err := s.gameRepo.GetNatureInfoByID(petEntity.GetNature())
- if err != nil {
- return fmt.Errorf("无效的性格ID, nature: %d, 错误: %v", petEntity.GetNature(), err)
- }
-
- hp := util.CalculatePetHPPanelSize(
- petEntity.GetAsset().GetHp(),
- petEntity.GetIndividualValue(),
- petEntity.GetLevel(),
- petEntity.GetEvHp(),
- )
-
- attack := util.CalculatePetPanelSize(
- petEntity.GetAsset().GetAtk(),
- petEntity.GetIndividualValue(),
- petEntity.GetLevel(),
- petEntity.GetEvHp(),
- natureInfo.GetAttackCorrect(),
- )
-
- defense := util.CalculatePetPanelSize(
- petEntity.GetAsset().GetDef(),
- petEntity.GetIndividualValue(),
- petEntity.GetLevel(),
- petEntity.GetEvHp(),
- natureInfo.GetDefenseCorrect(),
- )
-
- specialAttack := util.CalculatePetPanelSize(
- petEntity.GetAsset().GetSpAtk(),
- petEntity.GetIndividualValue(),
- petEntity.GetLevel(),
- petEntity.GetEvHp(),
- natureInfo.GetSaCorrect(),
- )
-
- specialDefense := util.CalculatePetPanelSize(
- petEntity.GetAsset().GetSpDef(),
- petEntity.GetIndividualValue(),
- petEntity.GetLevel(),
- petEntity.GetEvHp(),
- natureInfo.GetSdCorrect(),
- )
-
- speed := util.CalculatePetPanelSize(
- petEntity.GetAsset().GetSpd(),
- petEntity.GetIndividualValue(),
- petEntity.GetLevel(),
- petEntity.GetEvHp(),
- natureInfo.GetSpeedCorrect(),
- )
-
- petEntity.SetMaxHp(hp)
- petEntity.SetCurrentHp(hp)
- petEntity.SetAttack(attack)
- petEntity.SetDefense(defense)
- petEntity.SetSpecialAttack(specialAttack)
- petEntity.SetSpecialDefense(specialDefense)
- petEntity.SetSpeed(speed)
-
- return nil
-}
-
-// SavePlayer 保存玩家信息到数据库
-func (s *Server) SavePlayer(player *entity.Player) (bool, error) {
- ctx := context.Background()
- tx, err := s.playerInfoRepo.BeginTransaction(ctx)
- if err != nil {
- return false, fmt.Errorf("开始事务失败: %v", err)
- }
- defer func() {
- if r := recover(); r != nil {
- tx.Rollback()
- log.Printf("保存玩家时发生panic: %v", r)
- } else if err != nil {
- tx.Rollback()
- } else {
- tx.Commit()
- }
- }()
-
- playerID := player.GetGameID()
- pets := player.GetPetBag().GetUsedPets()
- items := player.GetItemBag().GetItems()
-
- // 保存玩家信息
- if err := s.playerInfoRepo.Save(ctx, tx, player); err != nil {
- return false, fmt.Errorf("保存玩家信息失败: %v", err)
- }
-
- // 保存精灵信息
- if err := s.petRepo.SaveAll(ctx, tx, playerID, pets); err != nil {
- return false, fmt.Errorf("保存精灵信息失败: %v", err)
- }
-
- // 保存玩家背包信息
- if err := s.playerItemRepo.SaveAll(ctx, tx, playerID, items); err != nil {
- return false, fmt.Errorf("保存背包信息失败: %v", err)
- }
-
- return true, nil
-}
-
-// Destroy 销毁服务器,清理资源
-func (s *Server) Destroy() error {
- // 保存所有玩家数据
- s.mutex.RLock()
- for _, player := range s.players {
- go func(p *entity.Player) {
- if _, err := s.SavePlayer(p); err != nil {
- log.Printf("保存玩家 %d 数据失败: %v", p.GetAccountID(), err)
- }
- }(player)
- }
- s.mutex.RUnlock()
-
- log.Println("Destroying server ...")
- return nil
-}
diff --git a/common/serialize/ArraySerialize.go b/common/serialize/ArraySerialize.go
new file mode 100644
index 000000000..1c8ea2efe
--- /dev/null
+++ b/common/serialize/ArraySerialize.go
@@ -0,0 +1,10 @@
+package serialize
+
+type ArraySerialize struct {
+ OrderId int64 `v:"order-exist"`
+ ProductName string
+ Amount int64
+ // ...
+}
+var paddedContent byte=0//长度不足时填充的内容, 默认填充0
+
diff --git a/common/bytearray/bytearray.go b/common/serialize/bytearray/bytearray.go
similarity index 100%
rename from common/bytearray/bytearray.go
rename to common/serialize/bytearray/bytearray.go
diff --git a/common/bytearray/bytearray_test.go b/common/serialize/bytearray/bytearray_test.go
similarity index 100%
rename from common/bytearray/bytearray_test.go
rename to common/serialize/bytearray/bytearray_test.go
diff --git a/common/serialize/cheak.go b/common/serialize/cheak.go
new file mode 100644
index 000000000..aa8b3ff21
--- /dev/null
+++ b/common/serialize/cheak.go
@@ -0,0 +1,20 @@
+package serialize
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/gogf/gf/v2/util/gvalid"
+)
+
+type Request struct {
+ OrderId int64 `v:"order-exist"`
+ ProductName string `v:"order-exist"`
+ Amount int64
+ // ...
+}
+
+func RuleOrderExist(ctx context.Context, in gvalid.RuleFuncInput) error {
+ fmt.Println(in)
+ return nil
+}
diff --git a/common/serialize/cheak_test.go b/common/serialize/cheak_test.go
new file mode 100644
index 000000000..51eed8bb4
--- /dev/null
+++ b/common/serialize/cheak_test.go
@@ -0,0 +1,22 @@
+package serialize
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gctx"
+)
+
+func Test_main(t *testing.T) {
+ var (
+ ctx = gctx.New()
+ req = &Request{
+ OrderId: 65535,
+ ProductName: "HikingShoe",
+ Amount: 10000,
+ }
+ )
+ err := g.Validator().RuleFunc("order-exist", RuleOrderExist).Data(req).Run(ctx)
+ fmt.Println(err)
+}
diff --git a/common/serialize/ser.go b/common/serialize/ser.go
new file mode 100644
index 000000000..a71f66392
--- /dev/null
+++ b/common/serialize/ser.go
@@ -0,0 +1,236 @@
+package serialize
+
+import (
+ "bytes"
+ "context"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "reflect"
+ "strings"
+
+ "github.com/gogf/gf/v2/frame/g"
+ "github.com/gogf/gf/v2/os/gctx"
+ "github.com/gogf/gf/v2/util/gconv"
+ "github.com/gogf/gf/v2/util/gvalid"
+ "github.com/tnnmigga/enum"
+)
+
+var lengthtype = enum.New[struct {
+ LENGTH_FIRST int
+ FIXED_LENGTH int
+}]()
+
+// PacketSerializer 定义序列化函数类型,将数据转换为字节切片
+type PacketSerializer[T any] func(data T) ([]byte, error)
+
+// PacketDeserializer 定义反序列化函数类型,将字节切片转换为数据
+type PacketDeserializer[T any] func(data []byte) (T, error)
+
+// PacketHandler 封装序列化和反序列化处理函数
+type PacketHandler[T any] struct {
+ Serialize PacketSerializer[T] // 序列化函数
+ Deserialize PacketDeserializer[T] // 反序列化函数
+}
+
+
+
+func serializebase[T any](field reflect.StructField, buf *bytes.Buffer, writedata any) error {
+
+
+ if field.Type.Kind() == reflect.Slice { //|| field.Type.Kind() == reflect.Array}
+
+ datatype := make(chan int, 1)
+ FIXED_LENGTH := func(ctx context.Context, in gvalid.RuleFuncInput) error {
+ if in.Field == field.Name { //判断相同
+ datatype <- lengthtype.FIXED_LENGTH
+
+ }
+ return nil
+ }
+ LENGTH_FIRST := func(ctx context.Context, in gvalid.RuleFuncInput) error {
+ datatype <- lengthtype.FIXED_LENGTH
+ // fmt.Println(in)
+ return nil
+ }
+ length := func(ctx context.Context, in gvalid.RuleFuncInput) error {
+ tem := <-datatype
+ close(datatype)
+ writelen := 0
+ if parts := strings.Split(in.Rule, ":"); len(parts) > 1 {
+ writelen = gconv.Int(strings.TrimSpace(parts[1]))
+
+ }
+ switch tem {
+ case lengthtype.FIXED_LENGTH: //in.value
+ tempslice := gconv.SliceAny(writedata)
+ temp := make([]byte, writelen-len(tempslice))
+
+ for i := 0; i < len(tempslice); i++ {
+ tempdata := tempslice[i]
+ fmt.Println(i)
+ serializebase[T]( field, buf, tempdata) //todo递归序列化
+ // copy(temp, date1)
+ // if err := binary.Write(buf, binary.BigEndian, temp); err != nil {
+ // return nil
+ // }
+ }
+
+ if err := binary.Write(buf, binary.BigEndian, temp); err != nil {
+ return nil
+ }
+ case lengthtype.LENGTH_FIRST:
+ // temp := make([]byte, writelen)
+ // date1 := []byte(writedata.(string))
+ // copy(temp, date1)
+ // if err := binary.Write(buf, binary.BigEndian, temp); err != nil {
+ // return nil
+ // }
+ }
+
+ return nil
+ }
+ rules := make(map[string]gvalid.RuleFunc, 3)
+ rules["LENGTH_FIRST"] = LENGTH_FIRST
+ rules["FIXED_LENGTH"] = FIXED_LENGTH
+ rules["length"] = length
+ g.Validator().RuleFuncMap(rules).Data(writedata).Run(gctx.New())
+ // serializeslice[T](field, buf, writedata)
+ } else {
+ if err := binary.Write(buf, binary.BigEndian, writedata); err != nil {
+
+
+ }
+ }
+ return nil
+}
+
+// DefaultPacketSerializer 默认序列化实现,使用大端序写入数据
+func DefaultPacketSerializer[T any]() PacketSerializer[T] {
+ return func(data T) ([]byte, error) {
+ var buf bytes.Buffer
+ // 使用大端序写入数据
+ // 1. 使用reflect获取结构体类型
+ typ := reflect.TypeOf(data)
+ fmt.Println("结构体类型名称:", typ.Name())
+ fmt.Println("字段数量:", typ.NumField())
+
+ for i := 0; i < typ.NumField(); i++ {
+ field := typ.Field(i)
+ fmt.Printf("字段名: %s, 类型: %s",
+ field.Name, field.Type)
+ fmt.Println("字段值:", reflect.ValueOf(data).Field(i).Interface())
+
+ writedata := reflect.ValueOf(data).Field(i).Interface()
+ fmt.Println(field.Type.Kind())
+
+ serializebase[T]( field, &buf, writedata)
+
+ }
+
+ return buf.Bytes(), nil
+ }
+}
+
+// DefaultPacketDeserializer 默认反序列化实现,使用大端序读取数据
+func DefaultPacketDeserializer[T any]() PacketDeserializer[T] {
+ return func(data []byte) (T, error) {
+ var result T
+ reader := bytes.NewReader(data)
+ // 使用大端序读取数据
+ if err := binary.Read(reader, binary.BigEndian, &result); err != nil {
+ var zero T
+ return zero, err
+ }
+ return result, nil
+ }
+}
+
+// NewDefaultPacketHandler 创建默认的数据包处理句柄
+func NewDefaultPacketHandler[T any]() *PacketHandler[T] {
+ return &PacketHandler[T]{
+ Serialize: DefaultPacketSerializer[T](),
+ Deserialize: DefaultPacketDeserializer[T](),
+ }
+}
+
+// 示例:使用自定义类型演示序列化与反序列化
+type ExampleData struct {
+ ID int32
+ Name string
+ Data []byte
+}
+
+// 自定义序列化函数(处理结构体类型)
+func CustomSerializer() PacketSerializer[ExampleData] {
+ return func(data ExampleData) ([]byte, error) {
+ var buf bytes.Buffer
+
+ // 先序列化基本类型字段
+ if err := binary.Write(&buf, binary.BigEndian, data.ID); err != nil {
+ return nil, err
+ }
+
+ // 序列化字符串长度和内容
+ lenName := int32(len(data.Name))
+ if err := binary.Write(&buf, binary.BigEndian, lenName); err != nil {
+ return nil, err
+ }
+ if _, err := buf.Write([]byte(data.Name)); err != nil {
+ return nil, err
+ }
+
+ // 序列化字节数组长度和内容
+ lenData := int32(len(data.Data))
+ if err := binary.Write(&buf, binary.BigEndian, lenData); err != nil {
+ return nil, err
+ }
+ if _, err := buf.Write(data.Data); err != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
+ }
+}
+
+// 自定义反序列化函数(处理结构体类型)
+func CustomDeserializer() PacketDeserializer[ExampleData] {
+ return func(data []byte) (ExampleData, error) {
+ var result ExampleData
+ reader := bytes.NewReader(data)
+
+ // 读取基本类型字段
+ if err := binary.Read(reader, binary.BigEndian, &result.ID); err != nil {
+ return result, err
+ }
+
+ // 读取字符串长度和内容
+ var lenName int32
+ if err := binary.Read(reader, binary.BigEndian, &lenName); err != nil {
+ return result, err
+ }
+ if lenName > int32(reader.Len()) {
+ return result, errors.New("invalid name length")
+ }
+ nameBuf := make([]byte, lenName)
+ if _, err := reader.Read(nameBuf); err != nil {
+ return result, err
+ }
+ result.Name = string(nameBuf)
+
+ // 读取字节数组长度和内容
+ var lenData int32
+ if err := binary.Read(reader, binary.BigEndian, &lenData); err != nil {
+ return result, err
+ }
+ if lenData > int32(reader.Len()) {
+ return result, errors.New("invalid data length")
+ }
+ result.Data = make([]byte, lenData)
+ if _, err := reader.Read(result.Data); err != nil {
+ return result, err
+ }
+
+ return result, nil
+ }
+}
diff --git a/common/socket/ServerEvent.go b/common/socket/ServerEvent.go
index ca8fc5f7e..c4626b85c 100644
--- a/common/socket/ServerEvent.go
+++ b/common/socket/ServerEvent.go
@@ -5,6 +5,7 @@ import (
"github.com/panjf2000/gnet/v2"
"github.com/panjf2000/gnet/v2/pkg/logging"
+ "blazing/common/data/entity"
)
func (s *Server) Boot() error {
@@ -35,19 +36,18 @@ func (s *Server) OnBoot(eng gnet.Engine) gnet.Action {
func (s *Server) OnTraffic(conn gnet.Conn) (action gnet.Action) {
-
+ conn.SetContext(entity.NewClientData())//注入data
if s.network == "tcp" {
return s.handleTcp(conn)
}
-
-
return gnet.None
}
-
func (s *Server) handleTcp(conn gnet.Conn) (action gnet.Action) {
+
for {
+
data, err := s.codec.Decode(conn)
if err != nil {
break
@@ -73,11 +73,11 @@ func (s *Server) handleTcp(conn gnet.Conn) (action gnet.Action) {
}
func (s *Server) parser(c gnet.Conn, line []byte) {
-
+ //todo 这里待实现注入player实体
s.handler.Handle(line)
}
func (s *Server) Start() {
-
+
err := gnet.Run(s, s.network+"://"+s.addr, gnet.WithMulticore(s.multicore))
logging.Infof("server exits with error: %v", err)
}
diff --git a/common/socket/cmd/cmd.go b/common/socket/cmd/cmd.go
new file mode 100644
index 000000000..1574a7dcf
--- /dev/null
+++ b/common/socket/cmd/cmd.go
@@ -0,0 +1,98 @@
+package cmd
+
+import (
+ "github.com/tnnmigga/enum"
+)
+
+// Enum 辅助类型定义
+type EnumValue struct {
+ Value int
+ Name string
+}
+
+// MessageCommandIDRegistry 消息命令ID注册表
+var MessageCommandIDRegistry = enum.New[struct {
+ // 在线相关命令
+ Commend_OnLine int `enum:"105"` // 在线命令
+ Login_In int `enum:"1001"` // 玩家登录
+ System_Time int `enum:"1002"` // 返回当前时间戳
+ Map_Hot int `enum:"1004"` // 显示地图热度(此地图内玩家数量)
+ Gold_Online_Check_Remain int `enum:"1106"` // 返回玩家金豆数量
+
+ // 地图相关命令
+ Enter_Map int `enum:"2001"` // 告知后端玩家进入新地图
+ Leave_Map int `enum:"2002"` // 玩家离开地图
+ List_Map_Player int `enum:"2003"` // 返回当前地图玩家列表
+ Map_Ogre_List int `enum:"2004"` // 精灵刷新
+
+ // 用户信息相关命令
+ Get_Sim_UserInfo int `enum:"2051"` // 返回邮人物简单信息
+ Get_More_UserInfo int `enum:"2052"` // 返回人物详细信息
+ Change_Nick_Name int `enum:"2061"` // 修改玩家名字
+
+ // 动作相关命令
+ People_Walk int `enum:"2101"` // 玩家走路包
+ Chat int `enum:"2102"` // 公屏聊天
+ Aimat int `enum:"2104"` // 射击
+
+ // 精灵相关命令
+ Get_Pet_Info int `enum:"2301"` // 获取精灵详细信息
+ Get_Pet_List int `enum:"2303"` // 获取所有的精灵列表
+ Pet_Release int `enum:"2304"` // 精灵加入背包或放回仓库
+ Pet_Show int `enum:"2305"` // 展示精灵
+ Pet_Cure int `enum:"2306"` // 恢复精灵状态,NONO恢复所有精灵
+ Pet_Study_Skill int `enum:"2307"` // 升级学习替换技能
+ Pet_Default int `enum:"2308"` // 设置精灵首发
+ Pet_One_Cure int `enum:"2310"` // 恢复精灵状态,精灵恢复单只精灵
+ Pet_Skill_Switch int `enum:"2312"` // 切换精灵技能
+ Pet_Set_Exp int `enum:"2318"` // 分配精灵经验
+ Pet_Get_Exp int `enum:"2319"` // 获取积累经验
+ Pet_Room int `enum:"2325"` // 跟随精灵获取信息
+ Get_Soul_Bead_List int `enum:"2354"` // 返回元神珠信息
+
+ // 战斗相关命令
+ Ready_To_Fight int `enum:"2404"` // 客户端通知服务端可以开始战斗, 此包表示客户端可以开始战斗, 无需服务端回复此包内容
+ Use_Skill int `enum:"2405"` // 使用技能
+ Change_Pet int `enum:"2407"` // 切换精灵
+ Fight_NPC_Monster int `enum:"2408"` // 与野怪对战的申请进入战斗
+ Catch_Monster int `enum:"2409"` // 捕捉精灵
+ Challenge_Boss int `enum:"2411"` // 与当前地图的Boss类型野怪进入战斗
+ Note_ReadyTo_Fight int `enum:"2503"` // 通知客户端已经可以开始战斗
+ Note_Start_Fight int `enum:"2504"` // 在客户端告知服务端可以开始战斗后, 服务端回给客户端战斗开始
+ Note_Use_Skill int `enum:"2505"` // 通知使用技能
+ Fight_Over int `enum:"2506"` // 战斗结束
+ Note_Update_Skill int `enum:"2507"` // 升级获得学习技能
+ Note_Update_Prop int `enum:"2508"` // 返回升级后的信息
+
+ // 装备物品相关命令
+ Change_Cloth int `enum:"2604"` // 修改玩家装备
+ Item_List int `enum:"2605"` // 返回玩家物品列表
+
+ // 奖励相关命令
+ Talk_Count int `enum:"2701"` // 玩家领取奖励的次数(挖矿,礼包等)
+ Talk_Cate int `enum:"2702"` // 领取奖品的内容
+ Mail_Get_Unread int `enum:"2757"` // 返回邮件数量
+
+ // 系统相关命令
+ System_Message int `enum:"8002"` // 后端主动发送面板消息
+ Get_Boss_Monster int `enum:"8004"` // 返回战斗结束后的奖励包或主动发放奖励
+
+ // NONO相关命令
+ Nono_Info int `enum:"9003"` // 通过米米号获取nono信息
+ Nono_Follow_Or_Home int `enum:"9019"` // nono跟随或回家
+
+ // 特殊命令
+ Get_Quadruple_Exe_Time int `enum:"50007"` // 返回已使用四倍剩余时间
+
+ // 暂未处理的包
+ Item_Buy int `enum:"2601"` // 物品购买
+ Item_Sale int `enum:"2602"` // 物品出售
+ Friend_Add int `enum:"2151"` // 添加好友
+ Friend_Remove int `enum:"2153"` // 移除好友
+ Invite_To_Fight int `enum:"2401"` // 邀请战斗
+ Escape_Fight int `enum:"2410"` // 逃离战斗
+ Join_Game int `enum:"5001"` // 加入游戏
+ Game_Over int `enum:"5002"` // 游戏结束
+ Leave_Game int `enum:"5003"` // 离开游戏
+}]()
+
diff --git a/common/socket/cmd/cmd_test.go b/common/socket/cmd/cmd_test.go
new file mode 100644
index 000000000..e18bca649
--- /dev/null
+++ b/common/socket/cmd/cmd_test.go
@@ -0,0 +1,14 @@
+package cmd
+
+import (
+ "testing"
+)
+
+func BenchmarkCmd(b *testing.B) {
+ b.ReportAllocs()
+ //写入
+ for i := 0; i < b.N; i++ {
+ b.Log(MessageCommandIDRegistry.Change_Cloth)
+
+ }
+}
diff --git a/common/socket/codec/CrossDomain.go b/common/socket/codec/CrossDomain.go
deleted file mode 100644
index ea7b1088e..000000000
--- a/common/socket/codec/CrossDomain.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package codec
-
-import (
- "log"
-
- "github.com/panjf2000/gnet/v2"
-)
-
-// CROSS_DOMAIN 定义跨域策略文件内容
-const CROSS_DOMAIN = "\x00"
-
-// TEXT 定义跨域请求的文本格式
-const TEXT = "\x00"
-
-// Handle 处理网络连接
-func Handle(conn gnet.Conn) error {
- // 读取数据并检查是否为跨域请求
- data, err := conn.Peek(len(TEXT))
- if err != nil {
- log.Printf("Error reading cross-domain request: %v", err)
- return err
- }
-
- if string(data) == TEXT { //判断是否是跨域请求
- log.Printf("Received cross-domain request from %s", conn.RemoteAddr())
- // 处理跨域请求
- conn.Write([]byte(CROSS_DOMAIN))
- conn.Discard(len(TEXT))
- return nil
- }
-
- return nil
-}
diff --git a/common/socket/codec/SocketCodec.go b/common/socket/codec/SocketCodec.go
index 79d974174..78600cf00 100644
--- a/common/socket/codec/SocketCodec.go
+++ b/common/socket/codec/SocketCodec.go
@@ -10,4 +10,5 @@ type SocketCodec interface {
Encode([]byte) ([]byte, error)
Decode(gnet.Conn) ([]byte, error)
+
}
\ No newline at end of file
diff --git a/common/socket/codec/SocketCodec_Tomee.go b/common/socket/codec/SocketCodec_Tomee.go
index 37745ceef..44c36b6e2 100644
--- a/common/socket/codec/SocketCodec_Tomee.go
+++ b/common/socket/codec/SocketCodec_Tomee.go
@@ -1,13 +1,21 @@
package codec
import (
+ "blazing/common/data/entity"
"encoding/binary"
"errors"
"io"
+ "log"
"github.com/panjf2000/gnet/v2"
)
+// CROSS_DOMAIN 定义跨域策略文件内容
+const CROSS_DOMAIN = "\x00"
+
+// TEXT 定义跨域请求的文本格式
+const TEXT = "\x00"
+
var ErrIncompletePacket = errors.New("incomplete packet")
// TomeeSocketCodec 协议格式:
@@ -23,26 +31,54 @@ var ErrIncompletePacket = errors.New("incomplete packet")
// * | ... ... |
// * +-----------+
type TomeeSocketCodec struct{}
-var _ SocketCodec = (*TomeeSocketCodec)(nil)
+var _ SocketCodec = (*TomeeSocketCodec)(nil)
func NewTomeeSocketCodec() *TomeeSocketCodec {
return &TomeeSocketCodec{}
}
+
+func handle(c gnet.Conn) {
+ clientdata:=c.Context().(*entity.ClientData)
+ if(clientdata.IsCrossDomain){
+ return
+
+ }
+ // 读取数据并检查是否为跨域请求
+ data, err := c.Peek(len(TEXT))
+ if err != nil {
+ log.Printf("Error reading cross-domain request: %v", err)
+ return
+ }
+
+ if string(data) == TEXT { //判断是否是跨域请求
+ log.Printf("Received cross-domain request from %s", c.RemoteAddr())
+ // 处理跨域请求
+ c.Write([]byte(CROSS_DOMAIN))
+ c.Discard(len(TEXT))
+
+ clientdata.IsCrossDomain=true
+ return
+ }
+
+ return
+}
func (codec TomeeSocketCodec) Encode(buf []byte) ([]byte, error) {
bodyLen := len(buf)
data := make([]byte, 4+bodyLen)
-
+
// 写入4字节的包长度
binary.BigEndian.PutUint32(data[:4], uint32(bodyLen))
// 写入包体
copy(data[4:], buf)
-
+
return data, nil
}
func (codec TomeeSocketCodec) Decode(c gnet.Conn) ([]byte, error) {
+
+ handle(c)
// 先读取4字节的包长度
lenBuf, err := c.Peek(4)
if err != nil {
@@ -51,10 +87,10 @@ func (codec TomeeSocketCodec) Decode(c gnet.Conn) ([]byte, error) {
}
return nil, err
}
-
+
bodyLen := binary.BigEndian.Uint32(lenBuf)
totalLen := 4 + int(bodyLen)
-
+
// 检查整个包是否完整
buf, err := c.Peek(totalLen)
if err != nil {
@@ -63,13 +99,13 @@ func (codec TomeeSocketCodec) Decode(c gnet.Conn) ([]byte, error) {
}
return nil, err
}
-
+
// 提取包体
body := make([]byte, bodyLen)
copy(body, buf[4:totalLen])
-
+
// 从缓冲区中丢弃已读取的数据
_, _ = c.Discard(totalLen)
-
+
return body, nil
}
diff --git a/go.work b/go.work
index af1928640..b273ddd4f 100644
--- a/go.work
+++ b/go.work
@@ -4,7 +4,7 @@ use (
./common
./common/contrib/drivers/mysql
./common/contrib/files/local
- ./cool
+ ./common/cool
./logic
./login
./modules/base
diff --git a/logic/main.go b/logic/main.go
index d94fbe4bc..a9f0c225b 100644
--- a/logic/main.go
+++ b/logic/main.go
@@ -1,7 +1,21 @@
package main
-import "blazing/common/socket"
+import (
+ "blazing/common/bytearray/serialize"
+ "blazing/common/core/info"
+ "blazing/common/socket"
+ "fmt"
+)
func main() {
+
+
+ tt:=info.NewServerInfo()
+ tt.OnlineID=99
+ tt.IP=[]byte("127.0.0.1")
+ tt1:=serialize.NewDefaultPacketHandler[info.ServerInfo]()
+ tg,_:=tt1.Serialize(*tt)
+
+ fmt.Println(tg)
socket.NewServer(socket.WithPort("9999")).Start()
}