• 欢迎来到HiMCBBS论坛~ 论坛发帖/回帖等功能临时维护 发布/查看资源请到导航栏的【资源中心】!
  • 用爱发电——支持论坛~ 您可以不花一分钱支持我们啦!详见此处

teddyxlandlee

【Lv:1】
楼主
成员
2024-03-07
4
4
金粒
1,426金粒
钻石
0钻石
因为你坛限制比较少,同时也是出于对你站站长的信任,所以就在这发了,当然我的意思不是说要发不能发的啊

愚人节的前一天,破天荒地水了个模组 PoemLover,大概是想作为一个要长期潜水的开发者的一个愚人节玩笑吧。
好几天前就有这个想法,于是翻了翻 Linkie,写了个草案,里面详细地描述了模组的作用机制,精细到要对原版作出什么修改。
(毕竟是小Mod嘛,所以还是一贯地使用 ASM,并且不导入 MC 依赖,但是这次不去适配 1.16 了,所以做到 LowCode 还相对容易一些)
目标:让玩家每次通过出口传送门时都能看到终末之诗

Side: 仅限客户端

目标用户:>=1.18.2,Fabric/Forge/Quilt/Neo

为何在客户端可用:
当跳入传送门时,服务器简单地发送一个数据包:
`ClientboundGameEventPacket.WIN_GAME(param: float)`。是客户端决定在`param`在[-0.5,0.5)时立即重生,或在`param`在[0.5,1.5)时看到诗篇并在附近重生。简而言之,是客户端根据`param`值决定何时重生(根据原版客户端中的`param`值)。

对客户端进行hack:
找到`ClientPacketListener#handleGameEvent`。`clientboundGameEventPacket`指的是参数1。
重定向`clientboundGameEventPacket.getParam()`:当`clientboundGameEventPacket.getEvent()`等于`WIN_GAME`时,返回`1.1451F`

Mappings (使用MojMaps作为主要):
| int | intermediary |
| srg | srg above 1.17 |
通过Linkie在1.18.2和1.20.4进行了可用性检查

net.minecraft.network.protocol.game.ClientboundGameEventPacket.getParam:()F
int: net.minecraft.class_2668.method_11492:()F
srg: net.minecraft.network.protocol.game.ClientboundGameEventPacket.m_132181_:()F

net.minecraft.network.protocol.game.ClientboundGameEventPacket.getEvent:()Lnet/minecraft/network/protocol/game/ClientboundGameEventPacket$Type;
int: net.minecraft.class_2668.method_11491:()Lnet/minecraft/class_2668$class_5402;
srg: net.minecraft.network.protocol.game.ClientboundGameEventPacket.m_132178_:()Lnet/minecraft/network/protocol/game/ClientboundGameEventPacket$Type;

net.minecraft.network.protocol.game.ClientboundGameEventPacket.WIN_GAME:Lnet/minecraft/network/protocol/game/ClientboundGameEventPacket$Type;
int: net.minecraft.class_2668.field_25649:Lnet/minecraft/class_2668$class_5402;
srg: net.minecraft.network.protocol.game.ClientboundGameEventPacket.f_132157_:Lnet/minecraft/network/protocol/game/ClientboundGameEventPacket$Type;

net.minecraft.client.multiplayer.ClientPacketListener.handleGameEvent:(Lnet/minecraft/network/protocol/game/ClientboundGameEventPacket;)V
int: net.minecraft.class_634.method_11085:(Lnet/minecraft/class_2668;)V
srg: net.minecraft.client.multiplayer.ClientPacketListener.m_7616_:(Lnet/minecraft/network/protocol/game/ClientboundGameEventPacket;)V
但现在学业比较忙了嘛,甚至没有工夫测试了,所以我把编译好的 Mod 往小群里一丢,请求大家帮我测试。
出乎我意料的是,一遍过,所有功能全部正常。
然后我就在 MineBBS 和本站发了帖子了。KLPBBS 再次维护,所以也压根就发不了。
后来还在 Modrinth 上发了一份,今天刚审核通过:https://modrinth.com/mod/poem-lover




另外,我还破天荒地给 LangPatch 写了个 NeoForge 兼容。
本来想尝试把 Fabric、Forge、Neo 的跨平台最基本 API(如 SideOnly、Mod 注解等)放到一个假的依赖库里,然后让 LangPatch 编译时依赖这个库,这样就可以继续保持不导入MC本体的情况——于是就有了lowcode-universal
然后我就发现这玩意不够用了。

好在很早之前写过一个 Forge Init Injector Gradle 插件,可以在不导入 Forge 本体的情况下,不仅能生成 Mod 类,还能调用模组初始化的钩子,甚至可以在一定条件下(如:XXX 类是否存在)执行一些自定义的操作。当时比较爱倒腾 ASM,所以就写了个这个。
1.18 开始,Forge 就引入 Lowcode Provider 了,这也就是 PoemLover 为啥可以不引入 Forge 依赖的原因。
但是 LangPatch 需要执行 Mixin/ASM 以外的初始化步骤,加上还要兼顾 1.16 版本,所以享不了这个福,用 Forge Init Injector 已经是上策了。

NeoForge 刚出来那会,想过在 Forge Init Injector 中添加对 NeoForge 的支持,但是当时着重想的一个问题是『怎么尽可能减小生成的类的体积,也就是尽可能复用类和方法』,但 Forge 和 Neo 至少存在包名上的差异(包括注解类和事件类等),脑容量不够,遂卒。
现在“想开了”,所以干脆对于事件类的处理上,直接采用了 Forge 和 Neo 分开的方式,即一边一类。同时启用了一个选项(supportNeo),默认是关上的。
我不得不承认,Forge Init Injector 是需要重构的。但鉴于根本没时间重构,就只能在屎山上打补丁了。

然后事情就简单了:给 LangPatch 的 Forge Init Injector 升个级(→1.1.0),再改改 Forge 端的 Mixin 插件,完工。

顺便我真的想说一下,Neo 在直接使用 MojMaps这一决策上,非常明智,非常牛逼,使我的 Tiny Remapper 停转。(真的是褒奖,没有反讽的意思)




其他的,好像没啥了。

也就是把 COVID-Trump maven 搬到了 mvn.7c7.icu 上。
原因为啥?COVID-Trump 连个干净点儿的初始提交记录都没有,导致往上 Merge 新的文件非常困难,需要下载至少 70MiB 的归档,我受不了。
然后我就写了个 Actions 把 COVID-Trump maven 不带编辑记录地搬了过来,Actions 本身就作为那个初始提交记录了。
现在,把 COVID-Trump maven 的链接 https://covid-trump.github.io/mvn 直接换成 https://mvn.7c7.icu 就行。后者 URL 更短,还更容易被接受。

写的有点多,发些金粒吧。下次上线不知道又是什么时候了。
Edit: 好像搞错红包大小了QAQ
 
最后编辑:
打赏用户
HiTech0926
teddyxlandlee

HiBBS有你更精彩

还可以输入20字数。
领取红包用户
wzxzgr QWERTY770 BoXueDuoCai lizimeili33
好好好(MOD是那个出地狱显示终末之诗的MOD吗?)