跳转至

⚙️ 配置

Pier 的设置都在 plugins/Pier/config.json 里。第一次启动时,如果这个文件不存在,Pier 会写一份默认的;之后它只读不写,你改过的内容会一直保留。

默认的文件长这样:

JSON
{
  "language": "auto",
  "mods": {
    "disabled": []
  },
  "hooks": {
    "disabled": [],
    "decision_ttl_ms": 250
  },
  "watchdog": {
    "enabled": true,
    "warn_ms": 2000,
    "hang_ms": 30000,
    "shutdown_ms": 10000
  }
}

新版本 Pier 增加的设置项,不会出现在你已有的旧文件里,这时它用默认值。想改它,自己把这一项加进文件即可。

写错的键会被直接忽略

Pier 不认识的键会被丢掉,日志里也不会提。改了设置却没效果,先对照上面的文件检查一下拼写。 类型写错的值(比如在要数字的地方写了文字)会被忽略,日志里会有一行写明是哪个键、要什么类型。

日志语言 language

决定 Pier 的日志用哪种语言。翻译文件放在 plugins/Pier/lang/ 里,随发行包一起发。

  • "auto":跟着游戏的语言走。服务器只用一种语言的话,用这个就行。
  • 写一个语言码,就固定用那一种,比如 "zh_CN"。zh_CN 和 zh-CN 两种写法都认。

某一句在你选的语言里没有翻译时,Pier 会先找英文,英文也没有就直接显示这句话的键名。所以翻到一半的语言文件也能用。

启动时有一行会说明用的是哪种语言,以及是谁决定的:

Text Only
[host] 语言 zh_CN(config.json 里指定的):29 个键,来自 plugins/Pier/lang

如果你指定的语言码没有对应的文件,还会多出一行 WARN。这时上面那行的键数看起来一切正常,因为每一句都由内置的英文顶上了,那行 WARN 就是用来提醒你这件事的。

想加一种语言,不用重新编译:把 en_US.lang 复制一份,改成新的语言码,翻译以后放进 lang/。详见 加一门语言。

禁用某个模组 mods.disabled

不想让某个 Pier 模组加载,又不想把它的文件删掉?把它的名字写进这里:

JSON
"mods": { "disabled": ["some-mod"] }
  • 名字要和那个模组 manifest.json 里的 name 一字不差。
  • Pier 在加载 DLL 之前就会拒绝它,所以这个模组的任何代码都不会运行,包括它的静态构造和 DllMain。

关掉某个 Pier 事件 hooks.disabled

不想让任何模组拦截某件事,比如丢物品?把这个事件的名字写进来:

JSON
"hooks": { "disabled": ["PlayerDropItemEvent"] }
  • 之后有模组想订阅这个事件,订阅会失败,日志里会有一行写明是哪个模组在订阅。
  • 模组拿到的是订阅失败,不会拿到一个永远不触发的监听器。所以一个保护类模组不会在日志里继续报告自己正在保护某样东西,而实际上什么都没在拦。
  • 想关掉某一项拦截、又不想卸掉整个模组时,用这个设置。那个模组之后的表现,会和这个事件根本不存在时一样。

压力板判定的缓存 hooks.decision_ttl_ms

压力板、活塞推动这类判定,结果会缓存多少毫秒。默认 250,也就是 5 个游戏刻;可以设 0 到 5000,超出范围会被拉回范围内,并在日志里说明。

为什么要缓存:每个站在压力板上的实体,每一刻都会触发一次判定。每次判定,Pier 都要拼出事件内容、交给模组、模组解析它、去查领地数据、再把结果交回来。一个玩家站着不动,这个过程每秒就要跑 20 遍。

  • 设成 0:每一刻都真的去问模组。这是给正在开发领地模组的人看清每一次调用用的,正常运行的服务器不建议这样设。
  • 设得更大:一次「放行」被记住的时间更长。坐标是缓存条件的一部分,玩家挪动一格,缓存就失效;会出问题的情况是玩家站着不动,而他的权限在这段时间里被改了。

看门狗 watchdog

Pier 模组是直接跑在服务器线程上的原生代码。一个永远不返回的回调(死循环、死锁、卡住的网络请求)会让服务器停止运转;卡在关服阶段(on_disable、on_unload、DLL 的析构)会让服务器一直关不掉。

看门狗盯着这些情况。模组占住线程太久,它先在日志里写下是谁;再久,它就结束进程,好让面板或守护程序把服务器重新拉起来。

JSON
1
2
3
4
5
6
"watchdog": {
  "enabled": true,
  "warn_ms": 2000,
  "hang_ms": 30000,
  "shutdown_ms": 10000
}
键 默认值 范围 作用
enabled true 设成 false 关掉整个看门狗
warn_ms 2000 0–3600000 模组占住线程这么多毫秒,就在日志里点名告警;0 表示不告警
hang_ms 30000 0–3600000 服务器运行时,占住这么多毫秒就结束进程;0 表示永不结束
shutdown_ms 10000 0–3600000 关服开始以后的同一个时限;0 表示一直等下去

Pier 每次执行模组的代码都在看门狗的视线里:加载和卸载 DLL、pier_main、三个生命周期函数,以及所有事件、命令、任务、表单、总线、服务、数据包和钩子回调。

日志会写明模组名、卡在哪个入口、哪个线程。慢的调用最后返回时,还会记下花了多久:

Text Only
[watchdog] 'land-claims' has held thread 4812 inside event for 2000 ms
[watchdog] 'land-claims' returned from event after about 2600 ms

超时以后会发生什么

Pier 先把原因写进控制台和日志,然后以退出码 70 结束整个服务器进程。

为什么不只停掉那一个模组:它的代码正跑在服务器自己的线程上,手里可能握着锁、写着写到一半的数据。把线程从中间拽出来,那些锁会一直被占着,数据停在写到一半的样子,服务器之后的行为就没法预料了。

上次自动保存以后的改动会丢失,这和服主手动结束一个卡死的服务器结果一样,只是来得更早,而且日志里点明了是谁。面板或守护程序只要设置成「非零退出时自动重启」,服务器就会自己回来。

计时的细节

  • 看门狗用自己的时钟计时,每一步最多算 200 毫秒。进程被暂停、电脑休眠的那段时间,不会算到模组头上。
  • 挂着调试器时不会结束进程:超时只记一次日志,进程继续运行。你在模组里打断点调试,会话不会被杀掉。

某个模组启动时确实很慢?

调大 hang_ms,不要直接关掉看门狗。只在排查问题、需要排除看门狗影响的时候,才把 enabled 设成 false。

配置文件读不出来的时候

比如 JSON 里少写了一个逗号。这时 Pier 会:

  1. 这一次运行里,每一项都用默认值;
  2. 打一条 error,写明这样做的后果。比如:mods.disabled 这一次是空的,你写在里面的模组会照常加载;
  3. 照常启动。

Pier 是加载器,它不启动,服务器上所有的模组都跟着起不来,所以它选择用默认值启动。默认值比你的设置更宽松的那些地方,就是那条 error 要写清楚的内容。