// pvfdump 打印 Script.pvf 里指定文件的内容(可截断、可按子串过滤行)。 // 用来核对 NPC 列表、城镇刷怪配置等 PVF 文本,而不是靠猜。 // // go run ./cmd/scratch/pvfdump -pvf -file npc/npc.lst -grep boken package main import ( "flag" "fmt" "os" "strings" platformpvf "longheng.io/server/internal/platform/pvf" ) func main() { pvfPath := flag.String("pvf", `../runtime/data/dnf/Script.pvf`, "Script.pvf path") file := flag.String("file", "", "归档内路径") grep := flag.String("grep", "", "只打印包含该子串的行(大小写不敏感)") head := flag.Int("head", 60, "最多打印多少行(0=全部)") tail := flag.Int("tail", 0, "只打印最后 N 行") flag.Parse() if strings.TrimSpace(*file) == "" { fmt.Fprintln(os.Stderr, "usage: pvfdump -file [-grep s] [-head n]") os.Exit(2) } archive, err := platformpvf.Open(*pvfPath) if err != nil { fmt.Fprintln(os.Stderr, "open:", err) os.Exit(1) } text, err := archive.ReadText(*file) if err != nil { fmt.Fprintf(os.Stderr, "read %s: %v\n", *file, err) os.Exit(1) } lines := strings.Split(strings.ReplaceAll(text, "\r\n", "\n"), "\n") fmt.Printf("file=%s lines=%d\n", *file, len(lines)) needle := strings.ToLower(strings.TrimSpace(*grep)) hit := 0 printed := 0 for _, line := range lines { if needle != "" && !strings.Contains(strings.ToLower(line), needle) { continue } hit++ } if needle != "" { fmt.Printf("grep=%q hits=%d\n", needle, hit) } start := 0 end := len(lines) if needle == "" { if *tail > 0 && *tail < len(lines) { start = len(lines) - *tail } if *head > 0 && end-start > *head { end = start + *head } } for i := start; i < end; i++ { line := lines[i] if needle != "" && !strings.Contains(strings.ToLower(line), needle) { continue } fmt.Printf("%6d| %s\n", i+1, line) printed++ if *head > 0 && needle != "" && printed >= *head { break } } }