Resource Pack Manager 故障排查
本页面只覆盖目前在 ResourcePackManager 代码中已确认的行为。
针对 RSPM 出现的任何问题,最有用的第一步是:
/rspm status
它会打印版本、部署模式(独立 vs network-backend)、一段简短且不含机密的网络密钥指纹以及该密钥的来源、Java 与基岩版资源包状态、当前激活的分发路径与 URL、解析得到的外部主机名 + 自动检测到的公网 IP、所有相关配置开关、一条代理部署提醒(网络代理 jar 就是同一个 ResourcePackManager.jar),以及 Floodgate / Geyser-Spigot 的检测情况。当该 jar 运行在代理上时也有同名命令,会打印代理侧的等价信息(后端列表、各后端的拉取结果、合并后的资源包状态)。
控制台默认只显示少量信息
每当 RSPM 全新初始化一条分发路径时,它只打印一行信息 —— 结果:
[ResourcePackManager] Resource pack is live via self-hosting — http://play.example.com:25566/rspm.zip
[ResourcePackManager] Resource pack is live via automatic hosting — https://magmaguy.com/rsp/<uuid>
其他所有内容 —— 暂存的每个资源包、合并的每个集群、每次稳定性检查、每次自托管探测及其结果 —— 默认都会被抑制。RSPM 能够自行恢复的状况不会作为警告上报。 如果一次自托管探测失败、RSPM 静默切换到远程托管,那是一次成功而不是故障,控制台对此只字不提。
结果行说明 RSPM 已选定并发布分发 URL,不能证明某个客户端已经下载或显示资源包。请让玩家加入并检查一个已知的自定义物品或模型。报告托管或合并问题前,先启用详细日志:
/rspm verbose on
然后执行 /rspm reload。该命令会替你把 verboseLogging: true 写入 plugins/ResourcePackManager/config.yml,并且该设置会在重启后保留,所以排查完毕后请执行 /rspm verbose off。手动编辑这个键效果完全相同。基岩版转换器有独立的开关 bedrockConverterDebug,它只能在配置中修改。
你确实可能合理看到的警告都是真正的故障:对某个特定玩家反复下发资源包失败、客户端报告 INVALID_URL、HTTP 端口无法绑定、两条分发路径同时失败,或者代理连续轮询多个周期都没有任何后端产出内容。
玩家收不到资源包
请先检查这些:
- 若希望使用正常的自动分发,必须启用
autoHost(selfHostForce是用于测试的显式覆盖开关) - 合并后的资源包必须存在,并且至少有一条分发路径(自托管或远程)已成功
- 玩家在加入服务器时收到资源包。在没有已发布资源包时加入的玩家,会在托管就绪时收到它,包括在会话后期重新注册托管的情况(例如远程会话过期之后)
- Floodgate 玩家会被 Java 分发有意跳过,因为他们的基岩版资源包会话由 Geyser 负责
如有需要:
- 运行
/rspm status,查看 "Hosting" 部分。Active delivery显示当前使用的是自托管、远程,还是都没启用。 - 如果显示 "active delivery: not yet ready" — 合并或上传仍在进行中。当玩家加入过早时,插件会在控制台大字提示,并会在分发就绪的瞬间自动把资源包发给玩家。
- 如果显示 "active delivery: none — hosting disabled or failed" —
autoHost已关闭,或自托管探测和远程上传都失败了。参阅下文 “自托管完整性检查失败” 与 “自动托管无法连接到远程服务器”。 - 设置
verboseLogging: true,运行/rspm reload,在控制台观察上传 / 自托管探测的结果,再用一个测试玩家重新加入。(不打开该开关时不会打印探测步骤——只会打印最终那一行 "Resource pack is live via ..." 的结果。)
加入时的资源包下发会延迟约一秒。如果 Java 客户端报告 FAILED_DOWNLOAD 或 DISCARDED,RSPM 会针对该玩家会话自动重试,最多三次。它不会对玩家主动拒绝、INVALID_URL 或 FAILED_RELOAD 重试;重试次数耗尽和无效 URL 都会作为真正的故障记录下来。
FAILED_RELOAD 表示客户端已下载资源包,但其自身的资源重载失败,因此再次下载同一个资源包也无济于事。RSPM 会记录 Client <name> reported FAILED_RELOAD for the resource pack. Check that client's latest.log for the resource reload error; not retrying.。请阅读该玩家客户端的 latest.log,找出客户端拒绝的资源或资源包元数据。
如果由其他系统负责托管和分发(autoHost: false),RSPM 不会推送 URL。若在 RSPM 前部署 HTTPS 反向代理,请保持 autoHost: true,并使用 selfHostExternalUrl。这样可以保留自动分发和远程托管备用路径。
已安装 ItemsAdder,但最终资源包里没有它的内容
这通常意味着 ItemsAdder 仍以某种方式阻止了 ResourcePackManager 读取或托管其输出。
请使用:
/rspm itemsadder configure
该命令目前会:
- 启用
resource-pack.hosting.no-host.enabled - 禁用
protection_1、protection_2和protection_3 - 将
resource-pack.zip.compress-json-files设为false - 运行
/iareload,再运行/iazip - 等待 RSPM 合并重新生成的 ItemsAdder 导出,并报告合并是否成功
它不会重载 ResourcePackManager。看到合并消息后,请用 /rspm status 检查托管情况。
如果该命令提示 ItemsAdder 已经在自托管资源包,请先手动禁用 ItemsAdder 的托管,再重新运行该命令。
合并后的资源包无效或上传失败
ResourcePackManager 的自动托管集成会显式处理以下服务端错误类型:
- 缺少必需文件
- 文件过大
- 文件格式无效
- 会话缺失
- 远程服务器不可用
RSPM 会在上传前自行检查文件大小限制:超过 50,000 KiB(51,200,000 字节)的 Java 资源包不会被上传,控制台会打印 Automatic hosting skipped: resource pack is <size> bytes; the limit is 51200000 bytes.。随后 RSPM 会改为尝试经过验证的自托管。参见自托管。
遇到其中之一时:
- 运行
/rspm reload重新构建资源包。 - 检查是否有某个源资源包格式错误、被加密或无法读取。
- 检查最终合并后的资源包根目录是否仍然包含有效的
pack.mcmeta和pack.png。
如果某个已启用的资源包无法被解压或暂存,本次合并会中止,控制台会指出出问题的那个资源包。请修复该资源包、移除手动添加的 ZIP,或在其自动集成配置中设置 isEnabled: false,然后再重新加载。
覆盖层元数据与压缩包结构
最终合并保留作者的覆盖层格式声明,包括 formats、min_format、max_format 和额外元数据。多个包共享覆盖层目录时,采用优先级较高的条目。
RSPM 只会做一处改写。当覆盖层列表中有任一覆盖层覆盖到资源包格式 64 或更低、而另一个覆盖层没有声明 formats 时,Minecraft 1.21.9 及更高版本会拒绝整个 pack.mcmeta。两个各自有效的资源包,在其覆盖层列表合并后就可能违反这条规则。当合并后的列表中包含下界为 64 或更低的覆盖层时,RSPM 会为每个只声明了 min_format 和 max_format 的条目添加 formats 范围。该范围覆盖的客户端与条目自身的边界相同;若起点为 64 或更低,则上限截至 64。冲突日志会记录 Added the formats range to N overlay entries。已经声明了 formats 的条目,或边界无法解析的条目,会保持原样。除此之外,RSPM 不会统一针对不同年代客户端的范围,也不会修复无效声明;请在源资源包中修正不兼容的元数据。
RSPM 检查覆盖层目录是否为非空的相对路径,并确保它不会超出组装后资源包的根目录。绝对路径、规范化后超出根目录的路径以及无效路径会被拒绝。通过此检查不代表 Minecraft 一定接受覆盖层名称或格式元数据。
若 ZIP 内是 Pack Name/assets/ 和 Pack Name/pack.mcmeta,说明多了一层外部目录。RSPM 会发出提示;请重新压缩,使 assets/ 和 pack.mcmeta 位于 ZIP 根目录。经过内容去重的压缩包会通过中央目录读取,以保留共享压缩数据的条目,包括纹理动画元数据。
方块图集纹理
合并后的方块图集会将目录来源展开为资源包内的具体 PNG 资源,并保留来源顺序与精灵 ID。若动画帧尺寸不适合所需的 mip 层级,系统会用最近邻缩放在 resourcepackmanager_internal:mip_safe/ 下生成结果确定的副本。原文件不变,供字体等其他加载器使用。
不要在保留的 resourcepackmanager_internal 命名空间下创建内容;冲突会被拒绝。此过程不是 Java 到基岩版转换,也不保证兼容所有自定义客户端着色器或图集扩展。
损坏的资源包不会永久阻塞分发
一个无法暂存的资源包在每次重试时都会以同样的方式失败,放任不管就会让分发永久卡死——合并永远完不成,同样的错误无限重复。在同一个文件连续失败三次之后,RSPM 会把该资源包从合并中剔除,让其余资源包得以发布,并且会明确、响亮地说明一次:
[ResourcePackManager] Resource pack X.zip failed to stage 3 times in a row and has been excluded
from the merge so the remaining packs can be delivered. The merged pack is now INCOMPLETE ...
请按字面理解这句话:玩家现在拿到的资源包缺少那个插件的内容。常见原因是 zip 损坏或写入不完整。
这种剔除会自行解除。失败记录以该文件的大小和修改时间为键,因此修复或替换该文件会自动解除隔离,该资源包会重新加入下一次合并——无需命令,也无需重启。/rspm reload 同样会把所有隔离记录清零重来。任何一次成功的合并之后,尚未达到三次的失败计数都会被丢弃,因此长时间运行中零散出现的无关瞬时故障不会累积成一次剔除。
当远程 auto-host 报 SESSION_NOT_FOUND 错误时,RSPM 会清掉自己的会话 UUID,并在下一次保活心跳时重新初始化——无需人工干预。
一个插件的资源覆盖了另一个插件的资源
这由下面这个文件中的 priorityOrder 控制:
plugins/ResourcePackManager/config.yml
靠上的条目会胜过靠下的条目。
对于不可合并的文件,ResourcePackManager 会替换低优先级文件。对于可合并的 JSON 文件,则会合并内容。当前可合并的 JSON 类别有:
sounds.json- 语言文件
- 位于
minecraft/models/item的原版物品模型 JSON(非递归合并:跨资源包只合并overrides数组,文件其余部分遵循最高优先级取胜) - 图集(atlas)文件
- 字体(font)文件
- 位于
items/的 1.21.4+ 物品模型定义(格式感知合并,尊重 predicate 树结构)
pack.mcmeta 也有专门的合并处理:采用最高的 pack_format,并组合声明的资源包格式范围。覆盖层条目保留作者指定的范围及额外元数据;目录重复时采用优先级较高的条目。唯一的补充是为需要的条目添加 formats 范围,以便合并后的列表能在 1.21.9+ 客户端上加载(参见覆盖层元数据)。除此之外,RSPM 不会修复不兼容的元数据。其他无冲突的元数据也会保留。基础图集来源会合入覆盖层图集,防止覆盖层遮蔽基础条目。
如需查看最近一次合并发生了什么,请查阅:
plugins/ResourcePackManager/collision_log.txt
GUI 文本或基于字体的元素显示异常
字体文件是 ResourcePackManager 会合并的 JSON 类别之一,但这并不保证两套不同的字体系统在 Minecraft 中能够良好共存。
如果某个基于字体的菜单或 HUD 显示异常:
- 修改
priorityOrder,让你希望胜出的资源包靠前。 - 运行
/rspm reload。 - 检查
collision_log.txt,确认冲突发生在你预期的位置。
资源包变更没有立即生效
ResourcePackManager 对受支持的资源包来源具有看门狗机制。
它会等到某个发生变化的资源包持续 3 秒不再变化为止,然后在所有被监视资源包都稳定之后立即开始重新合并。
如果你正在主动重新生成另一插件的资源包,请在文件写入停止后再给它几秒时间。如果仍不确定,可在上游插件完成后运行 /rspm reload。
/rspm status 显示远程托管,但我预期的是自托管
当 preferSelfHost: true(默认)且自托管检查失败时,可能出现这种情况。可达性检查记录在详细日志级别,不启用 verboseLogging: true 就不显示;部分消息包含“This is OK.”。远程托管成功时,结果为 Resource pack is live via automatic hosting — ...。无效设置、监听器故障和远程通信失败仍可能产生警告。
运行 /rspm verbose on(或设置 verboseLogging: true)并执行 /rspm reload,即可看到是三层中的哪一层失败了:
- 第 1 层(启发式) — 解析得到的外部主机名是 RFC1918 / 回环地址 / 链路本地。请将
selfHostExternalHost设为你真正的公网主机名,或确保插件能访问 api.ipify.org / checkip.amazonaws.com。 - 第 2 层(本地及公告 URL 下载) — RSPM 从
http://127.0.0.1:<port>/rspm.zip和玩家确切 URL 下载开头最多 1 KiB,并分别与本地资源包比较。要求 HTTP 200 或 206、报告长度匹配,且 206 具有预期的Content-Range。重定向、错误字节、文件缺失和服务器侧 NAT 回流故障会拒绝自托管。 - 第 3 层(外部可达性探测) — magmaguy.com 必须报告公告 URL 可达且返回 HTTP 200 或 206。HTTP 端口关闭、请求失败或探测服务不可用都会拒绝自动自托管。状态与任何原因代码可通过
verboseLogging查看。
按推荐顺序处理:在防火墙和路由器上放通 HTTP 端口,将 selfHostExternalHost 设为可访问的主机名,或设置 preferSelfHost: false 来优先尝试远程托管。若连备用路径也不能使用自托管,还需设置 selfHostEnabled: false,并保持 selfHostForce: false。
探测服务不可达时,自托管保持未验证状态,RSPM 会尝试远程托管。远程失败后的回退也必须通过同样的自托管检查。只有 selfHostForce: true 可跳过验证;两条自动路径均失败时,RSPM 无法公告新的分发 URL。探测成功也不能证明每位玩家网络上的完整下载和资源包接受都成功。
完整决策树请参阅自托管。
自动托管无法连接到远程服务器
ResourcePackManager 内置的远程托管会与下面这个地址通信:
https://magmaguy.com/rsp/
如果该连接失败,插件会记录通信警告,并且在重新连接成功之前无法使用远程回退。
你的选项有:
- 修复服务器的出站 HTTPS 连接
- 等待远程服务恢复可达
- 禁用
autoHost,自行托管生成的 zip - 放通 HTTP 端口,将
selfHostExternalHost设为公网主机名,保持preferSelfHost: true。显式名称跳过公网 IP 自动检测,但本地、公告 URL 和外部检查仍须通过。探测服务不可达会阻止自动选择自托管。
我想通过自己的 Web 服务器自托管合并后的资源包
代码层面支持的做法是:
- 设置
autoHost: false。 - 如果希望 ResourcePackManager 额外把一份副本写入某个已存在的文件夹,则设置
resourcePackRerouting。 - 自己托管
ResourcePackManager_RSP.zip。
resourcePackRerouting 相对于 plugins 目录解析,且目标文件夹必须已存在。
如果你想使用 RSPM 内置的自托管 HTTP 服务器(这是另一件事——它与插件运行在同一个 JVM 中),请参阅自托管。
我需要查看本服务器在远程存储了哪些数据
请使用:
/rspm data_compliance_request
如果存在活动的远程托管会话,ResourcePackManager 会把响应下载到:
plugins/ResourcePackManager/data_compliance/data.zip
RSPM 还会在同一个 data_compliance 文件夹中写入 ReadMe.md。
如果没有远程会话(例如你正在使用自托管),该命令会报告当前没有可请求的远程数据。
没有生成基岩版资源包
bedrockConversionEnabled 默认值为 true,因此应当会自动运行。请先运行 /rspm status——Bedrock Pack 部分会告诉你资源包为何不在磁盘上:
- "No Bedrock target detected" — 本地没有 Geyser-Spigot、没有 Floodgate,也不在网络模式下。转换被有意跳过。安装 Floodgate(用于代理部署)或 Geyser-Spigot(用于独立部署)后运行
/rspm reload。 - "Network mode is active so this backend SHOULD produce a Bedrock pack. The file is missing" — 通常是第一次合并周期还没完成(启动后大约等 30 秒),或转换既没找到可转换的物品映射也没找到被允许的实体资源包,或转换抛了异常。在控制台中搜索
[BedrockConverter]警告。启用bedrockConverterDebug: true时,扫描器还会记录Generic scanner: discovered N item definitions;数量为 0 表示合并后的资源包中没有可转换的物品定义。(状态诊断中引用这一行时写作discovered 0 items definition files。)
如果 Geyser 自动检测失败:
- 在
config.yml中将bedrockGeyserFolder设为 Geyser 的数据目录路径(例如Geyser-Spigot)。 - 绝对路径可用。相对路径会先从服务器工作目录尝试,再按相对于
plugins目录尝试。
转换器会自动在 plugins/Geyser-Spigot/、任何 plugins/Geyser-*/ 变体,或者 Fabric/NeoForge 部署下的 config/Geyser-*/ 中查找 Geyser。
如需逐物品 / 逐骨骼的日志输出,将 bedrockConverterDebug: true 并重新加载。
基岩版:因存在遗留资源包而跳过了实时分发提供器
如果控制台报告 Legacy RSPM Bedrock pack detected,说明 Geyser 在启动时已经从其资源包目录扫描过一个旧的 ResourcePackManager_Bedrock.zip。在进程运行期间删除那个文件,会让 Geyser 在内存中持有一个指向已不存在路径的编解码器,因此 RSPM 会在那次启动中有意跳过自己的实时资源包提供器。
请完全停止服务器,只删除 RSPM 打印出来的那个确切的遗留文件路径,然后重新启动服务器。不要用 /reload 来完成这次迁移。当前的资源包仍然位于 plugins/ResourcePackManager/output/ 并按会话分发;它不属于 Geyser 的 packs/ 目录。
基岩版玩家看到手持物品位置错误
先确认预期模型和最新资源包已加载:让基岩版客户端重新连接,以便它收到当前的资源包。RSPM 根据 Java 模型的 display.firstperson_righthand 和 display.thirdperson_righthand 变换推导手持姿势,因此如果姿势在 Java 版上也不对,应在 Java 模型中修正。如果 Java 版看起来正确而基岩版不正确,请附上模型文件进行报告。
bedrock_display_offsets.yml 及其偏移设置已被移除且不再读取;编辑旧副本不会产生任何效果。参见手持物品姿势。
基岩版玩家身上看不到自定义盔甲贴图
自定义盔甲在基岩版上的渲染方式是:将原版盔甲几何体与 Java 贴图组合为可见层。要让它工作,源插件的资源包必须在物品定义旁边提供 assets/<namespace>/equipment/<material>.json 装备文件。如果转换日志中显示了该物品,但游戏中没看到盔甲贴图,请确认该文件存在于合并后的资源包中。
代理:某个后端说它没有网络密钥
在该后端上,/rspm status 显示 Network key source: not set — the proxy sends one when a player next connects here,控制台反复输出 "This backend is behind a proxy but has no network key yet"。
缺少 plugins/floodgate/key.pem 不是原因——那个文件现在是可选的。密钥由代理持有:它会加载自己的 network-key 文件,或在存在 Floodgate key.pem 时一次性地从中播种,或者生成一个全新的密钥,然后在有玩家连接到某个后端时把它推送过去。
请按顺序检查:
- 自代理启动以来,有玩家连接过那个后端吗?密钥授予是随玩家连接一起发生的。
- 代理上真的有
ResourcePackManager.jar吗?后端会替你在plugins/ResourcePackManager/proxy-extension/ResourcePackManager.jar暂存一份自身 jar 的副本并打印该路径——把它复制到代理的plugins/并重启代理。 - 在使用现代转发的 Velocity 上,后端的转发密钥与代理的一致吗?配置为现代转发的后端会有意拒绝未签名或签名错误的授予;它的日志会指明是哪一种。在两侧修正密钥后,下一次玩家连接会自行重试。
- 对比两侧
/rspm status的Network key fingerprint。指纹相同表示使用同一网络身份;还需检查获取结果来验证连接是否正常。密钥本身不会显示。
完整流程请参阅代理网络。
如果 /rspm status 显示 NetworkSync isn't running 并提示缺少 Floodgate 的 key.pem,请查看更早的启动错误。该提示已过时:当前代理可在没有 Floodgate 的情况下生成并保存自己的密钥。下一步应根据初始化错误、文件权限及后端连通性决定。如果代理上完全没有 /rspm 命令,请在启动日志中查找网络身份故障。
发布回滚不完整
如果 Bedrock 资源包、代理接收的数据或合并资源包发布失败,且无法完整还原先前的文件,RSPM 会保留恢复副本,并记录其目录及受影响的目标。它也会尝试停止使用这组不完整的文件。请保留日志中指定的恢复目录,解决文件系统错误,并检查资源包与映射的一致性后再重试。回滚失败并不表示发布成功。
代理:报 "Could not establish persistent RSPM network identity"
当前版本不会使用未保存的密钥运行。如果代理无法把新确定的密钥保存到 network-key,或无法读取已有的 network-key 文件,代理角色会在启动期间停止,并报告 Could not establish persistent RSPM network identity: ... 或 Cannot read established RSPM network identity。网络同步、基岩版分发以及代理上的 /rspm 命令都不会启动,因此各后端会保留现有密钥,而不会被关联到一个可能在下次重启时改变的密钥上。
请修复代理插件数据文件夹的文件系统权限(Velocity 上为 plugins/resourcepackmanager/,BungeeCord 上为 plugins/ResourcePackManager/),然后重启代理。可以读取但格式错误的 network-key 文件会被自动替换。
代理:经过几轮轮询后仍 "no merged pack"
先在 /rspm status 检查已确认参与 RSPM 的后端数量。没有确认参与者的新代理会继续发现后端,不会把每个已注册服务器都当作故障 RSPM 后端。未确认的服务器不会延误资源包同步。
存在已确认参与者时,连续四轮未取得内容会触发诊断,列出参与者、尝试的 HTTP URL 及结果。默认轮询间隔为五秒,网络操作可能延长实际耗时。诊断会说明常见的修复方法:
- 每个后端都返回
CONNECT_FAILED→ 代理无法访问后端的 HTTP 端口。检查velocity.toml/config.yml中的地址是不是代理真正能访问到的(而不是诸如 Docker 内部名之类、从代理网络解析不到的地址),并确认代理与后端之间后端公告的 HTTP 端口是放通的。横幅会打印它尝试访问的确切 URL;在某个后端公告其端口之前,代理会回退到mcPort + network-http-offset-v2,所以早期的CONNECT_FAILED也可能意味着那个回退端口暂时还不可达。 - 每个后端都返回
NOT_FOUND_404→ 后端已就绪,但没有生成基岩版资源包。在每个后端运行/rspm status;Bedrock Pack 诊断块会告诉你原因。
每个卡住期内横幅只触发一次,当至少有一个后端重新开始返回内容时,会记录一行 "NetworkSync: recovered"。详见代理网络。
代理:第一次启动代理时基岩版玩家看不到任何模型
Geyser 只在代理启动时注册其自定义物品表。如果代理在任何后端生成基岩版资源包之前就启动了,Geyser 就会带着空的映射表运行,并在整个会话期间保持空表。
在代理记录 Merged Bedrock pack published at ... 后重启代理。RSPM 会在启动时预先部署上次运行保存的映射,使后续启动能够注册它们。启动后引入的新标识符可能再次需要这一步。
后端:报 "Backend HTTP server failed to bind on port X"
在网络模式下,后端会通过一个小型 HTTP 服务器暴露其基岩版输出。如果端口被占用或不可用,控制台会出现多行 [ERROR] 块。修复方法:
- 在
config.yml中把selfHostPort设为另一个正整数值。 - 或者修改
networkHttpOffset-v2,把自动派生出的端口避开冲突(例如 RCON 占用了mcPort + 1?改成 2 或 3)。你不需要同步更新代理:一旦后端成功绑定,它会自动把自己实际的 HTTP 端口公告给代理,因此代理自己的network-http-offset-v2仅作为公告之前的猜测才有意义。
在后端 HTTP 服务器无法启动期间,该后端的基岩版资源包无法通过直连方式送达代理。magmaguy.com 中继回退仍然可用(后端把文件推送到中继,代理从中继获取它们)。
清理过时的 v1 配置
从 RSPM v1 升级的运维人员,config.yml 中可能仍有一个已废弃的 networkHttpOffset(不带 -v2)键。RSPM v2 故意不读取旧键——下次启动时会自动把 v2 默认值(1)写入配置。废弃的 v1 键会以无害遗留物的形式留在你的配置中,等你手动清理它。