@@ -7,4 +7,101 @@ hide_table_of_contents: false
77
88---
99
10- #
10+ # 网络包注解处理器
11+
12+ 基础的使用介绍参考[ 网络包] ( 5 ) 一节。
13+
14+
15+
16+ ## ClientHandler
17+
18+ 在1.21.7之前,你可能习惯于直接在网络包的` clientHandler ` 方法里调用仅客户端的类,然后在方法上加` OnlyIn ` 。显然这个方法在新版本已经不适用,为了方便你的编写,T88提供一个简单的编译器插件,能够在编译时自动把` clientHandler ` 方法体用` Runnable ` 包起来以实现延迟加载。
19+
20+ 为了使用这个插件,除去常规的导入之外:
21+
22+ ``` groovy
23+ dependencies {
24+ implementation "net.neoforged:neoforge:${neo_version}"
25+
26+ implementation("cn.ussshenzhou:t88:0.+")
27+ annotationProcessor("cn.ussshenzhou:t88:0.+")
28+ }
29+ ```
30+
31+ 还需要在你的` build.gradle ` 里加上这么一段:
32+
33+ ``` groovy
34+ tasks.withType(JavaCompile).configureEach {
35+ options.fork = true
36+ options.forkOptions.jvmArgs += [
37+ '--add-exports', 'jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED',
38+ '--add-exports', 'jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',
39+ '--add-exports', 'jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED',
40+ '--add-exports', 'jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',
41+ ]
42+ options.compilerArgs += ['-Xplugin:T88ClientHandlerWrapper']
43+ }
44+ ```
45+
46+ 然后重新编译项目,对比源代码的从字节码反编译的结果:
47+
48+ ``` java
49+ @ClientHandler
50+ public void clientHandler(IPayloadContext context) {
51+ Level level = Minecraft . getInstance(). level;
52+ if (level != null ) {
53+ Random r = new Random ();
54+ var player = Minecraft . getInstance(). level. getPlayerByUUID(sourcePlayerUUID);
55+ if (player == null ) {
56+ return ;
57+ }
58+ var posOffset = getNozzlePosInWorld(player, 4 , 0 );
59+ var speed = getSpeedVec(player);
60+ for (int i = 0 ; i < particleOption. amount(); i++ ) {
61+ level. addParticle(
62+ particleOption,
63+ true ,
64+ particleOption. alwaysRender(). get(),
65+ posOffset. x + MathHelper . signedRandom(r) * particleOption. xDiffuse(),
66+ posOffset. y + MathHelper . signedRandom(r) * particleOption. yDiffuse(),
67+ posOffset. z + MathHelper . signedRandom(r) * particleOption. zDiffuse(),
68+ speed. x + MathHelper . signedRandom(r) * particleOption. vxDiffuse(),
69+ speed. y + MathHelper . signedRandom(r) * particleOption. vyDiffuse(),
70+ speed. z + MathHelper . signedRandom(r) * particleOption. vzDiffuse()
71+ );
72+ }
73+ }
74+ }
75+ ```
76+
77+ ``` java
78+ public void clientHandler(IPayloadContext context) {
79+ Runnable wrapped = new Runnable () {
80+ public void run () {
81+ Level level = Minecraft . getInstance(). level;
82+ if (level != null ) {
83+ Random r = new Random ();
84+ Player player = Minecraft . getInstance(). level. getPlayerByUUID(MadParticleTadaPacket . this . sourcePlayerUUID);
85+ if (player == null ) {
86+ return ;
87+ }
88+
89+ Vec3 posOffset = MadParticleTadaPacket . this . getNozzlePosInWorld(player, 4.0F , 0.0F );
90+ Vec3 speed = MadParticleTadaPacket . this . getSpeedVec(player);
91+
92+ for (int i = 0 ; i < MadParticleTadaPacket . this . particleOption. amount(); ++ i) {
93+ level. addParticle(MadParticleTadaPacket . this . particleOption, true , MadParticleTadaPacket . this . particleOption. alwaysRender(). get(), posOffset. x + MathHelper . signedRandom(r) * (double )MadParticleTadaPacket . this . particleOption. xDiffuse(), posOffset. y + MathHelper . signedRandom(r) * (double )MadParticleTadaPacket . this . particleOption. yDiffuse(), posOffset. z + MathHelper . signedRandom(r) * (double )MadParticleTadaPacket . this . particleOption. zDiffuse(), speed. x + MathHelper . signedRandom(r) * (double )MadParticleTadaPacket . this . particleOption. vxDiffuse(), speed. y + MathHelper . signedRandom(r) * (double )MadParticleTadaPacket . this . particleOption. vyDiffuse(), speed. z + MathHelper . signedRandom(r) * (double )MadParticleTadaPacket . this . particleOption. vzDiffuse());
94+ }
95+ }
96+
97+ }
98+ };
99+ wrapped. run();
100+ }
101+ ```
102+
103+ ::: tip
104+
105+ 在此过程中,` T88ClientHandlerWrapper ` 会自动地将` this ` 和` super ` 转换成` OuterClass.this ` 和` OuterClass.super ` ,但需要注意的是,T88并不会主动处理匿名内部类方法要求参数均为effective final的特性,effective final依靠方法体内实现自行保证。
106+
107+ :::
0 commit comments