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);
}
⚠️ 两个问题:
-
节流条件
getTotalWorldTime() % 20 != 0在phase判定之前。getTotalWorldTime()每 tick 递增,所以% 20 == 0每 20 tick 命中一次 —— 1 秒 1 次,符合意图。 但因为它在event.side == Side.SERVER之前执行, 客户端的 WorldTickEvent 也会跑这个取模与isEmpty()检查 (虽然随后被 side 判定挡掉)。逻辑未短路,浪费微小。 -
每秒向整个维度广播,且数据客户端可自行推算 ——
worldInfo.getRainTime()是客户端WorldClient自己持有的WorldClient.getWorldInfo()也读得到的值(虽然具体同步时机不同)。 这是本 mod 唯一的持续性网络流量。
多维度服上,P 个维度 × 每秒 1 条 × 每条 4 字节 + FML 封包开销。
异常处理
整段包在 try/catch (Exception) 里,
失败只 logger.error("Failed to get rain!", ex)(:28)。
相关
- PacketHandler - 注册处(id 1)
- WorldHandler - 发送方
- MessageSeed - 另一条消息(id 0,登录时一次)
- Tag - 静态字段宿主