Skip to content

Commit f398a32

Browse files
committed
Use event tick stages
1 parent bc883f8 commit f398a32

File tree

20 files changed

+201
-113
lines changed

20 files changed

+201
-113
lines changed

common/src/main/java/com/lambda/mixin/MinecraftClientMixin.java

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,16 @@
2424
import com.lambda.event.events.TickEvent;
2525
import com.lambda.module.modules.player.Interact;
2626
import com.lambda.module.modules.player.PacketMine;
27+
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
28+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
29+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
2730
import net.minecraft.client.MinecraftClient;
2831
import net.minecraft.client.gui.screen.Screen;
2932
import net.minecraft.client.gui.screen.ingame.ScreenHandlerProvider;
3033
import net.minecraft.client.network.ClientPlayerEntity;
3134
import net.minecraft.client.network.ClientPlayerInteractionManager;
35+
import net.minecraft.client.render.WorldRenderer;
36+
import net.minecraft.client.sound.SoundManager;
3237
import net.minecraft.util.thread.ThreadExecutor;
3338
import net.minecraft.util.Hand;
3439
import net.minecraft.util.hit.HitResult;
@@ -40,7 +45,7 @@
4045
import org.spongepowered.asm.mixin.injection.Redirect;
4146
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
4247

43-
@Mixin(MinecraftClient.class)
48+
@Mixin(value = MinecraftClient.class, priority = Integer.MAX_VALUE)
4449
public class MinecraftClientMixin {
4550
@Shadow
4651
@Nullable
@@ -49,24 +54,46 @@ public class MinecraftClientMixin {
4954
@Nullable
5055
public HitResult crosshairTarget;
5156

52-
@Inject(method = "tick", at = @At("HEAD"))
53-
void onTickPre(CallbackInfo ci) {
54-
EventFlow.post(new TickEvent.Pre());
57+
@WrapMethod(method = "render")
58+
void onLoopTick(boolean tick, Operation<Void> original) {
59+
EventFlow.post(TickEvent.Render.Pre.INSTANCE);
60+
original.call(tick);
61+
EventFlow.post(TickEvent.Render.Post.INSTANCE);
5562
}
5663

57-
@Inject(method = "tick", at = @At("RETURN"))
58-
void onTickPost(CallbackInfo ci) {
59-
EventFlow.post(new TickEvent.Post());
64+
@WrapMethod(method = "tick")
65+
void onTick(Operation<Void> original) {
66+
EventFlow.post(TickEvent.Pre.INSTANCE);
67+
original.call();
68+
EventFlow.post(TickEvent.Post.INSTANCE);
6069
}
6170

62-
@Inject(method = "render", at = @At("HEAD"))
63-
void onLoopTickPre(CallbackInfo ci) {
64-
EventFlow.post(new TickEvent.Render.Pre());
71+
@WrapOperation(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;tick()V"))
72+
void onNetwork(ClientPlayerInteractionManager instance, Operation<Void> original) {
73+
EventFlow.post(TickEvent.Network.Pre.INSTANCE);
74+
original.call(instance);
75+
EventFlow.post(TickEvent.Network.Post.INSTANCE);
6576
}
6677

67-
@Inject(method = "render", at = @At("RETURN"))
68-
void onLoopTickPost(CallbackInfo ci) {
69-
EventFlow.post(new TickEvent.Render.Post());
78+
@WrapOperation(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;handleInputEvents()V"))
79+
void onInput(MinecraftClient instance, Operation<Void> original) {
80+
EventFlow.post(TickEvent.Input.Pre.INSTANCE);
81+
original.call(instance);
82+
EventFlow.post(TickEvent.Input.Post.INSTANCE);
83+
}
84+
85+
@WrapOperation(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;tick()V"))
86+
void onWorldRenderer(WorldRenderer instance, Operation<Void> original) {
87+
EventFlow.post(TickEvent.WorldRender.Pre.INSTANCE);
88+
original.call(instance);
89+
EventFlow.post(TickEvent.WorldRender.Post.INSTANCE);
90+
}
91+
92+
@WrapOperation(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/sound/SoundManager;tick(Z)V"))
93+
void onSound(SoundManager instance, boolean paused, Operation<Void> original) {
94+
EventFlow.post(TickEvent.Sound.Pre.INSTANCE);
95+
original.call(instance, paused);
96+
EventFlow.post(TickEvent.Sound.Post.INSTANCE);
7097
}
7198

7299
@Inject(at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;info(Ljava/lang/String;)V", shift = At.Shift.AFTER, remap = false), method = "stop")

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import com.lambda.interaction.PlayerPacketManager;
2626
import com.lambda.interaction.request.rotation.RotationManager;
2727
import com.lambda.module.modules.player.PortalGui;
28+
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
29+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
2830
import net.minecraft.client.MinecraftClient;
2931
import net.minecraft.client.gui.screen.DeathScreen;
3032
import net.minecraft.client.gui.screen.Screen;
@@ -129,14 +131,11 @@ void sendBegin(CallbackInfo ci) {
129131
autoJumpEnabled = Lambda.getMc().options.getAutoJump().getValue();
130132
}
131133

132-
@Inject(method = "tick", at = @At(value = "HEAD"))
133-
void onTickPre(CallbackInfo ci) {
134-
EventFlow.post(new TickEvent.Player.Pre());
135-
}
136-
137-
@Inject(method = "tick", at = @At(value = "RETURN"))
138-
void onTickPost(CallbackInfo ci) {
139-
EventFlow.post(new TickEvent.Player.Post());
134+
@WrapMethod(method = "tick")
135+
void onTick(Operation<Void> original) {
136+
EventFlow.post(TickEvent.Player.Pre.INSTANCE);
137+
original.call();
138+
EventFlow.post(TickEvent.Player.Post.INSTANCE);
140139
}
141140

142141
@Redirect(method = "tickNewAi", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getYaw()F"))

common/src/main/kotlin/com/lambda/config/groups/BreakSettings.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.lambda.config.groups
1919

2020
import com.lambda.config.Configurable
21+
import com.lambda.event.events.TickEvent
2122
import com.lambda.interaction.request.Priority
2223
import com.lambda.interaction.request.breaking.BreakConfig
2324
import com.lambda.util.BlockUtils.allSigns
@@ -32,7 +33,7 @@ class BreakSettings(
3233
override val breakThreshold by c.setting("Break Threshold", 0.7f, 0.1f..1.0f, 0.02f, "The break amount at which the block is considered broken") { vis() }
3334
override val doubleBreak by c.setting("Double Break", true, "Allows breaking two blocks at once") { vis() }
3435
override val breakDelay by c.setting("Break Delay", 0, 0..5, 1, "The delay between breaking blocks", " ticks") { vis() }
35-
override val breakStageMask by c.setting("Break Stage Mask", setOf(*TickStage.entries.toTypedArray()), "The sub-tick timing at which break actions can be performed", vis)
36+
override val breakStageMask by c.setting("Break Stage Mask", setOf(TickEvent.Pre, TickEvent.Input.Pre, TickEvent.Player.Post), "The sub-tick timing at which break actions can be performed", vis)
3637
override val swing by c.setting("Swing Mode", SwingMode.Constant, "The times at which to swing the players hand") { vis() }
3738
override val swingType by c.setting("Break Swing Type", BuildConfig.SwingType.Vanilla, "The style of swing") { vis() && swing != SwingMode.None }
3839
override val sounds by c.setting("Break Sounds", true, "Plays the breaking sounds") { vis() }
@@ -47,4 +48,4 @@ class BreakSettings(
4748
override val forceSilkTouch by c.setting("Force Silk Touch", false, "Force silk touch when breaking blocks") { vis() }
4849
override val forceFortunePickaxe by c.setting("Force Fortune Pickaxe", false, "Force fortune pickaxe when breaking blocks") { vis() }
4950
override val minFortuneLevel by c.setting("Min Fortune Level", 1, 1..3, 1, "The minimum fortune level to use") { vis() && forceFortunePickaxe }
50-
}
51+
}

common/src/main/kotlin/com/lambda/config/groups/HotbarSettings.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.lambda.config.groups
1919

2020
import com.lambda.config.Configurable
21+
import com.lambda.event.events.TickEvent
2122
import com.lambda.interaction.request.Priority
2223
import com.lambda.interaction.request.hotbar.HotbarConfig
2324

@@ -30,5 +31,5 @@ class HotbarSettings(
3031
override val swapDelay by c.setting("Swap Delay", 0, 0..3, 1, "The number of ticks delay before allowing another hotbar selection swap", " ticks", vis)
3132
override val swapsPerTick by c.setting("Swaps Per Tick", 3, 1..10, 1, "The number of hotbar selection swaps that can take place each tick") { swapDelay <= 0 && vis() }
3233
override val swapPause by c.setting("Swap Pause", 0, 0..20, 1, "The delay in ticks to pause actions after switching to the slot", " ticks", vis)
33-
override val sequenceStageMask by c.setting("Hotbar Stage Mask", setOf(*TickStage.entries.toTypedArray()), "The sub-tick timing at which hotbar actions are performed", vis)
34-
}
34+
override val sequenceStageMask by c.setting("Hotbar Stage Mask", setOf(TickEvent.Pre, TickEvent.Input.Pre, TickEvent.Player.Post), "The sub-tick timing at which hotbar actions are performed", vis)
35+
}

common/src/main/kotlin/com/lambda/config/groups/PlaceSettings.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.lambda.config.groups
1919

2020
import com.lambda.config.Configurable
21+
import com.lambda.event.events.TickEvent
2122
import com.lambda.interaction.request.Priority
2223
import com.lambda.interaction.request.placing.PlaceConfig
2324

@@ -29,11 +30,11 @@ class PlaceSettings(
2930
override val rotateForPlace by c.setting("Rotate For Place", true, "Rotate towards block while placing") { vis() }
3031
override val airPlace by c.setting("Air Place", AirPlaceMode.None, "Allows for placing blocks without adjacent faces") { vis() }
3132
override val axisRotateSetting by c.setting("Axis Rotate", true, "Overrides the Rotate For Place setting and rotates the player on each axis to air place rotational blocks") { vis() && airPlace.isEnabled() }
32-
override val placeStageMask by c.setting("Place Sequence Mode", setOf(*TickStage.entries.toTypedArray()), "The sub-tick timing at which break actions are performed") { vis() }
33+
override val placeStageMask by c.setting("Place Sequence Mode", setOf(TickEvent.Pre, TickEvent.Input.Pre, TickEvent.Player.Post), "The sub-tick timing at which break actions are performed") { vis() }
3334
override val placeConfirmationMode by c.setting("Place Confirmation", PlaceConfirmationMode.PlaceThenAwait, "Wait for block placement confirmation") { vis() }
3435
override val maxPendingPlacements by c.setting("Max Pending Placements", 5, 0..30, 1, "The maximum amount of pending placements") { vis() }
3536
override val placementsPerTick by c.setting("Places Per Tick", 1, 1..30, 1, "Maximum instant block places per tick") { vis() }
3637
override val swing by c.setting("Swing", true, "Swings the players hand when placing") { vis() }
3738
override val swingType by c.setting("Place Swing Type", BuildConfig.SwingType.Vanilla, "The style of swing") { vis() && swing }
3839
override val sounds by c.setting("Place Sounds", true, "Plays the placing sounds") { vis() }
39-
}
40+
}

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

Lines changed: 81 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -19,51 +19,97 @@ package com.lambda.event.events
1919

2020
import com.lambda.event.Event
2121

22+
/**
23+
* Phases:
24+
*
25+
* 1. **Pre-Tick**: Increments uptime, steps world tick manager, decrement item use cooldown.
26+
* 2. **GUI Update**: Processes delayed messages, updates HUD.
27+
* 3. **Game Mode Update**: Updates targeted entity, ticks tutorial, and interaction managers.
28+
* 4. **Texture Update**: Ticks texture manager.
29+
* 5. **Screen Handling**: Manages screen logic, ticks current screen.
30+
* 6. **Debug HUD Update**: Resets debug HUD chunk.
31+
* 7. **Input Handling**: Handles input events, decrements attack cooldown.
32+
* 8. **World Update**: Ticks game and world renderers, world entities.
33+
* 9. **Music and Sound Update**: Ticks music tracker and sound manager.
34+
* 10. **Tutorial and Social Interactions**: Handles tutorial and social interactions, ticks world.
35+
* 11. **Pending Connection**: Ticks integrated server connection.
36+
* 12. **Keyboard Handling**: Polls for debug crash key presses.
37+
*
38+
* @see net.minecraft.client.MinecraftClient.tick
39+
*/
2240
sealed class TickEvent {
2341
/**
2442
* Triggered before each iteration of the game loop.
2543
*
2644
* Phases:
2745
*
28-
* 1. **Pre-Tick**: Increments uptime, steps world tick manager, decrement item use cooldown.
29-
* 2. **GUI Update**: Processes delayed messages, updates HUD.
30-
* 3. **Game Mode Update**: Updates targeted entity, ticks tutorial, and interaction managers.
31-
* 4. **Texture Update**: Ticks texture manager.
32-
* 5. **Screen Handling**: Manages screen logic, ticks current screen.
33-
* 6. **Debug HUD Update**: Resets debug HUD chunk.
34-
* 7. **Input Handling**: Handles input events, decrements attack cooldown.
35-
* 8. **World Update**: Ticks game and world renderers, world entities.
36-
* 9. **Music and Sound Update**: Ticks music tracker and sound manager.
37-
* 10. **Tutorial and Social Interactions**: Handles tutorial and social interactions, ticks world.
38-
* 11. **Pending Connection**: Ticks integrated server connection.
39-
* 12. **Keyboard Handling**: Polls for debug crash key presses.
40-
*
41-
* @see net.minecraft.client.MinecraftClient.tick
46+
* 1. Increments uptime
47+
* 2. Steps world tick manager
48+
* 3. Decrements item use cooldown
4249
*/
43-
class Pre : Event
50+
data object Pre : Event
4451

4552
/**
4653
* Triggered after each iteration of the game loop.
47-
* Targeted at 20 ticks per second.
54+
*/
55+
data object Post : Event
56+
57+
/**
58+
* Triggered during the network tick stage only
59+
*
60+
* Phases:
61+
*
62+
* 1. Synchronizes player inventory slot changes
63+
* 2. Clears the outgoing packet queue
64+
* 3. Ticks packet listeners
65+
* 4. Flushes the connection channel
66+
* 5. Updates network statistics
67+
* 6. Updates the packet logger
68+
*
69+
* @see net.minecraft.client.network.ClientPlayerInteractionManager.tick
70+
*/
71+
sealed class Network {
72+
data object Pre : Event
73+
data object Post : Event
74+
}
75+
76+
/**
77+
* Triggered during the input tick stage
4878
*
4979
* Phases:
5080
*
51-
* 1. **Pre-Tick**: Increments uptime, steps world tick manager, decrement item use cooldown.
52-
* 2. **GUI Update**: Processes delayed messages, updates HUD.
53-
* 3. **Game Mode Update**: Updates targeted entity, ticks tutorial, and interaction managers.
54-
* 4. **Texture Update**: Ticks texture manager.
55-
* 5. **Screen Handling**: Manages screen logic, ticks current screen.
56-
* 6. **Debug HUD Update**: Resets debug HUD chunk.
57-
* 7. **Input Handling**: Handles input events, decrements attack cooldown.
58-
* 8. **World Update**: Ticks game and world renderers, world entities (such as [TickEvent.Player]).
59-
* 9. **Music and Sound Update**: Ticks music tracker and sound manager.
60-
* 10. **Tutorial**: Handles tutorials, ticks world.
61-
* 11. **Pending Connection**: Ticks integrated server connection.
62-
* 12. **Keyboard Handling**: Polls for debug crash key presses.
63-
*
64-
* @see net.minecraft.client.MinecraftClient.tick
81+
* 1. Handles various game specific keys
82+
* 2. Handles block breaking
83+
* 3. Adds block breaking particles
84+
* 4. Swings the player arm
85+
* 5. Decrements attack cooldown
86+
*
87+
* @see net.minecraft.client.MinecraftClient.handleInputEvents
88+
*/
89+
sealed class Input {
90+
data object Pre : Event
91+
data object Post : Event
92+
}
93+
94+
/**
95+
* Triggered during the world render tick stage
96+
*
97+
* @see net.minecraft.client.render.WorldRenderer.tick
6598
*/
66-
class Post : Event
99+
sealed class WorldRender {
100+
data object Pre : Event
101+
data object Post : Event
102+
}
103+
104+
/**
105+
* Triggered during the sound update tick stage
106+
*
107+
* @see net.minecraft.client.sound.SoundManager.tick
108+
*/
109+
sealed class Sound {
110+
data object Pre : Event
111+
data object Post : Event
112+
}
67113

68114
/**
69115
* Triggered before ([Pre]) and after ([Post]) each render tick.
@@ -82,12 +128,12 @@ sealed class TickEvent {
82128
/**
83129
* Triggered before each render tick ([TickEvent.Render]) of the game loop.
84130
*/
85-
class Pre : Event
131+
data object Pre : Event
86132

87133
/**
88134
* Triggered after each render tick ([TickEvent.Render]) of the game loop.
89135
*/
90-
class Post : Event
136+
data object Post : Event
91137
}
92138

93139
/**
@@ -106,11 +152,11 @@ sealed class TickEvent {
106152
/**
107153
* Triggered before each player tick ([TickEvent.Player]).
108154
*/
109-
class Pre : Event
155+
data object Pre : Event
110156

111157
/**
112158
* Triggered after each player tick ([TickEvent.Player]).
113159
*/
114-
class Post : Event
160+
data object Post : Event
115161
}
116162
}

common/src/main/kotlin/com/lambda/interaction/request/Request.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ abstract class Request (
2424
var fresh = true
2525

2626
abstract val done: Boolean
27-
}
27+
}

0 commit comments

Comments
 (0)