feat: 增强踢人逻辑与BOSS脚本支持
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful

优化踢人超时处理和僵尸连接清理,支持BOSS动作脚本并增加测试,修复事件匹配与战斗循环中的并发问题。
This commit is contained in:
xinian
2026-04-05 21:59:22 +08:00
committed by cnb
parent 36dd93b076
commit c021b40fbe
16 changed files with 457 additions and 151 deletions

View File

@@ -2,6 +2,10 @@ package model
import (
"blazing/cool"
"fmt"
"strings"
"github.com/dop251/goja"
)
const (
@@ -46,3 +50,47 @@ func NewBossConfig() *BossConfig {
func init() {
cool.CreateTable(&BossConfig{})
}
// RunHookActionScript 执行BOSS脚本中的 hookAction并传入 fight 的 hookaction 参数。
// 返回值遵循 HookAction 语义true 允许继续出手false 阻止继续出手。
func (b *BossConfig) RunHookActionScript(hookAction any) (bool, error) {
if b == nil || strings.TrimSpace(b.Script) == "" {
return true, nil
}
program, err := goja.Compile("boss_hook_action.js", b.Script, false)
if err != nil {
return false, fmt.Errorf("compile boss script: %w", err)
}
vm := goja.New()
if _, err = vm.RunProgram(program); err != nil {
return false, fmt.Errorf("run boss script: %w", err)
}
var (
callable goja.Callable
ok bool
)
for _, fnName := range []string{"hookAction", "HookAction", "hookaction"} {
callable, ok = goja.AssertFunction(vm.Get(fnName))
if ok {
break
}
}
if !ok {
return false, fmt.Errorf("boss script function not found: hookAction")
}
result, err := callable(goja.Undefined(), vm.ToValue(hookAction))
if err != nil {
return false, fmt.Errorf("execute boss hookAction: %w", err)
}
// 与既有HookAction默认行为保持一致未显式返回时视为允许继续出手。
if goja.IsUndefined(result) || goja.IsNull(result) {
return true, nil
}
return result.ToBoolean(), nil
}

View File

@@ -0,0 +1,44 @@
package model
import "testing"
type testHookAction struct {
Allow bool
Round int
}
func TestBossConfigRunHookActionScript(t *testing.T) {
boss := &BossConfig{
Script: `
function hookAction(hookaction) {
return hookaction.Allow && hookaction.Round >= 2;
}
`,
}
ok, err := boss.RunHookActionScript(testHookAction{Allow: true, Round: 2})
if err != nil {
t.Fatalf("RunHookActionScript returned error: %v", err)
}
if !ok {
t.Fatalf("RunHookActionScript = false, want true")
}
}
func TestBossConfigRunHookActionScriptEmptyReturnDefaultsTrue(t *testing.T) {
boss := &BossConfig{
Script: `
function hookAction(hookaction) {
var _ = hookaction;
}
`,
}
ok, err := boss.RunHookActionScript(testHookAction{Allow: false, Round: 1})
if err != nil {
t.Fatalf("RunHookActionScript returned error: %v", err)
}
if !ok {
t.Fatalf("RunHookActionScript = false, want true")
}
}