服务端(Go): - GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面 - GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新 - 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新) - 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍 - 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0) - 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算 启动器(Python/JS): - 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭 - GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐) - 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
76 lines
2.4 KiB
Go
76 lines
2.4 KiB
Go
package annotations
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"pvfine/internal/pvf"
|
|
)
|
|
|
|
func BenchmarkAnnotateManyRules(b *testing.B) {
|
|
for _, count := range []int{100, 1000, 10000} {
|
|
b.Run(fmt.Sprint(count), func(b *testing.B) {
|
|
rules := make([]Rule, count)
|
|
for i := range rules {
|
|
rules[i] = Rule{
|
|
ID: fmt.Sprint(i), Match: MatchSpec{Extensions: []string{".equ"}},
|
|
Target: TargetSpec{Kind: "token", Section: fmt.Sprintf("section%d", i), Index: intPtr(0)},
|
|
Annotation: AnnotationSpec{Title: "说明", Type: "text"},
|
|
}
|
|
}
|
|
engine, err := Compile(Document{Version: 1, Rules: rules})
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
var text strings.Builder
|
|
for i := 0; i < 100; i++ {
|
|
fmt.Fprintf(&text, "[section%d]\n1 2 3 4 5\n", i)
|
|
}
|
|
view := pvf.ParseScriptView(text.String())
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
engine.Annotate("a.equ", view, nil)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// BenchmarkAnnotatePathManyRules guards the bulk path note lookup: without the
|
|
// literal glob and "<dir>/**" buckets every tree node would scan all rules.
|
|
func BenchmarkAnnotatePathManyRules(b *testing.B) {
|
|
const files, directories = 15000, 2000
|
|
rules := make([]Rule, 0, files+directories+4)
|
|
for i := 0; i < files; i++ {
|
|
rules = append(rules, Rule{
|
|
ID: fmt.Sprintf("file.%d", i), Match: MatchSpec{Glob: fmt.Sprintf("dir%02d/sub%02d/file%05d.ani", i%40, i%50, i)},
|
|
Target: TargetSpec{Kind: "path"}, Annotation: AnnotationSpec{Title: "文件说明", Type: "text"},
|
|
})
|
|
}
|
|
for i := 0; i < directories; i++ {
|
|
rules = append(rules, Rule{
|
|
ID: fmt.Sprintf("dir.%d", i), Match: MatchSpec{Glob: fmt.Sprintf("dir%02d/sub%02d/**", i%40, i%50)},
|
|
Target: TargetSpec{Kind: "path"}, Annotation: AnnotationSpec{Title: "目录说明", Type: "text"},
|
|
})
|
|
}
|
|
rules = append(rules,
|
|
Rule{ID: "star", Match: MatchSpec{Glob: "**/*.ani"}, Target: TargetSpec{Kind: "path"}, Annotation: AnnotationSpec{Title: "通配", Type: "text"}},
|
|
Rule{ID: "all", Target: TargetSpec{Kind: "path"}, Annotation: AnnotationSpec{Title: "全部", Type: "text"}},
|
|
)
|
|
engine, err := Compile(Document{Version: 1, Rules: rules})
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
paths := []string{
|
|
"dir01/sub01/file00001.ani",
|
|
"dir01/sub01/file00001.ani.bak",
|
|
"dir39/sub49/deep/deeper/1.ani",
|
|
"unknown/path.dat",
|
|
"dir01/sub01",
|
|
}
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
engine.AnnotatePath(paths[i%len(paths)], false)
|
|
}
|
|
}
|