Skip to content

About

僵尸毁灭工程 Build 42 专用服务器存档清理器:删除安全屋以外的所有区块文件,重启服务器后该区域按地图包重新生成,玩家的家原样保留。内置地图预览可先核对范围、安全屋自动保护、删除前二次确认。 | PZ B42 chunk cleaner for dedicated servers: keeps safehouses, regenerates everything else, with a built-in map preview.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

僵毁区块清理器(PZ Chunk Cleaner)

在 Project Zomboid Build 42 专用服务器存档上,删除除安全屋范围以外的所有区块文件 (map/<X>/<Y>.bin),服务器重启后这些区域按地图包重新生成——地形、建筑、战利品、丧尸全部刷新, 而玩家的安全屋(含基地建筑与箱子)原样保留。

适合:跑久了的世界想"翻新",但不想动任何玩家的家。

关于 map_meta.bin Build 42 没有公开这个文件的格式。本项目靠一条特征签名(屋主字符串在记录里出现两次) 给记录定界,再按固定偏移读矩形和字符串。字段布局跟游戏版本绑定,官方一改就可能失效, 届时跑一次 --list 立刻能看出来。图形界面、备份还原、批处理流程、中文界面均为本项目自加。

从源码跑(图形界面本身只依赖 Python 自带的 tkinter):

pip install pywebview              # 只有"地图嵌进窗口"需要;没装会自动退回系统浏览器
python gui.py                      # 打开图形界面
python tests/gui_test.py           # 界面回归测试(22 项)
python tests/web_server_test.py    # 内置预览服务测试(12 项)
node   tests/coord_test.js         # 网页回归测试(26 项,需要 node)
python build.bat                   # 打包成 dist\区块清理器.exe(需要 pyinstaller)

生成底图的两个脚本要额外装 pillow,用法见下面「底图」一节。打包成 exe 后这些都自带,用户不用装任何东西。


一、快速开始(服务器上)

  1. 把 区块清理器.exe 和 web\ 文件夹放到同一个文件夹(拷整个 dist\ 目录最省事)。
  2. 先关闭僵尸毁灭工程服务器(关掉服务器进程/窗口)。
  3. 双击 区块清理器.exe —— 打开图形界面,没有黑框。
  4. 选存档(「自动查找」会扫常见位置),需要的话填备份目录和外扩格数。
  5. 点 ① 分析 → 界面上出现:已生成区块 / 保留 / 将被删除 / 安全屋数量,以及安全屋清单。
  6. 想在地图上核对就点 打开网页预览(紫=已有区块 绿=保留 红=将被删除 黄框=安全屋)。
  7. 点 ② 执行清理,在确认框里手动输入 删除 两个字,开始删除。
  8. 看到"清理完成"后启动服务器,被删区域已重新生成。

命令行用法(可选,需要装 Python,在源码目录运行):

python pz_chunk_cleaner.py "D:\Zomboid\Saves\Multiplayer\servertest"   # 指定存档
python pz_chunk_cleaner.py --dry                                       # 只分析,不删除
python pz_chunk_cleaner.py --list                                      # 只列出安全屋
python pz_chunk_cleaner.py --pad 20 --backup-dir "E:\PZ备份"           # 外扩 20 格 + 备份到 E 盘
参数 说明
--pad N 安全屋四周额外保护 N 格(默认读配置,0)
--backup-dir DIR 本次备份到 DIR(不写则用 config.json 的 backup_root)
--no-backup 本次不备份,即使 backup_root 已设置
--dry 只分析 + 生成网页索引,不删任何文件
--yes / -y 跳过二次确认(危险,慎用)
--force 跳过服务器进程检测
--list 列出所有安全屋(屋主/城镇/坐标/成员)后退出
--no-keep 忽略 keep.json 额外保护区
--no-web 不提示打开网页预览

备不备份,只看 backup_root:填了路径就备份,留 null/"" 就完全不备份(也不会建任何目录)。 界面上"备份目录"留空就是这个意思。


二、安全机制

机制 说明
进程检测 每次删除前用 PowerShell 查 ProjectZomboid* 进程与 zombie.network.GameServer 命令行,运行中直接拒绝;检测不了则要求手动输 yes 确认
安全屋为 0 则中止 解析不到任何安全屋时拒绝执行(否则会删光全图),这是最重要的一道闸
输入确认 必须手动输入 删除 两个字(可在配置里改)才能继续
默认保留安全屋 安全屋矩形内(+可配置缓冲)的区块一律不动
备份(可选) backup_root 填了路径才会备份:文件先移动到 <backup_root>\存档名_时间戳\,保留 X\Y.bin 目录结构,拷回即还原。留空则完全不备份
范围预览 删除前生成 web\save_index.json,可在网页地图上核对范围
只删区块文件 只处理 map/<数字>/<数字>.bin;map_zone.bin、map_meta.bin 等其它文件一律不碰

三、配置文件 config.json(exe 同目录,首次选存档后自动生成)

{
  "save_root": "",          // 上次用的存档路径
  "pad_tiles": 0,           // 安全屋外扩保护格数
  "backup_root": null,      // 备份目录;null 或 "" = 不备份(也可以填 "E:\\PZ备份" 这种绝对/相对路径)
  "confirm_word": "删除",    // 需要手动输入的确认词
  "check_server_process": true,
  "use_keep_file": true,    // 是否读取 keep.json 额外保护区
  "keep_file": "keep.json",
  "open_web": true          // 分析完成后询问是否打开网页预览
}

备份开关就是 backup_root 这一项:填了路径才备份,留 null 就一个文件都不动、 也不会创建任何备份目录。程序在实际删除前会把最终备份路径(含时间戳)打印在清理计划里。

分发出去的文件夹长这样(也就是 dist\ 的内容):

区块清理器.exe
config.json          # 运行时生成:上次的存档、缓冲格数、备份目录
keep.json            # 可选:网页导出的额外保护区
web\
  ├── index.html     # 网页预览(内置在 exe 里,首次运行释放出来)
  ├── map.jpg        # 底图总览(已随包提供)
  ├── tiles\         # 全分辨率瓦片(已随包提供,约 25 MB)
  └── save_index.json# 每次分析后生成
<backup_root>\       # 只有设置了备份目录才会出现

四、地图预览(核对用,可跳过)

主窗口有两个标签页,「② 地图预览」里的地图是直接嵌在程序窗口里的(WebView2),不弹浏览器。

进入这个标签页时程序会:

  1. 在本机起一个内置小服务(只监听 127.0.0.1,端口自动挑);
  2. 把 WebView2 控件挂进窗口那块区域,加载 http://127.0.0.1:<端口>/?auto=1;
  3. 页面自动拉取当前这次分析的结果——不用找文件、不用手动载入。
区块清理器.exe
 ├─ 内置服务(127.0.0.1)      /  网页   ·  /save_index.json 分析结果
 │                             /api/state 状态 · POST /api/keep 存回保护区
 └─ WebView2 嵌进窗口  ←───────┘
  • 往返是通的:在地图上 Shift 拖拽框出要额外保住的区域 → 点「保存到清理器」→ 写入 exe 同目录的 keep.json,窗口那边会自动重新分析把新保护区算进去。
  • 关掉程序时 WebView2 会被显式释放(不释放会留下 Chromium 子进程占内存)。
  • 万一嵌入失败(缺 WebView2 运行时等),会自动退回用系统浏览器打开,功能一样。 想手动确认组件是否就绪:区块清理器.exe --selftest。

想单独跑一次嵌入自检(会短暂显示窗口 5~10 秒,跑完自动释放): 区块清理器.exe --selftest-embed

地图上能看到:

  • 紫 已生成区块 绿 保留(安全屋) 红 将被删除
  • 左上角实时显示光标处的坐标:坐标 = 世界方格(和游戏内坐标一致),区块 = 世界坐标 ÷ 8 的区块号; 平移/缩放时读数会跟着刷新,鼠标移出画布显示 –,框选时改为显示选区的范围与尺寸
  • 黄色虚线 = 安全屋矩形,洋红虚线 = 本页框选的额外保护区; 悬停安全屋可看屋主 / 城镇 / 成员
  • 底图是 8192×6578 的正投影俯视图(北在上)+ 一整套瓦片金字塔,由 assets\Map.png 生成—— 1 像素 = 1 世界格的原版地图渲染,已配准;放大后自动换成全分辨率瓦片(见下面"底图"一节)
  • 底图对不齐时改左上角的 TR / BL 世界坐标锚点(当前底图对应 19797,0 / 0,15897)
  • 网格下拉只影响网格线,1 格 / 8 格(区块)/ 50 / 150 / 300; 颜色叠加层最细按 1 个区块统计(存档数据本身就只到区块级)

性能:底图和叠加层画在底层画布,光标十字/拖拽框画在上层。鼠标移动只重画上层, 平移缩放才重画底层;叠加层只遍历视野内的格子。实测 116 万区块的存档: 载入 41 ms、缩放时每帧 0.2~4.6 ms。

想额外保住某个基地/公共仓库:按住 Shift 拖拽框选,然后点"导出 keep.json", 把文件放到 exe 同目录,下次运行清理器会自动把这块也算进保护范围。

操作 作用
拖拽 / 滚轮 平移 / 缩放
Shift + 拖拽 增加一块额外保护区
Ctrl+Shift + 拖拽 减去一块
框内右键 删除该框
退格 撤销上一块

五、工作原理

  • B42 存档结构:每个区块 = map/<X>/<Y>.bin 一个文件,X = 世界x ÷ 8、Y = 世界y ÷ 8 (1 区块 = 8×8 世界方格)。删掉文件后,服务器加载到该位置发现没有存档数据, 就按地图包重新生成整块内容。
  • 安全屋解析:map_meta.bin(B42 未公开格式)里,安全屋记录长这样: [int32 x][int32 y][int32 w][int32 h][长度+屋主][int64][长度+屋主]——屋主字符串出现两次, 用它作为签名一次性定位。本工具用一条正则扫完整个文件(4.5 MB 约 0.05 秒), 比逐字节遍历快约 90 倍。
  • 保护范围:安全屋矩形(可外扩 pad_tiles 格)+ keep.json 里的额外保护区, 换算成区块坐标后,只删除不在保护集合里的 .bin。

说明:zpop/apop/chunkdata 等 metacell 级统计数据不随区块删除(格式不公开,不动它), 游戏会在区块重新生成后自行处理。


六、源码与重新打包

区块重置器\                      ← 仓库根
├── README.md
├── .gitignore / .gitattributes
├── gui.py                     # 图形界面(tkinter,Python 自带,无第三方依赖)
├── pz_chunk_cleaner.py        # 引擎 + 命令行模式(纯标准库)
├── web_server.py              # 内置预览服务(只监听 127.0.0.1,纯标准库)
├── embedded_view.py           # 把 WebView2 嵌进 Tk 窗口(Windows,需 pywebview)
├── pz-chunk-cleaner.spec      # PyInstaller 配置(窗口模式,产品名在 spec 里指定)
├── build.bat                  # 双击打包
├── web\
│   └── index.html             # 汉化网页预览(会被打进 exe)
├── tools\
│   ├── make_tiles.py          # 切瓦片金字塔 → web\tiles\(需 Pillow)
│   └── make_basemap.py        # 生成底图总览 → web\map.jpg(需 Pillow)
├── tests\
│   ├── fixture.py             # 生成样例存档(测试用,不依赖外部文件)
│   ├── coord_test.js          # 网页逻辑回归测试(node tests/coord_test.js)
│   ├── gui_test.py            # 界面回归测试(python tests/gui_test.py)
│   └── web_server_test.py     # 内置预览服务测试(python tests/web_server_test.py)
├── assets\                    # 底图源图放这里,见 assets\README.md
└── dist\                      # 打包产物(.gitignore,不进版本库)

哪些进版本库:源码、网页、测试、脚本。 哪些不进(.gitignore 挡住了,但会留在你本地磁盘上): assets\Map.png、assets\world.png(共 95 MB 的底图源图)、 web\map.jpg、web\tiles\(由脚本生成)、dist\(打包产物)、 config.json / save_index.json / keep.json(运行时生成)。

底图(web\map.jpg + web\tiles\)

源图是放在 assets\ 的 Map.png / world.png:1 像素 = 1 世界格,内容左上角就是世界坐标 (0,0)。 这个对应关系不是猜的,是用配准算出来的(与 1:1 世界坐标基准做多尺度互相关, 结果 k=1.0000 像素/格、偏移 (0,0),峰值尖锐);world.png 与之坐标完全一致(平移 0,0)。

为什么要切瓦片:源图 19797×15897 = 3.15 亿像素,整张解码要占 1.26 GB 内存 (Chrome 的图片上限约 2.68 亿像素,直接超了),所以单张图最多只能压到 8192 宽(0.41 像素/格)。 切成瓦片后网页只解码视野内的块——全分辨率 1 像素 = 1 格,内存反而只有几十 MB。

web\map.jpg            8192×6578 总览图(3.8 MB):秒出、垫底,瓦片没到位时先顶
web\tiles\<级别>\<x>_<y>.jpg   金字塔,级别 0 = 全分辨率,共 1677 块 24.7 MB
pip install pillow

# 重新生成瓦片(推荐做法)
python tools/make_tiles.py                                  # 从 assets/Map.png,级别 0..6
python tools/make_tiles.py --from-image assets/world.png    # 换成地形渲染
python tools/make_tiles.py --tile 1024 --quality 80         # 块更大 / 压得更狠

# 总览图(一并换掉;瓦片缺失时靠它兜底)
python tools/make_basemap.py --from-image assets/Map.png --width 8192

网页按缩放级别自动选瓦片(放大到 1:1 时用第 0 级),只请求视野内、每块只请求一次, 视野外按 LRU 淘汰(上限约 360 块)。瓦片文件夹不存在也没关系——自动退到总览图,不会一直刷 404。 生成后脚本会打印该用的 TR / BL 锚点(当前是 19797,0 / 0,15897)。

为什么没用 pzmap.org 的"俯视图":网站上的 Scheme 俯视模式是浏览器端用矢量数据实时画的, 没有可下载的图片;它唯一的栅格瓦片是 45° 等距渲染,且东侧部分瓦片缺失(404)。

重新打包(需要 pip install pyinstaller):双击 build.bat,或

python -m PyInstaller --noconfirm --clean pz-chunk-cleaner.spec

开发调试:python gui.py(开图形界面)、python pz_chunk_cleaner.py --dry(命令行模式),都不用打包。


七、常见问题

Q: 界面上「执行清理」是灰的? 要先点「分析」。另外改了存档路径/外扩格数之后,之前的结果会作废,需要重新分析—— 这是故意的,防止拿旧结果去删新参数下的区块。

Q: 双击 exe 没反应? 这是窗口程序,不会弹黑框。如果窗口没出来,多半是缺东西;用 区块清理器.exe --selftest 自检一下(退出码 0 正常,出错详情写在 %TEMP%\pz_cleaner_selftest.txt)。

Q: 提示"没有解析到任何安全屋"? 用 --list 看看。若存档确实没有安全屋,工具会拒绝执行(防误删全图)。 真要清空全图,请手动删除或改用其它工具。

Q: 想保留某个区域(公共农场、活动场地)? 打开网页预览,Shift 框选后导出 keep.json 放到 exe 同目录。

Q: 删错了想恢复? 只有在配置里填了 backup_root 才会备份,才可恢复:把 <backup_root>\存档名_时间戳\X\Y.bin 按原路径拷回存档的 map\ 目录即可。 没设备份位置就删了,无法恢复。

Q: 安全屋名/成员名单不准? map_meta.bin 是未公开格式,屋主和坐标可靠,名字和成员是启发式猜的,仅供参考。

Q: 杀毒软件报警? PyInstaller 打包的 exe 常见误报。可改用源码运行:python pz_chunk_cleaner.py。


免责声明

本工具直接修改服务器存档文件。使用前请务必停止服务器,并建议首次使用时开启 --backup。地图版权归 The Indie Stone 所有。

本仓库代码由 Arwy269 编写,按 MIT 许可发布。

About

僵尸毁灭工程 Build 42 专用服务器存档清理器:删除安全屋以外的所有区块文件,重启服务器后该区域按地图包重新生成,玩家的家原样保留。内置地图预览可先核对范围、安全屋自动保护、删除前二次确认。 | PZ B42 chunk cleaner for dedicated servers: keeps safehouses, regenerates everything else, with a built-in map preview.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages