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

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

85 lines
2.3 KiB
Go

// 扫描 Script.pvf 里所有带 [purchase limit] 的脚本,打印路径 + 道具名 + 该字段原文,
// 用于确认"账号永久/账号每周/角色永久/角色每周"四种限购在 PVF 里的实际写法。
package main
import (
"flag"
"fmt"
"sort"
"strings"
platformpvf "longheng.io/server/internal/platform/pvf"
)
func main() {
pvfPath := flag.String("pvf", `D:/test/地下城与勇士/Script.pvf`, "Script.pvf path")
limit := flag.Int("limit", 60, "max files to print")
flag.Parse()
archive, err := platformpvf.Open(*pvfPath)
if err != nil {
panic(err)
}
type row struct {
path string
name string
block string
}
rows := make([]row, 0, 256)
shapes := map[string]int{}
files := 0
for _, file := range archive.Files() {
text, readErr := archive.ReadText(file.ArchivePath)
if readErr != nil {
continue
}
lower := strings.ToLower(text)
idx := strings.Index(lower, "[purchase limit]")
if idx < 0 {
continue
}
files++
// [name] 块
name := ""
if n := strings.Index(lower, "[name]"); n >= 0 {
rest := text[n+len("[name]"):]
if a := strings.Index(rest, "`"); a >= 0 {
if b := strings.Index(rest[a+1:], "`"); b >= 0 {
name = strings.TrimSpace(rest[a+1 : a+1+b])
}
}
}
// [purchase limit] 之后到下一个 '[' 之前的内容
rest := text[idx:]
end := len(rest)
if e := strings.Index(rest[len("[purchase limit]"):], "\n["); e >= 0 {
end = len("[purchase limit]") + e
}
block := strings.Join(strings.Fields(rest[:end]), " ")
rows = append(rows, row{path: file.ArchivePath, name: name, block: block})
shapes[block]++
}
sort.Slice(rows, func(i, j int) bool { return rows[i].path < rows[j].path })
fmt.Printf("带 [purchase limit] 的文件数=%d,不同写法=%d 种\n\n", files, len(shapes))
fmt.Println("=== 不同字段写法(按出现次数) ===")
type kv struct {
k string
n int
}
list := make([]kv, 0, len(shapes))
for k, n := range shapes {
list = append(list, kv{k, n})
}
sort.Slice(list, func(i, j int) bool { return list[i].n > list[j].n })
for _, e := range list {
fmt.Printf("%4d 次 | %s\n", e.n, e.k)
}
fmt.Printf("\n=== 前 %d 个文件明细 ===\n", *limit)
for i, r := range rows {
if i >= *limit {
break
}
fmt.Printf("%-60s %-28s %s\n", r.path, r.name, r.block)
}
}