Skip to content

Commit 0d79c25

Browse files
committed
ref: events
1 parent a537676 commit 0d79c25

37 files changed

+449
-303
lines changed

common/src/main/java/com/lambda/mixin/entity/ClientPlayInteractionManagerMixin.java

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
package com.lambda.mixin.entity;
1919

2020
import com.lambda.event.EventFlow;
21-
import com.lambda.event.events.AttackEvent;
22-
import com.lambda.event.events.InteractionEvent;
21+
import com.lambda.event.events.LocalPlayerEvent;
2322
import net.minecraft.client.MinecraftClient;
2423
import net.minecraft.client.network.ClientPlayerEntity;
2524
import net.minecraft.client.network.ClientPlayerInteractionManager;
@@ -51,46 +50,31 @@ public class ClientPlayInteractionManagerMixin {
5150
@Inject(method = "interactBlock", at = @At("HEAD"))
5251
public void interactBlockHead(final ClientPlayerEntity player, final Hand hand, final BlockHitResult hitResult, final CallbackInfoReturnable<ActionResult> cir) {
5352
if (client.world == null) return;
54-
EventFlow.post(new InteractionEvent.Block(client.world, hitResult));
53+
EventFlow.post(new LocalPlayerEvent.BlockInteract(client.world, hitResult));
5554
}
5655

5756
@Inject(method = "clickSlot", at = @At("HEAD"), cancellable = true)
5857
public void clickSlotHead(int syncId, int slotId, int button, SlotActionType actionType, PlayerEntity player, CallbackInfo ci) {
5958
if (syncId != player.currentScreenHandler.syncId) return;
60-
var click = new InteractionEvent.SlotClick(syncId, slotId, button, actionType, player.currentScreenHandler);
59+
var click = new LocalPlayerEvent.SlotClick(syncId, slotId, button, actionType, player.currentScreenHandler);
6160
if (EventFlow.post(click).isCanceled()) ci.cancel();
6261
}
6362

6463
@Inject(method = "attackEntity", at = @At("HEAD"), cancellable = true)
6564
void onAttackPre(PlayerEntity player, Entity target, CallbackInfo ci) {
66-
if (EventFlow.post(new AttackEvent.Pre(target)).isCanceled()) ci.cancel();
67-
}
68-
69-
@Inject(method = "attackEntity", at = @At("TAIL"))
70-
void onAttackPost(PlayerEntity player, Entity target, CallbackInfo ci) {
71-
EventFlow.post(new AttackEvent.Post(target));
65+
if (EventFlow.post(new LocalPlayerEvent.EntityAttack(target)).isCanceled()) ci.cancel();
7266
}
7367

7468
@Inject(method = "attackBlock", at = @At("HEAD"), cancellable = true)
7569
public void onAttackBlock(BlockPos pos, Direction side, CallbackInfoReturnable<Boolean> cir) {
76-
if (EventFlow.post(new InteractionEvent.BlockAttack.Pre(pos, side)).isCanceled()) cir.cancel();
77-
}
78-
79-
@Inject(method = "attackBlock", at = @At("TAIL"))
80-
public void onAttackBlockPost(BlockPos pos, Direction side, CallbackInfoReturnable<Boolean> cir) {
81-
EventFlow.post(new InteractionEvent.BlockAttack.Post(pos, side));
70+
if (EventFlow.post(new LocalPlayerEvent.BlockAttack(pos, side)).isCanceled()) cir.cancel();
8271
}
8372

8473
@Inject(method = "updateBlockBreakingProgress", at = @At("HEAD"), cancellable = true)
8574
private void updateBlockBreakingProgressPre(BlockPos pos, Direction side, CallbackInfoReturnable<Boolean> cir) {
86-
var event = EventFlow.post(new InteractionEvent.BreakingProgress.Pre(pos, side, currentBreakingProgress));
75+
var event = EventFlow.post(new LocalPlayerEvent.BreakingProgress(pos, side, currentBreakingProgress));
8776
if (event.isCanceled()) cir.cancel();
8877

8978
currentBreakingProgress = event.getProgress();
9079
}
91-
92-
@Inject(method = "updateBlockBreakingProgress", at = @At("TAIL"))
93-
private void updateBlockBreakingProgressPost(BlockPos pos, Direction side, CallbackInfoReturnable<Boolean> cir) {
94-
EventFlow.post(new InteractionEvent.BreakingProgress.Post(pos, side, currentBreakingProgress));
95-
}
9680
}

common/src/main/java/com/lambda/mixin/entity/ClientPlayerEntityMixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import com.lambda.Lambda;
2121
import com.lambda.event.EventFlow;
22-
import com.lambda.event.events.EntityEvent;
22+
import com.lambda.event.events.LocalPlayerEvent;
2323
import com.lambda.event.events.MovementEvent;
2424
import com.lambda.event.events.TickEvent;
2525
import com.lambda.interaction.PlayerPacketManager;
@@ -125,6 +125,6 @@ float fixHeldItemPitch(ClientPlayerEntity instance) {
125125

126126
@Inject(method = "swingHand", at = @At("HEAD"), cancellable = true)
127127
void onSwingHandPre(Hand hand, CallbackInfo ci) {
128-
if (EventFlow.post(new EntityEvent.SwingHand(hand)).isCanceled()) ci.cancel();
128+
if (EventFlow.post(new LocalPlayerEvent.SwingHand(hand)).isCanceled()) ci.cancel();
129129
}
130130
}

common/src/main/java/com/lambda/mixin/entity/EntityMixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import com.lambda.Lambda;
2121
import com.lambda.event.EventFlow;
22-
import com.lambda.event.events.EntityEvent;
22+
import com.lambda.event.events.LocalPlayerEvent;
2323
import com.lambda.event.events.WorldEvent;
2424
import com.lambda.interaction.RotationManager;
2525
import com.lambda.util.math.Vec2d;
@@ -87,7 +87,7 @@ float fixDirectionPitch2(Entity entity) {
8787

8888
@Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true)
8989
private void changeLookDirection(double cursorDeltaX, double cursorDeltaY, CallbackInfo ci) {
90-
if (EventFlow.post(new EntityEvent.ChangeLookDirection(cursorDeltaX, cursorDeltaY)).isCanceled()) ci.cancel();
90+
if (EventFlow.post(new LocalPlayerEvent.ChangeLookDirection(cursorDeltaX, cursorDeltaY)).isCanceled()) ci.cancel();
9191
}
9292

9393
@Inject(method = "onTrackedDataSet(Lnet/minecraft/entity/data/TrackedData;)V", at = @At("TAIL"))

common/src/main/java/com/lambda/mixin/input/KeyboardMixin.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
package com.lambda.mixin.input;
1919

2020
import com.lambda.event.EventFlow;
21-
import com.lambda.event.events.KeyPressEvent;
21+
import com.lambda.event.events.KeyboardEvent;
2222
import net.minecraft.client.Keyboard;
2323
import org.spongepowered.asm.mixin.Mixin;
2424
import org.spongepowered.asm.mixin.injection.At;
@@ -28,9 +28,19 @@
2828
@Mixin(Keyboard.class)
2929
public class KeyboardMixin {
3030
@Inject(method = "onKey", at = @At("HEAD"))
31-
void onKey(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) {
31+
private void onKey(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) {
3232
if (key <= 0) return;
33-
if (action != 1) return;
34-
EventFlow.post(new KeyPressEvent(key, scancode, action, modifiers));
33+
if (action != 1) return; // TODO: Post events on both press and release ?
34+
35+
EventFlow.post(new KeyboardEvent.Press(key, scancode, action, modifiers));
36+
}
37+
38+
@Inject(method = "onChar", at = @At("HEAD"))
39+
private void onChar(long window, int codePoint, int modifiers, CallbackInfo ci) {
40+
char[] chars = Character.toChars(codePoint);
41+
42+
for (char c : chars) {
43+
EventFlow.post(new KeyboardEvent.Char(c));
44+
}
3545
}
3646
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2024 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.mixin.input;
19+
20+
import com.lambda.event.EventFlow;
21+
import com.lambda.event.events.MouseEvent;
22+
import net.minecraft.client.Mouse;
23+
import org.spongepowered.asm.mixin.Mixin;
24+
import org.spongepowered.asm.mixin.Shadow;
25+
import org.spongepowered.asm.mixin.injection.At;
26+
import org.spongepowered.asm.mixin.injection.Inject;
27+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
28+
29+
@Mixin(Mouse.class)
30+
public class MouseMixin {
31+
@Shadow private double x;
32+
33+
@Shadow private double y;
34+
35+
@Inject(method = "onMouseButton(JIII)V", at = @At("HEAD"), cancellable = true)
36+
private void onMouseButton(long window, int button, int action, int mods, CallbackInfo ci) {
37+
com.lambda.util.Mouse.Button btn = com.lambda.util.Mouse.Button.Companion.fromMouseCode(button);
38+
com.lambda.util.Mouse.Action act = com.lambda.util.Mouse.Action.Companion.fromActionCode(action);
39+
com.lambda.util.math.Vec2d position = new com.lambda.util.math.Vec2d(x, y);
40+
41+
if (EventFlow.post(new MouseEvent.Click(btn, act, mods, position)).isCanceled()) {
42+
ci.cancel();
43+
}
44+
}
45+
46+
@Inject(method = "onMouseScroll(JDD)V", at = @At("HEAD"), cancellable = true)
47+
private void onMouseScroll(long window, double horizontal, double vertical, CallbackInfo ci) {
48+
com.lambda.util.math.Vec2d delta = new com.lambda.util.math.Vec2d(horizontal, vertical);
49+
50+
if (EventFlow.post(new MouseEvent.Scroll(delta)).isCanceled()) {
51+
ci.cancel();
52+
}
53+
}
54+
55+
@Inject(method = "onCursorPos(JDD)V", at = @At("HEAD"), cancellable = true)
56+
private void onCursorPos(long window, double x, double y, CallbackInfo ci) {
57+
if (x + y == this.x + this.y) return;
58+
59+
com.lambda.util.math.Vec2d position = new com.lambda.util.math.Vec2d(x, y);
60+
61+
if (EventFlow.post(new MouseEvent.Move(position)).isCanceled()) {
62+
ci.cancel();
63+
}
64+
}
65+
}

common/src/main/java/com/lambda/mixin/world/ClientChunkManagerMixin.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ private void onChunkLoad(
5252
Consumer<ChunkData.BlockEntityVisitor> consumer,
5353
CallbackInfoReturnable<WorldChunk> info
5454
) {
55-
EventFlow.post(new WorldEvent.ChunkEvent.Load(this.world, info.getReturnValue()));
55+
EventFlow.post(new WorldEvent.ChunkEvent.Load(info.getReturnValue()));
5656
}
5757

5858
@Inject(method = "loadChunkFromPacket", at = @At(value = "NEW", target = "net/minecraft/world/chunk/WorldChunk", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD)
@@ -68,13 +68,13 @@ private void onChunkUnload(
6868
ChunkPos chunkPos
6969
) {
7070
if (chunk != null) {
71-
EventFlow.post(new WorldEvent.ChunkEvent.Unload(this.world, chunk));
71+
EventFlow.post(new WorldEvent.ChunkEvent.Unload(chunk));
7272
}
7373
}
7474

7575
@Inject(method = "unload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap;compareAndSet(ILnet/minecraft/world/chunk/WorldChunk;Lnet/minecraft/world/chunk/WorldChunk;)Lnet/minecraft/world/chunk/WorldChunk;"), locals = LocalCapture.CAPTURE_FAILHARD)
7676
private void onChunkUnload(ChunkPos pos, CallbackInfo ci, int i, WorldChunk chunk) {
77-
EventFlow.post(new WorldEvent.ChunkEvent.Unload(this.world, chunk));
77+
EventFlow.post(new WorldEvent.ChunkEvent.Unload(chunk));
7878
}
7979

8080
// @Inject(

common/src/main/kotlin/com/lambda/event/events/AttackEvent.kt

Lines changed: 0 additions & 28 deletions
This file was deleted.

common/src/main/kotlin/com/lambda/event/events/ClientEvent.kt

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,26 @@ import com.lambda.event.callback.Cancellable
2222
import com.lambda.event.callback.ICancellable
2323
import net.minecraft.client.sound.SoundInstance
2424

25+
sealed class ClientEvent {
26+
/**
27+
* Triggered upon client initialization
28+
*/
29+
class Startup : Event
2530

26-
abstract class ClientEvent : Event {
27-
class Shutdown : ClientEvent()
28-
class Startup : ClientEvent()
29-
class Timer(var speed: Double) : ClientEvent()
30-
class Sound(val sound: SoundInstance) : ClientEvent(), ICancellable by Cancellable()
31+
/**
32+
* Triggered upon client shutdown
33+
*/
34+
class Shutdown : Event
35+
36+
/**
37+
* Triggered upon game logic tick
38+
*
39+
* @property speed The speed of the timer.
40+
*/
41+
data class Timer(var speed: Double) : Event
42+
43+
/**
44+
* Triggered before playing a sound
45+
*/
46+
data class Sound(val sound: SoundInstance) : ICancellable by Cancellable()
3147
}

common/src/main/kotlin/com/lambda/event/events/ConnectionEvent.kt

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,54 +27,52 @@ import net.minecraft.text.Text
2727
import java.security.PublicKey
2828
import javax.crypto.SecretKey
2929

30-
/**
31-
* Sealed class representing connection events.
32-
*/
33-
sealed class ConnectionEvent : Event {
34-
/**
35-
* Sealed class representing various stages of connection establishment.
36-
*/
30+
sealed class ConnectionEvent {
3731
sealed class Connect {
3832
/**
39-
* Event representing a pre-connection attempt.
40-
* @property address The address of the connection attempt.
41-
* @property port The port of the connection attempt.
42-
* @property listener The packet listener associated with the connection.
43-
* @property intent The connection intent.
33+
* Event representing a pre-connection attempt
34+
*
35+
* @property address The address of the connection attempt
36+
* @property port The port of the connection attempt
37+
* @property listener The packet listener associated with the connection
38+
* @property intent The connection intent
4439
*/
45-
class Pre(
40+
data class Pre(
4641
val address: String,
4742
val port: Int,
4843
val listener: PacketListener,
4944
val intent: ConnectionIntent,
50-
) : ConnectionEvent(), ICancellable by Cancellable()
45+
) : ICancellable by Cancellable()
5146

5247
/**
53-
* Event representing a handshake during connection.
54-
* @property protocolVersion The protocol version of the connection.
55-
* @property address The address of the connection attempt.
56-
* @property port The port of the connection attempt.
57-
* @property intent The connection intent.
48+
* Event representing a handshake during connection
49+
*
50+
* @property protocolVersion The protocol version of the connection
51+
* @property address The address of the connection attempt
52+
* @property port The port of the connection attempt
53+
* @property intent The connection intent
54+
*
55+
* @see <a href="https://wiki.vg/Server_List_Ping#Handshake">Server_List_Ping#Handshake</a>
5856
*/
59-
class Handshake(
57+
data class Handshake(
6058
val protocolVersion: Int,
6159
val address: String,
6260
val port: Int,
6361
val intent: ConnectionIntent,
64-
) : ConnectionEvent()
62+
) : Event
6563

66-
/**
67-
* Sealed class representing login-related connection events.
68-
*/
69-
sealed class Login : ConnectionEvent() {
64+
sealed class Login {
7065
/**
71-
* @see <a href="https://wiki.vg/index.php?title=Protocol&oldid=19208#Encryption_Request">Encryption Request</a>
66+
* This event is not received by the client, it is sent from the client
67+
* to the server, this event simply intercepts the outbound packet
68+
*
69+
* @see <a href="https://wiki.vg/index.php?title=Protocol#Encryption_Request">Protocol#Encryption_Request</a>
7270
*/
7371
class EncryptionRequest(
7472
val serverId: String,
7573
val publicKey: PublicKey,
7674
val nonce: ByteArray,
77-
) : ConnectionEvent()
75+
) : Event
7876

7977
/**
8078
* Event representing the exchange of cryptographic keys during login
@@ -87,26 +85,25 @@ sealed class ConnectionEvent : Event {
8785
* This can be done by calling the `destroy()` method on the secret key object
8886
* We are not responsible for any incidents that may occur due to improper handling of cryptographic keys
8987
*
90-
* @see <a href="https://wiki.vg/index.php?title=Protocol&oldid=19208#Encryption_Response">Encryption Response</a>
88+
* @see <a href="https://wiki.vg/index.php?title=Protocol#Encryption_Response">Protocol#Encryption_Response</a>
9189
*/
9290
class EncryptionResponse(
9391
val secretKey: SecretKey,
9492
val publicKey: PublicKey,
9593
val nonce: ByteArray,
96-
) : ConnectionEvent()
94+
) : Event
9795
}
9896

9997
/**
100-
* Event representing post-connection actions.
101-
* @property profile The game profile associated with the connection.
98+
* Triggered upon successful connection process end
10299
*/
103-
class Post(
100+
data class Post(
104101
val profile: GameProfile,
105-
) : ConnectionEvent()
102+
) : Event
106103
}
107104

108105
/**
109-
* @property reason The reason for disconnection.
106+
* Triggered upon connection failure
110107
*/
111-
class Disconnect(val reason: Text) : ConnectionEvent()
108+
data class Disconnect(val reason: Text) : Event
112109
}

0 commit comments

Comments
 (0)