DNF90 服务端与启动器完整源码(含 GM 工具功能增强)

服务端(Go):
- GM 塞背包/带属性装备发放:在线角色推送 op14 增量物品行,背包实时刷新,无需回角色选择界面
- GM 改金币/改等级:去掉在线拒绝,落库后推送 op14 钱包/op37 等级状态,在线实时刷新
- 等级端点统一切换到新版 GMSetCharacterLevel(自带在线刷新)
- 无限/锁死疲劳模式 + 燃烧疲劳:每房间消耗 2 点、打怪与通关经验双倍
- 燃烧疲劳开关时给所有在线角色推送系统提示(op12 mode 0)
- 深渊史诗掉率:GM 全局倍率 + 城镇增益药剂窗口倍率,真实接入掉落结算

启动器(Python/JS):
- 标题栏自绘、窗口 1204x717、禁止拖拽改大小、仅最小化/关闭
- GM 工具:疲劳与燃烧、深渊史诗掉率、拍卖行上架(单一定价对齐)
- 拍卖行上架前端对齐服务端单一价格语义,修复 400 报错
This commit is contained in:
hanfuit committed 2026-11-04 14:31:55 +08:00
commit 645b64fe21
4388 files changed
+1405457

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
// pvfref 在 PVF 全库按**子串**搜引用,只打印命中文件与命中片段。
//
// 与 cmd/scratch/pvfgrep 的区别:pvfgrep 走 dnfpvf.Index(受前缀/扩展名限制),
// pvfref 直接用 platform/pvf 的 RangePaths 遍历**全部 100 万+ 成员**,
// 因此能找到 ui/ 下的 .ani / .xui 等界面资源引用。
//
// 跑法:
//
// go run ./cmd/scratch/pvfref -pvf Script.pvf -find interface2_reward_ver2_cn \
// -ext .ani,.xui,.als -limit 40
package main
import (
"flag"
"fmt"
"strings"
platformpvf "longheng.io/server/internal/platform/pvf"
)
func main() {
pvfPath := flag.String("pvf", "", "Script.pvf (required)")
find := flag.String("find", "", "要搜索的子串 (required)")
extFlag := flag.String("ext", "", "只搜这些扩展名,逗号分隔;留空=全部")
limit := flag.Int("limit", 40, "最多命中文件数")
width := flag.Int("width", 90, "命中片段前后各取多少字符")
flag.Parse()
if *pvfPath == "" || *find == "" {
panic("-pvf and -find are required")
}
needle := strings.ToLower(*find)
var exts []string
for _, e := range strings.Split(*extFlag, ",") {
if e = strings.ToLower(strings.TrimSpace(e)); e != "" {
exts = append(exts, e)
}
}
archive, err := platformpvf.Open(*pvfPath)
if err != nil {
panic(err)
}
fmt.Printf("PVF %s 成员 %d 搜索 %q\n", *pvfPath, archive.FileCount(), *find)
files, scanned := 0, 0
archive.RangePaths(func(p string) bool {
lower := strings.ToLower(p)
if len(exts) > 0 {
ok := false
for _, e := range exts {
if strings.HasSuffix(lower, e) {
ok = true
break
}
}
if !ok {
return true
}
}
scanned++
text, readErr := archive.ReadText(p)
if readErr != nil || !strings.Contains(strings.ToLower(text), needle) {
return true
}
files++
fmt.Printf("\n=== %s ===\n", p)
for _, line := range strings.Split(text, "\n") {
at := strings.Index(strings.ToLower(line), needle)
if at < 0 {
continue
}
from := at - *width
if from < 0 {
from = 0
}
to := at + len(*find) + *width
if to > len(line) {
to = len(line)
}
fmt.Printf(" >> %s\n", strings.TrimSpace(line[from:to]))
}
return files < *limit
})
fmt.Printf("\n扫描 %d 个文件,命中 %d 个\n", scanned, files)
}