From 6831861e0d842f898128c93f4f25a3ce10ddade6 Mon Sep 17 00:00:00 2001 From: 1 <1@72wo.cn> Date: Tue, 18 Nov 2025 22:16:55 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=A9=BA=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logic/controller/fight_boss.go | 4 +-- logic/controller/fight_leitai.go | 15 ++++++--- logic/controller/fight_pvp_king.go | 8 ++--- logic/controller/fight_pvp_withplayer.go | 6 ++-- logic/controller/map.go | 12 ++------ logic/service/common/playeri.go | 4 +-- logic/service/fight/info/info.go | 2 +- logic/service/fight/input.go | 6 ++-- logic/service/fight/loop.go | 2 ++ logic/service/player/ai.go | 4 +-- logic/service/player/base.go | 12 ++++++-- logic/service/player/fight.go | 12 ++++---- logic/service/player/player.go | 39 +++++++++++++++--------- logic/service/space/in_out.go | 15 ++++++--- logic/service/space/space.go | 18 +++++------ 15 files changed, 92 insertions(+), 67 deletions(-) diff --git a/logic/controller/fight_boss.go b/logic/controller/fight_boss.go index de8e9c818..1fb129087 100644 --- a/logic/controller/fight_boss.go +++ b/logic/controller/fight_boss.go @@ -94,7 +94,7 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla } } - c.PVPinfo = &info.PVPinfo{ + c.Fightinfo = &info.Fightinfo{ Status: info.BattleStatus.FIGHT_WITH_BOSS, Mode: info.BattleMode.MULTI_MODE, @@ -134,7 +134,7 @@ func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundIn moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName moinfo.PetList = append(moinfo.PetList, *mo) ai := player.NewAI_player(moinfo) - c.PVPinfo = &info.PVPinfo{ + c.Fightinfo = &info.Fightinfo{ Mode: info.BattleMode.MULTI_MODE, Status: info.BattleStatus.FIGHT_WITH_NPC, } diff --git a/logic/controller/fight_leitai.go b/logic/controller/fight_leitai.go index b545d33f1..80eec42c7 100644 --- a/logic/controller/fight_leitai.go +++ b/logic/controller/fight_leitai.go @@ -3,6 +3,7 @@ package controller import ( "blazing/common/socket/errorcode" + "blazing/logic/service/common" "blazing/logic/service/fight" "blazing/logic/service/fight/info" "blazing/logic/service/player" @@ -33,17 +34,21 @@ func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.P return nil, errorcode.ErrorCodes.ErrPokemonNotEligible } - t := space.GetSpace(c.Info.MapID).Can_ARENA(c) - if t != nil { - t.(*player.Player).PVPinfo = &info.PVPinfo{ + space.GetSpace(c.Info.MapID).Can_ARENA(func(ownerID common.PlayerI) common.PlayerI { + c.Fightinfo = &info.Fightinfo{ Mode: info.BattleMode.SINGLE_MODE, Status: info.BattleStatus.FIGHT_WITH_PLAYER, } - fight.NewFight(t, c, func(foi *info.FightOverInfo) { + _, fighterr := fight.NewFight(c, ownerID, func(foi *info.FightOverInfo) { //我方邀请擂主挑战,我方先手 }) ///开始对战,房主方以及被邀请方 - } + if fighterr != nil { + return nil + } + return c + }) + return } diff --git a/logic/controller/fight_pvp_king.go b/logic/controller/fight_pvp_king.go index 4c13d6d0c..7ed71d8b0 100644 --- a/logic/controller/fight_pvp_king.go +++ b/logic/controller/fight_pvp_king.go @@ -15,7 +15,7 @@ func (h Controller) PET_MELEE(data *fight.StartPetWarInboundInfo, c *player.Play return nil, errorcode.ErrorCodes.ErrPokemonNotEligible } - c.PVPinfo = &info.PVPinfo{ + c.Fightinfo = &info.Fightinfo{ Mode: info.BattleMode.PET_MELEE, Status: info.BattleStatus.FIGHT_WITH_PLAYER} g := c.Pet_joinFight() @@ -33,15 +33,15 @@ func (h Controller) PET_King(data *fight.PetKingJoinInboundInfo, c *player.Playe return nil, errorcode.ErrorCodes.ErrPokemonNotEligible } - c.PVPinfo = &info.PVPinfo{ + c.Fightinfo = &info.Fightinfo{ Status: info.BattleStatus.FIGHT_WITH_PLAYER} switch data.Type { case 5: - c.PVPinfo.Mode = info.BattleMode.SINGLE_MODE + c.Fightinfo.Mode = info.BattleMode.SINGLE_MODE case 6: - c.PVPinfo.Mode = info.BattleMode.MULTI_MODE + c.Fightinfo.Mode = info.BattleMode.MULTI_MODE } g := c.Pet_joinFight() if g != nil { diff --git a/logic/controller/fight_pvp_withplayer.go b/logic/controller/fight_pvp_withplayer.go index 4b9fe6978..ebe5f8b05 100644 --- a/logic/controller/fight_pvp_withplayer.go +++ b/logic/controller/fight_pvp_withplayer.go @@ -2,6 +2,8 @@ package controller import ( "blazing/common/socket/errorcode" + "sync/atomic" + "unsafe" "blazing/logic/service/fight" "blazing/logic/service/fight/info" @@ -31,7 +33,7 @@ func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInf //进入邀请,以及确认对战模式 - c.PVPinfo = &info.PVPinfo{PlayerID: data.UserID, + c.Fightinfo = &info.Fightinfo{PlayerID: data.UserID, Mode: data.Mode, Status: info.BattleStatus.FIGHT_WITH_PLAYER} @@ -42,7 +44,7 @@ func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInf // 取消和他人战斗 func (h Controller) OnPlayerCanceledOtherInviteFight(data *fight.InviteFightCancelInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - c.PVPinfo = nil + atomic.StorePointer(unsafe.Pointer(c.Fightinfo), nil) return nil, 0 } diff --git a/logic/controller/map.go b/logic/controller/map.go index 0cacef865..9ef7646a7 100644 --- a/logic/controller/map.go +++ b/logic/controller/map.go @@ -10,11 +10,8 @@ import ( "blazing/logic/service/space" "github.com/jinzhu/copier" - "github.com/panjf2000/ants/v2" ) -var mappool, _ = ants.NewPool(-1) - func (h *Controller) MapEnter(data *maps.InInfo, c *player.Player) (result *info.OutInfo, err errorcode.ErrorCode) { //这个时候player应该是空的 c.Info.MapID = data.MapId //登录地图 @@ -23,10 +20,8 @@ func (h *Controller) MapEnter(data *maps.InInfo, c *player.Player) (result *info result = info.NewOutInfo() c.Info.Pos = data.Point copier.Copy(result, c.Info) - mappool.Submit(func() { - c.GetSpace().EnterMap(c) - }) + defer c.GetSpace().EnterMap(c) return result, 0 } func (h Controller) MapHot(data *maphot.InInfo, c *player.Player) (result *maphot.OutInfo, err errorcode.ErrorCode) { @@ -43,9 +38,8 @@ func (h *Controller) MapLeave(data *maps.LeaveMapInboundInfo, c *player.Player) c.Canmon = false c.Changemap = true //可以刷怪 //data.Broadcast(c.Info.MapID, info.LeaveMapOutboundInfo{UserID: c.Info.UserID}) //同步广播 - mappool.Submit(func() { - c.GetSpace().LeaveMap(c) //玩家离开地图 - }) + + defer c.GetSpace().LeaveMap(c) //玩家离开地图 // 如果有正在运行的刷怪协程,发送停止信号 diff --git a/logic/service/common/playeri.go b/logic/service/common/playeri.go index ed41c1cd8..76d5c54b0 100644 --- a/logic/service/common/playeri.go +++ b/logic/service/common/playeri.go @@ -9,11 +9,11 @@ type PlayerI interface { GetPlayerCaptureContext() *info.PlayerCaptureContext Roll(int, int) (bool, float64, float64) //SendPack(b []byte) error - Getfightinfo() info.PVPinfo + Getfightinfo() info.Fightinfo GetInfo() *model.PlayerInfo SetFightC(FightI) - + QuitFight() SendPackCmd(cmd uint32, b any) } diff --git a/logic/service/fight/info/info.go b/logic/service/fight/info/info.go index 5c701b0ab..882cc1e3b 100644 --- a/logic/service/fight/info/info.go +++ b/logic/service/fight/info/info.go @@ -43,7 +43,7 @@ type S2C_NOTE_HANDLE_FIGHT_INVITE struct { // 4=对方不在线 Result uint32 } -type PVPinfo struct { +type Fightinfo struct { PlayerID uint32 Mode EnumBattleMode Status EnumBattleMode diff --git a/logic/service/fight/input.go b/logic/service/fight/input.go index fc487186d..c78c720fc 100644 --- a/logic/service/fight/input.go +++ b/logic/service/fight/input.go @@ -18,7 +18,7 @@ import ( type FightC struct { ReadyInfo info.NoteReadyToFightInfo - Info info.PVPinfo + Info info.Fightinfo IsReady bool ownerID uint32 // 战斗发起者ID Our *input.Input //始终等于房主ID @@ -195,7 +195,7 @@ func NewFight(p1, p2 common.PlayerI, fn func(*info.FightOverInfo)) (*FightC, err f.Info = p1.Getfightinfo() //这里应该挪到玩家初始化执行 - p1.(*player.Player).PVPinfo = nil //清空战斗消息 + p1.(*player.Player).Fightinfo = nil //清空战斗消息 f.ReadyInfo.Mode = f.Info.Mode @@ -235,7 +235,7 @@ func NewFight(p1, p2 common.PlayerI, fn func(*info.FightOverInfo)) (*FightC, err //todo 将血量和技能pp传回enterturn ff.Player.SendPackCmd(2506, f.FightOverInfo) - + ff.Player.QuitFight() }) } diff --git a/logic/service/fight/loop.go b/logic/service/fight/loop.go index 72a846f2c..452c1c2e1 100644 --- a/logic/service/fight/loop.go +++ b/logic/service/fight/loop.go @@ -65,6 +65,8 @@ func (f *FightC) battleLoop() { } ff.Player.SendPackCmd(2506, f.FightOverInfo) + ff.Player.QuitFight() + //待退出玩家战斗状态 }) diff --git a/logic/service/player/ai.go b/logic/service/player/ai.go index 348356650..fb585e2e2 100644 --- a/logic/service/player/ai.go +++ b/logic/service/player/ai.go @@ -12,8 +12,8 @@ type AI_player struct { CanCapture bool } -func (p *AI_player) Getfightinfo() info.PVPinfo { - return info.PVPinfo{} +func (p *AI_player) Getfightinfo() info.Fightinfo { + return info.Fightinfo{} } func (f *AI_player) SendPack(b []byte) error { return nil diff --git a/logic/service/player/base.go b/logic/service/player/base.go index 353942b9c..1ec928d1e 100644 --- a/logic/service/player/base.go +++ b/logic/service/player/base.go @@ -5,12 +5,14 @@ import ( "blazing/logic/service/fight/info" "blazing/modules/blazing/model" "math/rand" + "sync/atomic" "time" ) type baseplayer struct { - Info *model.PlayerInfo - FightC common.FightI //绑定战斗标识 替代本身的是否战斗标记 //IsFighting bool + Info *model.PlayerInfo + canFight uint32 + FightC common.FightI //绑定战斗标识 替代本身的是否战斗标记 //IsFighting bool *info.PlayerCaptureContext } @@ -32,9 +34,13 @@ func (p *baseplayer) GetInfo() *model.PlayerInfo { return p.Info } func (f *baseplayer) SetFightC(ff common.FightI) { + f.FightC = ff } - +func (f *baseplayer) QuitFight() { + //将战斗标记设置为0 这里的标记是 + atomic.StoreUint32(&f.canFight, 0) +} func (f *baseplayer) GetPlayerCaptureContext() *info.PlayerCaptureContext { return f.PlayerCaptureContext } diff --git a/logic/service/player/fight.go b/logic/service/player/fight.go index f51a63ae5..11ddd7cec 100644 --- a/logic/service/player/fight.go +++ b/logic/service/player/fight.go @@ -10,7 +10,7 @@ import ( // 邀请玩家加入战斗 邀请者,被邀请者,邀请模式 func (lw *Player) InvitePlayerToBattle() { - pinfo := lw.PVPinfo + pinfo := lw.Fightinfo space.GetSpace(lw.Info.MapID).User.Range(func(key uint32, v common.PlayerI) bool { value := v.(*Player) @@ -37,11 +37,11 @@ func (p *Player) Pet_joinFight() *Player { value := v.(*Player) - if value.PVPinfo != nil && value != p { + if value.Fightinfo != nil && value != p { //确认是乱斗模式 - if *value.PVPinfo == *p.PVPinfo { - p.PVPinfo = nil //先将自身的准备信息置空 + if *value.Fightinfo == *p.Fightinfo { + p.Fightinfo = nil //先将自身的准备信息置空 //value.PVPinfo = nil lw = value return true @@ -100,14 +100,14 @@ func (lw *Player) AgreeBattle(userid, flag uint32, mode info.EnumBattleMode) (bo } // 检查邀请者的邀请是否有效(对方已取消邀请) - if inviter.PVPinfo == nil { + if inviter.Fightinfo == nil { resp.Result = 4 // 邀请已取消 inviter.SendPack(respHeader.Pack(resp)) return false, nil } // 检查战斗模式是否匹配 - if inviter.PVPinfo.Mode != mode { + if inviter.Fightinfo.Mode != mode { return false, nil // 模式不匹配,不响应(或根据业务加错误码) } diff --git a/logic/service/player/player.go b/logic/service/player/player.go index 99cf54f89..aef3e374b 100644 --- a/logic/service/player/player.go +++ b/logic/service/player/player.go @@ -9,6 +9,7 @@ import ( "blazing/logic/service/space" "math/rand" "strings" + "sync/atomic" "blazing/modules/blazing/model" blservice "blazing/modules/blazing/service" @@ -52,8 +53,9 @@ type Player struct { StopChan timer.TimeNoder context.Context - PVPinfo *info.PVPinfo //当前邀请的玩家ID - Logintime uint32 //当前登录时间 + Fightinfo *info.Fightinfo //当前邀请的玩家ID + + Logintime uint32 //当前登录时间 OgreInfo OgreInfo Service *blservice.UserService @@ -84,27 +86,36 @@ func (p *Player) UseCoins(t uint32) bool { func (p *Player) GetAction() { } -func (p *Player) Getfightinfo() info.PVPinfo { - return *p.PVPinfo +func (p *Player) Getfightinfo() info.Fightinfo { + return *p.Fightinfo } func (p *Player) GetSpace() *space.Space { return space.GetSpace(p.Info.MapID) } func (p *Player) CanFight() bool { - if p.FightC != nil { - return false - } - if p.GetSpace().ARENA.ChallengerID == p.Info.UserID || p.GetSpace().ARENA.Id == p.Info.UserID { + if atomic.CompareAndSwapUint32(&p.canFight, 0, 1) { //先判断是否竞态条件被挑战 + + //成功,继续判断 + + if p.FightC != nil { + return false + + } + // if p.GetSpace().ARENA.ChallengerID == p.Info.UserID || p.GetSpace().ARENA.Id == p.Info.UserID { + // return false + // } + for _, v := range p.Info.PetList { + if v.Hp > 0 { // 只要找到一个血量大于0的宠物,就可以战斗 + return true + } + } + // 遍历完所有宠物,都没有血量大于0的,才不能战斗 + return false } - for _, v := range p.Info.PetList { - if v.Hp > 0 { // 只要找到一个血量大于0的宠物,就可以战斗 - return true - } - } - // 遍历完所有宠物,都没有血量大于0的,才不能战斗 + return false } diff --git a/logic/service/space/in_out.go b/logic/service/space/in_out.go index 0e0029568..d29804db7 100644 --- a/logic/service/space/in_out.go +++ b/logic/service/space/in_out.go @@ -7,19 +7,24 @@ import ( "sync/atomic" "github.com/jinzhu/copier" + "github.com/panjf2000/ants/v2" "golang.org/x/time/rate" ) +var mappool, _ = ants.NewPool(-1) + // 向其他人广播,不含自己 func (s *Space) Broadcast(c common.PlayerI, cmd uint32, data any) { + mappool.Submit(func() { - go s.User.Range(func(k uint32, v common.PlayerI) (stop bool) { + s.User.Range(func(k uint32, v common.PlayerI) (stop bool) { - if k != c.GetInfo().UserID { - v.SendPackCmd(cmd, data) + if k != c.GetInfo().UserID { + v.SendPackCmd(cmd, data) - } - return false + } + return false + }) }) } diff --git a/logic/service/space/space.go b/logic/service/space/space.go index fae4a7a92..25bb6b8f4 100644 --- a/logic/service/space/space.go +++ b/logic/service/space/space.go @@ -3,6 +3,7 @@ package space import ( "blazing/common/data/xmlres" "blazing/common/utils" + "sync/atomic" "blazing/logic/service/common" "blazing/logic/service/fight/info" @@ -22,19 +23,18 @@ type Space struct { Name string //地图名称 ARENA info.S2C_ARENA_GET_INFO ARENA_Player common.PlayerI - // DefaultPos model.Pos //默认位置DefaultPos - - //Positions map[uint32]model.Pos //从上一个地图跳转后默认位置 无任何写操作 } -func (s *Space) Can_ARENA(c common.PlayerI) common.PlayerI { +func (s *Space) Can_ARENA(tt func(c common.PlayerI) common.PlayerI) { + + //原子操作,修改擂台状态 + if atomic.CompareAndSwapUint32(&s.ARENA.Flag, 1, 2) { + r := tt(s.ARENA_Player) + if r != nil { + atomic.SwapUint32(&s.ARENA.ChallengerID, r.GetInfo().UserID) //传回的指针赋值给ID + } - if s.ARENA.Flag == 1 { - s.ARENA.Flag = 2 - s.ARENA.ChallengerID = c.GetInfo().UserID - return s.ARENA_Player } - return nil }