button和input怎么放在一行_怎么知道原版是怎么实现 X 的?

本文作者3TUSK(@3TUSK),使用CC0协议发布至公有领域。

今天在 Harbinger[1] & Sputnik[2]反馈群中遇到一个问题:

请问 1.15 的 Forge 怎么执行指令啊

显然是一个 XY 问题[3]。我追问:

你的目标真的是执行命令吗?

得到的回复是:

在屏幕上显示一行字
目前我只会用 title 指令……

Good,我们回到了一个老话题上去:

我们经常会告诉新人「学会读原版的代码」,但是怎么读?

我随即演示了一遍怎么读,然后把流程趁我记忆还清晰时记录了下来:

1. 明确目标:「我要在屏幕上打出一行字」。

2. 明确我已知的解决方案:「我只知道 /title 指令可以做到这一点」。

3. 确定我的目标:「所以我去找 /title 命令在哪实现的」。

4. 开始尝试定位这个实现在哪。问问题的人说是在 Forge 环境下,所以我随手从我的二十几个 Mod 的工程目录中找了一个 Forge 31.2.4 的出来,用 VSCode 打开。既然是 Forge,那映射表自然就是 MCP。MCP 对于类的命名有一套不成文的体系,我们暂且不去讨论这套体系是什么,只需要知道「MCP 会把所有命令相关的类都放在 net.minecraft.command包下,而对于具体的命令实现则是 net.minecraft.command.impl 下」就够了。其中,impl指的是 implementation(英文「实现」),是一个非常常见的缩写。

5. 上文说到 MCP 有一套「不成文」的命名体系,其实有一些规则[4]还是有明确记载的,比如前缀命名。换言之,/title 命令的实现细节所在的类,它的名称会是 TitleCommand 而不是 CommandTitle

fd55c3fc274ec6d6762331af65ba37af.png

6. 双击打开这个类。

7. 迎面(海量)lambda 表达式糊脸,先别管这么多:我们直接看到有几个 executes 的实现是用到了一个叫 show 的方法。

2b2713f6e5e01ea04f6889ad73218a51.png

你以为我真的看到那个 executes 的实现是用到了 show 这个方法吗?其实并不,我的判断依据有两个,一是 lambda 表达式的排版,二是 show 这个单词本身反复出现三次,且含义和同级缩进的 clearreset 含义相反。

8. 右键 show 选择 Go to definition

e9dfa8ce543d97ac19937905ec619ef2.png

9. 然后我们知道了它的实现方式是向指定玩家发送 STitlePacket 这个包。

df4ef0002ca5cd28e978b8cb7928e668.png

所以我们也可以构造一个 STitlePacket 包。

10. 右键 STitlePacket,点 Go to definition。

68a6d10ce3f6dc7df4381177da916cf2.png

被跳转到了这里,我们有一个访问级是 public 构造器那就好说了。

2217f7053cdd4a6519222855841cd7ee.png

11. 然后我们就可以写出这样的代码了。

new STitlePacket(STitlePacket.Type.TITLE, new StringTextComponent("把XXX打在公屏上"));

什么,你问我那个 STitlePacket.Type 是怎么来的?

当然是继续用 Go to definition 直接跳转过去……

d93d95e6c42b5aedb5c6fad701bfa1cf.png

12. 好的然后我们注意到只有 ServerPlayerEntityconnection 这个字段,所以我们需要做一个检查。

if (player instanceof ServerPlayerEntity) {
    ((ServerPlayerEntity) player).connection.sendPacket(…);
}

故事到这就告一段落了……吗?其实并没有。

第 11 步中的 StringTextComponent 其实应该换成 TranslationTextComponent,以提供更好的国际化支持。

当然,如果你是在帮别人定制 Mod,国际化与本地化支持倒是可以忽略掉……感谢 zzzz 提出此条建议。


不过,经过一番讨论后,原提问者似乎认为构造数据包发送的方式太过复杂,最后仍然决定尝试执行命令……或许这确实不是一个 XY 问题。

参考

  1. ^https://harbinger.covertdragon.team/
  2. ^https://sputnik.covertdragon.team/
  3. ^http://xyproblem.info/
  4. ^https://github.com/ModCoderPack/MCPBot-Issues/issues/819
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值