MessageNextRain

服务端 → 客户端:距下次下雨的 tick

基本信息

属性 值
路径 com.github.lunatrius.ingameinfo.network.message.MessageNextRain
行数 41
网络 id 1
方向 Side.CLIENT(接收)
载荷 int(1 个定长字段)

类结构

与 MessageSeed 完全对称:

public class MessageNextRain implements IMessage, IMessageHandler<MessageNextRain, IMessage>
public int nextRainTime;
成员 说明
无参构造 字段置 0(FML 反序列化用)
fromBytes / toBytes readInt() / writeInt()
onMessage 写进 Tag 的静态字段

消费方是 TagWorld 的 nextrain tag。

与 MessageSeed 的对比

维度 MessageSeed 本类
id 0 1
字段类型 long int
发送方式 sendTo(单个玩家) sendToDimension(整维度)
触发事件 PlayerLoggedInEvent WorldTickEvent
频率 每玩家每次登录 1 次 每维度每秒 1 次

发送方的节流有缺陷

WorldHandler(:16-31):

if (world.playerEntities.isEmpty() || world.getTotalWorldTime() % 20 != 0) return;
if (event.side == Side.SERVER && event.phase == TickEvent.Phase.END) {
    PacketHandler.INSTANCE.sendToDimension(new MessageNextRain(world.getWorldInfo().getRainTime()),
                                            world.provider.dimensionId);
}

⚠️ 两个问题:

  1. 节流条件 getTotalWorldTime() % 20 != 0 在 phase 判定之前。 getTotalWorldTime() 每 tick 递增,所以 % 20 == 0 每 20 tick 命中一次 —— 1 秒 1 次,符合意图。 但因为它在 event.side == Side.SERVER 之前执行, 客户端的 WorldTickEvent 也会跑这个取模与 isEmpty() 检查 (虽然随后被 side 判定挡掉)。逻辑未短路,浪费微小。

  2. 每秒向整个维度广播,且数据客户端可自行推算 —— worldInfo.getRainTime() 是客户端 WorldClient 自己持有的 WorldClient.getWorldInfo() 也读得到的值(虽然具体同步时机不同)。 这是本 mod 唯一的持续性网络流量。

多维度服上,P 个维度 × 每秒 1 条 × 每条 4 字节 + FML 封包开销。

异常处理

整段包在 try/catch (Exception) 里, 失败只 logger.error("Failed to get rain!", ex)(:28)。

相关