fix(fight): 修复战斗逻辑中的一些潜在问题

- 在 `fight_leitai.go` 中增加玩家是否可以战斗的判断,避免非法挑战
- 注释掉部分冗余的日志打印与广播调用,并调整了擂台状态更新逻辑
- 修正 `effect_62.go` 中镇魂歌效果持续时间的处理方式,引入独立计数器 `duy`
- 优化随机精灵生成逻辑,确保 CatchTime 正确设置
- 增加对数据库操作错误的 panic 处理,提高代码健壮性
- 调整部分结构体指针传递,统一返回结构体指针以避免拷贝问题
- 移除未使用的导入包和调试日志,清理无用代码
```
This commit is contained in:
2025-11-20 21:37:37 +08:00
parent 9f89f9f259
commit 105c6f5a23
11 changed files with 62 additions and 33 deletions

View File

@@ -77,11 +77,11 @@ func PackWithOptions(w io.Writer, data interface{}, options *Options) error {
val = val.Convert(reflect.TypeOf([]byte{}))
}
size := packer.Sizeof(val, options)
if size == 0 {
// if size == 0 {
fmt.Println("size==0")
// fmt.Println("size==0")
}
// }
buf := make([]byte, size)
if _, err := packer.Pack(buf, val, options); err != nil {
return err

View File

@@ -39,6 +39,9 @@ func (h Controller) ARENA_SET_OWENR(data *fight.ARENA_SET_OWENR, c *player.Playe
// 并不会通知对方是否接受挑战。只要有人挑战就直接进入对战
func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
if !c.CanFight() {
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
}
//原子操作,修改擂台状态
if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.Flag, 1, 2) {
//成功发起擂台挑战后才修改我放状态
@@ -51,14 +54,19 @@ func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.P
if err <= 0 { //发起战斗成功
atomic.StoreUint32(&c.GetSpace().Owner.ChallengerID, c.GetInfo().UserID) //传回的指针赋值给ID
c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner)
c.SendPackCmd(2419, &c.GetSpace().Owner)
//c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner)
//c.SendPackCmd(2419, &c.GetSpace().Owner)
} else {
//发起失败,改回1
c.GetSpace().Owner.HostWins = 0 //连胜重置
c.GetSpace().Owner.UserID = c.GetInfo().UserID //添加用户ID
c.GetSpace().Owner.Nick = c.GetInfo().Nick
c.GetSpace().ARENA_Player = c //添加用户
atomic.StoreUint32(&c.GetSpace().Owner.Flag, 1)
}
c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner)
c.SendPackCmd(2419, &c.GetSpace().Owner)
return
}
return nil, errorcode.ErrorCodes.ErrChampionExists

View File

@@ -118,14 +118,14 @@ func (h *Controller) PetRelease(
// 精灵展示
func (h *Controller) PlayerShowPet(
data *pet.PetShowInboundInfo, c *player.Player) (result *pet.PetShowOutboundInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
results := pet.PetShowOutboundInfo{}
result = &pet.PetShowOutboundInfo{}
for _, pi := range c.Info.PetList {
if pi.CatchTime == data.CatchTime {
copier.Copy(&results, pi)
results.Flag = data.Flag
results.UserID = data.Head.UserID
c.GetSpace().Broadcast(c, data.Head.CMD, results)
copier.Copy(&result, pi)
result.Flag = data.Flag
result.UserID = data.Head.UserID
c.GetSpace().Broadcast(c, data.Head.CMD, result)
}

View File

@@ -5,6 +5,7 @@ import (
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"fmt"
"math"
"github.com/shopspring/decimal"
)
@@ -21,6 +22,7 @@ type Effect62 struct {
}
type Effect62_sub struct {
node.EffectNode
duy int
//bindpet *info.BattlePetEntity
//bind *input.Input
@@ -28,18 +30,24 @@ type Effect62_sub struct {
}
func (e *Effect62_sub) Turn_End() {
e.duy--
}
// 这个实际上在对方回合执行的
func (e *Effect62_sub) OnSkill() bool {
fmt.Println("镇魂歌剩余回合", e.Duration())
fmt.Println("镇魂歌剩余回合", e.duy)
//defer e.Alive(false)
if e.Duration() == 0 { //说明对方没有切换精灵
if e.duy <= 0 { //说明对方没有切换精灵
//直接扣除所有血量OnSkill
//相当于对方给自己的伤害
e.Ctx().Our.Damage(e.Ctx().Opp, &info.DamageZone{
Type: info.DamageType.Fixed,
Damage: decimal.NewFromInt(int64(e.Ctx().Our.CurrentPet.Info.MaxHp)),
})
e.Alive(false)
}
return true
}
@@ -90,8 +98,9 @@ func (e *Effect62) OnSkill() bool {
// bindpet: ctx.CurrentPet,
// bind: ctx.Input,
}
ee.EffectNode.Duration(e.EffectNode.SideEffectArgs[0]) //给对方挂3回合子buff
ee.ID(e.ID() + int(input.EffectType.Sub)) //子效果ID
ee.duy = e.EffectNode.SideEffectArgs[0]
ee.EffectNode.Duration(math.MaxInt) //给对方挂3回合子buff
ee.ID(e.ID() + int(input.EffectType.Sub)) //子效果ID
//e.e.EffectNode.Duration(e.EffectNode.SideEffectArgs[0])
//给对方添加我方施加的buff
ee.SetArgs(e.Ctx().Our, e.SideEffectArgs...)

View File

@@ -106,7 +106,7 @@ func (f *FightC) LoadPercent(c common.PlayerI, percent int32) {
func (f *FightC) initplayer(c common.PlayerI) (*input.Input, errorcode.ErrorCode) {
if len(c.GetInfo().PetList) == 0 {
return nil, 0
return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon
}
@@ -131,8 +131,12 @@ func (f *FightC) initplayer(c common.PlayerI) (*input.Input, errorcode.ErrorCode
in.AllPet = make([]*info.BattlePetEntity, 0)
for _, v := range RandomElfIDs(3) {
p := model.GenPetInfo(v, 24, -1, -1, -1, 100)
p.CatchTime = uint32(v)
//p.CatchTime = uint32(v)
p.Update()
p = model.GenPetInfo(int(p.ID), 24, -1, -1, -1, 100)
//p.CalculatePetPane()
p.CatchTime = uint32(v)
in.AllPet = append(in.AllPet, info.CreateBattlePetEntity(*p, f.rand))
}

View File

@@ -63,7 +63,12 @@ func (f *FightC) battleLoop() {
}
}
} else {
//大乱斗,给个延迟
<-time.After(500)
}
ff.Player.SendPackCmd(2506, &f.FightOverInfo)
ff.Player.QuitFight()
@@ -212,9 +217,9 @@ func (f *FightC) handleItemAction(a *action.UseItemAction) {
item, ok := xmlres.ItemsMAP[int(a.ItemID)]
if !ok {
f.enterturn(nil, nil)
return
}
switch {
case gconv.Int(item.Bonus) != 0:
@@ -226,15 +231,16 @@ func (f *FightC) handleItemAction(a *action.UseItemAction) {
our.Service.Pet.PetAdd(f.Opp.CurrentPet.Info)
our.SendPack(common.NewTomeeHeader(2409, f.ownerID).Pack(info.CatchMonsterOutboundInfo{
our.SendPack(common.NewTomeeHeader(2409, f.ownerID).Pack(&info.CatchMonsterOutboundInfo{
CatchTime: uint32(f.Opp.CurrentPet.Info.CatchTime),
PetId: uint32(f.Opp.CurrentPet.ID),
}))
//f.Reason = info.BattleOverReason.PlayerCatch
//f.WinnerId = 0 //捕捉成功不算胜利
f.closefight = true
} else {
our.SendPack(common.NewTomeeHeader(2409, f.ownerID).Pack(info.CatchMonsterOutboundInfo{}))
our.SendPack(common.NewTomeeHeader(2409, f.ownerID).Pack(&info.CatchMonsterOutboundInfo{}))
}
}

View File

@@ -1,14 +1,12 @@
package player
import (
"blazing/cool"
"blazing/logic/service/common"
"context"
)
func (p *Player) SendPackCmd(cmd uint32, b any) {
cool.Loger.Debug(context.Background(), "发送数据", p.Info.UserID, cmd)
// cool.Loger.Debug(context.Background(), "发送数据", p.Info.UserID, cmd)
p.SendPack(common.NewTomeeHeader(cmd, p.Info.UserID).Pack(b))
}

View File

@@ -5,7 +5,6 @@ import (
"blazing/cool"
"blazing/logic/service/common"
"encoding/binary"
"encoding/hex"
"sync"
"context"
@@ -115,7 +114,7 @@ func (h *ClientData) Recv(data common.TomeeHeader) {
}
t1 := data.Pack(ret[0].Interface())
cool.Loger.Debug(context.Background(), "发送数据_回包", data.UserID, data.CMD, ret[0].Interface(), hex.EncodeToString(t1))
//cool.Loger.Debug(context.Background(), "发送数据_回包", data.UserID, data.CMD, ret[0].Interface(), hex.EncodeToString(t1))
//data.Version = 49
t.SendPack(t1)

View File

@@ -39,7 +39,7 @@ func (s *Space) LeaveMap(c common.PlayerI) {
s.Broadcast(c, 2419, &s.Owner)
}
s.Broadcast(c, 2002, info.LeaveMapOutboundInfo{UserID: c.GetInfo().UserID})
s.Broadcast(c, 2002, &info.LeaveMapOutboundInfo{UserID: c.GetInfo().UserID})
s.User.Delete(c.GetInfo().UserID)
s.UserInfo.Delete(c.GetInfo().UserID)

View File

@@ -32,11 +32,10 @@ func NewSpace() *Space {
csmap.WithShardCount[uint32, common.PlayerI](32),
// // if don't set custom hasher, use the built-in maphash.
// csmap.WithCustomHasher[string, int](func(key string) uint64 {
// hash := fnv.New64a()
// hash.Write([]byte(key))
// return hash.Sum64()
// }),
csmap.WithCustomHasher[uint32, common.PlayerI](func(key uint32) uint64 {
return uint64(key)
}),
// set the total capacity, every shard map has total capacity/shard count capacity. the default value is 0.
// csmap.WithSize[string, int](1000),
@@ -44,7 +43,10 @@ func NewSpace() *Space {
UserInfo: csmap.New[uint32, maps.OutInfo](
// set the number of map shards. the default value is 32.
csmap.WithShardCount[uint32, maps.OutInfo](32),
csmap.WithCustomHasher[uint32, maps.OutInfo](func(key uint32) uint64 {
return uint64(key)
}),
// // if don't set custom hasher, use the built-in maphash.
// csmap.WithCustomHasher[string, int](func(key string) uint64 {
// hash := fnv.New64a()

View File

@@ -21,7 +21,10 @@ func (s *ItemService) Get(min, max uint32) []model.Item {
}
func (s *ItemService) AddItem(id, count uint32) {
if t, _ := s.GModel(s.Model).Where("item_id", id).Count(); t != 0 {
s.GModel(s.Model).Where("item_id", id).Increment("item_cnt", count)
_, err := s.GModel(s.Model).Where("item_id", id).Increment("item_cnt", count)
if err != nil {
panic(err)
}
} else {
s.GModel(s.Model).Data(g.Map{
"player_id": s.userid,