// pvfblk 打印 etc/storydigest/scene.etc 与 etc/townmovielist.etc 的原始令牌字节, // 用于确认影片段的精确结构,以便安全地复制/新增影片段。 package main import ( "encoding/binary" "flag" "fmt" platformpvf "longheng.io/server/internal/platform/pvf" ) func u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) } func dumpTok(label string, raw []byte, i, n int) { toks := len(raw) / 5 fmt.Printf(" [%s] #%-4d ", label, i) if i >= toks { fmt.Println("(越界)") return } b := raw[i*5 : i*5+5] fmt.Printf("type=%d raw=0x%08X bytes= %02X %02X %02X %02X %02X\n", b[0], u32(b[1:5]), b[0], b[1], b[2], b[3], b[4]) _ = n } func main() { input := flag.String("pvf", "", "input PVF") flag.Parse() archive, err := platformpvf.Open(*input) if err != nil { panic(err) } scene, err := archive.ReadRaw("etc/storydigest/scene.etc") if err != nil { panic(err) } stoks := len(scene) / 5 fmt.Printf("=== scene.etc: %d 字节, %d 令牌 ===\n", len(scene), stoks) // 找 901 段([scene] 后跟整数 901) for i := 0; i+3 < stoks; i++ { if scene[i*5] == 3 && u32(scene[i*5+1:i*5+5]) == 0x025138C6 && scene[(i+1)*5] == 0 && u32(scene[(i+1)*5+1:(i+1)*5+5]) == 901 { fmt.Println("901 段 token 序列:") for j := i; j < i+4; j++ { dumpTok("scene", scene, j, 0) } fmt.Println() fmt.Println("同一序列的十六进制(连续 20 字节):") seg := scene[i*5 : (i+4)*5] fmt.Printf(" ") for k, c := range seg { if k > 0 && k%5 == 0 { fmt.Printf(" | ") } fmt.Printf("%02X ", c) } fmt.Println() break } } fmt.Println() fmt.Println("最后 4 个令牌(文件尾):") for i := stoks - 4; i < stoks; i++ { dumpTok("scene", scene, i, 0) } // townmovielist 的池引用 tm, err := archive.ReadRaw("etc/townmovielist.etc") if err != nil { panic(err) } tt := len(tm) / 5 fmt.Printf("\n=== townmovielist.etc: %d 字节, %d 令牌 ===\n", len(tm), tt) fmt.Println("全部 type=6 反引号串的池引用:") for i := 0; i < tt; i++ { if tm[i*5] == 6 { fmt.Printf(" #%-4d ref=0x%08X\n", i, u32(tm[i*5+1:i*5+5])) } } }