WorldHandler

服务端:每秒广播下一场雨的时间

基本信息

属性 值
路径 com.github.lunatrius.ingameinfo.handler.WorldHandler
行数 32
注册方 ServerProxy.init(:22)
事件 TickEvent.WorldTickEvent

唯一方法 onWorldTick(:15-31)

@SubscribeEvent
public void onWorldTick(TickEvent.WorldTickEvent event) {
    World world = event.world;
    if (world.playerEntities.isEmpty() || world.getTotalWorldTime() % 20 != 0) return;   // ①
    if (event.side == Side.SERVER && event.phase == TickEvent.Phase.END) {              // ②
        try {
            PacketHandler.INSTANCE.sendToDimension(
                new MessageNextRain(world.getWorldInfo().getRainTime()),
                world.provider.dimensionId);                                            // ③
        } catch (Exception ex) {
            Reference.logger.error("Failed to get rain!", ex);
        }
    }
}
# 条件 / 动作
① 无玩家 或 不是 20 的倍数 → 直接返回
② 必须 Side.SERVER 且 Phase.END
③ sendToDimension 广播到该维度全部玩家

两个条件的语义

① 的节流:% 20

world.getTotalWorldTime() 每 tick 递增 1, % 20 == 0 即每 20 tick 命中一次 = 每 1 秒(20 TPS)。

⚠️ 取模在 side 判定之前执行: 客户端的 WorldTickEvent 也会跑 playerEntities.isEmpty() 与取模, 然后才被 ② 挡掉。逻辑未短路,属于微小浪费(每 tick 一次取模)。

① 的空检查

world.playerEntities.isEmpty() 避免向无人维度广播。 多维度服上只有玩家所在的维度会发。

这是本 mod 唯一的持续网络流量

对比 PlayerHandler 本类
频率 每玩家每次登录 1 次 每秒(每有玩家的维度)
范围 sendTo 单人 sendToDimension 整维度
载荷 long(8 字节) int(4 字节)

多维度服 P 个有玩家维度: 每秒 P 条消息 × (4 字节 + FML 封包开销)。

⚠️ 客户端本可自行推算: WorldClient 持有 WorldClient.getWorldInfo(), getRainTime() 也在其中(虽由服务端分块同步时机决定)。 每秒广播是过度设计,属实际可优化的点。

异常处理

catch (Exception ex) → logger.error("Failed to get rain!", ex)。 失败不重试,等下一秒的 tick 自然再试。

只在服务端注册

ServerProxy(:22)注册。 客户端不注册 —— 虽然方法里有 event.side == Side.SERVER 判定 (说明作者预期它可能在客户端也被调用), 但实际只在服务端注册,该判定是冗余保险。

相关