MC 1.18.2 Forge实现玩家进世界发送可点击链接聊天消息
原代码失效原因
- 代码里对
String.format的用法完全错误,这个方法仅用于字符串占位符替换,和聊天组件的点击事件绑定没有任何关系,你传给方法的ClickEvent参数根本没被用到 - 你构造的
TextComponent只存了纯文本内容,没有通过样式方法绑定点击跳转事件,自然点了没反应 - 用静态变量
messageAlreadyReceived做消息发送标记会在多人环境下出现逻辑冲突,所有玩家共用同一个标记会导致部分玩家收不到消息,且切维度时事件重复触发会导致消息重复发送/不发送 - 没有做服务端逻辑判断,客户端侧触发事件时发消息会出现重复、指令不生效问题
原生组件实现方案(推荐)
直接构造带点击事件的聊天组件发送即可,不需要走tellraw命令,最简可用代码如下:
@SubscribeEvent public static void onEntityJoinWorld(EntityJoinWorldEvent event) { // 仅在服务端线程执行逻辑,避免客户端侧重复触发 if (event.getLevel().isClientSide()) return; if (!(event.getEntity() instanceof ServerPlayer player)) return; // 从玩家自身持久化标签取标记,避免切维度重复发消息、多玩家逻辑冲突 CompoundTag playerData = player.getPersistentData(); if (playerData.getBoolean("mod_join_msg_sent")) return; playerData.putBoolean("mod_join_msg_sent", true); // 构造可点击的消息组件 Component clickMsg = new TextComponent("点击前往项目Bug反馈页") .withStyle(style -> style.withClickEvent( new ClickEvent(ClickEvent.Action.OPEN_URL, "你自己的项目反馈页地址") )); // 发送系统消息 player.sendMessage(clickMsg, Util.NIL_UUID); }
需要导入的相关类均在net.minecraft.network.chat、net.minecraft.server.level.ServerPlayer、net.minecraft.nbt.CompoundTag、net.minecraft.Util包下。
tellraw命令实现方案
如果你已经写好可用的tellraw命令JSON,直接在服务端执行对应命令即可,代码参考:
// 把下方字符串替换为你自己写好的tellraw命令,注意拼接对玩家名参数 String tellrawCommand = "tellraw " + player.getName().getString() + " 你编写好的tellraw JSON内容"; player.server.getCommands().performPrefixedCommand( player.server.createCommandSourceStack(), tellrawCommand );
注意:所有消息发送、命令执行逻辑必须放在服务端判断分支内,不要在客户端线程执行服务端指令,否则会出现权限不足、逻辑不生效的问题。
内容的提问来源于stack exchange,提问作者AGMPenguin
相关产品推荐
相关产品推荐

