diff --git a/common/socket/ServerEvent.go b/common/socket/ServerEvent.go index 04847a09a..85326db6a 100644 --- a/common/socket/ServerEvent.go +++ b/common/socket/ServerEvent.go @@ -48,8 +48,10 @@ 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, _ := c.Context().(*player.ClientData) + v.LF.Close() if v.Player != nil { v.SaveL.Do(func() { //使用保存锁,确保在踢人和掉线的时候只保存一次 //cool.Loger.Info(context.TODO(), "准备保存", v.Player.Info.UserID) @@ -140,7 +142,8 @@ func (s *Server) OnTraffic(c gnet.Conn) (action gnet.Action) { //client := conn.RemoteAddr().String() s.workerPool.Submit(func() { //TODO 这里可能存在顺序执行问题,待修复 for _, msg := range messages { - t.OnEvent(msg.Payload) + t.LF.Producer().Write(msg.Payload) + //t.OnEvent(msg.Payload) } }) @@ -164,8 +167,8 @@ func (s *Server) handleTcp(conn gnet.Conn) (action gnet.Action) { } s.workerPool.Submit(func() { //TODO 这里可能存在顺序执行问题,待修复 - conn.Context().(*player.ClientData).OnEvent(data) - + //conn.Context().(*player.ClientData).OnEvent(data) + conn.Context().(*player.ClientData).LF.Producer().Write(data) }) if conn.InboundBuffered() > 0 { diff --git a/logic/controller/fight.go b/logic/controller/fight.go index 06b2cb9c1..e718c33d2 100644 --- a/logic/controller/fight.go +++ b/logic/controller/fight.go @@ -126,9 +126,7 @@ func (h Controller) OnReadyToFight(data *fight.ReadyToFightInboundInfo, c *playe // 接收战斗或者取消战斗的包 func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - if !c.CanFight() { - return nil, errorcode.ErrorCodes.ErrPokemonNotEligible - } + if ok, p1 := c.AgreeBattle(data.UserID, data.Flag, data.Mode); ok { fight.NewFight(data.Mode, info.BattleStatus.FIGHT_WITH_PLAYER, c, p1) ///开始对战,房主方以及被邀请方 } @@ -164,15 +162,23 @@ func (h Controller) UseSkill(data *fight.UseSkillInInfo, c *player.Player) (resu // 战斗逃跑 func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + if c.FightC == nil { + return nil, 0 + } + if !c.FightC.CanEscape() { + + return nil, 0 + } c.FightC.Over(c, info.BattleOverReason.PlayerEscape) return nil, 0 } // 切换精灵 func (h Controller) ChangePet(data *fight.ChangePetInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - - c.FightC.ChangePet(c, data.CatchTime) + if c.FightC != nil { + c.FightC.ChangePet(c, data.CatchTime) + } return nil, -1 } diff --git a/logic/controller/pet.go b/logic/controller/pet.go index f04cac3d4..b41b05963 100644 --- a/logic/controller/pet.go +++ b/logic/controller/pet.go @@ -69,24 +69,23 @@ func (h *Controller) PetRelease( switch data.Flag { case 0: + var temp []model.PetInfo - removeIndex := -1 - for i, v := range c.Info.PetList { + for _, v := range c.Info.PetList { if v.CatchTime == uint32(data.CatchTime) { - removeIndex = i - break // 只移除第一个匹配值,若需移除所有,可省略 break 继续循环 + c.Service.PetInfo_One_exec(data.CatchTime, func(t *model.PetEX) { + t.Data = v + t.InBag = 0 + + }) + + } else { + temp = append(temp, v) } } - if removeIndex != -1 { - c.Service.PetInfo_One_exec(data.CatchTime, func(t *model.PetEX) { - t.Data = c.Info.PetList[removeIndex] - t.InBag = 0 - - }) - c.Info.PetList = append(c.Info.PetList[:removeIndex], c.Info.PetList[removeIndex+1:]...) - } - + c.Info.PetList = temp + // break // 只移除第一个匹配值,若需移除所有,可省略 break 继续循环 case 1: //todo 背包 c.Service.PetInfo_One_exec(data.CatchTime, func(t *model.PetEX) { diff --git a/logic/controller/task.go b/logic/controller/task.go index 97482e8ee..3d40f83f6 100644 --- a/logic/controller/task.go +++ b/logic/controller/task.go @@ -39,14 +39,14 @@ func (h Controller) AddTaskBuf(data *task.AddTaskBufInboundInfo, c *player.Playe // if data.Head.CMD != 2204 { //判断是每日任务 // isdaliy = true // } - result = &task.AddTaskBufOutboundInfo{} + c.Service.Task(data.TaskId, func(te *model.TaskEX) bool { te.Data = data.TaskList return true }) - return &task.AddTaskBufOutboundInfo{}, 0 + return result, 0 } /** diff --git a/logic/go.mod b/logic/go.mod index 77e3c6c74..67cafc6cb 100644 --- a/logic/go.mod +++ b/logic/go.mod @@ -22,6 +22,7 @@ require ( github.com/BurntSushi/toml v1.4.0 // indirect github.com/antlabs/stl v0.0.2 // indirect github.com/bits-and-blooms/bitset v1.5.0 // indirect + github.com/bruceshao/lockfree v1.1.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/clbanning/mxj/v2 v2.7.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect diff --git a/logic/go.sum b/logic/go.sum index 9269a0094..8a9d7583e 100644 --- a/logic/go.sum +++ b/logic/go.sum @@ -8,6 +8,8 @@ github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLo github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df/go.mod h1:hiVxq5OP2bUGBRNS3Z/bt/reCLFNbdcST6gISi1fiOM= github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bruceshao/lockfree v1.1.2 h1:V3j7bZWS+yDjazffbobpR+ZCVq98DNJcZMvO8vWFLmc= +github.com/bruceshao/lockfree v1.1.2/go.mod h1:zkhImea4VTfzWvFF1Lleo1esCZeJLGgrYN+mUuqNrMA= github.com/brunoga/deep v1.2.5 h1:bigq4eooqbeJXfvTfZBn3AH3B1iW+rtetxVeh0GiLrg= github.com/brunoga/deep v1.2.5/go.mod h1:GDV6dnXqn80ezsLSZ5Wlv1PdKAWAO4L5PnKYtv2dgaI= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= diff --git a/logic/service/common/fight.go b/logic/service/common/fight.go index cfdbd8bd1..8f3e4f82f 100644 --- a/logic/service/common/fight.go +++ b/logic/service/common/fight.go @@ -15,6 +15,6 @@ type FightI interface { Capture(c PlayerI, id uint32) GetRand() *rand.Rand LoadPercent(c PlayerI, percent int32) - + CanEscape() bool IsFirst(c PlayerI) bool } diff --git a/logic/service/fight/fightc.go b/logic/service/fight/fightc.go index aaeb23992..e7a5ec573 100644 --- a/logic/service/fight/fightc.go +++ b/logic/service/fight/fightc.go @@ -36,6 +36,10 @@ type FightC struct { closefight bool } +func (f *FightC) CanEscape() bool { + + return f.Info.Status != info.BattleStatus.FIGHT_WITH_PLAYER +} func (f *FightC) Ownerid() uint32 { return f.ownerID @@ -260,7 +264,7 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S attacker.Exec(func(t input.Effect) bool { //计算命中 miss改命中 t.Skill_Hit(input.Ctx{ //计算变威力 - Input: attacker, + Input: defender, SelectSkillAction: a, }) //相当于先调整基础命中,不光调整命中,这里还能调整技能属性,暴击率 @@ -295,9 +299,10 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S if attacker.AttackValue.IsCritical == 1 { //暴击破防 - if a.SkillEntity.Category() == info.Category.PHYSICAL { + if a.SkillEntity.Category() == info.Category.PHYSICAL && defender.Prop[1] > 0 { + defender.Prop[1] = 0 - } else if a.SkillEntity.Category() == info.Category.SPECIAL { + } else if a.SkillEntity.Category() == info.Category.SPECIAL && defender.Prop[3] > 0 { defender.Prop[3] = 0 } @@ -565,11 +570,13 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { t := f.First.GetEffect(input.EffectType.Status, i) if t != nil { //状态都是叠层类的 - ret.FAttack.Status[i] = int8(t.Duration()) + + ret.FAttack.Status[i] = int8(t.Duration()) + 1 + } t = f.Second.GetEffect(input.EffectType.Status, i) if t != nil { - ret.SAttack.Status[i] = int8(t.Duration()) + ret.SAttack.Status[i] = int8(t.Duration()) + 1 } } diff --git a/logic/service/fight/input/fight.go b/logic/service/fight/input/fight.go index f8638e972..d70806773 100644 --- a/logic/service/fight/input/fight.go +++ b/logic/service/fight/input/fight.go @@ -311,7 +311,7 @@ func (i *Input) CalculatePower(deftype *Input, skill *info.SkillEntity) decimal. Add(decimal.NewFromInt(2)) var typeRate decimal.Decimal - fmt.Println(skill.Type().ID, deftype.CurrentPet.Type().ID) + //fmt.Println(skill.Type().ID, deftype.CurrentPet.Type().ID) t, _ := element.NewElementCalculator().GetOffensiveMultiplier(skill.Type().ID, deftype.CurrentPet.Type().ID) typeRate = decimal.NewFromFloat(t) diff --git a/logic/service/fight/input/input.go b/logic/service/fight/input/input.go index 6de2d6e0c..decd678c9 100644 --- a/logic/service/fight/input/input.go +++ b/logic/service/fight/input/input.go @@ -56,6 +56,7 @@ func (i *Input) GetPetInfo() *info.BattlePetEntity { } func (i *Input) ResetAttackValue() { i.AttackValue.SkillID = 0 + i.AttackValue.IsCritical = 0 } diff --git a/logic/service/fight/input/node.go b/logic/service/fight/input/node.go index f76f3d9c4..9b0089ef5 100644 --- a/logic/service/fight/input/node.go +++ b/logic/service/fight/input/node.go @@ -70,7 +70,7 @@ func (c *Input) GetProp(id int, istue bool) int { func (c *Input) GetEffect(etype EnumEffectType, id int) Effect { var ret []Effect for _, v := range c.Effects { - if v.ID() == id { + if v.ID() == id &&v.Alive(){ ret = append(ret, v) } diff --git a/logic/service/fight/playeraction.go b/logic/service/fight/playeraction.go index 9c2f60d8d..974fce65d 100644 --- a/logic/service/fight/playeraction.go +++ b/logic/service/fight/playeraction.go @@ -92,7 +92,6 @@ func (f *FightC) UseSkill(c common.PlayerI, id int32) { ret := &action.SelectSkillAction{ BaseAction: action.NewBaseAction(c.GetInfo().UserID), } - //ret.PetInfo = f.GetInputByPlayer(c, false).CurrentPet for _, v := range f.GetInputByPlayer(c, false).CurrentPet.Skills { diff --git a/logic/service/player/SocketHandler_Tomee.go b/logic/service/player/SocketHandler_Tomee.go index 0fa9fa864..7247c4263 100644 --- a/logic/service/player/SocketHandler_Tomee.go +++ b/logic/service/player/SocketHandler_Tomee.go @@ -5,6 +5,7 @@ import ( "blazing/common/utils/bytearray" "blazing/cool" "sync" + "time" "context" @@ -12,6 +13,7 @@ import ( "fmt" "reflect" + "github.com/bruceshao/lockfree" "github.com/gobwas/ws" "github.com/gobwas/ws/wsutil" "github.com/gogf/gf/v2/os/glog" @@ -205,19 +207,29 @@ type ClientData struct { Wsmsg *WsCodec Conn gnet.Conn SaveL sync.Once //保存锁 - SaveDone chan struct{} + LF *lockfree.Lockfree[[]byte] + //SaveDone chan struct{} } func NewClientData(c gnet.Conn) *ClientData { // 创建事件处理器 + // 创建消费端串行处理的Lockfree - cd := ClientData{ + cd := &ClientData{ - Player: nil, - Conn: c, - Wsmsg: &WsCodec{}, + Conn: c, + Wsmsg: &WsCodec{}, } - return &cd + cd.LF = lockfree.NewLockfree[[]byte]( + 1024*1024, + cd, + lockfree.NewSleepBlockStrategy(time.Millisecond), + ) + // 启动Lockfree + if err := cd.LF.Start(); err != nil { + panic(err) + } + return cd } @@ -244,7 +256,14 @@ func XORDecrypt(encryptedData []byte, keyStr string) []byte { return decrypted } func (h *ClientData) OnEvent(v []byte) { + defer func() { + if err := recover(); err != nil { // 恢复 panic,err 为 panic 错误值 + // 1. 打印错误信息 + cool.Loger.Error(context.TODO(), "panic 错误:", err) + + } + }() header := TomeeHeader{} tempdata := bytearray.CreateByteArray(v) diff --git a/logic/service/player/fight.go b/logic/service/player/fight.go index 0470caa6a..fd44749a5 100644 --- a/logic/service/player/fight.go +++ b/logic/service/player/fight.go @@ -88,7 +88,7 @@ func (lw *Player) AgreeBattle(userid, flag uint32, mode info.EnumBattleMode) (bo return false, nil } if v.Info.UserID == userid && v.PVPinfo.Mode == mode { //成功找到,同意对战 - if lw.CanFight() { + if lw.CanFight() &&v.CanFight(){ ret.Result = 1 v.SendPack(t1.Pack(ret)) diff --git a/login/main.go b/login/main.go index 4d1628395..326b4a4ba 100644 --- a/login/main.go +++ b/login/main.go @@ -1,14 +1,9 @@ package main import ( - "fmt" - "reflect" - "strings" - _ "github.com/gogf/gf/contrib/nosql/redis/v2" _ "blazing/contrib/drivers/pgsql" - "blazing/modules/base/service" _ "blazing/contrib/files/local" @@ -27,11 +22,10 @@ import ( "blazing/login/internal/cmd" "github.com/gogf/gf/v2/os/gctx" - "github.com/gogf/gf/v2/util/gconv" ) func main() { - service.TestSendVerificationCode() + //service.TestSendVerificationCode() cmd.Main.Run(gctx.New()) } @@ -47,23 +41,3 @@ func kick(id int) { // fmt.Println(err) // }() } - -type ssss struct { - ttt int `cmd:"111|222"` -} - -func Test_kick() { - value := reflect.ValueOf(ssss{}) - - // 获取类型 - typ := value.Type() - // 遍历结构体字段 - // fmt.Printf("结构体 %s 的字段信息:\n", t.Name()) - for i := 0; i < typ.NumField(); i++ { - field := typ.Field(i) - t := field.Tag.Get("cmd") - //t1 := strings.Split(t, "|") - t2 := gconv.SliceUint32(strings.Split(t, "|")) - fmt.Println(t2) - } -}