新闻详情

新闻详情

首页 / 资讯中心 / 详情

忧世之浪士 全部章节文本导出文本和解码脚本

发布时间:2026/9/28 20:36:10来源:尧图网络
忧世之浪士 全部章节文本导出文本和解码脚本
分享链接有全部主线流程视频和提取的主线流程文本和中文翻译另外chapter文件里面有原始的加密pak包和AI解码的txt文件和python脚本链接:https://pan.baidu.com/s/1-nxReAZ669dM_QZyUOyCSg 提取码:1234#!/usr/bin/env python3 # -*- coding: utf-8 -*- decode_zpts_pak.py — PS3 游戏 .pak (ZPTS/$CMP/$CL0) 教程文本解码器 完全从二进制逆向得出的格式 (已对全部 64 个 Tutorial_txt_*.pak 验证): 容器结构 (嵌套块): ZPTS 头 (16 字节): ZPTS | u32le 版本(1) | u32le 计数 | u32le 首个块偏移 $CMP 头 (32 字节): $CMP | u32be 负载大小 | 8B 保留 | u32be 解压后大小 | u32be 压缩大小 | 8B 保留 $CL0 头 (16 字节): $CL0 | u32be 解压后大小 | u32be 压缩大小 | u32be 保留 压缩数据: 自定义 LZ 算法 $CL0 压缩算法 (逐命令解码, 直到输出达到声明的解压大小): 读取 1 个命令字节 C: C 为偶数 - 把随后 (C 1) 个字面字节原样拷贝到输出 (长度 0-127) C 为奇数 - 再读 1 字节 B, 从输出末尾向前拷贝: 长度 n (C 1) 0x1F (5 位, 0-31) 距离 d B | ((C 6) 8) (10 位, 1-1023) 逐字节拷贝 (允许重叠, d1 即 RLE) 文件尾部可能有对齐填充字节, 解压够大小即停止。 解压后得到 KPTS 文本包: KPTS 头 (16 字节): KPTS | u32le 版本 | u32le 条目数 | u32le 表偏移(0x10) 条目 (48 字节): u32le 内容偏移 | u32le 内容长度 | 8B 保留 | 32B ASCII 名称 条目内容两种形态: 文本条目 u16 0xFEFF 标记 UTF-16LE 正文 u16 0x0000 终止 名称条目 纯 ASCII 消息名 (chapter 系列中作为文本的标签) 说明: 文本中的 U32A6 等封闭 CJK 码位是游戏字库里的按键图标 (如 PAD㊦ 表示左摇杆), 不是乱码。 用法: python decode_zpts_pak.py pak文件或目录 [--dump] 传入目录时批量解码目录下所有 *.pak; 每个 pak 输出一个同名 .txt (UTF-8-BOM, Win11 记事本可直接打开); --dump 额外导出解压后的原始 KPTS 二进制 (*.kpts.bin) 供调试。 import os import re import struct import sys # --------------------------------------------------------------------------- # 1. $CL0 解压 # --------------------------------------------------------------------------- def decompress_cl0(data: bytes, expected_size: int) - bytes: 按 $CL0 自定义 LZ 算法解压, 输出长度必须恰好为 expected_size。 out bytearray() pos 0 while len(out) expected_size: if pos len(data): raise ValueError( 压缩数据提前耗尽: 已输出 %d/%d 字节 % (len(out), expected_size)) c data[pos] pos 1 if c 1: # 奇数: 回引拷贝 n (c 1) 0x1F # 5 位长度 if pos len(data): raise ValueError(回引命令缺少距离字节) d data[pos] | ((c 6) 8) # 10 位距离 (C 高 2 位 8 | B) pos 1 if d 0 or d len(out): raise ValueError( 非法回引距离 %d (输出位置 %d) % (d, len(out))) for _ in range(n): # 逐字节拷贝以支持重叠 (d n) out.append(out[-d]) else: # 偶数: 字面拷贝 n c 1 # 7 位长度 if pos n len(data): raise ValueError(字面数据不足) out data[pos:pos n] pos n return bytes(out) # --------------------------------------------------------------------------- # 2. ZPTS/$CMP/$CL0 容器解析 # --------------------------------------------------------------------------- def parse_pak(path: str): 解析 .pak, 返回 (解压后的 KPTS 字节串, 解压大小, 压缩大小)。 raw open(path, rb).read() if raw[:4] ! bZPTS: raise ValueError(不是 ZPTS 文件 (magic 不符): %s % path) i raw.find(b$CL0) if i 0: raise ValueError(未找到 $CL0 压缩块: %s % path) usize, csize, _reserved struct.unpack(III, raw[i 4:i 16]) comp raw[i 16:i 16 csize] blob decompress_cl0(comp, usize) return blob, usize, csize # --------------------------------------------------------------------------- # 3. KPTS 条目表解析 文本提取 # --------------------------------------------------------------------------- def parse_kpts_entries(blob: bytes): 按 KPTS 条目表精确提取文本。 返回 [(name, text), ...]; 表不可用时返回 None (调用方走启发式兜底)。 支持两种条目形态: - 文本条目: 内容以 u16 0xFEFF 开头 (UTF-16LE 正文, 0x0000 终止) - 名称条目: 内容为纯 ASCII 的消息名 (chapter 系列文件中, 每条文本前都有一条名称条目, 如 MES_..._0010_JP_tag) if blob[:4] ! bKPTS or len(blob) 0x10: return None count, table_off struct.unpack(II, blob[8:16]) if count 0 or count 4096 or table_off count * 0x30 len(blob): return None entries [] pending_label None for k in range(count): eoff table_off k * 0x30 toff, tlen struct.unpack(II, blob[eoff:eoff 8]) if toff 0 and tlen 0: # 空条目 表终止符 break hdr_name blob[eoff 16:eoff 48].split(b\x00)[0].decode(ascii, replace) if tlen 1 or toff tlen len(blob): return None seg blob[toff:toff tlen] if seg[:2] b\xff\xfe: # 文本条目: 去掉 u16 0xFEFF 条目标记 text seg[2:].decode(utf-16le, replace) text text.split(\x00)[0] # 去掉 u16 0x0000 终止符及填充 entries.append([hdr_name or pending_label or , text]) pending_label None else: # 名称条目: 内容必须是纯 ASCII raw_name seg.split(b\x00)[0] if raw_name and all(0x20 b 0x7E for b in raw_name): # chapter 布局中名称条目位于对应文本条目之前 pending_label raw_name.decode(ascii) else: return None return [(n, t) for n, t in entries] def _is_text_unit(u: int) - bool: 判断一个 UTF-16 码元是否属于教程文本字符集 (启发式兜底用)。 return ( 0x20 u 0x7E # ASCII 可见字符 or 0x3000 u 0x30FF # 日文标点 / 平假名 / 片假名 or 0x3200 u 0x33FF # 封闭 CJK (游戏字库中的按键图标, 如 U32A6摇杆图标) or 0x4E00 u 0x9FFF # CJK 汉字 or 0xE000 u 0xF8FF # 私用区 (游戏自定义字形) or 0xFF00 u 0xFFEF # 全角 ASCII / 半角片假名 or u in (0x09, 0x0A, 0x0D) # 制表 / 换行 ) def extract_utf16_text_fallback(blob: bytes, min_units: int 8, min_kana: int 2): 启发式扫描 UTF-16LE 文本段 (仅在 KPTS 条目表不可用时使用)。 def kana_count(s): return sum(1 for ch in s if 0x3040 ord(ch) 0x30FF) segments [] for align in (0, 1): pos align run_start None while pos 1 len(blob): u blob[pos] | (blob[pos 1] 8) if _is_text_unit(u): if run_start is None: run_start pos pos 2 else: if run_start is not None and (pos - run_start) // 2 min_units: text blob[run_start:pos].decode(utf-16le, strict) if kana_count(text) min_kana: segments.append((run_start, text)) run_start None pos 2 if run_start is not None and (len(blob) - run_start) // 2 min_units: text blob[run_start:].decode(utf-16le, strict) if kana_count(text) min_kana: segments.append((run_start, text)) segments.sort(keylambda x: x[0]) return segments # --------------------------------------------------------------------------- # 4. 清理文本 (规整换行/空白) # --------------------------------------------------------------------------- def clean_text(text: str) - str: text text.replace(\r\n, \n).replace(\r, \n) text re.sub(r[ \t ]\n, \n, text) # 行尾空白 text re.sub(r\n{3,}, \n\n, text) # 超过 2 行的连续空行 return text.strip() # --------------------------------------------------------------------------- # 5. 主流程 # --------------------------------------------------------------------------- def decode_one(pak_path: str, dump: bool False) - str: blob, usize, csize parse_pak(pak_path) print( 容器: 解压后 %d 字节, 压缩数据 %d 字节 % (usize, csize)) if dump: dump_path os.path.splitext(pak_path)[0] .kpts.bin with open(dump_path, wb) as f: f.write(blob) print( 已导出调试文件: %s % dump_path) entries parse_kpts_entries(blob) parts [] if entries is not None: print( KPTS 条目表: %d 条 % len(entries)) for name, text in entries: print( [%s] %d 字符 % (name, len(text))) if text.strip(): parts.append(clean_text(text)) else: print( 警告: KPTS 条目表不可用, 使用启发式扫描) for off, text in extract_utf16_text_fallback(blob): print( 文本段 0x%04X: %d 字符 % (off, len(text))) parts.append(clean_text(text)) return \n\n.join(p for p in parts if p) def main(): args [a for a in sys.argv[1:] if a ! --dump] dump --dump in sys.argv if args: target args[0] else: # 默认: 解码本脚本所在目录的 Tutorial_txt_00.pak target os.path.join(os.path.dirname(os.path.abspath(__file__)), Tutorial_txt_00.pak) if os.path.isdir(target): paks sorted(f for f in os.listdir(target) if f.lower().endswith(.pak)) if not paks: print(目录中没有 .pak 文件: %s % target) return for name in paks: pak_path os.path.join(target, name) print([%s] % name) try: text decode_one(pak_path, dump) except Exception as e: print( 解码失败: %s % e) continue out_path os.path.splitext(pak_path)[0] .txt with open(out_path, w, encodingutf-8-sig) as f: f.write(text) print( 已保存: %s\n % out_path) else: print([%s] % os.path.basename(target)) text decode_one(target, dump) out_path os.path.splitext(target)[0] .txt with open(out_path, w, encodingutf-8-sig) as f: f.write(text) print( 已保存: %s % out_path) print(- * 60) print(text) if __name__ __main__: if os.name nt: os.system(chcp 65001 nul) # Win11 控制台 UTF-8 main()
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

开源模型端侧落地实战:量化、推理加速与Agent上下文管理 2026/9/28 23:59:38

开源模型端侧落地实战:量化、推理加速与Agent上下文管理

1. 从"追平"到"端侧落地":开源模型这波到底变了什么如果你最近半年一直在关注模型圈的动态,应该能明显感觉到一个拐点:开源模型和闭源旗舰之间的差距,正在从"代差"变成"身位差"。以前大家…

阅读更多 →
Java采购管理系统实战:从数据库设计到事务一致性 2026/9/28 23:59:25

Java采购管理系统实战:从数据库设计到事务一致性

简介:这是一套面向Java Web初学者与课程设计者的采购管理系统完整源码,采用JSP技术搭建,配合MySQL数据库,用于解决企业采购信息的管理问题,适合作为毕业设计、课程大作业或进销存类项目的参考模板。系统实现了用户登录…

阅读更多 →
AI Evals实战指南:从零搭建LLM应用评估体系与CI/CD集成 2026/9/28 23:59:25

AI Evals实战指南:从零搭建LLM应用评估体系与CI/CD集成

1. 为什么AI Evals值得你花时间搞明白做LLM应用的人,迟早会撞上同一堵墙:模型输出飘忽不定,今天答得好好的,明天换个问法就胡说八道。你改了一版提示词,感觉好像好了点,但到底好了多少?说不清。…

阅读更多 →
LSTM时间序列预测实战:从数据窗口构造到模型调参避坑 2026/9/28 23:59:18

LSTM时间序列预测实战:从数据窗口构造到模型调参避坑

简介:这份资源面向高校学生与Python初学者,提供一套可直接运行的LSTM时间序列预测完整项目,适用于期末大作业、课程设计及入门级深度学习实践。项目以空气质量等真实数据为样本,覆盖数据预处理、模型搭建、训练与预测全流程&#…

阅读更多 →
LSTM时间序列预测实战:从期末大作业到可复现Python源码 2026/9/28 23:59:12

LSTM时间序列预测实战:从期末大作业到可复现Python源码

简介:这份资源面向高校学生与Python初学者,提供一套可直接运行的LSTM时间序列预测完整项目,适用于期末大作业、课程设计或入门深度学习实践。项目以空气质量等真实序列数据为样本,覆盖数据读取、预处理、模型搭建、训练与预测全流…

阅读更多 →
LLM红队实战:从攻击面枚举到防护策略的完整方法论 2026/9/28 23:59:12

LLM红队实战:从攻击面枚举到防护策略的完整方法论

1. 从“Lysios”这个名字说起:LLM红队到底在防什么第一次看到“Lysios – LLM red teaming org”这个标题,很多人会愣一下:Lysios是什么?是一个开源工具、一个组织代号,还是一套方法论?从命名习惯来看&…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉