refactor(socket): 重构 socket 模块
- 移除 common/data/socket 目录下的大部分文件 - 新增 service 目录,将 Player 和 Conn 结构体移至该目录 - 更新 LogicClient 中的方法签名,使用 service 包的类型 - 重构 Controller 中的方法,适应新的 service 包结构
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
package socket
|
||||
|
||||
func ConutPlayer() int {
|
||||
|
||||
count := 0
|
||||
Mainplayer.Range(func(uint32, *Player) bool {
|
||||
count++
|
||||
return true // 继续遍历
|
||||
})
|
||||
return count
|
||||
}
|
||||
|
||||
type ClientData struct {
|
||||
IsCrossDomain bool //是否跨域过
|
||||
Player *Player //客户实体
|
||||
//UserID uint32
|
||||
|
||||
Wsmsg *WsCodec
|
||||
}
|
||||
|
||||
func NewClientData() *ClientData {
|
||||
cd := ClientData{
|
||||
IsCrossDomain: false,
|
||||
Player: nil,
|
||||
|
||||
Wsmsg: &WsCodec{},
|
||||
}
|
||||
return &cd
|
||||
|
||||
}
|
||||
@@ -7,7 +7,8 @@ import (
|
||||
"time"
|
||||
|
||||
"blazing/common/data/share"
|
||||
"blazing/common/data/socket"
|
||||
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/maps"
|
||||
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
@@ -42,7 +43,7 @@ func (s *Server) Stop() error {
|
||||
func (s *Server) OnClose(c gnet.Conn, _ error) (action gnet.Action) {
|
||||
atomic.AddInt64(&s.connected, -1)
|
||||
//logging.Infof("conn[%v] disconnected", c.RemoteAddr().String())
|
||||
v, ok := c.Context().(*socket.ClientData)
|
||||
v, ok := c.Context().(*service.ClientData)
|
||||
if !ok {
|
||||
return
|
||||
|
||||
@@ -54,7 +55,7 @@ func (s *Server) OnClose(c gnet.Conn, _ error) (action gnet.Action) {
|
||||
maps.LeaveMap(v.Player)
|
||||
|
||||
v.Player.IsLogin = false
|
||||
socket.Mainplayer.Delete(v.Player.Info.UserID)
|
||||
service.Mainplayer.Delete(v.Player.Info.UserID)
|
||||
share.ShareManager.DeleteUserOnline(v.Player.Info.UserID) //设置用户登录服务器
|
||||
v.Player.Save() //保存玩家数据
|
||||
}
|
||||
@@ -77,7 +78,7 @@ func (s *Server) OnBoot(eng gnet.Engine) gnet.Action {
|
||||
|
||||
func (s *Server) OnOpen(conn gnet.Conn) (out []byte, action gnet.Action) {
|
||||
if conn.Context() == nil {
|
||||
conn.SetContext(socket.NewClientData()) //注入data
|
||||
conn.SetContext(service.NewClientData()) //注入data
|
||||
}
|
||||
|
||||
atomic.AddInt64(&s.connected, 1)
|
||||
@@ -90,7 +91,7 @@ func (s *Server) OnTraffic(c gnet.Conn) (action gnet.Action) {
|
||||
return gnet.Close
|
||||
}
|
||||
|
||||
ws := c.Context().(*socket.ClientData).Wsmsg
|
||||
ws := c.Context().(*service.ClientData).Wsmsg
|
||||
tt, len1 := ws.ReadBufferBytes(c)
|
||||
if tt == gnet.Close {
|
||||
|
||||
@@ -169,7 +170,7 @@ const CROSS_DOMAIN = "<?xml version=\"1.0\"?><!DOCTYPE cross-domain-policy><cros
|
||||
const TEXT = "<policy-file-request/>\x00"
|
||||
|
||||
func handle(c gnet.Conn) {
|
||||
clientdata := c.Context().(*socket.ClientData)
|
||||
clientdata := c.Context().(*service.ClientData)
|
||||
if clientdata.IsCrossDomain {
|
||||
return
|
||||
|
||||
|
||||
@@ -2,13 +2,58 @@ package socket
|
||||
|
||||
import (
|
||||
"blazing/common/socket/codec"
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/panjf2000/gnet/pkg/pool/goroutine"
|
||||
"github.com/panjf2000/gnet/v2"
|
||||
)
|
||||
|
||||
func GetPlayer(c *service.Conn, userid uint32) *service.Player { //TODO 这里待优化,可能存在内存泄漏问题
|
||||
c.Mu.Lock()
|
||||
defer c.Mu.Unlock()
|
||||
//检查player初始化,是否为conn初始后取map,防止二次连接后存在两个player
|
||||
|
||||
clientdata := c.MainConn.Context().(*service.ClientData)
|
||||
if clientdata.Player != nil {
|
||||
return clientdata.Player
|
||||
}
|
||||
|
||||
clientdata.Player = service.NewPlayer(
|
||||
|
||||
service.WithConn(c), //注入conn
|
||||
)
|
||||
|
||||
// gff := socket.NewClientData()
|
||||
|
||||
// gff.Player = clientdata.Player
|
||||
// c.MainConn.SetContext(gff)
|
||||
service.Mainplayer.Store(userid, clientdata.Player)
|
||||
|
||||
return clientdata.Player
|
||||
// return nil
|
||||
}
|
||||
func KickPlayer(userid uint32) { //踢出玩家
|
||||
//TODO 返回错误码
|
||||
//var player *entity.Player
|
||||
if player1, ok := service.Mainplayer.Load((userid)); ok {
|
||||
//取成功,否则创建
|
||||
head := service.NewTomeeHeader(1001, userid)
|
||||
head.Result = uint32(errorcode.ErrorCodes.ErrAccountLoggedInElsewhere)
|
||||
|
||||
player1.SendPack(head.Pack(nil))
|
||||
player1.MainConn.MainConn.Close()
|
||||
// clientdata.Player = player
|
||||
}
|
||||
|
||||
//return player
|
||||
// return nil
|
||||
}
|
||||
|
||||
type Handler interface {
|
||||
Handle(gnet.Conn, []byte)
|
||||
}
|
||||
type Server struct {
|
||||
gnet.BuiltinEventEngine
|
||||
eng gnet.Engine
|
||||
@@ -19,7 +64,7 @@ type Server struct {
|
||||
bufferSize int
|
||||
workerPool *goroutine.Pool
|
||||
codec codec.SocketCodec
|
||||
handler handler.Handler
|
||||
handler Handler
|
||||
discorse bool
|
||||
}
|
||||
|
||||
@@ -52,7 +97,7 @@ func WithCORS() Option {
|
||||
u.discorse = false
|
||||
}
|
||||
}
|
||||
func WithSocketHandler(handler handler.Handler) Option {
|
||||
func WithSocketHandler(handler Handler) Option {
|
||||
return func(u *Server) {
|
||||
u.handler = handler
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package handler
|
||||
|
||||
import "github.com/panjf2000/gnet/v2"
|
||||
|
||||
// Handler The handler receive every syslog entry at Handle method
|
||||
type Handler interface {
|
||||
Handle(gnet.Conn, []byte)
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/login"
|
||||
"blazing/modules/blazing/service"
|
||||
blservice "blazing/modules/blazing/service"
|
||||
)
|
||||
|
||||
// 处理命令: 1001
|
||||
func (h *Controller) CreatePlayer(data *login.CreatePlayerInboundInfo, c *socket.Conn) (result *login.CreatePlayerOutInfo, err errorcode.ErrorCode) {
|
||||
func (h *Controller) CreatePlayer(data *login.CreatePlayerInboundInfo, c *service.Conn) (result *login.CreatePlayerOutInfo, err errorcode.ErrorCode) {
|
||||
|
||||
service.NewUserService(data.Head.UserID).Reg(data.Nickname, data.Color)
|
||||
blservice.NewUserService(data.Head.UserID).Reg(data.Nickname, data.Color)
|
||||
return result, 0
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/friend"
|
||||
)
|
||||
|
||||
func (h Controller) OnSeeOnline(data *friend.SeeOnlineInboundInfo, c *socket.Player) (result *friend.SeeOnlineOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) OnSeeOnline(data *friend.SeeOnlineInboundInfo, c *service.Player) (result *friend.SeeOnlineOutboundInfo, err errorcode.ErrorCode) {
|
||||
result = &friend.SeeOnlineOutboundInfo{}
|
||||
result.Friends = make([]friend.OnlineInfo, 0)
|
||||
return
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/common/socket/handler"
|
||||
|
||||
"blazing/cool"
|
||||
"blazing/logic/service"
|
||||
"os"
|
||||
@@ -38,7 +38,7 @@ type LogicClient struct {
|
||||
func (h *LogicClient) KickPerson(a int) error {
|
||||
|
||||
fmt.Println("检测到踢人请求", a)
|
||||
service.KickPlayer(uint32(a))
|
||||
socket.KickPlayer(uint32(a))
|
||||
return nil
|
||||
}
|
||||
func (h *LogicClient) QuitSelf(a int) error {
|
||||
@@ -50,9 +50,9 @@ func (h *LogicClient) QuitSelf(a int) error {
|
||||
for {
|
||||
|
||||
//entity.ConutPlayer()
|
||||
fmt.Println("当前在线人数", socket.ConutPlayer())
|
||||
fmt.Println("当前在线人数", service.ConutPlayer())
|
||||
|
||||
if socket.ConutPlayer() <= 0 {
|
||||
if service.ConutPlayer() <= 0 {
|
||||
//执行退出逻辑
|
||||
os.Exit(1)
|
||||
}
|
||||
@@ -107,7 +107,7 @@ func init() { //默认初始化扫描
|
||||
|
||||
}
|
||||
glog.Debug(context.Background(), "注册方法", func_cmd, method.Name)
|
||||
// fmt.Println(methodValue.Interface().(func(gnet.Conn, handler.TomeeHeader)))
|
||||
// fmt.Println(methodValue.Interface().(func(gnet.Conn, service.TomeeHeader)))
|
||||
_, ok := cool.CmdCache.LoadOrStore(func_cmd, methodValue) //TODO 待实现对不同用户初始化方法以取消全局cmdcache
|
||||
|
||||
if ok { //方法已存在init
|
||||
@@ -136,7 +136,7 @@ func getcmd(t reflect.Type) []uint32 {
|
||||
field := t.Field(i)
|
||||
//fmt.Printf("- 字段名: %s\n", field.Name)
|
||||
//fmt.Printf(" 类型: %v\n", field.Type)
|
||||
if field.Type == reflect.TypeOf(handler.TomeeHeader{}) {
|
||||
if field.Type == reflect.TypeOf(service.TomeeHeader{}) {
|
||||
// fmt.Println(reflect.ValueOf(field))
|
||||
|
||||
return gconv.SliceUint32(strings.Split(field.Tag.Get("cmd"), "|"))
|
||||
@@ -158,7 +158,7 @@ func getcmd(t reflect.Type) []uint32 {
|
||||
}
|
||||
|
||||
// 遍历结构体方法并执行RECV_cmd
|
||||
func Recv(c *socket.Conn, data handler.TomeeHeader) {
|
||||
func Recv(c *service.Conn, data service.TomeeHeader) {
|
||||
|
||||
cmdlister, ok := cool.CmdCache.Load(data.CMD)
|
||||
if !ok {
|
||||
@@ -189,8 +189,8 @@ func Recv(c *socket.Conn, data handler.TomeeHeader) {
|
||||
if nameField.IsValid() && nameField.CanSet() {
|
||||
nameField.Set(reflect.ValueOf(data))
|
||||
}
|
||||
if cmdlister.Type().In(1) == reflect.TypeOf(&socket.Player{}) {
|
||||
t := service.GetPlayer(c, data.UserID)
|
||||
if cmdlister.Type().In(1) == reflect.TypeOf(&service.Player{}) {
|
||||
t := socket.GetPlayer(c, data.UserID)
|
||||
// fmt.Println(data.CMD, "接收 变量的地址 ", &t.Info, t.Info.UserID)
|
||||
err := t.WaitForLoginWithCtx(context.Background())
|
||||
if err != nil {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/common/socket/handler"
|
||||
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/fight"
|
||||
"blazing/logic/service/fight/info"
|
||||
"blazing/modules/blazing/model"
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
func (h Controller) OnPlayerFightNpcMonster(data *info.FightNpcMonsterInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundInfo, c *service.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
ttt := info.NoteReadyToFightInfo{
|
||||
OwnerID: data.Head.UserID,
|
||||
@@ -43,42 +43,42 @@ func (h Controller) OnPlayerFightNpcMonster(data *info.FightNpcMonsterInboundInf
|
||||
if err1 != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fight.NewFight(&ttt, c) //把两个玩家都传进去
|
||||
c.FightC = &service.FightC{}
|
||||
c.FightC.NewFight(&ttt, c) //把两个玩家都传进去
|
||||
|
||||
return nil, -1
|
||||
}
|
||||
|
||||
// 准备战斗
|
||||
func (h Controller) OnReadyToFight(data *info.ReadyToFightInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) OnReadyToFight(data *fight.ReadyToFightInboundInfo, c *service.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
fight.ReadyFight(c)
|
||||
c.FightC.ReadyFight(c)
|
||||
return nil, -1
|
||||
}
|
||||
|
||||
// 接收战斗或者取消战斗的包
|
||||
func (h Controller) OnPlayerHandleFightInvite(data *info.HandleFightInviteInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInboundInfo, c *service.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
return nil, -1
|
||||
}
|
||||
|
||||
// 使用技能包
|
||||
func (h Controller) UseSkill(data *info.UseSkillInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) UseSkill(data *fight.UseSkillInboundInfo, c *service.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
// 战斗逃跑
|
||||
func (h Controller) Escape(data *info.EscapeFightInboundInfo, c *socket.Player) (result *info.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *service.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
defer func() {
|
||||
//战斗结束Escape
|
||||
ttt := handler.NewTomeeHeader(2506, c.Info.UserID)
|
||||
ttt := service.NewTomeeHeader(2506, c.Info.UserID)
|
||||
|
||||
c.SendPack(ttt.Pack(&info.FightOverInfo{
|
||||
c.SendPack(ttt.Pack(&fight.FightOverInfo{
|
||||
Reason: 0,
|
||||
}))
|
||||
c.FightID = ""
|
||||
|
||||
}()
|
||||
|
||||
return nil, 0
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/commendsvr"
|
||||
)
|
||||
|
||||
// 处理命令: 105
|
||||
func (h *Controller) GetServer(data *commendsvr.SidInfo, c *socket.Conn) (result *commendsvr.CommendSvrInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
func (h *Controller) GetServer(data *commendsvr.SidInfo, c *service.Conn) (result *commendsvr.CommendSvrInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
result = commendsvr.NewInInfo()
|
||||
result.ServerList = commendsvr.GetServerInfoList()
|
||||
return
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/item"
|
||||
)
|
||||
|
||||
func (h Controller) UserItemList(data *item.ItemListInboundInfo, c *socket.Player) (result *item.ItemListOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) UserItemList(data *item.ItemListInboundInfo, c *service.Player) (result *item.ItemListOutboundInfo, err errorcode.ErrorCode) {
|
||||
result = &item.ItemListOutboundInfo{}
|
||||
|
||||
return result, 0
|
||||
|
||||
@@ -2,9 +2,10 @@ package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/share"
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket"
|
||||
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/common/socket/handler"
|
||||
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/login"
|
||||
"blazing/logic/service/maps"
|
||||
@@ -27,12 +28,12 @@ func IsToday(t time.Time) bool {
|
||||
}
|
||||
|
||||
// 处理命令: 1001
|
||||
func (h *Controller) Login(data *login.InInfo, c *socket.Conn) (result *login.OutInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
func (h *Controller) Login(data *login.InInfo, c *service.Conn) (result *login.OutInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
|
||||
if tt := data.CheakSession(); tt { //说明sid正确
|
||||
h.RPCClient.Kick(data.Head.UserID) //先踢人
|
||||
|
||||
t := service.GetPlayer(c, data.Head.UserID)
|
||||
t := socket.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()) //保存时间戳
|
||||
@@ -59,8 +60,8 @@ func (h *Controller) Login(data *login.InInfo, c *socket.Conn) (result *login.Ou
|
||||
|
||||
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 {
|
||||
t1 := service.NewTomeeHeader(2001, t.Info.UserID)
|
||||
defer space.GetSpace(t.Info.MapID).Set(t.Info.UserID, t).Range(func(playerID uint32, player service.PlayerI) bool {
|
||||
|
||||
player.SendPack(t1.Pack(&tt))
|
||||
return true
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/maphot"
|
||||
"blazing/logic/service/maps"
|
||||
"blazing/logic/service/space"
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
func (h *Controller) MapEnter(data *maps.InInfo, c *socket.Player) (result *maps.OutInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
func (h *Controller) MapEnter(data *maps.InInfo, c *service.Player) (result *maps.OutInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
|
||||
c.Info.MapID = data.MapId //登录地图
|
||||
space.GetSpace(c.Info.MapID).Set(c.Info.UserID, c) //添加玩家
|
||||
@@ -33,7 +33,7 @@ func (h *Controller) MapEnter(data *maps.InInfo, c *socket.Player) (result *maps
|
||||
|
||||
<-time.After(5 * time.Second)
|
||||
// 首次刷新
|
||||
if c.FightID == "" && c.Info.MapID != 0 {
|
||||
if c.FightC == nil && c.Info.MapID != 0 {
|
||||
data.SpawnMonsters(c, true)
|
||||
}
|
||||
//循环刷新怪物
|
||||
@@ -48,7 +48,7 @@ func (h *Controller) MapEnter(data *maps.InInfo, c *socket.Player) (result *maps
|
||||
return
|
||||
case <-ticker.C:
|
||||
// 刷新当前地图的怪物
|
||||
if c.FightID == "" && c.Info.MapID != 0 {
|
||||
if c.FightC == nil && c.Info.MapID != 0 {
|
||||
data.SpawnMonsters(c, false)
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (h *Controller) MapEnter(data *maps.InInfo, c *socket.Player) (result *maps
|
||||
}(c.StopChan, int(c.Info.MapID))
|
||||
return nil, -1
|
||||
}
|
||||
func (h Controller) MapHot(data *maphot.InInfo, c *socket.Player) (result *maphot.OutInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) MapHot(data *maphot.InInfo, c *service.Player) (result *maphot.OutInfo, err errorcode.ErrorCode) {
|
||||
|
||||
result = &maphot.OutInfo{
|
||||
|
||||
@@ -66,7 +66,7 @@ func (h Controller) MapHot(data *maphot.InInfo, c *socket.Player) (result *mapho
|
||||
|
||||
return
|
||||
}
|
||||
func (h *Controller) MapLeave(data *maps.LeaveMapInboundInfo, c *socket.Player) (result *maps.LeaveMapOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
func (h *Controller) MapLeave(data *maps.LeaveMapInboundInfo, c *service.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}) //同步广播
|
||||
@@ -79,14 +79,14 @@ func (h *Controller) MapLeave(data *maps.LeaveMapInboundInfo, c *socket.Player)
|
||||
c.Info.MapID = 0 // 重置当前地图
|
||||
return nil, -1
|
||||
}
|
||||
func (h *Controller) MapList(data *maps.ListMapPlayerInboundInfo, c *socket.Player) (result *maps.ListMapPlayerOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
func (h *Controller) MapList(data *maps.ListMapPlayerInboundInfo, c *service.Player) (result *maps.ListMapPlayerOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
|
||||
result = &maps.ListMapPlayerOutboundInfo{}
|
||||
result.Player = make([]maps.OutInfo, 0)
|
||||
|
||||
space.GetSpace(c.Info.MapID).Range(func(userID uint32, player *socket.Player) bool {
|
||||
space.GetSpace(c.Info.MapID).Range(func(userID uint32, player service.PlayerI) bool {
|
||||
result1 := maps.NewOutInfo()
|
||||
copier.Copy(result1, player.Info)
|
||||
copier.Copy(result1, player)
|
||||
result.Player = append(result.Player, *result1)
|
||||
return true
|
||||
})
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/pet"
|
||||
"blazing/modules/blazing/service"
|
||||
|
||||
blservice "blazing/modules/blazing/service"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
@@ -13,10 +13,10 @@ import (
|
||||
// 获取精灵信息
|
||||
func (h *Controller) GetPetInfo(
|
||||
data *pet.InInfo,
|
||||
c *socket.Player) (result *pet.OutInfo,
|
||||
c *service.Player) (result *pet.OutInfo,
|
||||
err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
|
||||
t := service.NewUserService(c.Info.UserID).GetPetInfo(data.CatchTime)
|
||||
t := blservice.NewUserService(c.Info.UserID).GetPetInfo(data.CatchTime)
|
||||
return &pet.OutInfo{
|
||||
PetInfo: t,
|
||||
}, 0
|
||||
@@ -25,7 +25,7 @@ func (h *Controller) GetPetInfo(
|
||||
// 获取仓库列表
|
||||
func (h *Controller) GetPetList(
|
||||
data *pet.GetPetListInboundEmpty,
|
||||
c *socket.Player) (result *pet.GetPetListOutboundInfo,
|
||||
c *service.Player) (result *pet.GetPetListOutboundInfo,
|
||||
err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
result = &pet.GetPetListOutboundInfo{}
|
||||
|
||||
@@ -43,7 +43,7 @@ func (h *Controller) GetPetList(
|
||||
// 精灵背包仓库切换
|
||||
func (h *Controller) PetRelease(
|
||||
data *pet.PetReleaseInboundInfo,
|
||||
c *socket.Player) (
|
||||
c *service.Player) (
|
||||
result *pet.PetReleaseOutboundInfo,
|
||||
err errorcode.ErrorCode) { //这个时候player应该是空的
|
||||
//放入背包=数据库置1+添加到背包+pet release发包 仓库=数据库置0+移除背包 设置首发等于取到首发精灵后重新排序
|
||||
@@ -51,7 +51,7 @@ func (h *Controller) PetRelease(
|
||||
result = &pet.PetReleaseOutboundInfo{}
|
||||
result.Flag = uint32(data.Flag)
|
||||
|
||||
t := service.NewUserService(c.Info.UserID).PetM(int(data.CatchTime), int(data.Flag))
|
||||
t := blservice.NewUserService(c.Info.UserID).PetM(int(data.CatchTime), int(data.Flag))
|
||||
switch data.Flag {
|
||||
case 0:
|
||||
//todo 仓库
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/room"
|
||||
)
|
||||
|
||||
// 获取基地物品
|
||||
func (h Controller) OnFitmentUsering(data *room.FitmentUseringInboundInfo, c *socket.Player) (result *room.FitmentUseringOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) OnFitmentUsering(data *room.FitmentUseringInboundInfo, c *service.Player) (result *room.FitmentUseringOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
result = &room.FitmentUseringOutboundInfo{UserId: c.Info.UserID, RoomId: data.TargetUserID}
|
||||
result.Fitments = make([]room.FitmentShowInfo, 0)
|
||||
@@ -17,14 +17,14 @@ func (h Controller) OnFitmentUsering(data *room.FitmentUseringInboundInfo, c *so
|
||||
}
|
||||
|
||||
// 获取基地展示精灵
|
||||
func (h Controller) OnGetRoomPetShowInfo(data *room.PetRoomListInboundInfo, c *socket.Player) (result *room.PetRoomListOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) OnGetRoomPetShowInfo(data *room.PetRoomListInboundInfo, c *service.Player) (result *room.PetRoomListOutboundInfo, err errorcode.ErrorCode) {
|
||||
result = &room.PetRoomListOutboundInfo{}
|
||||
result.Pets = make([]room.PetShowInfo, 0)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取自己房间的家具
|
||||
func (h Controller) OnGetFitmentAll(data *room.FitmentAllInboundEmpty, c *socket.Player) (result *room.FitmentAllOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) OnGetFitmentAll(data *room.FitmentAllInboundEmpty, c *service.Player) (result *room.FitmentAllOutboundInfo, err errorcode.ErrorCode) {
|
||||
result = &room.FitmentAllOutboundInfo{}
|
||||
result.Fitments = make([]room.FitmentItemInfo, 0)
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/systemtime"
|
||||
)
|
||||
|
||||
func (h Controller) SystemTimeInfo(data *systemtime.InInfo, c *socket.Player) (result *systemtime.OutInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) SystemTimeInfo(data *systemtime.InInfo, c *service.Player) (result *systemtime.OutInfo, err errorcode.ErrorCode) {
|
||||
|
||||
return systemtime.NewOutInfo(), 0
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/task"
|
||||
"blazing/modules/blazing/model"
|
||||
"blazing/modules/blazing/service"
|
||||
blservice "blazing/modules/blazing/service"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
/**
|
||||
* 接受任务
|
||||
*/
|
||||
func (h Controller) AcceptTask(data *task.AcceptTaskInboundInfo, c *socket.Player) (result *task.AcceptTaskOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) AcceptTask(data *task.AcceptTaskInboundInfo, c *service.Player) (result *task.AcceptTaskOutboundInfo, err errorcode.ErrorCode) {
|
||||
//isdaliy := false
|
||||
// if data.Head.CMD != 2201 { //判断是每日任务
|
||||
// //isdaliy = true
|
||||
@@ -31,20 +31,20 @@ 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) {
|
||||
func (h Controller) AddTaskBuf(data *task.AddTaskBufInboundInfo, c *service.Player) (result *task.AddTaskBufOutboundInfo, err errorcode.ErrorCode) {
|
||||
// isdaliy := false
|
||||
// if data.Head.CMD != 2204 { //判断是每日任务
|
||||
// isdaliy = true
|
||||
// }
|
||||
result = &task.AddTaskBufOutboundInfo{}
|
||||
|
||||
_, ok := service.NewUserService(c.Info.UserID).TaskInfo(data.TaskId)
|
||||
_, ok := blservice.NewUserService(c.Info.UserID).TaskInfo(data.TaskId)
|
||||
if ok {
|
||||
service.NewUserService(c.Info.UserID).TaskSet(data.TaskId, model.TaskInfo{
|
||||
blservice.NewUserService(c.Info.UserID).TaskSet(data.TaskId, model.TaskInfo{
|
||||
Info: data.TaskList,
|
||||
})
|
||||
} else {
|
||||
service.NewUserService(c.Info.UserID).TaskADD(data.TaskId, model.TaskInfo{
|
||||
blservice.NewUserService(c.Info.UserID).TaskADD(data.TaskId, model.TaskInfo{
|
||||
|
||||
Info: data.TaskList,
|
||||
})
|
||||
@@ -65,7 +65,7 @@ func randInt0To24() int {
|
||||
/**
|
||||
* 完成任务
|
||||
*/
|
||||
func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *socket.Player) (result *task.CompleteTaskOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *service.Player) (result *task.CompleteTaskOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
if c.Info.TaskList[data.TaskId] != 1 { //如果任务没有接受或者已经完成Complete_Task
|
||||
|
||||
@@ -94,7 +94,7 @@ func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *socket.
|
||||
r := model.GenPetInfo(1, 1, 1, 1006, 1, 5)
|
||||
result.CaptureTime = r.CatchTime
|
||||
result.PetTypeId = r.ID
|
||||
service.NewUserService(c.Info.UserID).PetAdd(*r)
|
||||
blservice.NewUserService(c.Info.UserID).PetAdd(*r)
|
||||
}
|
||||
if data.TaskId == 87 { //新手注册任务
|
||||
|
||||
@@ -113,8 +113,8 @@ 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) {
|
||||
info, _ := service.NewUserService(c.Info.UserID).TaskInfo(data.TaskId)
|
||||
func (h Controller) Get_Task_Buf(data *task.GetTaskBufInboundInfo, c *service.Player) (result *task.GetTaskBufOutboundInfo, err errorcode.ErrorCode) {
|
||||
info, _ := blservice.NewUserService(c.Info.UserID).TaskInfo(data.TaskId)
|
||||
result = &task.GetTaskBufOutboundInfo{}
|
||||
result.TaskId = data.TaskId
|
||||
result.TaskList = info.Info
|
||||
@@ -125,7 +125,7 @@ func (h Controller) Get_Task_Buf(data *task.GetTaskBufInboundInfo, c *socket.Pla
|
||||
/**
|
||||
* 删除任务
|
||||
*/
|
||||
func (h Controller) Delete_Task(data *task.DeleteTaskInboundInfo, c *socket.Player) (result *task.DeleteTaskOutboundInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) Delete_Task(data *task.DeleteTaskInboundInfo, c *service.Player) (result *task.DeleteTaskOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
// if data.Head.CMD == 2205 { //判断不是每日任务
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/space"
|
||||
"context"
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
func (h Controller) Walk(data *space.InInfo, c *socket.Player) (result *space.OutInfo, err errorcode.ErrorCode) {
|
||||
func (h Controller) Walk(data *space.InInfo, c *service.Player) (result *space.OutInfo, err errorcode.ErrorCode) {
|
||||
result = &space.OutInfo{}
|
||||
err1 := copier.Copy(result, data)
|
||||
result.UserID = data.Head.UserID
|
||||
|
||||
@@ -3,10 +3,11 @@ package main
|
||||
import (
|
||||
"blazing/common/rpc"
|
||||
"blazing/common/socket"
|
||||
"blazing/common/socket/handler"
|
||||
|
||||
"blazing/cool"
|
||||
"blazing/logic/controller"
|
||||
"blazing/modules/blazing/service"
|
||||
"blazing/logic/service"
|
||||
blservice "blazing/modules/blazing/service"
|
||||
|
||||
"fmt"
|
||||
"log"
|
||||
@@ -62,7 +63,7 @@ func isPortAvailable(port int) bool {
|
||||
// 如果id是0,那就是login server
|
||||
func Start(serverid uint16) {
|
||||
//ants.NewPool(100)
|
||||
head := handler.NewTomeeHandler()
|
||||
head := service.NewTomeeHandler()
|
||||
head.Callback = controller.Recv
|
||||
if serverid != 0 { //logic服务器
|
||||
// 确定端口
|
||||
@@ -77,7 +78,7 @@ func Start(serverid uint16) {
|
||||
controller.Maincontroller.RPCClient = *t //将RPC赋值Start
|
||||
controller.Maincontroller.Port = uint16(port) //赋值服务器ID
|
||||
|
||||
service.NewLoginServiceService().SetServerID(serverid, gconv.Uint16(port), t)
|
||||
blservice.NewLoginServiceService().SetServerID(serverid, gconv.Uint16(port), t)
|
||||
socket.
|
||||
NewServer(
|
||||
socket.WithCORS(),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package handler
|
||||
package service
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/utils/bytearray"
|
||||
|
||||
"bytes"
|
||||
@@ -37,7 +36,7 @@ func NewTomeeHeader(cmd uint32, userid uint32) *TomeeHeader {
|
||||
}
|
||||
|
||||
type TomeeHandler struct {
|
||||
Callback func(conn *socket.Conn, data TomeeHeader)
|
||||
Callback func(conn *Conn, data TomeeHeader)
|
||||
}
|
||||
|
||||
func NewTomeeHandler() *TomeeHandler {
|
||||
@@ -60,7 +59,7 @@ func (h *TomeeHandler) Handle(c gnet.Conn, data []byte) { //处理接收到的
|
||||
header.Result, _ = tempdata.ReadUInt32()
|
||||
header.Data = tempdata.BytesAvailable()
|
||||
//fmt.Println("接收封包", header)
|
||||
h.Callback(socket.NewConn(c), header)
|
||||
h.Callback(NewConn(c), header)
|
||||
//return header
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package commendsvr
|
||||
|
||||
import (
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/cool"
|
||||
"blazing/modules/base/service"
|
||||
"blazing/logic/service"
|
||||
baseservice "blazing/modules/base/service"
|
||||
"blazing/modules/blazing/model"
|
||||
|
||||
"github.com/butoften/array"
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
//var _ entity.Blazingservice = (*SidInfo)(nil)
|
||||
|
||||
type SidInfo struct { //这里直接使用组合来实现将传入的原始头部数据和结构体参数序列化
|
||||
Head handler.TomeeHeader `cmd:"105" struc:"[0]pad"` //玩家登录
|
||||
Head service.TomeeHeader `cmd:"105" struc:"[0]pad"` //玩家登录
|
||||
|
||||
Sid []byte `struc:"[20]byte"` // 登录会话ID,固定长度16字节
|
||||
ret []byte `struc:"[0]pad"`
|
||||
@@ -22,7 +22,7 @@ type SidInfo struct { //这里直接使用组合来实现将传入的原始头
|
||||
|
||||
// CommendSvrInfo 初始连接请求信息结构体
|
||||
type CommendSvrInfo struct {
|
||||
//Handler handler.TomeeHeader //` struc:"[0]pad"` //消息头 ,这里为传入的头部数据,遍历此头部实现解析CommendSvrInfo
|
||||
//Handler service.TomeeHeader //` struc:"[0]pad"` //消息头 ,这里为传入的头部数据,遍历此头部实现解析CommendSvrInfo
|
||||
MaxOnlineID uint32 `struc:"sizeof=ServerList"` // 最大连接数
|
||||
IsVip uint32 // 建议为0
|
||||
ServerInfoLen uint32 `struc:"sizeof=ServerList"` // 服务器信息长度 ServerInfo
|
||||
@@ -38,7 +38,7 @@ type CommendSvrInfo struct {
|
||||
// IsVip 和 ServerInfoLen 字段被初始化为 0
|
||||
func NewInInfo() *CommendSvrInfo {
|
||||
return &CommendSvrInfo{
|
||||
// Handler: handler.TomeeHeader{},
|
||||
// Handler: service.TomeeHeader{},
|
||||
// MaxOnlineID: 100,
|
||||
IsVip: 0,
|
||||
ServerInfoLen: 0,
|
||||
@@ -84,7 +84,7 @@ func GetServerInfoList() []ServerInfo {
|
||||
t.Structs(&ret)
|
||||
//fmt.Println(t)
|
||||
var ret1 []ServerInfo
|
||||
ip := service.NewBaseSysConfService().GetValue("server_ip")
|
||||
ip := baseservice.NewBaseSysConfService().GetValue("server_ip")
|
||||
|
||||
for _, v := range ret {
|
||||
tt := newServerInfo()
|
||||
|
||||
143
logic/service/fight.go
Normal file
143
logic/service/fight.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"blazing/logic/service/fight/info"
|
||||
"blazing/modules/blazing/model"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
type PlayerI interface {
|
||||
ID() uint32
|
||||
MapID() uint32
|
||||
GetInfo() model.PlayerInfo
|
||||
SendPack(b []byte) error
|
||||
SendReadyToFightInfo(info.FightStartOutboundInfo)
|
||||
SendNoteReadyToFightInfo(info.NoteReadyToFightInfo)
|
||||
}
|
||||
type FightC struct {
|
||||
Info info.NoteReadyToFightInfo
|
||||
Our PlayerI
|
||||
Opp PlayerI
|
||||
}
|
||||
|
||||
// var FightCache = make(map[string]*info.NoteReadyToFightInfo) //默认our是房主
|
||||
|
||||
func (f *FightC) ReadyFight(c PlayerI) {
|
||||
// tt, _ := FightCache[c.FightID]
|
||||
|
||||
rett := info.FightStartOutboundInfo{}
|
||||
copier.Copy(&rett.Info1, &f.Info.OurPetList[0]) //复制自己的信息
|
||||
switch f.Info.FightId { //判断战斗类型
|
||||
case 1:
|
||||
//1v1
|
||||
|
||||
if c == f.Our { //这个时候是房主发来的消息
|
||||
f.Info.AFinished = true
|
||||
if f.Info.BFinished {
|
||||
|
||||
copier.Copy(&rett.Info2, &f.Info.OpponentPetList[0]) //复制对方信息
|
||||
// f.Our.SendPack(t1.Pack(&rett)) //给自己发
|
||||
// f.Opp.SendPack(t1.Pack(&rett)) //给对方发
|
||||
}
|
||||
|
||||
} else {
|
||||
f.Our = c
|
||||
f.Info.BFinished = true
|
||||
if f.Info.AFinished { //如果房主完成
|
||||
|
||||
copier.Copy(&rett.Info2, &f.Info.OurPetList[0]) //复制房主信息,因为这时候不是房主发来的消息
|
||||
// f.Our.SendPack(t1.Pack(&rett)) //给自己发
|
||||
// f.Our.SendPack(t1.Pack(&rett)) //给房主发
|
||||
}
|
||||
}
|
||||
|
||||
case 3: //野怪战斗
|
||||
|
||||
copier.Copy(&rett.Info2, &f.Info.OpponentPetList[0])
|
||||
rett.Info1.UserID = f.Info.OurInfo.UserID
|
||||
// f.Our.SendPack(t1.Pack(&rett))
|
||||
}
|
||||
|
||||
f.Our.SendReadyToFightInfo(rett)
|
||||
f.Opp.SendReadyToFightInfo(rett)
|
||||
}
|
||||
func (f *FightC) NewFight(i *info.NoteReadyToFightInfo, plays PlayerI) {
|
||||
f.Our = plays
|
||||
|
||||
// t12, _ := uuid.NewV7()
|
||||
// uuid := strings.Replace(t12.String(), "-", "", -1) //绑定战斗ID
|
||||
// /FightCache[uuid] = i
|
||||
//先发送战斗准备包
|
||||
f.Info.FightId = i.FightId
|
||||
switch i.FightId {
|
||||
case 1:
|
||||
//1v1
|
||||
|
||||
case 3: //野怪战斗
|
||||
plays.SendNoteReadyToFightInfo(*i)
|
||||
// t1 := handler.NewTomeeHeader(2503, f.Info.OurInfo.UserID)
|
||||
|
||||
// plays.SendPack(t1.Pack(i)) //准备包由各自发,因为协议不一样
|
||||
|
||||
}
|
||||
|
||||
//调用技能产生effect参数后,创建effect实例,而非技能创建
|
||||
c := info.NewBattleContainer1v1(*i) //创建战斗容器
|
||||
t := info.BattleSkillEntity{} //
|
||||
t.SideEffectArgs = []int{1, 2, 3}
|
||||
//先提交effecet后然后计算伤害
|
||||
|
||||
//物理和特殊,百分比和固定伤害也算,真实伤害不分类别,故直接扣血就行,不需要计算
|
||||
if t.Category() == info.Category.PHYSICAL || t.Category() == info.Category.SPECIAL {
|
||||
|
||||
for _, v := range c.Effects {
|
||||
v.Exec(func(e info.Effect) bool {
|
||||
return e.PreDamage() //执行预处理效果
|
||||
})
|
||||
}
|
||||
|
||||
// Apply pre-damage effects for pet sources
|
||||
// battle.applyEffects(context, EffectTrigger.PreDamage)
|
||||
// if (context.crit) {
|
||||
// battle.applyEffects(context, EffectTrigger.OnCritPreDamage) // Trigger crit pre-damage effects
|
||||
// }
|
||||
//假如说这里需要能力提升
|
||||
// c.Exec(func(e Effect) func() {
|
||||
// return e.OnBeforeAddMark()
|
||||
// })
|
||||
//添加印记前的效果如果有任何一个false,说明组织了添加效果
|
||||
//这里能力提升
|
||||
// c.Exec(func(e Effect) bool {
|
||||
// return e.OnAnyMarkAdded()
|
||||
// })
|
||||
|
||||
// var candidates []*Effect
|
||||
// for _, eff := range c.Effects {
|
||||
// if eff.Trigger == trigger {
|
||||
// candidates = append(candidates, eff)
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 按优先级排序
|
||||
// sort.SliceStable(candidates, func(i, j int) bool {
|
||||
// return candidates[i].Priority > candidates[j].Priority
|
||||
// })
|
||||
|
||||
// // 执行
|
||||
// for _, eff := range candidates {
|
||||
// ctx.Effect = eff
|
||||
// keep := eff.Apply(ctx)
|
||||
|
||||
// if !keep {
|
||||
// // 持续回合结束 / 返回 false 的 effect 删除
|
||||
// c.removeEffect(eff)
|
||||
// }
|
||||
|
||||
// if ctx.Done {
|
||||
// break // 被拦截
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
package fight
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/logic/service/fight/info"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jinzhu/copier"
|
||||
)
|
||||
|
||||
var FightCache = make(map[string]*info.NoteReadyToFightInfo) //默认our是房主
|
||||
|
||||
func ReadyFight(c *socket.Player) {
|
||||
tt, _ := FightCache[c.FightID]
|
||||
t1 := handler.NewTomeeHeader(2504, c.Info.UserID)
|
||||
rett := info.FightStartOutboundInfo{
|
||||
IsCanAuto: 0,
|
||||
}
|
||||
copier.Copy(&rett.Info1, &c.Info.PetList[0]) //复制自己的信息
|
||||
switch tt.FightId { //判断战斗类型
|
||||
case 1:
|
||||
//1v1
|
||||
|
||||
if c.Info.UserID == tt.OwnerID { //这个时候是房主发来的消息
|
||||
tt.AFinished = true
|
||||
if tt.BFinished {
|
||||
|
||||
copier.Copy(&rett.Info2, &tt.OpponentPetList[0]) //复制对方信息
|
||||
c.SendPack(t1.Pack(&rett)) //给自己发
|
||||
tt.Opp.SendPack(t1.Pack(&rett)) //给对方发
|
||||
}
|
||||
|
||||
} else {
|
||||
tt.BFinished = true
|
||||
if tt.AFinished { //如果房主完成
|
||||
|
||||
copier.Copy(&rett.Info2, &tt.OurPetList[0]) //复制房主信息,因为这时候不是房主发来的消息
|
||||
c.SendPack(t1.Pack(&rett)) //给自己发
|
||||
tt.Our.SendPack(t1.Pack(&rett)) //给房主发
|
||||
}
|
||||
}
|
||||
|
||||
case 3: //野怪战斗
|
||||
|
||||
copier.Copy(&rett.Info2, &tt.OpponentPetList[0])
|
||||
rett.Info1.UserID = c.Info.UserID //用户ID复制进去
|
||||
c.SendPack(t1.Pack(&rett))
|
||||
}
|
||||
|
||||
}
|
||||
func NewFight(i *info.NoteReadyToFightInfo, plays *socket.Player) {
|
||||
|
||||
t12, _ := uuid.NewV7()
|
||||
uuid := strings.Replace(t12.String(), "-", "", -1) //绑定战斗ID
|
||||
FightCache[uuid] = i
|
||||
//先发送战斗准备包
|
||||
switch i.FightId {
|
||||
case 1:
|
||||
//1v1
|
||||
|
||||
case 3: //野怪战斗
|
||||
|
||||
t1 := handler.NewTomeeHeader(2503, plays.Info.UserID)
|
||||
|
||||
plays.FightID = uuid //绑定战斗ID
|
||||
plays.SendPack(t1.Pack(i)) //准备包由各自发,因为协议不一样
|
||||
|
||||
}
|
||||
|
||||
//调用技能产生effect参数后,创建effect实例,而非技能创建
|
||||
c := info.NewBattleContainer1v1(*i) //创建战斗容器
|
||||
t := info.BattleSkillEntity{} //
|
||||
t.SideEffectArgs = []int{1, 2, 3}
|
||||
//先提交effecet后然后计算伤害
|
||||
|
||||
//物理和特殊,百分比和固定伤害也算,真实伤害不分类别,故直接扣血就行,不需要计算
|
||||
if t.Category() == info.Category.PHYSICAL || t.Category() == info.Category.SPECIAL {
|
||||
|
||||
for _, v := range c.Effects {
|
||||
v.Exec(func(e info.Effect) bool {
|
||||
return e.PreDamage() //执行预处理效果
|
||||
})
|
||||
}
|
||||
|
||||
// Apply pre-damage effects for pet sources
|
||||
// battle.applyEffects(context, EffectTrigger.PreDamage)
|
||||
// if (context.crit) {
|
||||
// battle.applyEffects(context, EffectTrigger.OnCritPreDamage) // Trigger crit pre-damage effects
|
||||
// }
|
||||
//假如说这里需要能力提升
|
||||
// c.Exec(func(e Effect) func() {
|
||||
// return e.OnBeforeAddMark()
|
||||
// })
|
||||
//添加印记前的效果如果有任何一个false,说明组织了添加效果
|
||||
//这里能力提升
|
||||
// c.Exec(func(e Effect) bool {
|
||||
// return e.OnAnyMarkAdded()
|
||||
// })
|
||||
|
||||
// var candidates []*Effect
|
||||
// for _, eff := range c.Effects {
|
||||
// if eff.Trigger == trigger {
|
||||
// candidates = append(candidates, eff)
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 按优先级排序
|
||||
// sort.SliceStable(candidates, func(i, j int) bool {
|
||||
// return candidates[i].Priority > candidates[j].Priority
|
||||
// })
|
||||
|
||||
// // 执行
|
||||
// for _, eff := range candidates {
|
||||
// ctx.Effect = eff
|
||||
// keep := eff.Apply(ctx)
|
||||
|
||||
// if !keep {
|
||||
// // 持续回合结束 / 返回 false 的 effect 删除
|
||||
// c.removeEffect(eff)
|
||||
// }
|
||||
|
||||
// if ctx.Done {
|
||||
// break // 被拦截
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
60
logic/service/fight/info.go
Normal file
60
logic/service/fight/info.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package fight
|
||||
|
||||
import (
|
||||
"blazing/logic/service"
|
||||
)
|
||||
|
||||
// 野怪对战包
|
||||
type FightNpcMonsterInboundInfo struct {
|
||||
Head service.TomeeHeader `cmd:"2408" struc:"[0]pad"`
|
||||
// Number 地图刷新怪物结构体对应的序号(1-9的位置序号)
|
||||
// @UInt long类型,使用uint32保持无符号特性
|
||||
Number uint32 `fieldDesc:"地图刷新怪物结构体对应的序号 1 - 9 的位置序号" `
|
||||
}
|
||||
|
||||
type NullOutboundInfo struct {
|
||||
}
|
||||
|
||||
// 准备战斗包
|
||||
type ReadyToFightInboundInfo struct {
|
||||
Head service.TomeeHeader `cmd:"2404" struc:"[0]pad"`
|
||||
}
|
||||
|
||||
// 战斗逃跑
|
||||
type EscapeFightInboundInfo struct {
|
||||
Head service.TomeeHeader `cmd:"2410" struc:"[0]pad"`
|
||||
}
|
||||
|
||||
// FightOverInfo 战斗结束信息结构体 2506
|
||||
type FightOverInfo struct {
|
||||
Reason uint32 // 固定值0
|
||||
WinnerId uint32 // 胜者的米米号 野怪为0
|
||||
TwoTimes uint32 // 双倍经验剩余次数
|
||||
ThreeTimes uint32 // 三倍经验剩余次数
|
||||
AutoFightTimes uint32 // 自动战斗剩余次数
|
||||
EnergyTimes uint32 // 能量吸收器剩余次数
|
||||
LearnTimes uint32 // 双倍学习器剩余次数
|
||||
}
|
||||
|
||||
// HandleFightInviteInboundInfo 处理战斗邀请的入站消息
|
||||
// 回空包就行
|
||||
type HandleFightInviteInboundInfo struct {
|
||||
Head service.TomeeHeader `cmd:"2403" struc:"[0]pad"`
|
||||
UserID uint32 `json:"userId" codec:"userId,uint"` // 邀请我对战人的userid
|
||||
Flag uint32 `json:"flag" codec:"flag,uint"` // 1为同意对战 0为取消对战
|
||||
Mode uint32 `json:"mode" codec:"mode,uint"` // 战斗类型 1 = 1v1 2 = 6v6
|
||||
}
|
||||
|
||||
// 2502的回复包 PVP邀请消息
|
||||
type NoteHandleFightInviteOutboundInfo struct {
|
||||
UserID uint32
|
||||
Nickname string `struc:"[16]byte"` // 固定长度16字节
|
||||
Result uint32 // 0=拒绝 1=同意 2=在线超6小时 3=无出战精灵 4=不在线
|
||||
}
|
||||
|
||||
// 实现入站消息接口(Go中通过方法集隐式实现)
|
||||
type UseSkillInboundInfo struct {
|
||||
Head service.TomeeHeader `cmd:"2405" struc:"[0]pad"`
|
||||
// 技能id,
|
||||
SkillId uint32
|
||||
}
|
||||
@@ -1,39 +1,10 @@
|
||||
package info
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/modules/blazing/model"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 野怪对战包
|
||||
type FightNpcMonsterInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2408" struc:"[0]pad"`
|
||||
// Number 地图刷新怪物结构体对应的序号(1-9的位置序号)
|
||||
// @UInt long类型,使用uint32保持无符号特性
|
||||
Number uint32 `fieldDesc:"地图刷新怪物结构体对应的序号 1 - 9 的位置序号" `
|
||||
}
|
||||
|
||||
type NullOutboundInfo struct {
|
||||
}
|
||||
|
||||
// 准备战斗包
|
||||
type ReadyToFightInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2404" struc:"[0]pad"`
|
||||
}
|
||||
|
||||
type FightStartOutboundInfo struct {
|
||||
// @UInt long类型
|
||||
IsCanAuto uint32 `fieldDesc:"是否自动 默认给0 怀疑是自动战斗器使用的" `
|
||||
|
||||
// 当前战斗精灵信息1(前端通过userid判断是否为我方)
|
||||
Info1 FightPetInfo `fieldDesc:"当前战斗精灵的信息 可能不准.看前端代码是以userid来判断哪个结构体是我方的" serialize:"struct"`
|
||||
|
||||
// 当前战斗精灵信息2(前端通过userid判断是否为我方)
|
||||
Info2 FightPetInfo `fieldDesc:"当前战斗精灵的信息 可能不准.看前端代码是以userid来判断哪个结构体是我方的" serialize:"struct"`
|
||||
}
|
||||
|
||||
// FightPetInfo 战斗精灵信息结构体,FightPetInfo类
|
||||
type FightPetInfo struct {
|
||||
// 用户ID(野怪为0),@UInt long
|
||||
@@ -87,43 +58,15 @@ type NoteUseSkillOutboundInfo struct {
|
||||
SecondAttackInfo AttackValue // 本轮后手的精灵在释放技能结束后的状态
|
||||
}
|
||||
|
||||
// 战斗逃跑
|
||||
type EscapeFightInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2410" struc:"[0]pad"`
|
||||
}
|
||||
type FightStartOutboundInfo struct {
|
||||
// @UInt long类型
|
||||
IsCanAuto uint32 `fieldDesc:"是否自动 默认给0 怀疑是自动战斗器使用的" `
|
||||
|
||||
// FightOverInfo 战斗结束信息结构体 2506
|
||||
type FightOverInfo struct {
|
||||
Reason uint32 // 固定值0
|
||||
WinnerId uint32 // 胜者的米米号 野怪为0
|
||||
TwoTimes uint32 // 双倍经验剩余次数
|
||||
ThreeTimes uint32 // 三倍经验剩余次数
|
||||
AutoFightTimes uint32 // 自动战斗剩余次数
|
||||
EnergyTimes uint32 // 能量吸收器剩余次数
|
||||
LearnTimes uint32 // 双倍学习器剩余次数
|
||||
}
|
||||
// 当前战斗精灵信息1(前端通过userid判断是否为我方)
|
||||
Info1 FightPetInfo `fieldDesc:"当前战斗精灵的信息 可能不准.看前端代码是以userid来判断哪个结构体是我方的" serialize:"struct"`
|
||||
|
||||
// HandleFightInviteInboundInfo 处理战斗邀请的入站消息
|
||||
// 回空包就行
|
||||
type HandleFightInviteInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2403" struc:"[0]pad"`
|
||||
UserID uint32 `json:"userId" codec:"userId,uint"` // 邀请我对战人的userid
|
||||
Flag uint32 `json:"flag" codec:"flag,uint"` // 1为同意对战 0为取消对战
|
||||
Mode uint32 `json:"mode" codec:"mode,uint"` // 战斗类型 1 = 1v1 2 = 6v6
|
||||
}
|
||||
|
||||
// 2502的回复包 PVP邀请消息
|
||||
type NoteHandleFightInviteOutboundInfo struct {
|
||||
UserID uint32
|
||||
Nickname string `struc:"[16]byte"` // 固定长度16字节
|
||||
Result uint32 // 0=拒绝 1=同意 2=在线超6小时 3=无出战精灵 4=不在线
|
||||
}
|
||||
|
||||
// 实现入站消息接口(Go中通过方法集隐式实现)
|
||||
type UseSkillInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2405" struc:"[0]pad"`
|
||||
// 技能id,
|
||||
SkillId uint32
|
||||
// 当前战斗精灵信息2(前端通过userid判断是否为我方)
|
||||
Info2 FightPetInfo `fieldDesc:"当前战斗精灵的信息 可能不准.看前端代码是以userid来判断哪个结构体是我方的" serialize:"struct"`
|
||||
}
|
||||
|
||||
type FightUserInfo struct {
|
||||
@@ -148,17 +91,17 @@ type NoteReadyToFightInfo struct {
|
||||
FightId EnumBattleMode `fieldDesc:"战斗类型ID 但前端好像没有用到 与野怪战斗为3,与人战斗似乎是1" `
|
||||
|
||||
// 我方信息
|
||||
OurInfo FightUserInfo `fieldDesc:"我方信息" serialize:"struct"`
|
||||
Our *socket.Player `struc:"skip"`
|
||||
OurPetListLen uint32 `struc:"sizeof=OurPetList"`
|
||||
OurInfo FightUserInfo `fieldDesc:"我方信息" serialize:"struct"`
|
||||
// Our *socket.Player `struc:"skip"`
|
||||
OurPetListLen uint32 `struc:"sizeof=OurPetList"`
|
||||
// 我方携带精灵的信息
|
||||
// ArrayList<ReadyFightPetInfo>,使用切片模拟动态列表
|
||||
OurPetList []ReadyFightPetInfo `fieldDesc:"我方携带精灵的信息" serialize:"lengthFirst,lengthType=uint16,type=structArray"`
|
||||
|
||||
// 对方信息
|
||||
OpponentInfo FightUserInfo `fieldDesc:"对方信息" serialize:"struct"`
|
||||
Opp *socket.Player `struc:"skip"`
|
||||
OpponentPetListLen uint32 `struc:"sizeof=OpponentPetList"`
|
||||
OpponentInfo FightUserInfo `fieldDesc:"对方信息" serialize:"struct"`
|
||||
//Opp *socket.Player `struc:"skip"`
|
||||
OpponentPetListLen uint32 `struc:"sizeof=OpponentPetList"`
|
||||
// 敌方的精灵信息
|
||||
// 野怪战斗时:客户端接收此包前已生成精灵PetInfo,将部分信息写入该列表
|
||||
OpponentPetList []ReadyFightPetInfo `fieldDesc:"敌方的精灵信息 如果是野怪 那么再给客户端发送这个包体时就提前生成好了这只精灵的PetInfo,然后把从PetInfo中把部分信息写入到这个敌方的精灵信息中再发送这个包结构体" serialize:"lengthFirst,lengthType=uint16,type=structArray"`
|
||||
@@ -1,10 +1,10 @@
|
||||
package friend
|
||||
|
||||
import "blazing/common/socket/handler"
|
||||
import "blazing/logic/service"
|
||||
|
||||
//基地查看好友列表
|
||||
type SeeOnlineInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2157" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"2157" struc:"[0]pad"`
|
||||
|
||||
UserIdsLen uint32 `json:"userIdsLen" struc:"sizeof=UserIds"`
|
||||
UserIds []uint32 `json:"userIds" `
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package item
|
||||
|
||||
import "blazing/common/socket/handler"
|
||||
import "blazing/logic/service"
|
||||
|
||||
// 实现了入站消息接口(Go中通过方法集隐式实现)
|
||||
type ItemListInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2605" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"2605" struc:"[0]pad"`
|
||||
// 查询物品id的开始,对应Java的@UInt long
|
||||
Param1 uint32 `fieldDesc:"查询物品id的开始" messageType:"Item_List"`
|
||||
// 查询物品id的结尾,对应Java的@UInt long
|
||||
|
||||
@@ -2,7 +2,8 @@ package login
|
||||
|
||||
import (
|
||||
"blazing/common/data/share"
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/logic/service"
|
||||
|
||||
"blazing/modules/blazing/model"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
@@ -12,7 +13,7 @@ import (
|
||||
|
||||
// LoginSidInfo 登录携带的凭证结构体
|
||||
type InInfo struct { //这里直接使用组合来实现将传入的原始头部数据和结构体参数序列化
|
||||
Head handler.TomeeHeader `cmd:"1001" struc:"[0]pad"` //玩家登录
|
||||
Head service.TomeeHeader `cmd:"1001" struc:"[0]pad"` //玩家登录
|
||||
|
||||
Sid []byte `struc:"[16]byte"` // 登录会话ID,固定长度16字节
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package login
|
||||
|
||||
import "blazing/common/socket/handler"
|
||||
import "blazing/logic/service"
|
||||
|
||||
type CreatePlayerInboundInfo struct { //这里直接使用组合来实现将传入的原始头部数据和结构体参数序列化
|
||||
Head handler.TomeeHeader `cmd:"108" struc:"[0]pad"` //玩家登录
|
||||
Head service.TomeeHeader `cmd:"108" struc:"[0]pad"` //玩家登录
|
||||
|
||||
// 玩家昵称,@ArraySerialize注解
|
||||
Nickname string `struc:"[16]byte"` // 固定长度16字节
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package maphot
|
||||
|
||||
import (
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/space"
|
||||
)
|
||||
|
||||
type InInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"1004" struc:"[0]pad"` //玩家登录
|
||||
Head service.TomeeHeader `cmd:"1004" struc:"[0]pad"` //玩家登录
|
||||
}
|
||||
|
||||
// OutInfo 表示地图热度的出站消息
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package maps
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/data/xmlres"
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/space"
|
||||
|
||||
"blazing/modules/blazing/model"
|
||||
"math/rand"
|
||||
"strings"
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
type InInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2001" struc:"[0]pad"` //切换地图
|
||||
Head service.TomeeHeader `cmd:"2001" struc:"[0]pad"` //切换地图
|
||||
// 地图类型
|
||||
MapType uint32
|
||||
|
||||
@@ -29,7 +29,7 @@ type InInfo struct {
|
||||
|
||||
func (t *InInfo) Broadcast(mapid uint32, o OutInfo) {
|
||||
|
||||
space.GetSpace(mapid).Range(func(playerID uint32, player *socket.Player) bool {
|
||||
space.GetSpace(mapid).Range(func(playerID uint32, player service.PlayerI) bool {
|
||||
t.Head.Result = 0
|
||||
|
||||
player.SendPack(t.Head.Pack(&o))
|
||||
@@ -38,7 +38,7 @@ func (t *InInfo) Broadcast(mapid uint32, o OutInfo) {
|
||||
}
|
||||
|
||||
// 刷怪具体实现
|
||||
func (t *InInfo) SpawnMonsters(c *socket.Player, isfrist bool) {
|
||||
func (t *InInfo) SpawnMonsters(c *service.Player, isfrist bool) {
|
||||
// 获取当前地图的怪物配置
|
||||
|
||||
if c == nil || c.Info.MapID == 0 { //用户离线
|
||||
@@ -55,7 +55,7 @@ func (t *InInfo) SpawnMonsters(c *socket.Player, isfrist bool) {
|
||||
}
|
||||
|
||||
// 创建数据包
|
||||
tt := handler.NewTomeeHeader(2004, c.Info.UserID)
|
||||
tt := service.NewTomeeHeader(2004, c.Info.UserID)
|
||||
|
||||
if isfrist {
|
||||
t.monsters = generateThreeUniqueNumbers()
|
||||
@@ -81,16 +81,16 @@ func RandomStringFromSlice(s []string) string {
|
||||
}
|
||||
|
||||
// 应该根据怪物信息决定后端生成
|
||||
func (t *InInfo) genMonster(mapid uint32) *socket.OgreInfo {
|
||||
func (t *InInfo) genMonster(mapid uint32) *service.OgreInfo {
|
||||
// 设置怪物信息
|
||||
t1 := socket.OgreInfo{}
|
||||
t1 := service.OgreInfo{}
|
||||
mapss, ok := xmlres.MonsterMap[gconv.Int(mapid)]
|
||||
|
||||
if ok && mapss.Monsters != nil {
|
||||
for i, m := range mapss.Monsters.Monsters { //这里是9个
|
||||
id := strings.Split(m.ID, " ")
|
||||
lv := strings.Split(m.Lv, " ")
|
||||
ttt := socket.OgrePetInfo{
|
||||
ttt := service.OgrePetInfo{
|
||||
Id: gconv.Uint32(RandomStringFromSlice(id)),
|
||||
}
|
||||
if ttt.Id != 0 {
|
||||
@@ -103,7 +103,7 @@ func (t *InInfo) genMonster(mapid uint32) *socket.OgreInfo {
|
||||
|
||||
}
|
||||
|
||||
t2 := socket.OgreInfo{}
|
||||
t2 := service.OgreInfo{}
|
||||
for i := 0; i < 3; i++ {
|
||||
|
||||
t2.Data[t.monsters[i]] = t1.Data[t.monsters[i]]
|
||||
@@ -291,14 +291,3 @@ func NewOutInfo() *OutInfo {
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func LeaveMap(c *socket.Player) {
|
||||
t := handler.NewTomeeHeader(2002, c.Info.UserID)
|
||||
|
||||
space.GetSpace(c.Info.MapID).Range(func(playerID uint32, player *socket.Player) bool {
|
||||
|
||||
player.SendPack(t.Pack(&LeaveMapOutboundInfo{UserID: c.Info.UserID}))
|
||||
return true
|
||||
})
|
||||
space.GetSpace(c.Info.MapID).Delete(c.Info.UserID)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package maps
|
||||
|
||||
import (
|
||||
"blazing/common/socket/handler"
|
||||
)
|
||||
import "blazing/logic/service"
|
||||
|
||||
type ListMapPlayerInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2003" struc:"[0]pad"` //切换地图
|
||||
Head service.TomeeHeader `cmd:"2003" struc:"[0]pad"` //切换地图
|
||||
}
|
||||
|
||||
type ListMapPlayerOutboundInfo struct {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package maps
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/logic/service"
|
||||
"blazing/logic/service/space"
|
||||
)
|
||||
|
||||
@@ -12,15 +11,26 @@ type LeaveMapOutboundInfo struct {
|
||||
}
|
||||
|
||||
type LeaveMapInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2002" struc:"[0]pad"` //切换地图
|
||||
Head service.TomeeHeader `cmd:"2002" struc:"[0]pad"` //切换地图
|
||||
}
|
||||
|
||||
func (t *LeaveMapInboundInfo) Broadcast(mapid uint32, o LeaveMapOutboundInfo) {
|
||||
|
||||
space.GetSpace(mapid).Range(func(playerID uint32, player *socket.Player) bool {
|
||||
space.GetSpace(mapid).Range(func(playerID uint32, player service.PlayerI) bool {
|
||||
t.Head.Result = 0
|
||||
|
||||
player.SendPack(t.Head.Pack(&o))
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func LeaveMap(c service.PlayerI) {
|
||||
t := service.NewTomeeHeader(2002, c.ID())
|
||||
|
||||
space.GetSpace(c.MapID()).Range(func(playerID uint32, player service.PlayerI) bool {
|
||||
|
||||
player.SendPack(t.Pack(&LeaveMapOutboundInfo{UserID: c.ID()}))
|
||||
return true
|
||||
})
|
||||
space.GetSpace(c.MapID()).Delete(c.ID())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package nono
|
||||
|
||||
import "blazing/common/socket/handler"
|
||||
import "blazing/logic/service"
|
||||
|
||||
// NonoOutboundInfo 用于表示Nono相关的出站信息
|
||||
type NonoOutboundInfo struct {
|
||||
@@ -55,7 +55,7 @@ type NonoOutboundInfo struct {
|
||||
|
||||
type NonoInboundInfo struct {
|
||||
// 消息头部,命令ID对应MessageCommandIDRegistry.Nono_Info
|
||||
Head handler.TomeeHeader `cmd:"9003" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"9003" struc:"[0]pad"`
|
||||
|
||||
// 米米号,对应Java的@UInt long类型
|
||||
UserID uint32 `fieldDescription:"米米号" struc:"uint32" uint:"true"`
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package pet
|
||||
|
||||
import "blazing/common/socket/handler"
|
||||
import "blazing/logic/service"
|
||||
|
||||
type GetPetListInboundEmpty struct {
|
||||
Head handler.TomeeHeader `cmd:"2303" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"2303" struc:"[0]pad"`
|
||||
}
|
||||
type GetPetListOutboundInfo struct {
|
||||
ShortInfoListLen uint32 `struc:"int32,sizeof=ShortInfoList"`
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package pet
|
||||
|
||||
import (
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/logic/service"
|
||||
"blazing/modules/blazing/model"
|
||||
)
|
||||
|
||||
type InInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2301" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"2301" struc:"[0]pad"`
|
||||
|
||||
CatchTime uint32
|
||||
}
|
||||
@@ -25,7 +25,7 @@ type PetReleaseOutboundInfo struct {
|
||||
|
||||
// 放入背包或者加入仓库
|
||||
type PetReleaseInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2304" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"2304" struc:"[0]pad"`
|
||||
CatchTime uint32 `json:"catch_time" fieldDescription:"精灵生成时间" autoCodec:"true" uint:"true"`
|
||||
Flag uint32 `json:"flag" fieldDescription:"0为放入仓库,1为放入背包" autoCodec:"true" uint:"true"`
|
||||
}
|
||||
|
||||
@@ -1,210 +1,264 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"blazing/common/utils"
|
||||
|
||||
"blazing/modules/blazing/model"
|
||||
"blazing/modules/blazing/service"
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gobwas/ws"
|
||||
"github.com/gobwas/ws/wsutil"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/panjf2000/gnet/pkg/logging"
|
||||
"github.com/tnnmigga/enum"
|
||||
)
|
||||
|
||||
var Mainplayer = &utils.SyncMap[uint32, *Player]{} //玩家数据
|
||||
|
||||
func (c *Conn) SendPack(bytes []byte) error {
|
||||
if t, ok := c.MainConn.Context().(*ClientData); ok {
|
||||
if t.Wsmsg.Upgraded {
|
||||
// This is the echo server
|
||||
err := wsutil.WriteServerMessage(c.MainConn, ws.OpBinary, bytes)
|
||||
if err != nil {
|
||||
logging.Infof("conn[%v] [err=%v]", c.MainConn.RemoteAddr().String(), err.Error())
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
|
||||
_, err := c.MainConn.Write(bytes)
|
||||
if err != nil {
|
||||
logging.Error(err)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type OgreInfo struct {
|
||||
Data [9]OgrePetInfo
|
||||
}
|
||||
|
||||
type OgrePetInfo struct {
|
||||
Id uint32
|
||||
Shiny uint32
|
||||
Lv uint32 `struc:"skip"` //等级
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
MainConn *Conn
|
||||
|
||||
IsLogin bool //是否登录
|
||||
mu sync.Mutex
|
||||
|
||||
loginChan chan struct{} // 登录完成通知通道
|
||||
Info *model.PlayerInfo
|
||||
StopChan chan struct{} //停止刷怪协程
|
||||
|
||||
context.Context
|
||||
Playerinvite uint32 //当前邀请的玩家ID
|
||||
Onlinetime uint32 //当前登录时间
|
||||
OgreInfo *OgreInfo
|
||||
FightID string //绑定战斗标识 替代本身的是否战斗标记 //IsFighting bool
|
||||
//FightInfo info.NoteReadyToFightInfo
|
||||
}
|
||||
|
||||
// PlayerOption 定义配置 Player 的函数类型
|
||||
type PlayerOption func(*Player)
|
||||
|
||||
func WithConn(c *Conn) PlayerOption {
|
||||
return func(p *Player) {
|
||||
p.MainConn = c
|
||||
}
|
||||
}
|
||||
|
||||
// NewPlayer 使用 Options 模式创建 Player 实例
|
||||
func NewPlayer(opts ...PlayerOption) *Player {
|
||||
p := &Player{
|
||||
loginChan: make(chan struct{}),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(p)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Player) SendPack(b []byte) error {
|
||||
// fmt.Println("发送数据包", len(b))
|
||||
err := p.MainConn.SendPack(b)
|
||||
return err
|
||||
}
|
||||
func (p *Player) Cheak(b error) {
|
||||
if b != nil {
|
||||
g.Log().Error(context.Background(), "出现错误", p.Info.UserID, b.Error())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Save 保存玩家数据
|
||||
func (p *Player) Save() {
|
||||
|
||||
p.Info.TimeToday = p.Info.TimeToday + uint32(time.Now().Unix()) - uint32(p.Onlinetime) //保存电池时间
|
||||
p.Onlinetime = uint32(time.Now().Unix())
|
||||
|
||||
service.NewUserService(p.Info.UserID).Save(p.Info)
|
||||
|
||||
}
|
||||
|
||||
// IsLoggedIn 检查是否已登录
|
||||
func (lw *Player) IsLoggedIn() bool {
|
||||
lw.mu.Lock()
|
||||
defer lw.mu.Unlock()
|
||||
return lw.IsLogin
|
||||
}
|
||||
|
||||
// WaitForLogin 等待登录完成,无超时
|
||||
func (lw *Player) WaitForLogin() error {
|
||||
if lw.IsLoggedIn() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 阻塞等待登录完成
|
||||
<-lw.loginChan
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForLoginWithTimeout 带超时的登录等待
|
||||
func (lw *Player) WaitForLoginWithTimeout(timeout time.Duration) error {
|
||||
if lw.IsLoggedIn() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 使用定时器实现超时
|
||||
timer := time.NewTimer(timeout)
|
||||
defer timer.Stop()
|
||||
|
||||
select {
|
||||
case <-lw.loginChan:
|
||||
return nil
|
||||
case <-timer.C:
|
||||
return fmt.Errorf("登录等待超时: %v", timeout)
|
||||
}
|
||||
}
|
||||
|
||||
// WaitForLoginWithCtx 带上下文的登录等待
|
||||
func (lw *Player) WaitForLoginWithCtx(ctx context.Context) error {
|
||||
if lw.IsLoggedIn() {
|
||||
return nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-lw.loginChan:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err() // 上下文取消或超时
|
||||
}
|
||||
}
|
||||
|
||||
// CompleteLogin 标记登录完成并通知等待者
|
||||
func (lw *Player) CompleteLogin() {
|
||||
lw.mu.Lock()
|
||||
defer lw.mu.Unlock()
|
||||
|
||||
if !lw.IsLogin {
|
||||
lw.IsLogin = true
|
||||
close(lw.loginChan) // 关闭通道以通知所有等待者
|
||||
}
|
||||
}
|
||||
|
||||
// 战斗模式
|
||||
type EnumBattleMode int
|
||||
|
||||
var BattleMode_PVP = enum.New[struct {
|
||||
PVP_1V1 EnumBattleMode `enum:"1"`
|
||||
PVP_6V6 EnumBattleMode `enum:"2"`
|
||||
}]()
|
||||
var Playerinvitemap map[uint32][]Playerinvite = make(map[uint32][]Playerinvite) //玩家邀请信息 ,比如一个玩家被多人邀请对战
|
||||
|
||||
type Playerinvite struct { //挂载到[]Playerinvite上? 被邀请者->邀请者
|
||||
InviteID uint32 // 邀请者
|
||||
InviteTime EnumBattleMode //游戏模式
|
||||
}
|
||||
|
||||
// 邀请玩家加入战斗 邀请者,被邀请者,邀请模式
|
||||
func (lw *Player) InvitePlayerToBattle(target int64, mode EnumBattleMode) {
|
||||
t, ok := Playerinvitemap[uint32(target)] //被邀请者是否被邀请过
|
||||
if ok { //说明存在被邀请
|
||||
t = append(t, Playerinvite{uint32(lw.Info.UserID), mode})
|
||||
Playerinvitemap[uint32(target)] = t
|
||||
} else {
|
||||
Playerinvitemap[uint32(target)] = []Playerinvite{{uint32(lw.Info.UserID), mode}}
|
||||
}
|
||||
|
||||
lw.Playerinvite = uint32(target)
|
||||
}
|
||||
|
||||
// 取消对战邀请
|
||||
func (lw *Player) CancelBattle() {
|
||||
|
||||
if lw.Playerinvite == 0 {
|
||||
return
|
||||
}
|
||||
delete(Playerinvitemap, uint32(lw.Playerinvite)) //删除玩家邀请信息
|
||||
lw.Playerinvite = 0
|
||||
}
|
||||
package service
|
||||
|
||||
import (
|
||||
"blazing/common/utils"
|
||||
"blazing/logic/service/fight/info"
|
||||
|
||||
"blazing/modules/blazing/model"
|
||||
"blazing/modules/blazing/service"
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gobwas/ws"
|
||||
"github.com/gobwas/ws/wsutil"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/panjf2000/gnet/pkg/logging"
|
||||
"github.com/tnnmigga/enum"
|
||||
)
|
||||
|
||||
func ConutPlayer() int {
|
||||
|
||||
count := 0
|
||||
Mainplayer.Range(func(uint32, *Player) bool {
|
||||
count++
|
||||
return true // 继续遍历
|
||||
})
|
||||
return count
|
||||
}
|
||||
|
||||
type ClientData struct {
|
||||
IsCrossDomain bool //是否跨域过
|
||||
Player *Player //客户实体
|
||||
//UserID uint32
|
||||
|
||||
Wsmsg *WsCodec
|
||||
}
|
||||
|
||||
func NewClientData() *ClientData {
|
||||
cd := ClientData{
|
||||
IsCrossDomain: false,
|
||||
Player: nil,
|
||||
|
||||
Wsmsg: &WsCodec{},
|
||||
}
|
||||
return &cd
|
||||
|
||||
}
|
||||
|
||||
var Mainplayer = &utils.SyncMap[uint32, *Player]{} //玩家数据
|
||||
|
||||
func (c *Conn) SendPack(bytes []byte) error {
|
||||
if t, ok := c.MainConn.Context().(*ClientData); ok {
|
||||
if t.Wsmsg.Upgraded {
|
||||
// This is the echo server
|
||||
err := wsutil.WriteServerMessage(c.MainConn, ws.OpBinary, bytes)
|
||||
if err != nil {
|
||||
logging.Infof("conn[%v] [err=%v]", c.MainConn.RemoteAddr().String(), err.Error())
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
|
||||
_, err := c.MainConn.Write(bytes)
|
||||
if err != nil {
|
||||
logging.Error(err)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type OgreInfo struct {
|
||||
Data [9]OgrePetInfo
|
||||
}
|
||||
|
||||
type OgrePetInfo struct {
|
||||
Id uint32
|
||||
Shiny uint32
|
||||
Lv uint32 `struc:"skip"` //等级
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
MainConn *Conn
|
||||
|
||||
IsLogin bool //是否登录
|
||||
mu sync.Mutex
|
||||
|
||||
loginChan chan struct{} // 登录完成通知通道
|
||||
Info *model.PlayerInfo
|
||||
StopChan chan struct{} //停止刷怪协程
|
||||
|
||||
context.Context
|
||||
Playerinvite uint32 //当前邀请的玩家ID
|
||||
Onlinetime uint32 //当前登录时间
|
||||
OgreInfo *OgreInfo
|
||||
FightC *FightC //绑定战斗标识 替代本身的是否战斗标记 //IsFighting bool
|
||||
//FightInfo info.NoteReadyToFightInfo
|
||||
}
|
||||
|
||||
// PlayerOption 定义配置 Player 的函数类型
|
||||
type PlayerOption func(*Player)
|
||||
|
||||
func WithConn(c *Conn) PlayerOption {
|
||||
return func(p *Player) {
|
||||
p.MainConn = c
|
||||
}
|
||||
}
|
||||
|
||||
// NewPlayer 使用 Options 模式创建 Player 实例
|
||||
func NewPlayer(opts ...PlayerOption) *Player {
|
||||
p := &Player{
|
||||
loginChan: make(chan struct{}),
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(p)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Player) GetInfo() model.PlayerInfo {
|
||||
|
||||
return *p.Info
|
||||
}
|
||||
|
||||
func (p *Player) ID() uint32 {
|
||||
|
||||
return p.Info.UserID
|
||||
}
|
||||
func (p *Player) MapID() uint32 {
|
||||
|
||||
return p.Info.MapID
|
||||
}
|
||||
|
||||
func (p *Player) SendPack(b []byte) error {
|
||||
// fmt.Println("发送数据包", len(b))
|
||||
err := p.MainConn.SendPack(b)
|
||||
return err
|
||||
}
|
||||
func (p *Player) Cheak(b error) {
|
||||
if b != nil {
|
||||
g.Log().Error(context.Background(), "出现错误", p.Info.UserID, b.Error())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (p *Player) SendReadyToFightInfo(b info.FightStartOutboundInfo) {
|
||||
t1 := NewTomeeHeader(2504, p.Info.UserID)
|
||||
p.SendPack(t1.Pack(&b))
|
||||
}
|
||||
func (p *Player) SendNoteReadyToFightInfo(b info.NoteReadyToFightInfo) {
|
||||
t1 := NewTomeeHeader(2503, p.Info.UserID)
|
||||
|
||||
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
|
||||
}
|
||||
|
||||
// Save 保存玩家数据
|
||||
func (p *Player) Save() {
|
||||
|
||||
p.Info.TimeToday = p.Info.TimeToday + uint32(time.Now().Unix()) - uint32(p.Onlinetime) //保存电池时间
|
||||
p.Onlinetime = uint32(time.Now().Unix())
|
||||
|
||||
service.NewUserService(p.Info.UserID).Save(p.Info)
|
||||
|
||||
}
|
||||
|
||||
// IsLoggedIn 检查是否已登录
|
||||
func (lw *Player) IsLoggedIn() bool {
|
||||
lw.mu.Lock()
|
||||
defer lw.mu.Unlock()
|
||||
return lw.IsLogin
|
||||
}
|
||||
|
||||
// WaitForLogin 等待登录完成,无超时
|
||||
func (lw *Player) WaitForLogin() error {
|
||||
if lw.IsLoggedIn() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 阻塞等待登录完成
|
||||
<-lw.loginChan
|
||||
return nil
|
||||
}
|
||||
|
||||
// WaitForLoginWithTimeout 带超时的登录等待
|
||||
func (lw *Player) WaitForLoginWithTimeout(timeout time.Duration) error {
|
||||
if lw.IsLoggedIn() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 使用定时器实现超时
|
||||
timer := time.NewTimer(timeout)
|
||||
defer timer.Stop()
|
||||
|
||||
select {
|
||||
case <-lw.loginChan:
|
||||
return nil
|
||||
case <-timer.C:
|
||||
return fmt.Errorf("登录等待超时: %v", timeout)
|
||||
}
|
||||
}
|
||||
|
||||
// WaitForLoginWithCtx 带上下文的登录等待
|
||||
func (lw *Player) WaitForLoginWithCtx(ctx context.Context) error {
|
||||
if lw.IsLoggedIn() {
|
||||
return nil
|
||||
}
|
||||
|
||||
select {
|
||||
case <-lw.loginChan:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err() // 上下文取消或超时
|
||||
}
|
||||
}
|
||||
|
||||
// CompleteLogin 标记登录完成并通知等待者
|
||||
func (lw *Player) CompleteLogin() {
|
||||
lw.mu.Lock()
|
||||
defer lw.mu.Unlock()
|
||||
|
||||
if !lw.IsLogin {
|
||||
lw.IsLogin = true
|
||||
close(lw.loginChan) // 关闭通道以通知所有等待者
|
||||
}
|
||||
}
|
||||
|
||||
// 战斗模式
|
||||
type EnumBattleMode int
|
||||
|
||||
var BattleMode_PVP = enum.New[struct {
|
||||
PVP_1V1 EnumBattleMode `enum:"1"`
|
||||
PVP_6V6 EnumBattleMode `enum:"2"`
|
||||
}]()
|
||||
var Playerinvitemap map[uint32][]Playerinvite = make(map[uint32][]Playerinvite) //玩家邀请信息 ,比如一个玩家被多人邀请对战
|
||||
|
||||
type Playerinvite struct { //挂载到[]Playerinvite上? 被邀请者->邀请者
|
||||
InviteID uint32 // 邀请者
|
||||
InviteTime EnumBattleMode //游戏模式
|
||||
}
|
||||
|
||||
// 邀请玩家加入战斗 邀请者,被邀请者,邀请模式
|
||||
func (lw *Player) InvitePlayerToBattle(target int64, mode EnumBattleMode) {
|
||||
t, ok := Playerinvitemap[uint32(target)] //被邀请者是否被邀请过
|
||||
if ok { //说明存在被邀请
|
||||
t = append(t, Playerinvite{uint32(lw.Info.UserID), mode})
|
||||
Playerinvitemap[uint32(target)] = t
|
||||
} else {
|
||||
Playerinvitemap[uint32(target)] = []Playerinvite{{uint32(lw.Info.UserID), mode}}
|
||||
}
|
||||
|
||||
lw.Playerinvite = uint32(target)
|
||||
}
|
||||
|
||||
// 取消对战邀请
|
||||
func (lw *Player) CancelBattle() {
|
||||
|
||||
if lw.Playerinvite == 0 {
|
||||
return
|
||||
}
|
||||
delete(Playerinvitemap, uint32(lw.Playerinvite)) //删除玩家邀请信息
|
||||
lw.Playerinvite = 0
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package room
|
||||
|
||||
import "blazing/common/socket/handler"
|
||||
import (
|
||||
"blazing/logic/service"
|
||||
)
|
||||
|
||||
// FitmentShowInfo 表示家具展示信息
|
||||
type FitmentShowInfo struct {
|
||||
@@ -18,7 +20,7 @@ type FitmentShowInfo struct {
|
||||
|
||||
// FitmentUseringInboundInfo FitmentUseringInboundInfo类,实现InboundMessage接口
|
||||
type FitmentUseringInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"10006" struc:"[0]pad"` //玩家登录
|
||||
Head service.TomeeHeader `cmd:"10006" struc:"[0]pad"` //玩家登录
|
||||
// 需要获取基地信息的目标玩家账号ID
|
||||
TargetUserID uint32 `json:"targetUserId"`
|
||||
}
|
||||
@@ -45,12 +47,12 @@ type PetRoomListOutboundInfo struct {
|
||||
}
|
||||
|
||||
type PetRoomListInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2324" struc:"[0]pad"` //玩家登录
|
||||
Head service.TomeeHeader `cmd:"2324" struc:"[0]pad"` //玩家登录
|
||||
// 需要获取基地信息的目标玩家账号ID
|
||||
TargetUserID uint32 `json:"targetUserId"`
|
||||
}
|
||||
type FitmentAllInboundEmpty struct {
|
||||
Head handler.TomeeHeader `cmd:"10007" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"10007" struc:"[0]pad"`
|
||||
}
|
||||
type FitmentAllOutboundInfo struct {
|
||||
FitmentsLen uint32 `json:"fitmentsLen" struc:"sizeof=Fitments"`
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/errorcode"
|
||||
"blazing/common/socket/handler"
|
||||
)
|
||||
|
||||
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.Player != nil {
|
||||
return clientdata.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) { //踢出玩家
|
||||
//TODO 返回错误码
|
||||
//var player *entity.Player
|
||||
if player1, ok := socket.Mainplayer.Load((userid)); ok {
|
||||
//取成功,否则创建
|
||||
head := handler.NewTomeeHeader(1001, userid)
|
||||
head.Result = uint32(errorcode.ErrorCodes.ErrAccountLoggedInElsewhere)
|
||||
|
||||
player1.SendPack(head.Pack(nil))
|
||||
player1.MainConn.MainConn.Close()
|
||||
// clientdata.Player = player
|
||||
}
|
||||
|
||||
//return player
|
||||
// return nil
|
||||
}
|
||||
@@ -1,34 +1,35 @@
|
||||
package space
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/data/xmlres"
|
||||
"blazing/common/utils"
|
||||
"blazing/logic/service"
|
||||
|
||||
"blazing/modules/blazing/model"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Space 针对Player的并发安全map,键为uint32类型
|
||||
type Space struct {
|
||||
mu sync.RWMutex // 读写锁,读多写少场景更高效
|
||||
data map[uint32]*socket.Player // 存储玩家数据的map,键为玩家ID
|
||||
CanRefresh bool //是否能够刷怪
|
||||
ID uint32 // 地图ID
|
||||
Name string //地图名称
|
||||
DefaultPos model.Pos //默认位置DefaultPos
|
||||
Positions map[uint32]model.Pos //从上一个地图跳转后默认位置
|
||||
mu sync.RWMutex // 读写锁,读多写少场景更高效
|
||||
data map[uint32]service.PlayerI // 存储玩家数据的map,键为玩家ID
|
||||
CanRefresh bool //是否能够刷怪
|
||||
ID uint32 // 地图ID
|
||||
Name string //地图名称
|
||||
DefaultPos model.Pos //默认位置DefaultPos
|
||||
Positions map[uint32]model.Pos //从上一个地图跳转后默认位置
|
||||
}
|
||||
|
||||
// NewSyncMap 创建一个新的玩家同步map
|
||||
func NewSpace() *Space {
|
||||
return &Space{
|
||||
data: make(map[uint32]*socket.Player),
|
||||
data: make(map[uint32]service.PlayerI),
|
||||
}
|
||||
}
|
||||
|
||||
// Get 根据玩家ID获取玩家实例
|
||||
// 读操作使用RLock,允许多个goroutine同时读取
|
||||
func (m *Space) Get(playerID uint32) (*socket.Player, bool) {
|
||||
func (m *Space) Get(playerID uint32) (service.PlayerI, bool) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
val, exists := m.data[playerID]
|
||||
@@ -37,7 +38,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 service.PlayerI) *Space {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.data[playerID] = player
|
||||
@@ -63,7 +64,7 @@ func (m *Space) Len() int {
|
||||
|
||||
// Range 遍历所有玩家并执行回调函数
|
||||
// 读操作使用RLock,遍历过程中不会阻塞其他读操作
|
||||
func (m *Space) Range(f func(playerID uint32, player *socket.Player) bool) {
|
||||
func (m *Space) Range(f func(playerID uint32, player service.PlayerI) bool) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
for id, player := range m.data {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package space
|
||||
|
||||
import (
|
||||
"blazing/common/data/socket"
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/logic/service"
|
||||
"blazing/modules/blazing/model"
|
||||
)
|
||||
|
||||
type InInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2101" struc:"[0]pad"` //走路包
|
||||
Head service.TomeeHeader `cmd:"2101" struc:"[0]pad"` //走路包
|
||||
// Flag: 0为走,1为飞行模式,@UInt long
|
||||
Flag uint32
|
||||
|
||||
@@ -23,11 +22,11 @@ func (t *InInfo) Broadcast(mapid uint32, o OutInfo) {
|
||||
//tt := planetmap
|
||||
//g.Dump(GetSpace(mapid).Len())
|
||||
|
||||
GetSpace(mapid).Range(func(playerID uint32, player *socket.Player) bool {
|
||||
GetSpace(mapid).Range(func(playerID uint32, player service.PlayerI) bool {
|
||||
t.Head.Result = 0
|
||||
tt := t.Head.Pack(&o)
|
||||
err := player.SendPack(tt)
|
||||
player.Cheak(err)
|
||||
player.SendPack(tt)
|
||||
//player.Cheak(err)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package systemtime
|
||||
|
||||
import (
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/logic/service"
|
||||
"time"
|
||||
)
|
||||
|
||||
// LoginSidInfo 登录携带的凭证结构体
|
||||
type InInfo struct { //这里直接使用组合来实现将传入的原始头部数据和结构体参数序列化
|
||||
Head handler.TomeeHeader `cmd:"1002" struc:"[0]pad"` //玩家登录
|
||||
Head service.TomeeHeader `cmd:"1002" struc:"[0]pad"` //玩家登录
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package task
|
||||
|
||||
import "blazing/common/socket/handler"
|
||||
import "blazing/logic/service"
|
||||
|
||||
// AcceptTaskInboundInfo 对应Java的AcceptTaskInboundInfo类
|
||||
// 用于接收任务的入站信息
|
||||
type AcceptTaskInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2201|2231" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"2201|2231" struc:"[0]pad"`
|
||||
TaskId uint32 `json:"taskId" description:"任务ID"` // 任务ID,对应Java的@UInt long
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package task
|
||||
|
||||
import "blazing/common/socket/handler"
|
||||
import "blazing/logic/service"
|
||||
|
||||
// AddTaskBufInboundInfo 对应Java的AddTaskBufInboundInfo类
|
||||
// 用于接收添加任务缓冲区的入站信息
|
||||
type AddTaskBufInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2204|2235" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"2204|2235" struc:"[0]pad"`
|
||||
TaskId uint32 `json:"taskId" description:"任务ID"` // 任务ID,对应Java的@UInt long
|
||||
TaskList []uint32 `struc:"[20]byte"` // 任务步骤信息,对应Java的@ArraySerialize注解
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package task
|
||||
|
||||
import "blazing/common/socket/handler"
|
||||
import "blazing/logic/service"
|
||||
|
||||
type CompleteTaskInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2202|2233" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"2202|2233" struc:"[0]pad"`
|
||||
TaskId uint32 `json:"taskId" description:"任务ID"` // 任务ID,对应Java的@UInt long
|
||||
OutState uint32 `json:"outState" 分支"` // 当前状态,1表示完成任务,对应Java的@UInt long
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package task
|
||||
|
||||
import "blazing/common/socket/handler"
|
||||
import "blazing/logic/service"
|
||||
|
||||
// DeleteTaskInboundInfo 对应Java的DeleteTaskInboundInfo类
|
||||
type DeleteTaskInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2205|2232" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"2205|2232" struc:"[0]pad"`
|
||||
TaskId uint32 `json:"taskId" description:"任务ID"` // 使用uint64对应Java的@UInt long
|
||||
}
|
||||
type DeleteTaskOutboundInfo struct {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"blazing/common/socket/handler"
|
||||
"blazing/logic/service"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
type GetTaskBufInboundInfo struct {
|
||||
Head handler.TomeeHeader `cmd:"2203|2234" struc:"[0]pad"`
|
||||
Head service.TomeeHeader `cmd:"2203|2234" struc:"[0]pad"`
|
||||
|
||||
TaskId uint32 `json:"taskId" description:"任务ID"` // 任务ID,对应Java的@UInt long
|
||||
}
|
||||
|
||||
@@ -1,170 +1,170 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/gobwas/ws"
|
||||
"github.com/gobwas/ws/wsutil"
|
||||
"github.com/panjf2000/gnet/v2"
|
||||
"github.com/panjf2000/gnet/v2/pkg/logging"
|
||||
)
|
||||
|
||||
type Conn struct {
|
||||
MainConn gnet.Conn `struc:"[0]pad"` //TODO 不序列化,,序列化下面的作为blob存数据库
|
||||
Mu sync.Mutex
|
||||
}
|
||||
|
||||
func NewConn(c gnet.Conn) *Conn {
|
||||
return &Conn{MainConn: c}
|
||||
}
|
||||
|
||||
type WsCodec struct {
|
||||
Upgraded bool // 链接是否升级
|
||||
Buf bytes.Buffer // 从实际socket中读取到的数据缓存
|
||||
wsMsgBuf wsMessageBuf // ws 消息缓存
|
||||
//Isinitws bool
|
||||
}
|
||||
|
||||
type wsMessageBuf struct {
|
||||
curHeader *ws.Header
|
||||
cachedBuf bytes.Buffer
|
||||
}
|
||||
|
||||
type readWrite struct {
|
||||
io.Reader
|
||||
io.Writer
|
||||
}
|
||||
|
||||
func (w *WsCodec) Upgrade(c gnet.Conn) (ok bool, action gnet.Action) {
|
||||
if w.Upgraded {
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
buf := &w.Buf
|
||||
tmpReader := bytes.NewReader(buf.Bytes())
|
||||
oldLen := tmpReader.Len()
|
||||
logging.Infof("do Upgrade")
|
||||
|
||||
hs, err := ws.Upgrade(readWrite{tmpReader, c})
|
||||
skipN := oldLen - tmpReader.Len()
|
||||
if err != nil {
|
||||
if err == io.EOF || errors.Is(err, io.ErrUnexpectedEOF) { //数据不完整,不跳过 buf 中的 skipN 字节(此时 buf 中存放的仅是部分 "handshake data" bytes),下次再尝试读取
|
||||
return
|
||||
}
|
||||
buf.Next(skipN)
|
||||
logging.Errorf("conn[%v] [err=%v]", c.RemoteAddr().String(), err.Error())
|
||||
action = gnet.Close
|
||||
return
|
||||
}
|
||||
buf.Next(skipN)
|
||||
logging.Infof("conn[%v] upgrade websocket protocol! Handshake: %v", c.RemoteAddr().String(), hs)
|
||||
|
||||
ok = true
|
||||
w.Upgraded = true
|
||||
return
|
||||
}
|
||||
func (w *WsCodec) ReadBufferBytes(c gnet.Conn) (gnet.Action, int) {
|
||||
size := c.InboundBuffered()
|
||||
//buf := make([]byte, size)
|
||||
read, err := c.Peek(size)
|
||||
if err != nil {
|
||||
logging.Errorf("read err! %v", err)
|
||||
return gnet.Close, 0
|
||||
}
|
||||
// if read < size {
|
||||
// logging.Errorf("read bytes len err! size: %d read: %d", size, read)
|
||||
// return gnet.Close
|
||||
// }
|
||||
w.Buf.Write(read)
|
||||
return gnet.None, size
|
||||
}
|
||||
func (w *WsCodec) Decode(c gnet.Conn) (outs []wsutil.Message, err error) {
|
||||
// fmt.Println("do Decode")
|
||||
messages, err := w.readWsMessages()
|
||||
if err != nil {
|
||||
logging.Errorf("Error reading message! %v", err)
|
||||
return nil, err
|
||||
}
|
||||
if messages == nil || len(messages) <= 0 { //没有读到完整数据 不处理
|
||||
return
|
||||
}
|
||||
for _, message := range messages {
|
||||
if message.OpCode.IsControl() {
|
||||
err = wsutil.HandleClientControlMessage(c, message)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
if message.OpCode == ws.OpText || message.OpCode == ws.OpBinary {
|
||||
outs = append(outs, message)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (w *WsCodec) readWsMessages() (messages []wsutil.Message, err error) {
|
||||
msgBuf := &w.wsMsgBuf
|
||||
in := &w.Buf
|
||||
for {
|
||||
// 从 in 中读出 header,并将 header bytes 写入 msgBuf.cachedBuf
|
||||
if msgBuf.curHeader == nil {
|
||||
if in.Len() < ws.MinHeaderSize { //头长度至少是2
|
||||
return
|
||||
}
|
||||
var head ws.Header
|
||||
if in.Len() >= ws.MaxHeaderSize {
|
||||
head, err = ws.ReadHeader(in)
|
||||
if err != nil {
|
||||
return messages, err
|
||||
}
|
||||
} else { //有可能不完整,构建新的 reader 读取 head,读取成功才实际对 in 进行读操作
|
||||
tmpReader := bytes.NewReader(in.Bytes())
|
||||
oldLen := tmpReader.Len()
|
||||
head, err = ws.ReadHeader(tmpReader)
|
||||
skipN := oldLen - tmpReader.Len()
|
||||
if err != nil {
|
||||
if err == io.EOF || errors.Is(err, io.ErrUnexpectedEOF) { //数据不完整
|
||||
return messages, nil
|
||||
}
|
||||
in.Next(skipN)
|
||||
return nil, err
|
||||
}
|
||||
in.Next(skipN)
|
||||
}
|
||||
|
||||
msgBuf.curHeader = &head
|
||||
err = ws.WriteHeader(&msgBuf.cachedBuf, head)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
dataLen := (int)(msgBuf.curHeader.Length)
|
||||
// 从 in 中读出 data,并将 data bytes 写入 msgBuf.cachedBuf
|
||||
if dataLen > 0 {
|
||||
if in.Len() < dataLen { //数据不完整
|
||||
|
||||
logging.Infof("incomplete data")
|
||||
return
|
||||
}
|
||||
|
||||
_, err = io.CopyN(&msgBuf.cachedBuf, in, int64(dataLen))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if msgBuf.curHeader.Fin { //当前 header 已经是一个完整消息
|
||||
messages, err = wsutil.ReadClientMessage(&msgBuf.cachedBuf, messages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgBuf.cachedBuf.Reset()
|
||||
} else {
|
||||
logging.Infof("The data is split into multiple frames")
|
||||
}
|
||||
msgBuf.curHeader = nil
|
||||
}
|
||||
}
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/gobwas/ws"
|
||||
"github.com/gobwas/ws/wsutil"
|
||||
"github.com/panjf2000/gnet/v2"
|
||||
"github.com/panjf2000/gnet/v2/pkg/logging"
|
||||
)
|
||||
|
||||
type Conn struct {
|
||||
MainConn gnet.Conn `struc:"[0]pad"` //TODO 不序列化,,序列化下面的作为blob存数据库
|
||||
Mu sync.Mutex
|
||||
}
|
||||
|
||||
func NewConn(c gnet.Conn) *Conn {
|
||||
return &Conn{MainConn: c}
|
||||
}
|
||||
|
||||
type WsCodec struct {
|
||||
Upgraded bool // 链接是否升级
|
||||
Buf bytes.Buffer // 从实际socket中读取到的数据缓存
|
||||
wsMsgBuf wsMessageBuf // ws 消息缓存
|
||||
//Isinitws bool
|
||||
}
|
||||
|
||||
type wsMessageBuf struct {
|
||||
curHeader *ws.Header
|
||||
cachedBuf bytes.Buffer
|
||||
}
|
||||
|
||||
type readWrite struct {
|
||||
io.Reader
|
||||
io.Writer
|
||||
}
|
||||
|
||||
func (w *WsCodec) Upgrade(c gnet.Conn) (ok bool, action gnet.Action) {
|
||||
if w.Upgraded {
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
buf := &w.Buf
|
||||
tmpReader := bytes.NewReader(buf.Bytes())
|
||||
oldLen := tmpReader.Len()
|
||||
logging.Infof("do Upgrade")
|
||||
|
||||
hs, err := ws.Upgrade(readWrite{tmpReader, c})
|
||||
skipN := oldLen - tmpReader.Len()
|
||||
if err != nil {
|
||||
if err == io.EOF || errors.Is(err, io.ErrUnexpectedEOF) { //数据不完整,不跳过 buf 中的 skipN 字节(此时 buf 中存放的仅是部分 "handshake data" bytes),下次再尝试读取
|
||||
return
|
||||
}
|
||||
buf.Next(skipN)
|
||||
logging.Errorf("conn[%v] [err=%v]", c.RemoteAddr().String(), err.Error())
|
||||
action = gnet.Close
|
||||
return
|
||||
}
|
||||
buf.Next(skipN)
|
||||
logging.Infof("conn[%v] upgrade websocket protocol! Handshake: %v", c.RemoteAddr().String(), hs)
|
||||
|
||||
ok = true
|
||||
w.Upgraded = true
|
||||
return
|
||||
}
|
||||
func (w *WsCodec) ReadBufferBytes(c gnet.Conn) (gnet.Action, int) {
|
||||
size := c.InboundBuffered()
|
||||
//buf := make([]byte, size)
|
||||
read, err := c.Peek(size)
|
||||
if err != nil {
|
||||
logging.Errorf("read err! %v", err)
|
||||
return gnet.Close, 0
|
||||
}
|
||||
// if read < size {
|
||||
// logging.Errorf("read bytes len err! size: %d read: %d", size, read)
|
||||
// return gnet.Close
|
||||
// }
|
||||
w.Buf.Write(read)
|
||||
return gnet.None, size
|
||||
}
|
||||
func (w *WsCodec) Decode(c gnet.Conn) (outs []wsutil.Message, err error) {
|
||||
// fmt.Println("do Decode")
|
||||
messages, err := w.readWsMessages()
|
||||
if err != nil {
|
||||
logging.Errorf("Error reading message! %v", err)
|
||||
return nil, err
|
||||
}
|
||||
if messages == nil || len(messages) <= 0 { //没有读到完整数据 不处理
|
||||
return
|
||||
}
|
||||
for _, message := range messages {
|
||||
if message.OpCode.IsControl() {
|
||||
err = wsutil.HandleClientControlMessage(c, message)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
if message.OpCode == ws.OpText || message.OpCode == ws.OpBinary {
|
||||
outs = append(outs, message)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (w *WsCodec) readWsMessages() (messages []wsutil.Message, err error) {
|
||||
msgBuf := &w.wsMsgBuf
|
||||
in := &w.Buf
|
||||
for {
|
||||
// 从 in 中读出 header,并将 header bytes 写入 msgBuf.cachedBuf
|
||||
if msgBuf.curHeader == nil {
|
||||
if in.Len() < ws.MinHeaderSize { //头长度至少是2
|
||||
return
|
||||
}
|
||||
var head ws.Header
|
||||
if in.Len() >= ws.MaxHeaderSize {
|
||||
head, err = ws.ReadHeader(in)
|
||||
if err != nil {
|
||||
return messages, err
|
||||
}
|
||||
} else { //有可能不完整,构建新的 reader 读取 head,读取成功才实际对 in 进行读操作
|
||||
tmpReader := bytes.NewReader(in.Bytes())
|
||||
oldLen := tmpReader.Len()
|
||||
head, err = ws.ReadHeader(tmpReader)
|
||||
skipN := oldLen - tmpReader.Len()
|
||||
if err != nil {
|
||||
if err == io.EOF || errors.Is(err, io.ErrUnexpectedEOF) { //数据不完整
|
||||
return messages, nil
|
||||
}
|
||||
in.Next(skipN)
|
||||
return nil, err
|
||||
}
|
||||
in.Next(skipN)
|
||||
}
|
||||
|
||||
msgBuf.curHeader = &head
|
||||
err = ws.WriteHeader(&msgBuf.cachedBuf, head)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
dataLen := (int)(msgBuf.curHeader.Length)
|
||||
// 从 in 中读出 data,并将 data bytes 写入 msgBuf.cachedBuf
|
||||
if dataLen > 0 {
|
||||
if in.Len() < dataLen { //数据不完整
|
||||
|
||||
logging.Infof("incomplete data")
|
||||
return
|
||||
}
|
||||
|
||||
_, err = io.CopyN(&msgBuf.cachedBuf, in, int64(dataLen))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if msgBuf.curHeader.Fin { //当前 header 已经是一个完整消息
|
||||
messages, err = wsutil.ReadClientMessage(&msgBuf.cachedBuf, messages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgBuf.cachedBuf.Reset()
|
||||
} else {
|
||||
logging.Infof("The data is split into multiple frames")
|
||||
}
|
||||
msgBuf.curHeader = nil
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package model
|
||||
|
||||
// TeamInfo 战队信息结构
|
||||
type TeamInfo struct {
|
||||
//Head handler.TomeeHeader `cmd:"1001" struc:"[0]pad"` // 命令头
|
||||
//Head service.TomeeHeader `cmd:"1001" struc:"[0]pad"` // 命令头
|
||||
ID uint32 `struc:"uint32" default:"0"` // 默认值0
|
||||
Priv uint32 `struc:"uint32" default:"1"` // 默认值1
|
||||
SuperCore uint32 `struc:"uint32" default:"1"` // 默认值1
|
||||
|
||||
@@ -79,11 +79,11 @@ type PlayerInfo struct {
|
||||
VipEndTime uint32 `struc:"uint32" default:"4294967295" json:"vip_end_time"` // 尽可能大值
|
||||
FreshManBonus uint32 `struc:"uint32" json:"fresh_man_bonus"` // 固定0
|
||||
NonoChipList [80]byte `struc:"[80]byte" json:"nono_chip_list"` // 超no芯片列表
|
||||
DailyResArr [50]byte `struc:"[50]byte" default:"3" json:"daily_res_arr"` // 任务状态数组默认3
|
||||
DailyResArr [50]byte `struc:"[50]byte" default:"0" json:"daily_res_arr"` // 每日任务状态 40+是谱尼的
|
||||
TeacherID uint32 `struc:"uint32" json:"teacher_id"` // 教官id
|
||||
StudentID uint32 `struc:"uint32" json:"student_id"` // 学员id
|
||||
GraduationCount uint32 `struc:"uint32" default:"0" json:"graduation_count"` // 毕业人数
|
||||
MaxPuniLv uint32 `struc:"uint32" default:"0" json:"max_puni_lv"` // 默认0
|
||||
MaxPuniLv uint32 `struc:"uint32" default:"0" json:"max_puni_lv"` // 默认0, 虚无 元素 能量 生命 轮回 永恒 圣洁 最高为8
|
||||
PetMaxLevel uint32 `struc:"uint32" json:"pet_max_level"` // 精灵最高等级
|
||||
AllPetNumber uint32 `struc:"uint32" json:"all_pet_number"` // 精灵数量
|
||||
MonKingWin uint32 `struc:"uint32" json:"mon_king_win"` // 精灵王胜场
|
||||
|
||||
@@ -62,7 +62,9 @@ func Exec[T cool.UserModel, F any](userid uint32, s *cool.Service, processFunc f
|
||||
// 获取任务信息
|
||||
func (s *UserService) TaskInfo(id uint32) (ret model.TaskInfo, ok bool) {
|
||||
var gg model.Task
|
||||
m1 := cool.DBM(s.task.Model).Where("player_id", s.userid)
|
||||
m1 := cool.DBM(s.task.Model).
|
||||
Where("player_id", s.userid).
|
||||
Where("task_id", id)
|
||||
m1.Scan(&gg)
|
||||
|
||||
if gg.TaskID == 0 {
|
||||
@@ -87,7 +89,11 @@ func (s *UserService) TaskADD(id uint32, ret model.TaskInfo) {
|
||||
tt, _ := json.Marshal(&ret)
|
||||
gg.Data = string(tt)
|
||||
gg.TaskID = id
|
||||
cool.DBM(s.task.Model).Where("player_id", s.userid).Insert()
|
||||
gg.PlayerID = uint64(s.userid)
|
||||
_, err := cool.DBM(s.task.Model).Data(gg).Where("player_id", s.userid).Insert()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
func (s *UserService) TaskExec(t func([]model.TaskInfo) []model.TaskInfo) (ret bool) {
|
||||
|
||||
Reference in New Issue
Block a user