refactor: 重构战斗系统动作提交和竞技场锁定逻辑
Some checks failed
ci/woodpecker/push/my-first-workflow Pipeline failed

This commit is contained in:
xinian
2026-04-02 23:05:18 +08:00
committed by cnb
parent f221b299cd
commit 218e23ff81
13 changed files with 194 additions and 77 deletions

View File

@@ -1,14 +1,11 @@
package fight
import (
"blazing/cool"
"blazing/logic/service/common"
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/modules/player/model"
"context"
"time"
"github.com/jinzhu/copier"
)
@@ -26,6 +23,83 @@ func (*FightC) Compare(a, b action.BattleActionI) (action.BattleActionI, action.
return a, b // 速度相同时,发起方优先
}
const maxPendingActionsPerPlayer = 2
func (f *FightC) openActionWindow() {
f.actionMu.Lock()
f.acceptActions = true
f.pendingActions = f.pendingActions[:0]
f.actionMu.Unlock()
}
func (f *FightC) closeActionWindow() {
f.actionMu.Lock()
f.acceptActions = false
f.pendingActions = f.pendingActions[:0]
f.actionMu.Unlock()
}
func (f *FightC) submitAction(act action.BattleActionI) {
if act == nil || f.closefight {
return
}
f.actionMu.Lock()
if !f.acceptActions {
f.actionMu.Unlock()
return
}
count := 0
replaceIndex := -1
for i, pending := range f.pendingActions {
if pending == nil || pending.GetPlayerID() != act.GetPlayerID() {
continue
}
count++
replaceIndex = i
}
if count >= maxPendingActionsPerPlayer && replaceIndex >= 0 {
f.pendingActions[replaceIndex] = act
} else {
f.pendingActions = append(f.pendingActions, act)
}
notify := f.actionNotify
f.actionMu.Unlock()
if notify == nil {
return
}
select {
case notify <- struct{}{}:
default:
}
}
func (f *FightC) nextAction() action.BattleActionI {
f.actionMu.Lock()
if len(f.pendingActions) == 0 {
f.actionMu.Unlock()
return nil
}
act := f.pendingActions[0]
copy(f.pendingActions, f.pendingActions[1:])
f.pendingActions = f.pendingActions[:len(f.pendingActions)-1]
hasMore := len(f.pendingActions) > 0
notify := f.actionNotify
f.actionMu.Unlock()
if hasMore && notify != nil {
select {
case notify <- struct{}{}:
default:
}
}
return act
}
// 玩家逃跑/无响应/掉线
func (f *FightC) Over(c common.PlayerI, res model.EnumBattleOverReason) {
if f.closefight {
@@ -75,15 +149,7 @@ func (f *FightC) ChangePet(c common.PlayerI, id uint32) {
BaseAction: action.NewBaseAction(c.GetInfo().UserID),
Cid: id,
}
select {
case f.actionChan <- ret:
// 发送成功,可选记录日志
// log.Printf("send skill success, userID: %d, skillID: %d", c.GetInfo().UserID, id)
case <-time.After(time.Second * 60):
// 通道满时的降级处理
cool.Logger.Printf(context.Background(), "actionChan is full, failed to send skill, userID: %d, skillID: %d",
c.GetInfo().UserID, id)
}
f.submitAction(ret)
}
@@ -116,16 +182,7 @@ func (f *FightC) UseSkill(c common.PlayerI, id uint32) {
}
}
// 非阻塞发送避免goroutine永久阻塞
select {
case f.actionChan <- ret:
// 发送成功,可选记录日志
// log.Printf("send skill success, userID: %d, skillID: %d", c.GetInfo().UserID, id)
case <-time.After(time.Second * 60):
// 通道满时的降级处理
cool.Logger.Printf(context.Background(), "actionChan is full, failed to send skill, userID: %d, skillID: %d",
c.GetInfo().UserID, id)
}
f.submitAction(ret)
}
// 玩家使用技能
@@ -134,15 +191,7 @@ func (f *FightC) Capture(c common.PlayerI, id uint32) {
return
}
select {
case f.actionChan <- &action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: id}:
// 发送成功,可选记录日志
// log.Printf("send skill success, userID: %d, skillID: %d", c.GetInfo().UserID, id)
case <-time.After(time.Second * 60):
// 通道满时的降级处理
cool.Logger.Printf(context.Background(), "actionChan is full, failed to send Capture, userID: %d ",
c.GetInfo().UserID)
}
f.submitAction(&action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: id})
}
@@ -151,20 +200,12 @@ func (f *FightC) UseItem(c common.PlayerI, cacthid, itemid uint32) {
return
}
if f.Info.Mode== info.BattleMode.PET_MELEE {
go f.UseSkill(c, 0)
return
}
select {
case f.actionChan <- &action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: itemid, CacthTime: cacthid}:
// 发送成功,可选记录日志
// log.Printf("send skill success, userID: %d, skillID: %d", c.GetInfo().UserID, id)
case <-time.After(time.Second * 60):
// 通道满时的降级处理
cool.Logger.Printf(context.Background(), "actionChan is full, failed to send UseItem, userID: %d, skillID: %d",
c.GetInfo().UserID, cacthid)
if f.Info.Mode == info.BattleMode.PET_MELEE {
go f.UseSkill(c, 0)
return
}
f.submitAction(&action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: itemid, CacthTime: cacthid})
}
// ReadyFight 处理玩家战斗准备逻辑,当满足条件时启动战斗循环