Files
bl/logic/service/player/fight.go
昔念 6979b7018d ```
feat(space): 替换并发安全map实现以提升性能

将原来基于`utils.ConcurrentMap`的玩家存储结构替换为
`github.com/mhmtszr/concurrent-swiss-map`提供的`CsMap`,
以获得更高效的并发读写能力。

同时修改了相关API调用方式:
- `Set` 改为 `Store`
- `Remove` 改为 `Delete`
- `IterCb` 改为 `Range`,并支持提前终止迭代
- `Items()` 不再使用

此外,调整了部分业务逻辑中对玩家列表遍历的方式,
确保在发送网络包后及时跳出循环,避免不必要的操作。

新增战斗类型处理函数`PET_King`用于处理宠物王相关的
战斗请求,并修复了`PET_MELEE`方法中的逻辑问题。

更新了go.mod和go.sum引入新的依赖库。
```
2025-11-15 15:22:58 +08:00

140 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package player
import (
"blazing/logic/service/common"
"blazing/logic/service/fight/info"
"blazing/logic/service/space"
)
// 邀请玩家加入战斗 邀请者,被邀请者,邀请模式
func (lw *Player) InvitePlayerToBattle() {
pinfo := lw.PVPinfo
space.GetSpace(lw.Info.MapID).User.Range(func(key uint32, v common.PlayerI) bool {
value := v.(*Player)
if key == uint32(pinfo.PlayerID) { //说明这里是针对玩家邀请的
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
})
}
func (p *Player) Pet_joinFight() *Player {
var lw *Player
//pinfo := lw.PVPinfo
space.GetSpace(p.Info.MapID).User.Range(func(key uint32, v common.PlayerI) bool {
value := v.(*Player)
if value.PVPinfo != nil && value != p {
//确认是乱斗模式
if *value.PVPinfo == *p.PVPinfo {
p.PVPinfo = nil //先将自身的准备信息置空
value.PVPinfo = nil
lw = value
return true
}
}
return false
})
return lw
}
func (p *Player) SendLoadPercent(b info.LoadPercentOutboundInfo) {
t1 := NewTomeeHeader(2441, p.Info.UserID)
p.SendPack(t1.Pack(&b)) //准备包由各自发,因为协议不一样
}
// 同意对战
// AgreeBattle 处理战斗邀请响应(同意/拒绝)
// 参数:
//
// userid邀请者ID
// flag0-拒绝1-同意
// mode战斗模式
//
// 返回:
//
// bool是否成功仅同意且符合条件时为true
// common.PlayerI对应的邀请者玩家成功时有效
func (lw *Player) AgreeBattle(userid, flag uint32, mode info.EnumBattleMode) (bool, common.PlayerI) {
// 处理完毕后清空收到的邀请列表原defer逻辑保留
defer func() {
lw.HavePVPinfo = make([]*Player, 0)
}()
// 遍历收到的邀请,寻找目标邀请者
var inviter *Player
for _, p := range lw.HavePVPinfo {
if p == nil || p.Info.UserID != userid {
continue // 跳过空指针或非目标邀请者
}
inviter = p
break // 找到目标后退出循环
}
// 未找到对应的邀请者(如邀请已过期、不存在)
if inviter == nil {
return false, nil
}
// 构建响应消息(统一创建,避免重复代码)
respHeader := NewTomeeHeader(2502, inviter.Info.UserID)
resp := &info.S2C_NOTE_HANDLE_FIGHT_INVITE{
UserID: lw.Info.UserID,
Nick: lw.Info.Nick,
}
// 检查邀请者的邀请是否有效(对方已取消邀请)
if inviter.PVPinfo == nil {
resp.Result = 4 // 邀请已取消
inviter.SendPack(respHeader.Pack(resp))
return false, nil
}
// 检查战斗模式是否匹配
if inviter.PVPinfo.Mode != mode {
return false, nil // 模式不匹配,不响应(或根据业务加错误码)
}
// 处理拒绝逻辑
if flag == 0 {
resp.Result = 0 // 拒绝邀请
inviter.SendPack(respHeader.Pack(resp))
return false, nil
}
// 处理同意逻辑:检查自身状态
if !lw.IsLogin {
resp.Result = 4 // 玩家未登录(复用原错误码)
inviter.SendPack(respHeader.Pack(resp))
return false, nil
}
// 检查双方是否可战斗
if !lw.CanFight() || !inviter.CanFight() {
resp.Result = 3 // 不可战斗(如正在战斗中)
inviter.SendPack(respHeader.Pack(resp))
return false, nil
}
// 所有条件满足,同意战斗
resp.Result = 1 // 成功同意
inviter.SendPack(respHeader.Pack(resp))
return true, inviter
}