From 24f2a6d7c89b438304d682642dff852c1b72959b Mon Sep 17 00:00:00 2001 From: 1 <1@72wo.cn> Date: Tue, 18 Nov 2025 23:41:31 +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 --- common/socket/errorcode/error.go | 2 +- logic/controller/fight_base.go | 4 ++-- logic/controller/fight_leitai.go | 2 +- logic/controller/fight_pvp_withplayer.go | 30 ++++++++++++++---------- logic/service/common/playeri.go | 2 +- logic/service/fight/cmd.go | 4 ++-- logic/service/fight/info/battle.go | 9 +------ logic/service/fight/info/info.go | 16 ++++++------- logic/service/player/base.go | 2 ++ logic/service/player/fight.go | 29 +++++++++++------------ logic/service/player/new.go | 3 ++- logic/service/player/player.go | 12 +++++++--- logic/service/space/arena.go | 9 +++++++ logic/service/space/space.go | 2 +- 14 files changed, 71 insertions(+), 55 deletions(-) create mode 100644 logic/service/space/arena.go diff --git a/common/socket/errorcode/error.go b/common/socket/errorcode/error.go index dcbc81141..c2ffc8e0c 100644 --- a/common/socket/errorcode/error.go +++ b/common/socket/errorcode/error.go @@ -492,8 +492,8 @@ var ErrorCodes = enum.New[struct { // 你的电池能量已经无法支持保卫战所需的模拟呈现功能,请明天蓄满电池后再来参加保卫战! ErrBatteryLowForDefense ErrorCode `enum:"18030"` // 正在精灵对战中 - ErrInBattle ErrorCode `enum:"11024"` // 你们战队还没有报名参加对抗赛 + ErrInBattle ErrorCode `enum:"11024"` ErrTeamNotRegistered ErrorCode `enum:"18221"` // 你的战队的其他成员已经报名参加保卫战,请耐心等待比赛集合令提示。 ErrTeammateRegistered ErrorCode `enum:"18222"` diff --git a/logic/controller/fight_base.go b/logic/controller/fight_base.go index af5b35315..419804d59 100644 --- a/logic/controller/fight_base.go +++ b/logic/controller/fight_base.go @@ -30,9 +30,9 @@ func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *player.Player) return nil, 0 } - if !c.FightC.CanEscape() { + if !c.FightC.CanEscape() { //用户对战不能逃跑 - return nil, 0 + return nil, errorcode.ErrorCodes.ErrCannotFleePlayerBattle } c.FightC.Over(c, info.BattleOverReason.PlayerEscape) return nil, 0 diff --git a/logic/controller/fight_leitai.go b/logic/controller/fight_leitai.go index 80eec42c7..710a6daa1 100644 --- a/logic/controller/fight_leitai.go +++ b/logic/controller/fight_leitai.go @@ -55,7 +55,7 @@ func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.P // 获取星际擂台信息的包 进入空间站地图前端会发送请求包 或者 有人站到星际擂台上后 广播回包 // 前端到后端无数据内容 // 后端到前端 -func (h Controller) ARENA_GET_INFO(data *fight.ARENA_GET_INFO, c *player.Player) (result *info.S2C_ARENA_GET_INFO, err errorcode.ErrorCode) { +func (h Controller) ARENA_GET_INFO(data *fight.ARENA_GET_INFO, c *player.Player) (result *space.S2C_ARENA_GET_INFO, err errorcode.ErrorCode) { result = &space.GetSpace(c.Info.MapID).ARENA return diff --git a/logic/controller/fight_pvp_withplayer.go b/logic/controller/fight_pvp_withplayer.go index ebe5f8b05..659112d29 100644 --- a/logic/controller/fight_pvp_withplayer.go +++ b/logic/controller/fight_pvp_withplayer.go @@ -3,7 +3,6 @@ package controller import ( "blazing/common/socket/errorcode" "sync/atomic" - "unsafe" "blazing/logic/service/fight" "blazing/logic/service/fight/info" @@ -13,8 +12,12 @@ import ( // 接收战斗或者取消战斗的包 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 !c.CanFight() { + // return nil, errorcode.ErrorCodes.ErrPokemonNotEligible + // } + if !atomic.CompareAndSwapUint32(&c.Fightinfo.Status, 0, 1) { //邀请前提是自己没在战斗 + return nil, errorcode.ErrorCodes.ErrInBattle + } if ok, p1 := c.AgreeBattle(data.UserID, data.Flag, data.Mode); ok { @@ -27,24 +30,27 @@ func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInbou // 邀请其他人进行战斗 func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - if !c.CanFight() { - return nil, errorcode.ErrorCodes.ErrPokemonNotEligible - } //进入邀请,以及确认对战模式 - c.Fightinfo = &info.Fightinfo{PlayerID: data.UserID, - Mode: data.Mode, - Status: info.BattleStatus.FIGHT_WITH_PLAYER} + if !atomic.CompareAndSwapUint32(&c.Fightinfo.PlayerID, 0, data.UserID) { //邀请前提是自己没邀请别人 + return nil, errorcode.ErrorCodes.ErrCannotPerformAction + + } + c.Fightinfo.Mode = data.Mode c.InvitePlayerToBattle() return nil, 0 } -// 取消和他人战斗 +// 取消队列 func (h Controller) OnPlayerCanceledOtherInviteFight(data *fight.InviteFightCancelInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - atomic.StorePointer(unsafe.Pointer(c.Fightinfo), nil) - return nil, 0 + if atomic.LoadUint32(&c.Fightinfo.Status) != 0 { //如果没有战斗状态,则不做任何处理 + atomic.StoreUint32(&c.Fightinfo.Status, 0) //设置状态为0 + + } + //否则报错 + return nil, errorcode.ErrorCodes.ErrCannotCancelBattle } diff --git a/logic/service/common/playeri.go b/logic/service/common/playeri.go index 76d5c54b0..65f86cf98 100644 --- a/logic/service/common/playeri.go +++ b/logic/service/common/playeri.go @@ -12,7 +12,7 @@ type PlayerI interface { Getfightinfo() info.Fightinfo GetInfo() *model.PlayerInfo - + InvitePlayer(PlayerI) SetFightC(FightI) QuitFight() SendPackCmd(cmd uint32, b any) diff --git a/logic/service/fight/cmd.go b/logic/service/fight/cmd.go index 6cf67db03..2c1b173c0 100644 --- a/logic/service/fight/cmd.go +++ b/logic/service/fight/cmd.go @@ -73,10 +73,10 @@ type HandleFightInviteInboundInfo struct { type InviteToFightInboundInfo struct { Head player.TomeeHeader `cmd:"2401" struc:"[0]pad"` - UserID uint32 `codec:"true"` + UserID uint32 // Mode 战斗类型 1 = 1v1 2 = 6v6 - Mode info.EnumBattleMode `codec:"true"` + Mode info.EnumBattleMode } type InviteFightCancelInboundInfo struct { Head player.TomeeHeader `cmd:"2402" struc:"[0]pad"` diff --git a/logic/service/fight/info/battle.go b/logic/service/fight/info/battle.go index 602584b10..c051b9ca1 100644 --- a/logic/service/fight/info/battle.go +++ b/logic/service/fight/info/battle.go @@ -30,14 +30,7 @@ var BattleMode = enum.New[struct { SINGLE_MODE EnumBattleMode `enum:"1"` // 单人模式 MULTI_MODE EnumBattleMode `enum:"2"` // 多人模式 }]() -var BattleStatus = enum.New[struct { - // 原ActionScript中的常量映射 - - FIGHT_WITH_NPC EnumBattleMode `enum:"3"` // 与NPC战斗 - FIGHT_WITH_BOSS EnumBattleMode `enum:"2"` // 与BOSS战斗 - FIGHT_WITH_PLAYER EnumBattleMode `enum:"1"` // 与玩家战斗(PVP) - -}]() + // 玩家离线数据 type PlayerOfflineData struct { diff --git a/logic/service/fight/info/info.go b/logic/service/fight/info/info.go index 882cc1e3b..a85fa4be9 100644 --- a/logic/service/fight/info/info.go +++ b/logic/service/fight/info/info.go @@ -46,7 +46,13 @@ type S2C_NOTE_HANDLE_FIGHT_INVITE struct { type Fightinfo struct { PlayerID uint32 Mode EnumBattleMode - Status EnumBattleMode + // // FIGHT_WITH_NPC EnumBattleMode `enum:"3"` // 与NPC战斗 + // FIGHT_WITH_BOSS EnumBattleMode `enum:"2"` // 与BOSS战斗 + // FIGHT_WITH_PLAYER EnumBattleMode `enum:"1"` // 与玩家战斗(PVP) + // NULL EnumBattleMode `enum:"0"` // 与玩家战斗(PVP) + + //0无战斗,1PVP,2,BOOS,3PVE + Status uint32 } // FightPetInfo 战斗精灵信息结构体,FightPetInfo类 @@ -177,13 +183,7 @@ type NoteUseSkillOutboundInfo struct { FirstAttackInfo AttackValue // 本轮先手的精灵在释放技能结束后的状态 SecondAttackInfo AttackValue // 本轮后手的精灵在释放技能结束后的状态 } -type S2C_ARENA_GET_INFO struct { - Flag uint32 // 0=清除ArenaInfo(flag为0时其他字段全为空) 1=站上擂台的信息 2=挑战中的信息 - Id uint32 - Nick string `struc:"[16]byte"` - HostWins uint32 // 应该是擂台人的连胜数 - ChallengerID uint32 // 挑战者的userid -} + type FightStartOutboundInfo struct { // @UInt long类型 IsCanAuto uint32 `fieldDesc:"是否自动 默认给0 怀疑是自动战斗器使用的" ` diff --git a/logic/service/player/base.go b/logic/service/player/base.go index 1ec928d1e..742330b27 100644 --- a/logic/service/player/base.go +++ b/logic/service/player/base.go @@ -37,6 +37,8 @@ func (f *baseplayer) SetFightC(ff common.FightI) { f.FightC = ff } + + func (f *baseplayer) QuitFight() { //将战斗标记设置为0 这里的标记是 atomic.StoreUint32(&f.canFight, 0) diff --git a/logic/service/player/fight.go b/logic/service/player/fight.go index 11ddd7cec..054afce69 100644 --- a/logic/service/player/fight.go +++ b/logic/service/player/fight.go @@ -3,27 +3,26 @@ package player import ( "blazing/logic/service/common" "blazing/logic/service/fight/info" + "sync/atomic" "blazing/logic/service/space" ) // 邀请玩家加入战斗 邀请者,被邀请者,邀请模式 -func (lw *Player) InvitePlayerToBattle() { +func (p *Player) InvitePlayerToBattle() { - pinfo := lw.Fightinfo - space.GetSpace(lw.Info.MapID).User.Range(func(key uint32, v common.PlayerI) bool { + p.GetSpace().User.Range(func(key uint32, v common.PlayerI) bool { - value := v.(*Player) - if key == uint32(pinfo.PlayerID) { //说明这里是针对玩家邀请的 + if key == atomic.LoadUint32(&p.Fightinfo.PlayerID) { //说明这里是针对玩家邀请的 + + v.InvitePlayer(p) + + v.SendPackCmd(2501, info.NoteInviteToFightOutboundInfo{ + UserID: p.Info.UserID, + Nick: p.Info.Nick, + Mode: p.Fightinfo.Mode, + }) - value.HavePVPinfo = append([]*Player{lw}, value.HavePVPinfo...) - t1 := NewTomeeHeader(2501, value.Info.UserID) - t := info.NoteInviteToFightOutboundInfo{ - UserID: lw.Info.UserID, - Nick: lw.Info.Nick, - Mode: pinfo.Mode, - } - value.SendPack(t1.Pack(&t)) return true } return false @@ -74,13 +73,13 @@ func (p *Player) SendLoadPercent(b info.LoadPercentOutboundInfo) { func (lw *Player) AgreeBattle(userid, flag uint32, mode info.EnumBattleMode) (bool, common.PlayerI) { // 处理完毕后清空收到的邀请列表(原defer逻辑保留) defer func() { - lw.HavePVPinfo = make([]*Player, 0) + lw.HavePVPinfo = make([]common.PlayerI, 0) }() // 遍历收到的邀请,寻找目标邀请者 var inviter *Player for _, p := range lw.HavePVPinfo { - if p == nil || p.Info.UserID != userid { + if p == nil || p.Getfightinfo().PlayerID != userid { continue // 跳过空指针或非目标邀请者 } inviter = p diff --git a/logic/service/player/new.go b/logic/service/player/new.go index 82e111a56..1e01cabf6 100644 --- a/logic/service/player/new.go +++ b/logic/service/player/new.go @@ -2,6 +2,7 @@ package player import ( "blazing/cool" + "blazing/logic/service/common" "blazing/modules/blazing/model" "time" ) @@ -10,7 +11,7 @@ import ( func NewPlayer(opts ...PlayerOption) *Player { p := &Player{ - HavePVPinfo: make([]*Player, 0), + HavePVPinfo: make([]common.PlayerI, 0), baseplayer: newbaseplayer(), } p.monsters = generateThreeUniqueNumbers() diff --git a/logic/service/player/player.go b/logic/service/player/player.go index aef3e374b..e6fbbd98f 100644 --- a/logic/service/player/player.go +++ b/logic/service/player/player.go @@ -5,6 +5,7 @@ import ( "blazing/common/socket/errorcode" "blazing/common/utils" "blazing/cool" + "blazing/logic/service/common" "blazing/logic/service/fight/info" "blazing/logic/service/space" "math/rand" @@ -53,14 +54,14 @@ type Player struct { StopChan timer.TimeNoder context.Context - Fightinfo *info.Fightinfo //当前邀请的玩家ID + Fightinfo info.Fightinfo //当前邀请的玩家ID Logintime uint32 //当前登录时间 OgreInfo OgreInfo Service *blservice.UserService // PVP被邀请信息 - HavePVPinfo []*Player + HavePVPinfo []common.PlayerI monsters [3]int Canmon bool //可以刷怪 Changemap bool //是否切换过地图 @@ -85,9 +86,14 @@ func (p *Player) UseCoins(t uint32) bool { } func (p *Player) GetAction() { +} + +func (f *Player) InvitePlayer(ff common.PlayerI) { + f.HavePVPinfo = append(f.HavePVPinfo, ff) + } func (p *Player) Getfightinfo() info.Fightinfo { - return *p.Fightinfo + return p.Fightinfo } func (p *Player) GetSpace() *space.Space { diff --git a/logic/service/space/arena.go b/logic/service/space/arena.go new file mode 100644 index 000000000..884ada686 --- /dev/null +++ b/logic/service/space/arena.go @@ -0,0 +1,9 @@ +package space + +type S2C_ARENA_GET_INFO struct { + Flag uint32 // 0=清除ArenaInfo(flag为0时其他字段全为空) 1=站上擂台的信息 2=挑战中的信息 + Id uint32 + Nick string `struc:"[16]byte"` + HostWins uint32 // 应该是擂台人的连胜数 + ChallengerID uint32 // 挑战者的userid +} diff --git a/logic/service/space/space.go b/logic/service/space/space.go index 25bb6b8f4..a5eaee9c0 100644 --- a/logic/service/space/space.go +++ b/logic/service/space/space.go @@ -21,7 +21,7 @@ type Space struct { SuperValue *int32 //ID uint32 // 地图ID Name string //地图名称 - ARENA info.S2C_ARENA_GET_INFO + ARENA S2C_ARENA_GET_INFO ARENA_Player common.PlayerI }