Skip to content

Commit ec587e0

Browse files
Avanatikeremyfopsbeanbag44
authored
Feature: PacketMine (#20)
Co-authored-by: Kamigen <46357922+Edouard127@users.noreply.github.com> Co-authored-by: beanbag44 <pidgeonmaster64@gmail.com>
1 parent 19d70c1 commit ec587e0

File tree

11 files changed

+1685
-7
lines changed

11 files changed

+1685
-7
lines changed

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import net.minecraft.util.ActionResult;
1212
import net.minecraft.util.Hand;
1313
import net.minecraft.util.hit.BlockHitResult;
14+
import net.minecraft.util.math.BlockPos;
15+
import net.minecraft.util.math.Direction;
1416
import org.spongepowered.asm.mixin.Final;
1517
import org.spongepowered.asm.mixin.Mixin;
1618
import org.spongepowered.asm.mixin.Shadow;
@@ -26,6 +28,9 @@ public class ClientPlayInteractionManagerMixin {
2628
@Shadow
2729
private MinecraftClient client;
2830

31+
@Shadow
32+
public float currentBreakingProgress;
33+
2934
@Inject(method = "interactBlock", at = @At("HEAD"))
3035
public void interactBlockHead(final ClientPlayerEntity player, final Hand hand, final BlockHitResult hitResult, final CallbackInfoReturnable<ActionResult> cir) {
3136
if (client.world == null) return;
@@ -41,4 +46,27 @@ void onAttackPre(PlayerEntity player, Entity target, CallbackInfo ci) {
4146
void onAttackPost(PlayerEntity player, Entity target, CallbackInfo ci) {
4247
EventFlow.post(new AttackEvent.Post(target));
4348
}
49+
50+
@Inject(method = "attackBlock", at = @At("HEAD"), cancellable = true)
51+
public void onAttackBlock(BlockPos pos, Direction side, CallbackInfoReturnable<Boolean> cir) {
52+
if (EventFlow.post(new InteractionEvent.BlockAttack.Pre(pos, side)).isCanceled()) cir.cancel();
53+
}
54+
55+
@Inject(method = "attackBlock", at = @At("TAIL"))
56+
public void onAttackBlockPost(BlockPos pos, Direction side, CallbackInfoReturnable<Boolean> cir) {
57+
EventFlow.post(new InteractionEvent.BlockAttack.Post(pos, side));
58+
}
59+
60+
@Inject(method = "updateBlockBreakingProgress", at = @At("HEAD"), cancellable = true)
61+
private void updateBlockBreakingProgressPre(BlockPos pos, Direction side, CallbackInfoReturnable<Boolean> cir) {
62+
var event = EventFlow.post(new InteractionEvent.BreakingProgress.Pre(pos, side, currentBreakingProgress));
63+
if (event.isCanceled()) cir.cancel();
64+
65+
currentBreakingProgress = event.getProgress();
66+
}
67+
68+
@Inject(method = "updateBlockBreakingProgress", at = @At("TAIL"))
69+
private void updateBlockBreakingProgressPost(BlockPos pos, Direction side, CallbackInfoReturnable<Boolean> cir) {
70+
EventFlow.post(new InteractionEvent.BreakingProgress.Post(pos, side, currentBreakingProgress));
71+
}
4472
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33
import com.lambda.Lambda;
44
import com.lambda.event.EventFlow;
5+
import com.lambda.event.events.EntityEvent;
56
import com.lambda.event.events.MovementEvent;
67
import com.lambda.event.events.TickEvent;
78
import com.lambda.interaction.PlayerPacketManager;
89
import com.lambda.interaction.RotationManager;
910
import net.minecraft.client.input.Input;
1011
import net.minecraft.client.network.ClientPlayerEntity;
1112
import net.minecraft.entity.MovementType;
13+
import net.minecraft.util.Hand;
1214
import net.minecraft.util.math.Vec3d;
1315
import org.spongepowered.asm.mixin.Mixin;
1416
import org.spongepowered.asm.mixin.Shadow;
@@ -91,4 +93,9 @@ float fixHeldItemYaw(ClientPlayerEntity instance) {
9193
float fixHeldItemPitch(ClientPlayerEntity instance) {
9294
return Objects.requireNonNullElse(RotationManager.getHandPitch(), instance.getPitch());
9395
}
96+
97+
@Inject(method = "swingHand", at = @At("HEAD"), cancellable = true)
98+
void onSwingHandPre(Hand hand, CallbackInfo ci) {
99+
if (EventFlow.post(new EntityEvent.SwingHand(hand)).isCanceled()) ci.cancel();
100+
}
94101
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class RotationSettings(
1616
vis
1717
)
1818

19-
override val keepTicks by c.setting("Keep Rotation", 3, 1..10, 1, "Ticks to keep rotation", " ticks", vis)
19+
override val keepTicks by c.setting("Keep Rotation", 3, 0..10, 1, "Ticks to keep rotation", " ticks", vis)
2020
override val resetTicks by c.setting("Reset Rotation", 3, 1..10, 1, "Ticks before rotation is reset", " ticks", vis)
2121

2222
/**

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@ package com.lambda.event.events
33
import com.lambda.event.Event
44
import com.lambda.event.callback.Cancellable
55
import com.lambda.event.callback.ICancellable
6+
import net.minecraft.util.Hand
67

78
abstract class EntityEvent : Event {
89
class ChangeLookDirection(
910
val deltaYaw: Double,
1011
val deltaPitch: Double,
1112
) : EntityEvent(), ICancellable by Cancellable()
13+
14+
class SwingHand(
15+
val hand: Hand
16+
) : EntityEvent(), ICancellable by Cancellable()
1217
}
Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,42 @@
11
package com.lambda.event.events
22

33
import com.lambda.event.Event
4+
import com.lambda.event.callback.Cancellable
5+
import com.lambda.event.callback.ICancellable
46
import net.minecraft.client.world.ClientWorld
57
import net.minecraft.util.hit.BlockHitResult
8+
import net.minecraft.util.math.BlockPos
9+
import net.minecraft.util.math.Direction
610

711
sealed class InteractionEvent : Event {
812
class Block(
913
val world: ClientWorld,
1014
val blockHitResult: BlockHitResult
1115
) : InteractionEvent()
12-
}
16+
17+
sealed class BlockAttack : InteractionEvent() {
18+
class Pre(
19+
val pos: BlockPos,
20+
val side: Direction
21+
) : BlockAttack(), ICancellable by Cancellable()
22+
23+
class Post(
24+
val pos: BlockPos,
25+
val side: Direction
26+
) : BlockAttack()
27+
}
28+
29+
sealed class BreakingProgress : InteractionEvent() {
30+
class Pre(
31+
val pos: BlockPos,
32+
val side: Direction,
33+
var progress: Float,
34+
) : BreakingProgress(), ICancellable by Cancellable()
35+
36+
class Post(
37+
val pos: BlockPos,
38+
val side: Direction,
39+
val progress: Float,
40+
) : BreakingProgress()
41+
}
42+
}

common/src/main/kotlin/com/lambda/interaction/RotationManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ object RotationManager : Loadable {
3030
var currentRotation = Rotation.ZERO
3131
var prevRotation = Rotation.ZERO
3232

33-
private var currentContext: RotationContext? = null
33+
var currentContext: RotationContext? = null
3434

3535
private var keepTicks = 0
3636
private var pauseTicks = 0
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
package com.lambda.module.modules.player
2+
3+
import com.lambda.context.SafeContext
4+
import com.lambda.event.events.*
5+
import com.lambda.event.listener.SafeListener.Companion.listener
6+
import com.lambda.graphics.renderer.esp.DynamicAABB
7+
import com.lambda.graphics.renderer.esp.builders.buildFilled
8+
import com.lambda.graphics.renderer.esp.builders.buildOutline
9+
import com.lambda.graphics.renderer.esp.global.DynamicESP
10+
import com.lambda.module.Module
11+
import com.lambda.module.tag.ModuleTag
12+
import com.lambda.util.math.transform
13+
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket
14+
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action
15+
import com.lambda.util.math.MathUtils.lerp
16+
import net.minecraft.util.math.Box
17+
import java.awt.Color
18+
19+
object FastBreak : Module(
20+
name = "FastBreak",
21+
description = "Break blocks faster.",
22+
defaultTags = setOf(
23+
ModuleTag.PLAYER, ModuleTag.WORLD
24+
)
25+
) {
26+
private val page by setting("Page", Page.Mining)
27+
28+
private val breakDelay by setting("Break Delay", 5, 0..5, 1, unit = "ticks", description = "The tick delay between breaking blocks", visibility = { page == Page.Mining })
29+
private val breakThreshold by setting("Break Threshold", 0.7f, 0.2f..1.0f, 0.1f, description = "The progress at which the block will break.", visibility = { page == Page.Mining })
30+
31+
private val renderMode by setting("Render Mode", RenderMode.Out, "The animation style of the renders", visibility = { page == Page.Render })
32+
private val renderSetting by setting("Render Setting", RenderSetting.Both, "The different ways to draw the renders", visibility = { page == Page.Render && renderMode.isEnabled() })
33+
34+
private val fillColourMode by setting("Fill Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Outline })
35+
private val staticFillColour by setting("Static Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Static })
36+
private val startFillColour by setting("Start Fill Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic })
37+
private val endFillColour by setting("End Fill Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end fill of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Outline && fillColourMode == ColourMode.Dynamic })
38+
39+
private val outlineColourMode by setting("Outline Mode", ColourMode.Dynamic, visibility = { page == Page.Render && renderSetting != RenderSetting.Fill })
40+
private val staticOutlineColour by setting("Static Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the static outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Static })
41+
private val startOutlineColour by setting("Start Outline Colour", Color(1f, 0f, 0f, 0.3f), "The colour used to render the start outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic })
42+
private val endOutlineColour by setting("End Outline Colour", Color(0f, 1f, 0f, 0.3f), "The colour used to render the end outline of the box", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill && outlineColourMode == ColourMode.Dynamic })
43+
private val outlineWidth by setting("Outline Width", 1f, 0f..3f, 0.1f, "the thickness of the outline", visibility = { page == Page.Render && renderMode.isEnabled() && renderSetting != RenderSetting.Fill })
44+
45+
46+
private val renderer = DynamicESP
47+
private var boxSet = emptySet<Box>()
48+
49+
private enum class Page {
50+
Mining, Render
51+
}
52+
53+
private enum class RenderMode {
54+
Out, In, InOut, OutIn, Static, None;
55+
56+
fun isEnabled(): Boolean =
57+
this != None
58+
}
59+
60+
private enum class ColourMode {
61+
Static, Dynamic
62+
}
63+
64+
private enum class RenderSetting {
65+
Both, Fill, Outline
66+
}
67+
68+
init {
69+
listener<PacketEvent.Send.Pre> {
70+
if (it.packet !is PlayerActionC2SPacket
71+
|| it.packet.action != Action.STOP_DESTROY_BLOCK
72+
) return@listener
73+
74+
connection.sendPacket(
75+
PlayerActionC2SPacket(
76+
Action.ABORT_DESTROY_BLOCK,
77+
// For the exploit to work, the position must be outside the player range, so any
78+
// position farther than 6 blocks will work.
79+
// This is only required for grim 2 and potentially grim 3 in the future if they update it
80+
it.packet.pos.up(2024 - 4 - 18),
81+
it.packet.direction
82+
)
83+
)
84+
}
85+
86+
listener<TickEvent.Pre> {
87+
interaction.blockBreakingCooldown = interaction.blockBreakingCooldown.coerceAtMost(breakDelay)
88+
}
89+
90+
listener<InteractionEvent.BreakingProgress.Pre> {
91+
it.progress += world.getBlockState(it.pos)
92+
.calcBlockBreakingDelta(player, world, it.pos) * (1 - breakThreshold)
93+
}
94+
95+
listener<TickEvent.Post> {
96+
if (!renderMode.isEnabled()) return@listener
97+
98+
val pos = interaction.currentBreakingPos
99+
boxSet = world.getBlockState(pos).getOutlineShape(world, pos).boundingBoxes.toSet()
100+
}
101+
102+
listener<RenderEvent.World> {
103+
if (!interaction.isBreakingBlock || !renderMode.isEnabled()) return@listener
104+
105+
val pos = interaction.currentBreakingPos
106+
val breakDelta = world.getBlockState(pos).calcBlockBreakingDelta(player, world, pos)
107+
108+
renderer.clear()
109+
boxSet.forEach { box ->
110+
val previousFactor = interaction.currentBreakingProgress - breakDelta
111+
val nextFactor = interaction.currentBreakingProgress
112+
val currentFactor = lerp(previousFactor, nextFactor, mc.tickDelta)
113+
114+
val fillColour = if (fillColourMode == ColourMode.Dynamic) {
115+
lerp(startFillColour, endFillColour, currentFactor.toDouble())
116+
} else {
117+
staticFillColour
118+
}
119+
120+
val outlineColour = if (outlineColourMode == ColourMode.Dynamic) {
121+
lerp(startOutlineColour, endOutlineColour, currentFactor.toDouble())
122+
} else {
123+
staticOutlineColour
124+
}
125+
126+
val renderBox = if (renderMode != RenderMode.Static) {
127+
getLerpBox(box, currentFactor).offset(pos)
128+
} else {
129+
box.offset(pos)
130+
}
131+
132+
val dynamicAABB = DynamicAABB()
133+
dynamicAABB.update(renderBox)
134+
135+
if (renderSetting != RenderSetting.Outline) {
136+
renderer.buildFilled(dynamicAABB, fillColour)
137+
}
138+
139+
if (renderSetting != RenderSetting.Fill) {
140+
renderer.buildOutline(dynamicAABB, outlineColour)
141+
}
142+
}
143+
renderer.upload()
144+
}
145+
}
146+
147+
private fun getLerpBox(box: Box, factor: Float): Box {
148+
val boxCenter = Box(box.center, box.center)
149+
when (renderMode) {
150+
RenderMode.Out -> {
151+
return lerp(boxCenter, box, factor.toDouble())
152+
}
153+
154+
RenderMode.In -> {
155+
return lerp(box, boxCenter, factor.toDouble())
156+
}
157+
158+
RenderMode.InOut -> {
159+
return if (factor >= 0.5f) {
160+
lerp(boxCenter, box, (factor.toDouble() - 0.5) * 2)
161+
} else {
162+
lerp(box, boxCenter, factor.toDouble() * 2)
163+
}
164+
}
165+
166+
RenderMode.OutIn -> {
167+
return if (factor >= 0.5f) {
168+
lerp(box, boxCenter, (factor.toDouble() - 0.5) * 2)
169+
} else {
170+
lerp(boxCenter, box, factor.toDouble() * 2)
171+
}
172+
}
173+
174+
else -> {
175+
return box
176+
}
177+
}
178+
}
179+
180+
fun SafeContext.interpolateProgress(min: Double = 0.0, max: Double = 1.0) =
181+
transform(interaction.currentBreakingProgress.toDouble(), 0.0, 1.0, min, max)
182+
}

common/src/main/kotlin/com/lambda/module/modules/player/Interact.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ object Interact : Module(
88
description = "Modify players interaction with the world",
99
defaultTags = setOf(ModuleTag.PLAYER)
1010
) {
11-
// ToDo: Is this fast place / fast use? Should it be relocated with more options?
1211
@JvmStatic val placeDelay by setting("Item Use / Place Delay", 4, 0..20, 1, "Sets the delay between placing blocks or using items")
13-
// @JvmStatic val breakDelay by setting("Attack / Break Delay", 10, 0..20, 1)
1412
@JvmStatic val multiAction by setting("Multi Action", false, "Allows to use many items while breaking blocks")
1513
}

0 commit comments

Comments
 (0)