Lang: English | 简体中文
这是一个简单的小工具,用于移除 Minecraft Java 版存档中的无用区块,以腾出部分硬盘空间。
-
可以看作是 Java 语言实现的 Thanos。
-
仅支持 Anvil 文件格式(自 Minecraft JE 1.2.1 起)。
-
较好的情况下可以把游戏存档的硬盘占用减少超过 50%。
-
支持用区块坐标、区块坐标范围(支持通配符)配置每个世界的受保护区块,阻止某些区块被移除。
区块存储在 Anvil 文件内,Minecraft Java 版会为每个区块存储一个字段 InhabitedTime
,以记录玩家在这个区块内停留的累计时间刻(tick)数。
本工具通过 InhabitedTime
值筛选出玩家几乎没有停留的的区块,以进行移除。其既可以在本地游戏存档上使用,也可以在服务器存档上使用。
玩家只要在某个区块的 生物生成距离详见文档 内,这个区块的
InhabitedTime
就会增长。即玩家所在区块的周围区块的InhabitedTime
往往也会增长。
-
如果你采用的是 Paper 端,或者是以 Paper 为上游的服务端(比如 Purpur),请不要在 Paper 的世界配置文件中把
fixed-chunk-inhabited-time
详见文档 这一项设置为$\ge 0$ 的值,否则区块的InhabitedTime
会被固定,从而影响工具功能。 -
如果你的存档是通过模组 / 外部软件编辑得到的,而不是人为建造的,其中的区块的
InhabitedTime
值难以预料,这种情况下不建议使用本工具。当然,你也可以配置受保护的区块以防止某些区块被移除。
-
本工具会对区域区块 Anvil 文件进行原地处理,发生的更改都是先写入一个临时文件再替换回去。尽管如此,还是建议时不时做一下备份。
- 你应该已经安装了相应版本的 JRE(Java 运行环境),可以参考这个文档。
- 从 Releases 按照你的 Java 版本下载
PotatoPeeler*.jar
,找个位置放着即可(比如 Minecraft 服务端根目录)。
你可以在命令行运行此工具程序:
java [jvmOptions...] -jar PotatoPeeler*.jar
[--world-dirs <worldPath1>,<worldPath2>,...]
[--server-jar <serverJarPath>]
[--min-inhabited <ticks>]
[--help]
[--cool-down <minutes>]
[--threads-num <number>]
[--verbose]
[--skip-peeler]
[additionalOptions...]
标志项 | 说明 |
---|---|
--help |
显示帮助信息 |
--verbose |
往日志中输出详细信息 |
--skip-peeler |
直接跳过区块处理过程。若指定了 --server-jar 参数,会直接启动 Minecraft 服务端 |
参数项 | 默认值 | 说明 |
---|---|---|
--world-dirs |
用逗号分隔的世界存档路径。 * 比如 /opt/server/world,world_nether ,指定了两个世界目录,分别以绝对路径和相对路径的方式。程序会逐个处理这些世界。 |
|
--min-inhabited |
0 |
区块的 InhabitedTime 阈值(单位为 tick,20 ticks = 1 秒)。* 某个区块的 InhabitedTime 低于或等于这个值时,若其未受保护见下方,则会被移除。* 比如我想移除玩家总停留时间 100 。* 不建议将此值设置为 * 默认值 0 其实已经有不错的效果。 |
--cool-down |
0 |
距离上次区块处理过去多久后才能再次使用本工具(单位为分钟)。 * 注意是自上次所有指定世界的区块处理完成起计时。比如采用了 --skip-peeler 标志跳过了区块处理,就不计入在内。 |
--threads-num |
10 |
采用多少线程并发(多核情况下可能能并行)处理一个世界中的 Anvil 文件。 |
--server-jar |
指定 Minecraft 服务端 jar 包路径。 * 如果指定了可用的 jar 包,在本工具程序执行完后将会直接在当前 JVM 中运行此 jar 包,启动服务器。 |
|
jvmOptions | JVM 参数。 * 如果指定了 --server-jar ,JVM 参数会被服务端沿用。 |
|
additionalOptions | 剩余参数。 * 如果指定了 --server-jar ,这些参数会被传递给服务端。 |
-
注 1:对于原版存档格式,你可以这样指定各个世界维度:
--world-dirs world,world/DIM1,world/DIM-1
。实际上本工具会采用广度优先方式搜索目录下的
region
子目录。 -
注 2:如果不想在命令行写参数,你可以在
PotatoPeeler*.jar
的工作目录下建立一个文件potatopeeler.args
,把命令行参数全部写入此文件(JVM 参数除外)。仅当命令行中没有指定参数时(JVM 参数除外),本工具才会读取
potatopeeler.args
文件。
受保护的区块不会被移除,主要包含以下三类:
- 世界中强制加载的区块(/forceload)。
- 自定义的受保护区块。
- 数据量过大的区块。
你可以在世界维度根目录(也就是和 region
在同一级目录中)下建立一个文本文件 chunks.protected
,以指定要在这个世界中保护的区块。
点击查看这个文件所在位置的示例
world
├── DIM-1
│ ├── data
│ │ └── raids_end.dat
│ └── region
│ └── ...
├── DIM1
│ ├── data
│ │ └── raids_end.dat
│ ├── region
│ └── chunks.protected # 末地维度中要保护的区块
├── data
│ └── raids.dat
├── datapacks
├── entities
│ ├── r.-1.-1.mca
│ └── ...
│
├── level.dat
├── level.dat_old
├── chunks.protected # 主世界维度中要保护的区块
├── playerdata
├── region
│ ├── r.-1.-1.mca
│ ├── r.-1.0.mca
│ ├── r.0.-1.mca
│ └── r.0.0.mca
└── session.lock
注:非原版服务端可能把 DIM-1
, DIM1
这些维度单独存放在其他目录中,比较常见的则是 world_nether/DIM-1
,world_the_end/DIM1
。
- 一行指定一条规则,可以是形如
x,z
的单个区块坐标点,也可以是x1~x2,z1~z2
这样的矩形区域。 - 支持通配符
*
。(比如*~5,6
就可以保护$x \in [-2^{31},5], z = 6$ 这个长条形状区域内的区块。) - 支持以
#
开头的单行注释和行内注释。
点击查看文件内容示例
# 保护所有区块,这样的话本工具根本就没法在这个世界维度发挥作用
*,*
*~*,* # 这样写也是一样的
*,*~*
# 保护 x 从 -5 到 5,z = 6 的长条形状区域
-5~5,6
# 保护 x 从 -54 到 14,z 从 7 到 77 的矩形区域
-54 ~ 14 , 7 ~ 77 # 写松散点也没事
# ~ 两边的数字谁大谁小无所谓
1~4, 18~9 # 保护 x 从 1 到 4,z 从 9 到 18 的矩形区域
# 仅保护单个区块
12 , 450
所有输出到控制台的日志都会保存在本工具运行目录的 peeler_logs
子目录中。
# 从指定的三个世界中移除掉玩家总停留时间 <= 5 秒的区块
java -jar PotatoPeeler*.jar --min-inhabited 100 --world-dirs world,world_nether,/opt/server/world_the_end
# 或者可以更简单点,只指定世界路径。默认情况下只移除玩家总停留时间 = 0 秒的区块
java -jar PotatoPeeler*.jar --world-dirs world,world_nether,/opt/server/world_the_end
# 从指定的两个世界中移除掉玩家总停留时间 <= 5 秒的区块
# 移除完成后会在当前 JVM 中启动 purpur.jar
# JVM 参数 -Xms1G -Xmx4G 会被沿用
# 其他参数 / 标志 --nogui --forceUpgrade 会被传递给 purpur.jar
java -Xms1G -Xmx4G -jar PotatoPeeler*.jar --min-inhabited 100 --world-dirs world,world_nether --server-jar purpur.jar --nogui --forceUpgrade
可以给服务器设置定时重启任务。比如我每天凌晨四点执行重启,但是我又想每 4 天清理一次无用区块,就可以这样写服务器启动脚本:
#!/bin/bash
# 利用 --cool-down 参数配置每次清理完后冷却 5760 分钟才会进行下一次清理,即每 4 天清理一次无用区块
java -Xms1G -Xmx4G -jar PotatoPeeler*.jar --cool-down 5760 --world-dirs world,world_nether --server-jar purpur.jar --nogui
java -jar PotatoPeeler*.jar --world-dirs 'C:\Users\Administrator\AppData\Roaming\.minecraft\saves\MyWorld'
对于每个世界维度,如果有 chunks.protected
配置文件,程序就会在控制台打印:
Protected chunks from <path of chunks.protected> have been read.
如果
chunks.protected
格式错误无法读取,程序会提示错误的行号和部分内容。
如果这个世界中包含被强制加载的区块,将会打印:
Force-loaded chunks read.
点击查看此示例
当没有指定命令行参数时,程序会尝试从 potatopeeler.args
文件中读取参数。
可以把命令行参数(不包括 JVM 参数)全部写入 PotatoPeeler*.jar
工作目录下的 potatopeeler.args
文件。
potatopeeler.args
文件示例如下:
--min-inhabited 100 --world-dirs world,world_nether,world_the_end --server-jar purpur.jar
通常把 potatopeeler.args
和 PotatoPeeler*.jar
两个文件放到同一目录下:
Server Root
├── PotatoPeeler-1.0.0.jar # 本工具程序
├── bukkit.yml
├── config
├── plugins
├── potatopeeler.args # PotatoPeeler 参数文件
├── server.properties
├── spigot.yml
├── purpur.jar
├── whitelist.json
├── world
├── world_nether
└── world_the_end
然后直接执行 java -jar PotatoPeeler*.jar
即可,命令行参数会自动从 potatopeeler.args
文件中读取。
感谢开源开发者们的辛苦工作!
- 区域文件格式 - Minecraft Wiki
- 强制加载区块存储格式 - Minecraft Wiki
- Java版存档格式 - Minecraft Wiki
- 区块存储格式 - Minecraft Wiki
- NBT 二进制格式 - Minecraft Wiki
本项目使用 MIT 许可证,感谢你的使用 o(* ̄▽ ̄*)o。