开发文档内部
国际化 (i18n)
了解 Rebar 的国际化系统和翻译机制
最后更新时间
作者:Seggan
关于这一点...我从哪里开始...
Paper 中的翻译
Paper 服务器在发送数据给客户端之前,已经在服务端完成了大部分翻译工作,包括聊天消息、bossbar 和 action bar。但不知为何,物品名称和 lore 没有被覆盖到。这就给我们留下了两条路:要么在服务端做物品翻译(我们目前采用的方案),要么给客户端发一个带翻译的资源包。Rebar 的设计目标之一就是不依赖资源包,所以我们选择了服务端翻译。
数据包注入
显然我们不能直接修改物品堆栈本身——不同玩家用的语言不一样,直接改会造成混乱。我们的做法是向玩家的 Netty 通道注入一个处理器,拦截进出数据包来做翻译。
以下传出的数据包被拦截:
ClientboundContainerSetContentPacket:打开库存时发送,包含库存中的物品ClientboundContainerSetSlotPacket:当库存中的物品发生变化时发送,包含新物品ClientboundSetCursorItemPacket:当光标上的物品发生变化时发送,包含新物品ClientboundRecipeBookAddPacket:当配方添加到配方书中时发送,包含配方的物品ClientboundMerchantOffersPacket:当打开村民交易 GUI 时发送,包含交易中的物品ClientboundPlaceGhostRecipePacket:在制作网格中放置虚影配方时发送,包含配方中的物品
当数据包被拦截时,我们调用 Paper 翻译 API 来翻译其中的物品堆栈(名称和 lore)。因为拦截到的是物品副本,所以可以放心修改,不会影响实际的物品堆栈。
传入数据包只拦截了两个:ServerboundSetCreativeModeSlotPacket 和 ServerboundContainerClickPacket。拦截这两个包的目的是把物品堆栈反向翻译回原始名称和 lore,这样服务端收到后才能正确处理。反向翻译通过在 Rebar 物品注册表中查找原始物品堆栈来实现。
自动换行
作者:Idra
除此之外,我们还有一套自动换行系统,避免插件开发者和翻译者被文本溢出问题搞得焦头烂额。自动换行系统的实现在 LineWrapping.kt 中,里面有详细的注释和说明。如上文所述,自动换行和翻译是同步执行的。