From 36fb2ea0f830fa737b40bce0524fd1b377356fad Mon Sep 17 00:00:00 2001 From: 1zuna <1zuna@ccbluex.net> Date: Mon, 6 Jan 2025 20:29:09 +0100 Subject: [PATCH 01/13] fix(StorageESP): storage carts esp not working (#5209) --- .../mixins/minecraft/render/MixinWorldRenderer.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/render/MixinWorldRenderer.java b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/render/MixinWorldRenderer.java index a1028d9b3b3..6c3a797236b 100644 --- a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/render/MixinWorldRenderer.java +++ b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/render/MixinWorldRenderer.java @@ -199,6 +199,8 @@ private boolean shouldRenderOutline(Entity entity) { return true; } else if (ModuleTNTTimer.INSTANCE.getRunning() && ModuleTNTTimer.INSTANCE.getEsp() && entity instanceof TntEntity) { return true; + } else if (ModuleStorageESP.Glow.INSTANCE.getRunning() && ModuleStorageESP.categorize(entity) != null) { + return true; } else { return false; } @@ -217,9 +219,14 @@ private int injectTeamColor(int original, @Local Entity entity) { return ModuleItemESP.INSTANCE.getColor().toARGB(); } else if (entity instanceof TntEntity tntEntity && ModuleTNTTimer.INSTANCE.getRunning() && ModuleTNTTimer.INSTANCE.getEsp()) { return ModuleTNTTimer.INSTANCE.getTntColor(tntEntity.getFuse()).toARGB(); - } else { - return original; + } else if (ModuleStorageESP.Glow.INSTANCE.getRunning()) { + var color = ModuleStorageESP.categorize(entity); + if (color != null) { + return color.getColor().toARGB(); + } } + + return original; } @Inject(method = "method_62214", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/OutlineVertexConsumerProvider;draw()V", shift = At.Shift.BEFORE)) From 40dbb8a82dc52280eb08f41da7e1ea817dcac113 Mon Sep 17 00:00:00 2001 From: MukjepScarlet <93977077+MukjepScarlet@users.noreply.github.com> Date: Tue, 7 Jan 2025 03:29:29 +0800 Subject: [PATCH 02/13] chore: improve Chinese translations (#5175) --- src/main/resources/resources/liquidbounce/lang/zh_cn.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/resources/resources/liquidbounce/lang/zh_cn.json b/src/main/resources/resources/liquidbounce/lang/zh_cn.json index 15b8e7e0cf0..4d299390e53 100644 --- a/src/main/resources/resources/liquidbounce/lang/zh_cn.json +++ b/src/main/resources/resources/liquidbounce/lang/zh_cn.json @@ -211,6 +211,9 @@ "liquidbounce.command.panic.result.nonRender": "非渲染", "liquidbounce.command.ping.description": "查看你的延迟。", "liquidbounce.command.ping.result.pingCheck": "你的延迟是: %sms。", + "liquidbounce.command.tps.description": "估算服务器的 TPS。", + "liquidbounce.command.tps.result.tpsCheck": "服务器的 TPS 为 %s。", + "liquidbounce.command.tps.result.nan": "TPS 还未计算完成!", "liquidbounce.command.client.subcommand.prefix.description": "更改命令前缀。", "liquidbounce.command.client.subcommand.prefix.parameter.prefix.description": "新的命令前缀。", "liquidbounce.command.client.subcommand.prefix.result.prefixChanged": "成功将命令前缀更改为 \"%s\"。", @@ -621,6 +624,7 @@ "liquidbounce.module.packetMine.description": "使你能通过单次点击破坏方块。", "liquidbounce.module.fastExp.description": "自动用经验瓶修复你的装备。", "liquidbounce.module.bookBot.description": "自动在书中写字。", + "liquidbounce.module.itemChams.description": "在你的手持物品上添加视觉效果。", "liquidbounce.module.betterTab.description": "对标签列表进行了多项改进。", "liquidbounce.module.autoPearl.description": "瞄准并向敌方珍珠的轨迹投掷一颗珍珠。" } From c832dde43fe980ab70cdfac076f75b404f242a51 Mon Sep 17 00:00:00 2001 From: Izuna <1zuna@ccbluex.net> Date: Mon, 6 Jan 2025 20:57:53 +0100 Subject: [PATCH 03/13] fix(Lithium): injection point failure (#5210) --- .../mixins/lithium/MixinChunkAwareBlockCollisionSweeper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/lithium/MixinChunkAwareBlockCollisionSweeper.java b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/lithium/MixinChunkAwareBlockCollisionSweeper.java index c18a4317ef4..b81f547ad18 100644 --- a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/lithium/MixinChunkAwareBlockCollisionSweeper.java +++ b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/lithium/MixinChunkAwareBlockCollisionSweeper.java @@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.At; @Pseudo -@Mixin(value = ChunkAwareBlockCollisionSweeper.class, remap = false) +@Mixin(value = ChunkAwareBlockCollisionSweeper.class) public class MixinChunkAwareBlockCollisionSweeper { @Shadow From a97fd4f32181d4952a005beb68fc60bff03bb476 Mon Sep 17 00:00:00 2001 From: MukjepScarlet <93977077+MukjepScarlet@users.noreply.github.com> Date: Tue, 7 Jan 2025 06:56:59 +0800 Subject: [PATCH 04/13] chore(LiquidChat): code cleanup (#5193) * chore(LiquidChat): code cleanup 1. GSON creations 2. deprecated SSLContext creation 3. packet registration * hashmap --- .../liquidbounce/features/chat/ChatClient.kt | 65 ++++++++++--------- .../chat/packet/PacketGsonExtension.kt | 8 +++ 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/chat/ChatClient.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/chat/ChatClient.kt index e8ac9b71a30..0eaa04f03f5 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/chat/ChatClient.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/chat/ChatClient.kt @@ -37,40 +37,40 @@ import io.netty.handler.codec.http.HttpObjectAggregator import io.netty.handler.codec.http.websocketx.TextWebSocketFrame import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory import io.netty.handler.codec.http.websocketx.WebSocketVersion -import io.netty.handler.ssl.SslContext +import io.netty.handler.ssl.SslContextBuilder import io.netty.handler.ssl.util.InsecureTrustManagerFactory +import net.ccbluex.liquidbounce.api.core.withScope import net.ccbluex.liquidbounce.authlib.yggdrasil.GameProfileRepository import net.ccbluex.liquidbounce.event.EventManager import net.ccbluex.liquidbounce.event.events.* import net.ccbluex.liquidbounce.features.chat.packet.* import net.ccbluex.liquidbounce.utils.client.chat import net.ccbluex.liquidbounce.utils.client.mc -import net.minecraft.util.Util import java.net.URI import java.util.* class ChatClient { - var channel: Channel? = null + private var channel: Channel? = null private val serializer = PacketSerializer().apply { - registerPacket("RequestMojangInfo", ServerRequestMojangInfoPacket::class.java) - registerPacket("LoginMojang", ServerLoginMojangPacket::class.java) - registerPacket("Message", ServerMessagePacket::class.java) - registerPacket("PrivateMessage", ServerPrivateMessagePacket::class.java) - registerPacket("BanUser", ServerBanUserPacket::class.java) - registerPacket("UnbanUser", ServerUnbanUserPacket::class.java) - registerPacket("RequestJWT", ServerRequestJWTPacket::class.java) - registerPacket("LoginJWT", ServerLoginJWTPacket::class.java) + register("RequestMojangInfo") + register("LoginMojang") + register("Message") + register("PrivateMessage") + register("BanUser") + register("UnbanUser") + register("RequestJWT") + register("LoginJWT") } private val deserializer = PacketDeserializer().apply { - registerPacket("MojangInfo", ClientMojangInfoPacket::class.java) - registerPacket("NewJWT", ClientNewJWTPacket::class.java) - registerPacket("Message", ClientMessagePacket::class.java) - registerPacket("PrivateMessage", ClientPrivateMessagePacket::class.java) - registerPacket("Error", ClientErrorPacket::class.java) - registerPacket("Success", ClientSuccessPacket::class.java) + register("MojangInfo") + register("NewJWT") + register("Message") + register("PrivateMessage") + register("Error") + register("Success") } val connected: Boolean @@ -79,13 +79,24 @@ class ChatClient { private var isConnecting = false var loggedIn = false + private val serializerGson by lazy { + GsonBuilder() + .registerTypeAdapter(Packet::class.java, serializer) + .create() + } + + private val deserializerGson by lazy { + GsonBuilder() + .registerTypeAdapter(Packet::class.java, deserializer) + .create() + } + fun connectAsync() { if (isConnecting || connected) { return } - // Async connecting using IO worker from Minecraft - Util.getIoWorkerExecutor().execute { + withScope { connect() } } @@ -95,7 +106,7 @@ class ChatClient { * Supports SSL and non-SSL connections. * Be aware SSL takes insecure certificates. */ - fun connect() = runCatching { + private fun connect() = runCatching { EventManager.callEvent(ClientChatStateChange(ClientChatStateChange.State.CONNECTING)) isConnecting = true loggedIn = false @@ -104,7 +115,7 @@ class ChatClient { val ssl = uri.scheme.equals("wss", true) val sslContext = if (ssl) { - SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE) + SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build() } else { null } @@ -227,11 +238,7 @@ class ChatClient { * Send packet to server */ internal fun sendPacket(packet: Packet) { - val gson = GsonBuilder() - .registerTypeAdapter(Packet::class.java, serializer) - .create() - - channel?.writeAndFlush(TextWebSocketFrame(gson.toJson(packet, Packet::class.java))) + channel?.writeAndFlush(TextWebSocketFrame(serializerGson.toJson(packet, Packet::class.java))) } private fun handleFunctionalPacket(packet: Packet) { @@ -315,11 +322,7 @@ class ChatClient { * Handle incoming message of websocket */ internal fun handlePlainMessage(message: String) { - val gson = GsonBuilder() - .registerTypeAdapter(Packet::class.java, deserializer) - .create() - - val packet = gson.fromJson(message, Packet::class.java) + val packet = deserializerGson.fromJson(message, Packet::class.java) handleFunctionalPacket(packet) } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/chat/packet/PacketGsonExtension.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/chat/packet/PacketGsonExtension.kt index 118438bcca2..b0b48fc85b2 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/chat/packet/PacketGsonExtension.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/chat/packet/PacketGsonExtension.kt @@ -39,6 +39,10 @@ class PacketSerializer : JsonSerializer { packetRegistry[packetClass] = packetName } + inline fun register(name: String) { + registerPacket(name, T::class.java) + } + /** * Gson invokes this call-back method during serialization when it encounters a field of the * specified type. @@ -80,6 +84,10 @@ class PacketDeserializer : JsonDeserializer { packetRegistry[packetName] = packetClass } + inline fun register(name: String) { + registerPacket(name, T::class.java) + } + /** * Gson invokes this call-back method during deserialization when it encounters a field of the * specified type. From 4e5810f56df84a57614f921ef0e938ba22527c57 Mon Sep 17 00:00:00 2001 From: Izuna <1zuna@ccbluex.net> Date: Tue, 7 Jan 2025 02:52:48 +0100 Subject: [PATCH 05/13] fix(RotationManager): update too early (#5211) --- .../utils/aiming/RotationManager.kt | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt index 48a7674d640..d92a0902f37 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt @@ -20,16 +20,17 @@ package net.ccbluex.liquidbounce.utils.aiming import net.ccbluex.liquidbounce.event.EventListener import net.ccbluex.liquidbounce.event.EventManager -import net.ccbluex.liquidbounce.event.events.MovementInputEvent -import net.ccbluex.liquidbounce.event.events.PacketEvent -import net.ccbluex.liquidbounce.event.events.PlayerVelocityStrafe -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.EventState +import net.ccbluex.liquidbounce.event.events.* import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.ClientModule import net.ccbluex.liquidbounce.features.module.modules.combat.ModuleBacktrack import net.ccbluex.liquidbounce.utils.client.* import net.ccbluex.liquidbounce.utils.combat.CombatManager -import net.ccbluex.liquidbounce.utils.entity.* +import net.ccbluex.liquidbounce.utils.entity.SimulatedPlayer +import net.ccbluex.liquidbounce.utils.entity.lastRotation +import net.ccbluex.liquidbounce.utils.entity.rotation +import net.ccbluex.liquidbounce.utils.entity.set import net.ccbluex.liquidbounce.utils.inventory.InventoryManager import net.ccbluex.liquidbounce.utils.kotlin.EventPriorityConvention import net.ccbluex.liquidbounce.utils.kotlin.Priority @@ -40,10 +41,6 @@ import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket import net.minecraft.util.math.Vec3d -import kotlin.math.abs -import kotlin.math.atan2 -import kotlin.math.hypot -import kotlin.math.sqrt /** @@ -213,7 +210,6 @@ object RotationManager : EventListener { return player.rotation == player.lastRotation } - @Suppress("unused") val velocityHandler = handler { event -> if (workingAimPlan?.applyVelocityFix == true) { @@ -225,7 +221,10 @@ object RotationManager : EventListener { * Updates at movement tick, so we can update the rotation before the movement runs and the client sends the packet * to the server. */ - val tickHandler = handler(priority = EventPriorityConvention.READ_FINAL_STATE) { event -> + @Suppress("unused") + private val movementInputHandler = handler( + priority = EventPriorityConvention.READ_FINAL_STATE + ) { event -> val input = SimulatedPlayer.SimulatedPlayerInput.fromClientPlayer(event.directionalInput) input.set( @@ -240,7 +239,6 @@ object RotationManager : EventListener { player.setPosition(simulatedPlayer.pos) EventManager.callEvent(SimulatedTickEvent(event, simulatedPlayer)) - update() player.setPosition(oldPos) @@ -250,6 +248,15 @@ object RotationManager : EventListener { } } + @Suppress("unused") + private val networkTickHandler = handler( + priority = EventPriorityConvention.READ_FINAL_STATE + ) { event -> + if (event.state == EventState.POST) { + update() + } + } + /** * Track rotation changes * From 2baf8b70709a3ec434e9204959804c120e01f27f Mon Sep 17 00:00:00 2001 From: Izuna <1zuna@ccbluex.net> Date: Tue, 7 Jan 2025 17:51:51 +0100 Subject: [PATCH 06/13] fix(RenderedEntities): null on not in-game (#5214) --- .../liquidbounce/utils/entity/RenderedEntities.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/RenderedEntities.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/RenderedEntities.kt index 48fa1661b7f..dc21b1f4b20 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/RenderedEntities.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/RenderedEntities.kt @@ -1,9 +1,11 @@ package net.ccbluex.liquidbounce.utils.entity import net.ccbluex.liquidbounce.event.EventListener +import net.ccbluex.liquidbounce.event.events.DisconnectEvent import net.ccbluex.liquidbounce.event.events.GameTickEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.MinecraftShortcuts +import net.ccbluex.liquidbounce.utils.client.inGame import net.ccbluex.liquidbounce.utils.combat.shouldBeShown import net.ccbluex.liquidbounce.utils.kotlin.EventPriorityConvention import net.minecraft.entity.LivingEntity @@ -25,12 +27,22 @@ object RenderedEntities : Iterable, EventListener, MinecraftShortc registry.remove(subscriber) } + @Suppress("unused") private val tickHandler = handler(priority = EventPriorityConvention.FIRST_PRIORITY) { + if (!inGame) { + return@handler + } + @Suppress("UNCHECKED_CAST") entities = world.entities.filter { it is LivingEntity && it.shouldBeShown() } as Iterable } + @Suppress("unused") + private val disconnectHandler = handler { + registry.clear() + } + override fun iterator(): Iterator = entities.iterator() } From c3253639a3e96c5755139e06855fe278a1901902 Mon Sep 17 00:00:00 2001 From: Izuna <1zuna@ccbluex.net> Date: Tue, 7 Jan 2025 18:13:51 +0100 Subject: [PATCH 07/13] refactor(RotationManager): rotation update order (#5213) --- .../liquidbounce/event/EventManager.kt | 2 +- .../liquidbounce/event/events/ClientEvents.kt | 11 +-- .../module/modules/combat/ModuleAimbot.kt | 4 +- .../module/modules/combat/ModuleAutoShoot.kt | 9 +-- .../combat/crystalaura/ModuleCrystalAura.kt | 5 +- .../modules/combat/killaura/ModuleKillAura.kt | 4 +- .../module/modules/misc/ModuleAutoPearl.kt | 8 +- .../module/modules/movement/ModuleParkour.kt | 11 +-- .../techniques/FlyFireballCustomTechnique.kt | 4 +- .../techniques/FlyFireballLegitTechnique.kt | 4 +- .../cheststealer/features/FeatureChestAura.kt | 4 +- .../modules/player/nofall/modes/NoFallMLG.kt | 4 +- .../module/modules/world/ModuleBedDefender.kt | 5 +- .../module/modules/world/ModuleExtinguish.kt | 4 +- .../module/modules/world/ModuleHoleFiller.kt | 4 +- .../modules/world/ModuleProjectilePuncher.kt | 9 ++- .../module/modules/world/ModuleSurround.kt | 2 +- .../modules/world/autobuild/PlatformMode.kt | 4 +- .../modules/world/autobuild/PortalMode.kt | 4 +- .../modules/world/fucker/ModuleFucker.kt | 4 +- .../world/nuker/mode/LegitNukerMode.kt | 4 +- .../modules/world/scaffold/ModuleScaffold.kt | 63 +++++++++------ .../scaffold/features/ScaffoldLedgeFeature.kt | 39 +++++---- .../techniques/ScaffoldGodBridgeTechnique.kt | 79 ++++++++++++------- .../scaffold/techniques/ScaffoldTechnique.kt | 4 +- .../modules/world/traps/ModuleAutoTrap.kt | 4 +- .../utils/aiming/RaytracingExtensions.kt | 27 +++++-- .../utils/aiming/RotationManager.kt | 48 +++-------- .../utils/block/placer/BlockPlacer.kt | 31 ++++---- .../utils/entity/PlayerSimulationCache.kt | 6 +- 30 files changed, 215 insertions(+), 196 deletions(-) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt b/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt index 76e6df99650..9daa5177b68 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/event/EventManager.kt @@ -104,7 +104,7 @@ val ALL_EVENT_CLASSES: Array> = arrayOf( VirtualScreenEvent::class, FpsChangeEvent::class, ClientPlayerDataEvent::class, - SimulatedTickEvent::class, + RotationUpdateEvent::class, SplashOverlayEvent::class, SplashProgressEvent::class, RefreshArrayListEvent::class, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt b/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt index 399797f70af..05661abec22 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/event/events/ClientEvents.kt @@ -32,7 +32,6 @@ import net.ccbluex.liquidbounce.integration.interop.protocol.event.WebSocketEven import net.ccbluex.liquidbounce.integration.interop.protocol.rest.v1.game.PlayerData import net.ccbluex.liquidbounce.integration.theme.component.Component import net.ccbluex.liquidbounce.utils.client.Nameable -import net.ccbluex.liquidbounce.utils.entity.SimulatedPlayer import net.ccbluex.liquidbounce.utils.inventory.InventoryAction import net.ccbluex.liquidbounce.utils.inventory.InventoryActionChain import net.ccbluex.liquidbounce.utils.inventory.InventoryConstraints @@ -196,14 +195,8 @@ class ServerPingedEvent(val server: ServerInfo) : Event() @WebSocketEvent(serializer = GsonInstance.ACCESSIBLE_INTEROP) class ComponentsUpdate(val components: List) : Event() -/** - * The simulated tick event is called by the [MovementInputEvent] with a simulated movement context. - * This context includes a simulated player position one tick into the future. - * Position changes will not apply within the simulated tick. Only use this for prediction purposes as - * updating the rotation or target. - */ -@Nameable("simulatedTick") -class SimulatedTickEvent(val movementEvent: MovementInputEvent, val simulatedPlayer: SimulatedPlayer) : Event() +@Nameable("rotationUpdate") +object RotationUpdateEvent : Event() @Nameable("resourceReload") object ResourceReloadEvent : Event() diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAimbot.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAimbot.kt index 800054afaaa..f2e89a6e153 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAimbot.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAimbot.kt @@ -20,7 +20,7 @@ package net.ccbluex.liquidbounce.features.module.modules.combat import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable import net.ccbluex.liquidbounce.event.events.MouseRotationEvent -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.events.WorldRenderEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.Category @@ -73,7 +73,7 @@ object ModuleAimbot : ClientModule("Aimbot", Category.COMBAT, aliases = arrayOf( private var targetRotation: Rotation? = null private var playerRotation: Rotation? = null - private val tickHandler = handler { _ -> + private val tickHandler = handler { _ -> this.targetTracker.validateLock { target -> target.boxedDistanceTo(player) <= range } this.playerRotation = player.rotation diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAutoShoot.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAutoShoot.kt index 21327524f07..2381cb85349 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAutoShoot.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/ModuleAutoShoot.kt @@ -22,7 +22,7 @@ package net.ccbluex.liquidbounce.features.module.modules.combat import net.ccbluex.liquidbounce.config.types.NamedChoice -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.events.WorldRenderEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler @@ -47,16 +47,11 @@ import net.ccbluex.liquidbounce.utils.item.findHotbarSlot import net.ccbluex.liquidbounce.utils.item.isNothing import net.ccbluex.liquidbounce.utils.kotlin.Priority import net.ccbluex.liquidbounce.utils.render.WorldTargetRenderer -import net.ccbluex.liquidbounce.utils.render.trajectory.TrajectoryData import net.ccbluex.liquidbounce.utils.render.trajectory.TrajectoryInfo import net.minecraft.entity.LivingEntity import net.minecraft.item.Item import net.minecraft.item.Items import net.minecraft.util.Hand -import kotlin.math.atan -import kotlin.math.atan2 -import kotlin.math.pow -import kotlin.math.sqrt /** * A module that automatically shoots at the nearest enemy. @@ -115,7 +110,7 @@ object ModuleAutoShoot : ClientModule("AutoShoot", Category.COMBAT) { * as fast possible. This means we already pre-aim before we peek around the corner. */ @Suppress("unused") - val simulatedTickHandler = handler { + val simulatedTickHandler = handler { targetTracker.cleanup() // Find the recommended target diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/crystalaura/ModuleCrystalAura.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/crystalaura/ModuleCrystalAura.kt index 9d3b75894d9..f7088c322f7 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/crystalaura/ModuleCrystalAura.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/crystalaura/ModuleCrystalAura.kt @@ -19,7 +19,7 @@ package net.ccbluex.liquidbounce.features.module.modules.combat.crystalaura import net.ccbluex.liquidbounce.config.types.Configurable -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.events.WorldRenderEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.Category @@ -27,7 +27,6 @@ import net.ccbluex.liquidbounce.features.module.ClientModule import net.ccbluex.liquidbounce.render.renderEnvironmentForWorld import net.ccbluex.liquidbounce.utils.aiming.NoRotationMode import net.ccbluex.liquidbounce.utils.aiming.NormalRotationMode -import net.ccbluex.liquidbounce.utils.aiming.RotationMode import net.ccbluex.liquidbounce.utils.combat.CombatManager import net.ccbluex.liquidbounce.utils.combat.TargetTracker import net.ccbluex.liquidbounce.utils.kotlin.Priority @@ -81,7 +80,7 @@ object ModuleCrystalAura : ClientModule( } @Suppress("unused") - val simulatedTickHandler = handler { + val simulatedTickHandler = handler { CrystalAuraDamageOptions.cacheMap.clear() if (CombatManager.shouldPauseCombat) { return@handler diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt index c135a763cea..540ab61f190 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt @@ -22,7 +22,7 @@ import com.google.gson.JsonObject import net.ccbluex.liquidbounce.config.types.NamedChoice import net.ccbluex.liquidbounce.event.Sequence import net.ccbluex.liquidbounce.event.events.InputHandleEvent -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.events.WorldRenderEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler @@ -157,7 +157,7 @@ object ModuleKillAura : ClientModule("KillAura", Category.COMBAT) { } @Suppress("unused") - val rotationUpdateHandler = handler { + val rotationUpdateHandler = handler { // Make sure killaura-logic is not running while inventory is open val isInInventoryScreen = InventoryManager.isInventoryOpen || mc.currentScreen is GenericContainerScreen diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleAutoPearl.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleAutoPearl.kt index 8912004a6e5..0d200e42fbd 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleAutoPearl.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleAutoPearl.kt @@ -22,7 +22,7 @@ import com.oracle.truffle.runtime.collection.ArrayQueue import net.ccbluex.liquidbounce.config.types.NamedChoice import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable import net.ccbluex.liquidbounce.event.events.PacketEvent -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.sequenceHandler import net.ccbluex.liquidbounce.event.tickHandler @@ -30,8 +30,6 @@ import net.ccbluex.liquidbounce.features.module.Category import net.ccbluex.liquidbounce.features.module.ClientModule import net.ccbluex.liquidbounce.features.module.modules.combat.killaura.ModuleKillAura import net.ccbluex.liquidbounce.features.module.modules.player.invcleaner.HotbarItemSlot -import net.ccbluex.liquidbounce.utils.render.trajectory.TrajectoryInfo -import net.ccbluex.liquidbounce.utils.render.trajectory.TrajectoryInfoRenderer import net.ccbluex.liquidbounce.utils.aiming.Rotation import net.ccbluex.liquidbounce.utils.aiming.RotationManager import net.ccbluex.liquidbounce.utils.aiming.RotationUtil @@ -43,6 +41,8 @@ import net.ccbluex.liquidbounce.utils.inventory.OFFHAND_SLOT import net.ccbluex.liquidbounce.utils.inventory.useHotbarSlotOrOffhand import net.ccbluex.liquidbounce.utils.item.findHotbarItemSlot import net.ccbluex.liquidbounce.utils.kotlin.Priority +import net.ccbluex.liquidbounce.utils.render.trajectory.TrajectoryInfo +import net.ccbluex.liquidbounce.utils.render.trajectory.TrajectoryInfoRenderer import net.minecraft.entity.Entity import net.minecraft.entity.EntityDimensions import net.minecraft.entity.EntityType @@ -111,7 +111,7 @@ object ModuleAutoPearl : ClientModule("AutoPearl", Category.MISC, aliases = arra } @Suppress("unused") - private val simulatedTickHandler = sequenceHandler { + private val simulatedTickHandler = sequenceHandler { val rotation = queue.peek() ?: return@sequenceHandler CombatManager.pauseCombatForAtLeast(combatPauseTime) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleParkour.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleParkour.kt index 146317d5db8..6e6f1ca69cf 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleParkour.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/ModuleParkour.kt @@ -18,10 +18,11 @@ */ package net.ccbluex.liquidbounce.features.module.modules.movement -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.MovementInputEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.Category import net.ccbluex.liquidbounce.features.module.ClientModule +import net.ccbluex.liquidbounce.utils.entity.PlayerSimulationCache import net.ccbluex.liquidbounce.utils.entity.moving /** @@ -32,17 +33,17 @@ import net.ccbluex.liquidbounce.utils.entity.moving object ModuleParkour : ClientModule("Parkour", Category.MOVEMENT) { @Suppress("unused") - private val simulatedTickHandler = handler { event -> + private val simulatedTickHandler = handler { event -> + val simulatedPlayer = PlayerSimulationCache.getSimulationForLocalPlayer() val shouldJump = player.moving && player.isOnGround && !player.isSneaking && !mc.options.sneakKey.isPressed && !mc.options.jumpKey.isPressed && - !event.simulatedPlayer.onGround - val movementInput = event.movementEvent + !simulatedPlayer.getSnapshotAt(1).onGround if (shouldJump) { - movementInput.jump = true + event.jump = true } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/fly/modes/fireball/techniques/FlyFireballCustomTechnique.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/fly/modes/fireball/techniques/FlyFireballCustomTechnique.kt index 45342fc0ac1..2a3f5768af7 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/fly/modes/fireball/techniques/FlyFireballCustomTechnique.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/fly/modes/fireball/techniques/FlyFireballCustomTechnique.kt @@ -25,7 +25,7 @@ import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable import net.ccbluex.liquidbounce.event.events.MovementInputEvent import net.ccbluex.liquidbounce.event.events.PlayerMoveEvent -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.sequenceHandler import net.ccbluex.liquidbounce.features.module.modules.movement.fly.ModuleFly @@ -71,7 +71,7 @@ object FlyFireballCustomTechnique : Choice("Custom") { } @Suppress("unused") - private val rotationUpdateHandler = handler { + private val rotationUpdateHandler = handler { RotationManager.aimAt( Rotation(player.yaw, Rotations.pitch), configurable = Rotations, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/fly/modes/fireball/techniques/FlyFireballLegitTechnique.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/fly/modes/fireball/techniques/FlyFireballLegitTechnique.kt index 79e9fba33c7..67537fa4c91 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/fly/modes/fireball/techniques/FlyFireballLegitTechnique.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/movement/fly/modes/fireball/techniques/FlyFireballLegitTechnique.kt @@ -24,7 +24,7 @@ import net.ccbluex.liquidbounce.config.types.Choice import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable import net.ccbluex.liquidbounce.event.events.MovementInputEvent -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.sequenceHandler import net.ccbluex.liquidbounce.event.tickHandler @@ -64,7 +64,7 @@ object FlyFireballLegitTechnique : Choice("Legit") { } @Suppress("unused") - private val rotationUpdateHandler = handler { + private val rotationUpdateHandler = handler { RotationManager.aimAt( Rotation(if (Rotations.backwards) this.invertYaw(player.yaw) else player.yaw, Rotations.pitch), configurable = Rotations, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/cheststealer/features/FeatureChestAura.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/cheststealer/features/FeatureChestAura.kt index 0592cf0e448..c2092faffbf 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/cheststealer/features/FeatureChestAura.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/cheststealer/features/FeatureChestAura.kt @@ -21,7 +21,7 @@ package net.ccbluex.liquidbounce.features.module.modules.player.cheststealer.features import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler import net.ccbluex.liquidbounce.features.module.modules.player.cheststealer.ModuleChestStealer @@ -93,7 +93,7 @@ object FeatureChestAura : ToggleableConfigurable(ModuleChestStealer, "Aura", tru // Event handler responsible for updating the target block @Suppress("unused") - private val simulatedTickHandler = handler { + private val simulatedTickHandler = handler { val searchRadius = interactionRange + 1 val searchRadiusSquared = searchRadius * searchRadius val playerEyesPosition = player.eyes diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallMLG.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallMLG.kt index 135c350f444..6f866ff379d 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallMLG.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/nofall/modes/NoFallMLG.kt @@ -21,7 +21,7 @@ package net.ccbluex.liquidbounce.features.module.modules.player.nofall.modes import net.ccbluex.liquidbounce.config.types.Choice import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler import net.ccbluex.liquidbounce.features.module.modules.player.invcleaner.HotbarItemSlot @@ -70,7 +70,7 @@ internal object NoFallMLG : Choice("MLG") { } @Suppress("unused") - private val tickMovementHandler = handler { + private val tickMovementHandler = handler { val currentGoal = this.getCurrentGoal() this.currentTarget = currentGoal diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleBedDefender.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleBedDefender.kt index 5ef60675de5..25c958ee093 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleBedDefender.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleBedDefender.kt @@ -19,7 +19,7 @@ package net.ccbluex.liquidbounce.features.module.modules.world import it.unimi.dsi.fastutil.ints.IntObjectPair -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.Category import net.ccbluex.liquidbounce.features.module.ClientModule @@ -31,7 +31,6 @@ import net.ccbluex.liquidbounce.utils.block.placer.BlockPlacer import net.ccbluex.liquidbounce.utils.block.searchBedLayer import net.ccbluex.liquidbounce.utils.block.searchBlocksInCuboid import net.ccbluex.liquidbounce.utils.entity.eyes -import net.ccbluex.liquidbounce.utils.entity.getNearestPoint import net.ccbluex.liquidbounce.utils.inventory.HOTBAR_SLOTS import net.ccbluex.liquidbounce.utils.item.isFullBlock import net.ccbluex.liquidbounce.utils.kotlin.Priority @@ -101,7 +100,7 @@ object ModuleBedDefender : ClientModule("BedDefender", category = Category.WORLD private val requiresSneak by boolean("RequiresSneak", false) @Suppress("unused") - private val targetUpdater = handler { + private val targetUpdater = handler { if (!placer.ignoreOpenInventory && mc.currentScreen is HandledScreen<*>) { return@handler } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleExtinguish.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleExtinguish.kt index 6b94686a982..b080cd1f49d 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleExtinguish.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleExtinguish.kt @@ -19,7 +19,7 @@ package net.ccbluex.liquidbounce.features.module.modules.world import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler import net.ccbluex.liquidbounce.features.module.Category @@ -64,7 +64,7 @@ object ModuleExtinguish: ClientModule("Extinguish", Category.WORLD) { private var lastExtinguishPos: BlockPos? = null private val lastAttemptTimer = Chronometer() - val tickMovementHandler = handler { + val tickMovementHandler = handler { this.currentTarget = null val target = findAction() ?: return@handler diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleHoleFiller.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleHoleFiller.kt index bfcdd9ac3fb..48176f2bf1c 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleHoleFiller.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleHoleFiller.kt @@ -20,7 +20,7 @@ package net.ccbluex.liquidbounce.features.module.modules.world import it.unimi.dsi.fastutil.booleans.BooleanDoubleImmutablePair import it.unimi.dsi.fastutil.objects.ObjectDoubleImmutablePair -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.Category import net.ccbluex.liquidbounce.features.module.ClientModule @@ -123,7 +123,7 @@ object ModuleHoleFiller : ClientModule("HoleFiller", Category.WORLD), HoleManage } @Suppress("unused") - private val targetUpdater = handler { + private val targetUpdater = handler { // all holes, if required 1x1 holes filtered out val holes = HoleTracker.holes.filter { !only1by1 || it.type == Hole.Type.ONE_ONE } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleProjectilePuncher.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleProjectilePuncher.kt index 9fa517b6805..63f4c893550 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleProjectilePuncher.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleProjectilePuncher.kt @@ -18,7 +18,7 @@ */ package net.ccbluex.liquidbounce.features.module.modules.world -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler import net.ccbluex.liquidbounce.features.module.Category @@ -29,7 +29,10 @@ import net.ccbluex.liquidbounce.utils.aiming.facingEnemy import net.ccbluex.liquidbounce.utils.aiming.raytraceBox import net.ccbluex.liquidbounce.utils.combat.ClickScheduler import net.ccbluex.liquidbounce.utils.combat.attack -import net.ccbluex.liquidbounce.utils.entity.* +import net.ccbluex.liquidbounce.utils.entity.box +import net.ccbluex.liquidbounce.utils.entity.eyes +import net.ccbluex.liquidbounce.utils.entity.prevPos +import net.ccbluex.liquidbounce.utils.entity.squaredBoxedDistanceTo import net.ccbluex.liquidbounce.utils.kotlin.Priority import net.ccbluex.liquidbounce.utils.math.minus import net.ccbluex.liquidbounce.utils.math.plus @@ -62,7 +65,7 @@ object ModuleProjectilePuncher : ClientModule("ProjectilePuncher", Category.WORL target = null } - val tickHandler = handler { + val tickHandler = handler { if (player.isSpectator) { return@handler } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleSurround.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleSurround.kt index 05d14b52a3b..aa091bd2f88 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleSurround.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/ModuleSurround.kt @@ -279,7 +279,7 @@ object ModuleSurround : ClientModule("Surround", Category.WORLD, disableOnQuit = } @Suppress("unused") - private val targetUpdater = handler { + private val targetUpdater = handler { if (disableOnYChange && player.pos.y != startY) { enabled = false return@handler diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autobuild/PlatformMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autobuild/PlatformMode.kt index 0e6098dbd5d..24b8a7c0bdc 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autobuild/PlatformMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autobuild/PlatformMode.kt @@ -18,7 +18,7 @@ */ package net.ccbluex.liquidbounce.features.module.modules.world.autobuild -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler import net.ccbluex.liquidbounce.features.module.modules.player.invcleaner.HotbarItemSlot @@ -50,7 +50,7 @@ object PlatformMode : ModuleAutoBuild.AutoBuildMode("Platform") { } @Suppress("unused") - private val targetUpdater = handler { + private val targetUpdater = handler { val blocks1 = hashSetOf() val center = BlockPos.ofFloored(player.pos).down() val pos = center.mutableCopy() diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autobuild/PortalMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autobuild/PortalMode.kt index 5d81d243a50..12c9437cf59 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autobuild/PortalMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/autobuild/PortalMode.kt @@ -18,7 +18,7 @@ */ package net.ccbluex.liquidbounce.features.module.modules.world.autobuild -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.modules.player.invcleaner.HotbarItemSlot import net.ccbluex.liquidbounce.features.module.modules.world.autobuild.ModuleAutoBuild.placer @@ -49,7 +49,7 @@ object PortalMode : ModuleAutoBuild.AutoBuildMode("Portal") { } @Suppress("unused") - private val targetUpdater = handler { + private val targetUpdater = handler { if (!placer.isDone()) { return@handler } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/fucker/ModuleFucker.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/fucker/ModuleFucker.kt index 87a8fa161d5..cf368c4c779 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/fucker/ModuleFucker.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/fucker/ModuleFucker.kt @@ -21,7 +21,7 @@ package net.ccbluex.liquidbounce.features.module.modules.world.fucker import net.ccbluex.liquidbounce.config.types.NamedChoice import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable import net.ccbluex.liquidbounce.event.events.CancelBlockBreakingEvent -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler import net.ccbluex.liquidbounce.features.module.Category @@ -123,7 +123,7 @@ object ModuleFucker : ClientModule("Fucker", Category.WORLD, aliases = arrayOf(" } @Suppress("unused") - private val targetUpdater = handler { + private val targetUpdater = handler { if (!ignoreOpenInventory && mc.currentScreen is HandledScreen<*>) { return@handler } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/nuker/mode/LegitNukerMode.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/nuker/mode/LegitNukerMode.kt index df687074900..e9e2f95de8c 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/nuker/mode/LegitNukerMode.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/nuker/mode/LegitNukerMode.kt @@ -20,7 +20,7 @@ package net.ccbluex.liquidbounce.features.module.modules.world.nuker.mode import net.ccbluex.liquidbounce.config.types.Choice import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler import net.ccbluex.liquidbounce.features.module.modules.player.ModuleBlink @@ -60,7 +60,7 @@ object LegitNukerMode : Choice("Legit") { private val switchDelay by int("SwitchDelay", 0, 0..20, "ticks") @Suppress("unused") - private val simulatedTickHandler = handler { + private val simulatedTickHandler = handler { if (!ignoreOpenInventory && mc.currentScreen is HandledScreen<*>) { this.currentTarget = null return@handler diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/ModuleScaffold.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/ModuleScaffold.kt index bb7f65ec4ab..19466ed0be4 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/ModuleScaffold.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/ModuleScaffold.kt @@ -25,7 +25,7 @@ import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable import net.ccbluex.liquidbounce.event.EventManager import net.ccbluex.liquidbounce.event.events.BlockCountChangeEvent import net.ccbluex.liquidbounce.event.events.MovementInputEvent -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler import net.ccbluex.liquidbounce.features.module.Category @@ -288,7 +288,7 @@ object ModuleScaffold : ClientModule("Scaffold", Category.WORLD) { private fun updateRenderCount(count: Int? = null) = EventManager.callEvent(BlockCountChangeEvent(count)) @Suppress("unused") - val rotationUpdateHandler = handler { + private val rotationUpdateHandler = handler { NoFallBlink.waitUntilGround = true val blockInHotbar = findBestValidHotbarSlotForTarget() @@ -346,26 +346,6 @@ object ModuleScaffold : ClientModule("Scaffold", Category.WORLD) { if (rotationTiming == NORMAL) { val rotation = technique.getRotations(target) - // Ledge feature - AutoJump and AutoSneak - if (ledge) { - val ledgeRotation = rotation ?: RotationManager.currentRotation ?: player.rotation - val (requiresJump, requiresSneak) = ledge( - it.simulatedPlayer, - target, - ledgeRotation, - technique as? ScaffoldLedgeExtension - ) - - if (requiresJump) { - it.movementEvent.jump = true - } - - if (requiresSneak > 0) { - it.movementEvent.sneak = true - forceSneak = requiresSneak - } - } - RotationManager.aimAt( rotation ?: return@handler, considerInventory = considerInventory, @@ -392,11 +372,44 @@ object ModuleScaffold : ClientModule("Scaffold", Category.WORLD) { } @Suppress("unused") - private val movementInputHandler = handler(priority = EventPriorityConvention.SAFETY_FEATURE) { + private val movementInputHandler = handler( + priority = EventPriorityConvention.SAFETY_FEATURE + ) { event -> if (forceSneak > 0) { - it.sneak = true + event.sneak = true forceSneak-- } + + // Ledge feature - AutoJump and AutoSneak + if (ledge) { + val technique = if (isTowering) { + ScaffoldNormalTechnique + } else { + technique.activeChoice + } + + val (jump, sneak, stepStop) = ledge( + this.currentTarget, + RotationManager.currentRotation ?: player.rotation, + technique as? ScaffoldLedgeExtension + ) + ModuleDebug.debugParameter(this, "Jump", jump.toString()) + ModuleDebug.debugParameter(this, "Sneak", sneak.toString()) + ModuleDebug.debugParameter(this, "StepStop", stepStop.toString()) + + if (jump) { + event.jump = true + } + + if (stepStop) { + event.directionalInput = DirectionalInput.NONE + } + + if (sneak > forceSneak) { + event.sneak = true + forceSneak = sneak + } + } } @Suppress("unused") @@ -407,7 +420,7 @@ object ModuleScaffold : ClientModule("Scaffold", Category.WORLD) { } @Suppress("unused") - val tickHandler = tickHandler { + private val tickHandler = tickHandler { updateRenderCount(blockCount) if (player.isOnGround) { diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/features/ScaffoldLedgeFeature.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/features/ScaffoldLedgeFeature.kt index dc5ef740b9f..38084929850 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/features/ScaffoldLedgeFeature.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/features/ScaffoldLedgeFeature.kt @@ -21,48 +21,47 @@ package net.ccbluex.liquidbounce.features.module.modules.world.scaffold.features import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.ModuleScaffold import net.ccbluex.liquidbounce.utils.aiming.Rotation import net.ccbluex.liquidbounce.utils.block.targetfinding.BlockPlacementTarget -import net.ccbluex.liquidbounce.utils.entity.SimulatedPlayer +import net.ccbluex.liquidbounce.utils.client.player +import net.ccbluex.liquidbounce.utils.entity.isCloseToEdge +import net.ccbluex.liquidbounce.utils.movement.DirectionalInput import kotlin.math.max -data class LedgeState( - val requiresJump: Boolean, - val requiresSneak: Int +data class LedgeAction( + val jump: Boolean = false, + val sneakTime: Int = 0, + val stopInput: Boolean = false ) { companion object { - val NO_LEDGE = LedgeState(requiresJump = false, requiresSneak = 0) + val NO_LEDGE = LedgeAction(jump = false, sneakTime = 0, stopInput = false) } + } fun ledge( - simulatedPlayer: SimulatedPlayer, target: BlockPlacementTarget?, rotation: Rotation, extension: ScaffoldLedgeExtension? = null -): LedgeState { - val ticks = ModuleScaffold.ScaffoldRotationConfigurable.howLongToReach(rotation) - val simClone = simulatedPlayer.clone() - simClone.tick() +): LedgeAction { + if (player.isCloseToEdge(DirectionalInput(player.input))) { + val ticks = ModuleScaffold.ScaffoldRotationConfigurable.howLongToReach(rotation) - // [ledgeSoon] could be replaced with isCloseToEdge, but I feel like this is more consistent - val ledgeSoon = simulatedPlayer.clipLedged || simClone.clipLedged + val isLowOnBlocks = ModuleScaffold.blockCount <= 0 + val isNotReady = ticks >= 1 - if ((ticks >= 1 || ModuleScaffold.blockCount <= 0) && ledgeSoon) { - return LedgeState(requiresJump = false, requiresSneak = max(1, ticks)) + if (isLowOnBlocks || isNotReady) { + return LedgeAction(jump = false, sneakTime = max(1, ticks)) + } } return extension?.ledge( - ledge = simulatedPlayer.clipLedged, - ledgeSoon = ledgeSoon, target = target, rotation = rotation - ) ?: LedgeState.NO_LEDGE + ) ?: LedgeAction.NO_LEDGE } interface ScaffoldLedgeExtension { fun ledge( - ledge: Boolean, - ledgeSoon: Boolean, target: BlockPlacementTarget?, rotation: Rotation - ): LedgeState + ): LedgeAction } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldGodBridgeTechnique.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldGodBridgeTechnique.kt index ff8e6b128a8..f0cadf3ff09 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldGodBridgeTechnique.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldGodBridgeTechnique.kt @@ -19,9 +19,10 @@ package net.ccbluex.liquidbounce.features.module.modules.world.scaffold.techniques import net.ccbluex.liquidbounce.config.types.NamedChoice +import net.ccbluex.liquidbounce.features.module.modules.render.ModuleDebug import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.ModuleScaffold import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.ModuleScaffold.getTargetedPosition -import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.features.LedgeState +import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.features.LedgeAction import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.features.ScaffoldLedgeExtension import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.techniques.ScaffoldNormalTechnique.NORMAL_INVESTIGATION_OFFSETS import net.ccbluex.liquidbounce.utils.aiming.Rotation @@ -29,6 +30,7 @@ import net.ccbluex.liquidbounce.utils.aiming.raycast import net.ccbluex.liquidbounce.utils.block.getState import net.ccbluex.liquidbounce.utils.block.targetfinding.* import net.ccbluex.liquidbounce.utils.client.toRadians +import net.ccbluex.liquidbounce.utils.entity.PlayerSimulationCache import net.ccbluex.liquidbounce.utils.entity.getMovementDirectionOfInput import net.ccbluex.liquidbounce.utils.math.geometry.Line import net.ccbluex.liquidbounce.utils.math.toBlockPos @@ -37,7 +39,6 @@ import net.minecraft.entity.EntityPose import net.minecraft.item.ItemStack import net.minecraft.util.math.Direction import net.minecraft.util.math.Vec3d -import net.minecraft.util.math.Vec3i import kotlin.math.cos import kotlin.math.floor import kotlin.math.round @@ -49,6 +50,10 @@ object ScaffoldGodBridgeTechnique : ScaffoldTechnique("GodBridge"), ScaffoldLedg private enum class Mode(override val choiceName: String) : NamedChoice { JUMP("Jump"), SNEAK("Sneak"), + /** + * Might not be as consistent as the other modes. + */ + STOP_INPUT("StopInput"), RANDOM("Random") } @@ -57,44 +62,60 @@ object ScaffoldGodBridgeTechnique : ScaffoldTechnique("GodBridge"), ScaffoldLedg private var sneakTime by int("SneakTime", 1, 1..10) override fun ledge( - ledge: Boolean, - ledgeSoon: Boolean, target: BlockPlacementTarget?, rotation: Rotation - ): LedgeState { + ): LedgeAction { if (!isSelected) { - return LedgeState.NO_LEDGE + return LedgeAction.NO_LEDGE } - // todo: introduce rotation prediction because currently I abuse [howLongItTakes] to get the ticks - // and simply check for the correct rotation without considering the Rotation Manager at all - val currentCrosshairTarget = raycast(rotation) + val simulatedPlayerCache = PlayerSimulationCache.getSimulationForLocalPlayer() - if (target == null || currentCrosshairTarget == null) { - if (ledgeSoon) { - return LedgeState(requiresJump = false, requiresSneak = sneakTime) + // Check if the current rotation is capable of placing a block on the next tick position, + // this might be inconsistent when the rotation changes on the next tick as well, + // but we hope it does not. :) + val snapshotOne = simulatedPlayerCache.getSnapshotAt(1) + + ModuleDebug.debugParameter(this, "Snapshot", snapshotOne.toString()) + + return if (snapshotOne.clipLedged) { + val cameraPosition = snapshotOne.pos.add(0.0, player.standingEyeHeight.toDouble(), 0.0) + val currentCrosshairTarget = raycast(start = cameraPosition, direction = rotation.rotationVec) + + if (target == null) { + return LedgeAction.NO_LEDGE } - } else if (ledge) { + + val targetFullfillsRequirements = target.doesCrosshairTargetFullFillRequirements(currentCrosshairTarget) + val isValidCrosshairTarget = ModuleScaffold.isValidCrosshairTarget(currentCrosshairTarget) + + ModuleDebug.debugParameter(this, "targetFullfillsRequirements", targetFullfillsRequirements.toString()) + ModuleDebug.debugParameter(this, "isValidCrosshairTarget", isValidCrosshairTarget.toString()) + // Does the crosshair target meet the requirements? - if (!target.doesCrosshairTargetFullFillRequirements(currentCrosshairTarget) - || !ModuleScaffold.isValidCrosshairTarget(currentCrosshairTarget)) { - return when { - ModuleScaffold.blockCount < forceSneakBelowCount -> { - LedgeState(requiresJump = false, requiresSneak = sneakTime) - } - mode == Mode.JUMP -> LedgeState(requiresJump = true, requiresSneak = 0) - mode == Mode.SNEAK -> LedgeState(requiresJump = false, requiresSneak = sneakTime) - mode == Mode.RANDOM -> if (Random.nextBoolean()) { - LedgeState(requiresJump = true, requiresSneak = 0) - } else { - LedgeState(requiresJump = false, requiresSneak = sneakTime) - } - else -> LedgeState.NO_LEDGE + if (targetFullfillsRequirements && isValidCrosshairTarget) { + return LedgeAction.NO_LEDGE + } + + // If the crosshair target does not meet the requirements, + // we need to prevent the player from falling off the ledge e.g by jumping or sneaking. + when { + ModuleScaffold.blockCount < forceSneakBelowCount -> { + LedgeAction(sneakTime = this@ScaffoldGodBridgeTechnique.sneakTime) + } + mode == Mode.JUMP -> LedgeAction(jump = true) + mode == Mode.SNEAK -> LedgeAction(sneakTime = this@ScaffoldGodBridgeTechnique.sneakTime) + mode == Mode.STOP_INPUT -> LedgeAction(stopInput = true) + mode == Mode.RANDOM -> if (Random.nextBoolean()) { + LedgeAction(jump = true, sneakTime = 0) + } else { + LedgeAction(jump = false, sneakTime = this@ScaffoldGodBridgeTechnique.sneakTime) } + else -> LedgeAction.NO_LEDGE } + } else { + LedgeAction.NO_LEDGE } - - return LedgeState.NO_LEDGE } private var isOnRightSide = false diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldTechnique.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldTechnique.kt index 7f5578d2e8d..f77703d4578 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldTechnique.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldTechnique.kt @@ -27,6 +27,7 @@ import net.ccbluex.liquidbounce.utils.block.targetfinding.BlockPlacementTarget import net.ccbluex.liquidbounce.utils.math.geometry.Line import net.minecraft.entity.EntityPose import net.minecraft.item.ItemStack +import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.math.Vec3d abstract class ScaffoldTechnique(name: String) : Choice(name) { @@ -44,6 +45,7 @@ abstract class ScaffoldTechnique(name: String) : Choice(name) { open fun getRotations(target: BlockPlacementTarget?) = target?.rotation - open fun getCrosshairTarget(target: BlockPlacementTarget?, rotation: Rotation) = raycast(rotation) + open fun getCrosshairTarget(target: BlockPlacementTarget?, rotation: Rotation): BlockHitResult? = + raycast(rotation) } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/traps/ModuleAutoTrap.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/traps/ModuleAutoTrap.kt index 1bbd7a303a7..fc8d313c411 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/traps/ModuleAutoTrap.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/traps/ModuleAutoTrap.kt @@ -18,7 +18,7 @@ */ package net.ccbluex.liquidbounce.features.module.modules.world.traps -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.event.tickHandler import net.ccbluex.liquidbounce.features.module.Category @@ -61,7 +61,7 @@ object ModuleAutoTrap : ClientModule("AutoTrap", Category.WORLD, aliases = array } @Suppress("unused") - private val rotationUpdateHandler = handler { + private val rotationUpdateHandler = handler { if (timeout) { return@handler } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RaytracingExtensions.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RaytracingExtensions.kt index 9446f62466a..05e4426ae13 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RaytracingExtensions.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RaytracingExtensions.kt @@ -20,6 +20,7 @@ package net.ccbluex.liquidbounce.utils.aiming import net.ccbluex.liquidbounce.utils.client.mc import net.ccbluex.liquidbounce.utils.client.player +import net.ccbluex.liquidbounce.utils.client.world import net.ccbluex.liquidbounce.utils.entity.eyes import net.ccbluex.liquidbounce.utils.entity.rotation import net.minecraft.block.BlockState @@ -105,16 +106,26 @@ fun raycast( rotation: Rotation = RotationManager.currentRotation ?: player.rotation, range: Double = max(player.blockInteractionRange, player.entityInteractionRange), includeFluids: Boolean = false, - tickDelta: Float = 1.0f, -): BlockHitResult? { - val entity = mc.cameraEntity ?: return null - - val start = entity.getCameraPosVec(tickDelta) - val rotationVec = rotation.rotationVec + tickDelta: Float = 1f, +): BlockHitResult { + return raycast( + range = range, + includeFluids = includeFluids, + start = player.getCameraPosVec(tickDelta), + direction = rotation.rotationVec + ) +} - val end = start.add(rotationVec.x * range, rotationVec.y * range, rotationVec.z * range) +fun raycast( + range: Double = max(player.blockInteractionRange, player.entityInteractionRange), + includeFluids: Boolean = false, + start: Vec3d, + direction: Vec3d, + entity: Entity = mc.cameraEntity!!, +): BlockHitResult { + val end = start.add(direction.x * range, direction.y * range, direction.z * range) - return mc.world?.raycast( + return world.raycast( RaycastContext( start, end, diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt index d92a0902f37..2c1c2b75183 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/aiming/RotationManager.kt @@ -20,17 +20,17 @@ package net.ccbluex.liquidbounce.utils.aiming import net.ccbluex.liquidbounce.event.EventListener import net.ccbluex.liquidbounce.event.EventManager -import net.ccbluex.liquidbounce.event.EventState -import net.ccbluex.liquidbounce.event.events.* +import net.ccbluex.liquidbounce.event.events.GameTickEvent +import net.ccbluex.liquidbounce.event.events.PacketEvent +import net.ccbluex.liquidbounce.event.events.PlayerVelocityStrafe +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.ClientModule import net.ccbluex.liquidbounce.features.module.modules.combat.ModuleBacktrack import net.ccbluex.liquidbounce.utils.client.* import net.ccbluex.liquidbounce.utils.combat.CombatManager -import net.ccbluex.liquidbounce.utils.entity.SimulatedPlayer import net.ccbluex.liquidbounce.utils.entity.lastRotation import net.ccbluex.liquidbounce.utils.entity.rotation -import net.ccbluex.liquidbounce.utils.entity.set import net.ccbluex.liquidbounce.utils.inventory.InventoryManager import net.ccbluex.liquidbounce.utils.kotlin.EventPriorityConvention import net.ccbluex.liquidbounce.utils.kotlin.Priority @@ -211,36 +211,18 @@ object RotationManager : EventListener { } @Suppress("unused") - val velocityHandler = handler { event -> + private val velocityHandler = handler { event -> if (workingAimPlan?.applyVelocityFix == true) { event.velocity = fixVelocity(event.velocity, event.movementInput, event.speed) } } - /** - * Updates at movement tick, so we can update the rotation before the movement runs and the client sends the packet - * to the server. - */ @Suppress("unused") - private val movementInputHandler = handler( - priority = EventPriorityConvention.READ_FINAL_STATE + private val gameTickHandler = handler( + priority = EventPriorityConvention.FIRST_PRIORITY ) { event -> - val input = SimulatedPlayer.SimulatedPlayerInput.fromClientPlayer(event.directionalInput) - - input.set( - sneak = event.sneak, - jump = event.jump - ) - - val simulatedPlayer = SimulatedPlayer.fromClientPlayer(input) - simulatedPlayer.tick() - - val oldPos = player.pos - player.setPosition(simulatedPlayer.pos) - - EventManager.callEvent(SimulatedTickEvent(event, simulatedPlayer)) - - player.setPosition(oldPos) + EventManager.callEvent(RotationUpdateEvent) + update() // Reset the trigger if (triggerNoDifference) { @@ -248,15 +230,6 @@ object RotationManager : EventListener { } } - @Suppress("unused") - private val networkTickHandler = handler( - priority = EventPriorityConvention.READ_FINAL_STATE - ) { event -> - if (event.state == EventState.POST) { - update() - } - } - /** * Track rotation changes * @@ -312,4 +285,7 @@ object RotationManager : EventListener { return currVelocity } + override val running: Boolean + get() = inGame + } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/placer/BlockPlacer.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/placer/BlockPlacer.kt index 7c223afede9..f02c74058f1 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/placer/BlockPlacer.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/placer/BlockPlacer.kt @@ -21,7 +21,8 @@ package net.ccbluex.liquidbounce.utils.block.placer import it.unimi.dsi.fastutil.objects.Object2BooleanLinkedOpenHashMap import net.ccbluex.liquidbounce.config.types.Configurable import net.ccbluex.liquidbounce.event.EventListener -import net.ccbluex.liquidbounce.event.events.SimulatedTickEvent +import net.ccbluex.liquidbounce.event.events.MovementInputEvent +import net.ccbluex.liquidbounce.event.events.RotationUpdateEvent import net.ccbluex.liquidbounce.event.events.WorldChangeEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.ClientModule @@ -127,7 +128,7 @@ class BlockPlacer( private var sneakTimes = 0 @Suppress("unused") - private val targetUpdater = handler(priority = -20) { + private val targetUpdater = handler(priority = -20) { if (ticksToWait > 0) { ticksToWait-- } else if (ranAction) { @@ -141,12 +142,7 @@ class BlockPlacer( return@handler } - if (sneakTimes > 0) { - sneakTimes-- - it.movementEvent.sneak = true - } - - if (blocks.isEmpty()) { + if (blocks.isEmpty) { return@handler } @@ -157,18 +153,26 @@ class BlockPlacer( inaccessible.clear() rotationMode.activeChoice.onTickStart() - if (scheduleCurrentPlacements(itemStack, it)) { + if (scheduleCurrentPlacements(itemStack)) { return@handler } // no possible position found, now a support placement can be considered if (support.enabled && support.chronometer.hasElapsed(support.delay.toLong())) { - findSupportPath(itemStack, it) + findSupportPath(itemStack) + } + } + + @Suppress("unused") + private val movementInputHandler = handler { event -> + if (sneakTimes > 0) { + sneakTimes-- + event.sneak = true } } - private fun findSupportPath(itemStack: ItemStack, event: SimulatedTickEvent) { + private fun findSupportPath(itemStack: ItemStack) { val currentPlaceCandidates = mutableSetOf() var supportPath: Set? = null @@ -212,13 +216,13 @@ class BlockPlacer( }.forEach { pos -> addToQueue(pos, isSupport = true) } - scheduleCurrentPlacements(itemStack, event) + scheduleCurrentPlacements(itemStack) } support.chronometer.reset() } - private fun scheduleCurrentPlacements(itemStack: ItemStack, it: SimulatedTickEvent): Boolean { + private fun scheduleCurrentPlacements(itemStack: ItemStack): Boolean { var hasPlaced = false val iterator = blocks.object2BooleanEntrySet().iterator() @@ -264,7 +268,6 @@ class BlockPlacer( ) ) { sneakTimes = sneak - 1 - it.movementEvent.sneak = true } if (rotationMode.activeChoice(entry.booleanValue, pos, placementTarget)) { diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/PlayerSimulationCache.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/PlayerSimulationCache.kt index e09cb359e5e..8424e0ff1a9 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/PlayerSimulationCache.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/PlayerSimulationCache.kt @@ -5,6 +5,7 @@ import net.ccbluex.liquidbounce.event.events.GameTickEvent import net.ccbluex.liquidbounce.event.events.MovementInputEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.utils.client.player +import net.ccbluex.liquidbounce.utils.kotlin.EventPriorityConvention import net.ccbluex.liquidbounce.utils.movement.DirectionalInput import net.minecraft.entity.player.PlayerEntity import net.minecraft.util.math.Vec3d @@ -21,7 +22,9 @@ object PlayerSimulationCache: EventListener { this.otherPlayerCache.clear() } - private val movementHandler = handler { + private val movementHandler = handler( + priority = EventPriorityConvention.FIRST_PRIORITY + ) { val simulatedPlayer = SimulatedPlayer.fromClientPlayer( SimulatedPlayer.SimulatedPlayerInput.fromClientPlayer(it.directionalInput) ) @@ -130,6 +133,7 @@ class SimulatedPlayerSnapshot(s: SimulatedPlayer) { val fallDistance = s.fallDistance val velocity = s.velocity val onGround = s.onGround + val clipLedged = s.clipLedged } /** From 1c69e0f408f742ab7e33f83a98bd99deaa4a85de Mon Sep 17 00:00:00 2001 From: Izuna <1zuna@ccbluex.net> Date: Tue, 7 Jan 2025 18:30:24 +0100 Subject: [PATCH 08/13] feat(Scaffold): GodBridge input backwards mode (#5215) Similar to Stop Input, but we also run backwards for one tick, which makes it much more consistent. --- .../modules/world/scaffold/ModuleScaffold.kt | 27 ++++++++++++------- .../scaffold/features/ScaffoldLedgeFeature.kt | 3 ++- .../techniques/ScaffoldGodBridgeTechnique.kt | 9 ++++--- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/ModuleScaffold.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/ModuleScaffold.kt index 19466ed0be4..83cbacb27a1 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/ModuleScaffold.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/ModuleScaffold.kt @@ -357,10 +357,14 @@ object ModuleScaffold : ClientModule("Scaffold", Category.WORLD) { } var currentOptimalLine: Line? = null + var rawInput = DirectionalInput.NONE @Suppress("unused") - private val handleMovementInput = handler { event -> + private val handleMovementInput = handler( + priority = EventPriorityConvention.MODEL_STATE + ) { event -> this.currentOptimalLine = null + this.rawInput = event.directionalInput val currentInput = event.directionalInput @@ -373,6 +377,7 @@ object ModuleScaffold : ClientModule("Scaffold", Category.WORLD) { @Suppress("unused") private val movementInputHandler = handler( + // Runs after the model state priority = EventPriorityConvention.SAFETY_FEATURE ) { event -> if (forceSneak > 0) { @@ -388,26 +393,30 @@ object ModuleScaffold : ClientModule("Scaffold", Category.WORLD) { technique.activeChoice } - val (jump, sneak, stepStop) = ledge( + val ledgeAction = ledge( this.currentTarget, RotationManager.currentRotation ?: player.rotation, technique as? ScaffoldLedgeExtension ) - ModuleDebug.debugParameter(this, "Jump", jump.toString()) - ModuleDebug.debugParameter(this, "Sneak", sneak.toString()) - ModuleDebug.debugParameter(this, "StepStop", stepStop.toString()) - if (jump) { + if (ledgeAction.jump) { event.jump = true } - if (stepStop) { + if (ledgeAction.stopInput) { event.directionalInput = DirectionalInput.NONE } - if (sneak > forceSneak) { + if (ledgeAction.stepBack) { + event.directionalInput = event.directionalInput.copy( + forwards = false, + backwards = true + ) + } + + if (ledgeAction.sneakTime > forceSneak) { event.sneak = true - forceSneak = sneak + forceSneak = ledgeAction.sneakTime } } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/features/ScaffoldLedgeFeature.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/features/ScaffoldLedgeFeature.kt index 38084929850..cf15c579b6f 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/features/ScaffoldLedgeFeature.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/features/ScaffoldLedgeFeature.kt @@ -29,7 +29,8 @@ import kotlin.math.max data class LedgeAction( val jump: Boolean = false, val sneakTime: Int = 0, - val stopInput: Boolean = false + val stopInput: Boolean = false, + val stepBack: Boolean = false ) { companion object { val NO_LEDGE = LedgeAction(jump = false, sneakTime = 0, stopInput = false) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldGodBridgeTechnique.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldGodBridgeTechnique.kt index f0cadf3ff09..104e182cc9c 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldGodBridgeTechnique.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldGodBridgeTechnique.kt @@ -22,6 +22,7 @@ import net.ccbluex.liquidbounce.config.types.NamedChoice import net.ccbluex.liquidbounce.features.module.modules.render.ModuleDebug import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.ModuleScaffold import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.ModuleScaffold.getTargetedPosition +import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.ModuleScaffold.rawInput import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.features.LedgeAction import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.features.ScaffoldLedgeExtension import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.techniques.ScaffoldNormalTechnique.NORMAL_INVESTIGATION_OFFSETS @@ -54,6 +55,7 @@ object ScaffoldGodBridgeTechnique : ScaffoldTechnique("GodBridge"), ScaffoldLedg * Might not be as consistent as the other modes. */ STOP_INPUT("StopInput"), + BACKWARDS("Backwards"), RANDOM("Random") } @@ -106,6 +108,7 @@ object ScaffoldGodBridgeTechnique : ScaffoldTechnique("GodBridge"), ScaffoldLedg mode == Mode.JUMP -> LedgeAction(jump = true) mode == Mode.SNEAK -> LedgeAction(sneakTime = this@ScaffoldGodBridgeTechnique.sneakTime) mode == Mode.STOP_INPUT -> LedgeAction(stopInput = true) + mode == Mode.BACKWARDS -> LedgeAction(stepBack = true) mode == Mode.RANDOM -> if (Random.nextBoolean()) { LedgeAction(jump = true, sneakTime = 0) } else { @@ -140,15 +143,13 @@ object ScaffoldGodBridgeTechnique : ScaffoldTechnique("GodBridge"), ScaffoldLedg } override fun getRotations(target: BlockPlacementTarget?): Rotation? { - val dirInput = DirectionalInput(player.input) - - if (dirInput == DirectionalInput.NONE) { + if (rawInput == DirectionalInput.NONE) { target ?: return null return getRotationForNoInput(target) } - val direction = getMovementDirectionOfInput(player.yaw, dirInput) + 180 + val direction = getMovementDirectionOfInput(player.yaw, rawInput) + 180 // Round to 45°-steps (NORTH, NORTH_EAST, etc.) val movingYaw = round(direction / 45) * 45 From 96c3edfda58664bd3304dfc68ed50e63fb327bb9 Mon Sep 17 00:00:00 2001 From: Izuna <1zuna@ccbluex.net> Date: Tue, 7 Jan 2025 18:38:59 +0100 Subject: [PATCH 09/13] fix(Scaffold): breezily rotation inconsistency (#5216) --- .../techniques/ScaffoldBreezilyTechnique.kt | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldBreezilyTechnique.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldBreezilyTechnique.kt index e0486307574..9f790123340 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldBreezilyTechnique.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/world/scaffold/techniques/ScaffoldBreezilyTechnique.kt @@ -21,10 +21,13 @@ package net.ccbluex.liquidbounce.features.module.modules.world.scaffold.techniqu import net.ccbluex.liquidbounce.event.events.MovementInputEvent import net.ccbluex.liquidbounce.event.handler import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.ModuleScaffold.getTargetedPosition +import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.ModuleScaffold.rawInput import net.ccbluex.liquidbounce.features.module.modules.world.scaffold.techniques.ScaffoldNormalTechnique.NORMAL_INVESTIGATION_OFFSETS import net.ccbluex.liquidbounce.utils.aiming.Rotation import net.ccbluex.liquidbounce.utils.block.getState import net.ccbluex.liquidbounce.utils.block.targetfinding.* +import net.ccbluex.liquidbounce.utils.entity.getMovementDirectionOfInput +import net.ccbluex.liquidbounce.utils.kotlin.EventPriorityConvention import net.ccbluex.liquidbounce.utils.kotlin.random import net.ccbluex.liquidbounce.utils.math.geometry.Line import net.ccbluex.liquidbounce.utils.math.toBlockPos @@ -34,6 +37,7 @@ import net.minecraft.item.ItemStack import net.minecraft.util.math.Direction import net.minecraft.util.math.Vec3d import kotlin.math.floor +import kotlin.math.round object ScaffoldBreezilyTechnique : ScaffoldTechnique("Breezily") { @@ -65,7 +69,9 @@ object ScaffoldBreezilyTechnique : ScaffoldTechnique("Breezily") { } @Suppress("unused") - private val handleMovementInput = handler { event -> + private val handleMovementInput = handler( + priority = EventPriorityConvention.SAFETY_FEATURE + ) { event -> if (!event.directionalInput.forwards || player.isSneaking) { return@handler } @@ -120,7 +126,37 @@ object ScaffoldBreezilyTechnique : ScaffoldTechnique("Breezily") { } override fun getRotations(target: BlockPlacementTarget?): Rotation? { - return ScaffoldGodBridgeTechnique.getRotations(target) + if (rawInput == DirectionalInput.NONE) { + target ?: return null + + return getRotationForNoInput(target) + } + + val direction = getMovementDirectionOfInput(player.yaw, rawInput) + 180 + + // Round to 45°-steps (NORTH, NORTH_EAST, etc.) + val movingYaw = round(direction / 45) * 45 + val isMovingStraight = movingYaw % 90 == 0f + + return if (isMovingStraight) { + getRotationForStraightInput(movingYaw) + } else { + getRotationForDiagonalInput(movingYaw) + } + + } + + private fun getRotationForStraightInput(movingYaw: Float) = Rotation(movingYaw, 80f) + + private fun getRotationForDiagonalInput(movingYaw: Float) = Rotation(movingYaw, 75.6f) + + private fun getRotationForNoInput(target: BlockPlacementTarget): Rotation { + val axisMovement = floor(target.rotation.yaw / 90) * 90 + + val yaw = axisMovement + 45 + val pitch = 75f + + return Rotation(yaw, pitch) } } From 1fd9fa4d664741e9cea7399520ed602465da0d36 Mon Sep 17 00:00:00 2001 From: MukjepScarlet <93977077+MukjepScarlet@users.noreply.github.com> Date: Wed, 8 Jan 2025 01:39:29 +0800 Subject: [PATCH 10/13] refactor(BookBot): allow space option, code refactors (#5177) * refactor(BookBot): allow space option, code refactors - make GenerationMode private - class BookBuilder for writeBook operation * refactor * inline * ext -> member --------- Co-authored-by: sqlerrorthing <148702857+sqlerrorthing@users.noreply.github.com> --- .../module/modules/misc/ModuleBookBot.kt | 221 +++++++++--------- 1 file changed, 109 insertions(+), 112 deletions(-) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleBookBot.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleBookBot.kt index 1a24654a451..5c9cc6b785c 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleBookBot.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleBookBot.kt @@ -54,14 +54,9 @@ private const val MAX_LINE_WIDTH: Float = 114f object ModuleBookBot : ClientModule("BookBot", Category.MISC, disableOnQuit = true) { private val inventoryConstraints = tree(PlayerInventoryConstraints()) - val generationMode = - choices( - "Mode", - RandomGenerationMode, - arrayOf( - RandomGenerationMode, - ), - ).apply { tagBy(this) } + private val generationMode = choices("Mode", GenerationMode.Random, arrayOf(GenerationMode.Random)).apply { + tagBy(this) + } private object Sign : ToggleableConfigurable(ModuleBookBot, "Sign", true) { val bookName by text("Name", "Generated book #%count%") @@ -86,12 +81,12 @@ object ModuleBookBot : ClientModule("BookBot", Category.MISC, disableOnQuit = tr chronometer.reset() } - private val isCandidate: (ItemStack) -> Boolean = { - val component = it.get(DataComponentTypes.WRITABLE_BOOK_CONTENT) - it.item == Items.WRITABLE_BOOK && component?.pages?.isEmpty() == true + private fun isCandidate(itemStack: ItemStack): Boolean { + return itemStack.item == Items.WRITABLE_BOOK && + itemStack.get(DataComponentTypes.WRITABLE_BOOK_CONTENT)?.pages?.isEmpty() == true } - private val randomBook get() = findInventorySlot(isCandidate) + private val randomBook get() = findInventorySlot(::isCandidate) @Suppress("unused") private val scheduleInventoryAction = handler { event -> @@ -135,135 +130,137 @@ object ModuleBookBot : ClientModule("BookBot", Category.MISC, disableOnQuit = tr * @see PrimitiveIterator.OfInt * @see GenerationMode.generate */ - @Suppress("CognitiveComplexMethod", "NestedBlockDepth") private fun writeBook() { if (!isCandidate(player.mainHandStack)) { return } - val chars = generationMode.activeChoice.generate() - val widthRetriever = mc.textRenderer.textHandler.widthRetriever + val bookBuilder = BookBuilder() + bookBuilder.buildBookContent(generationMode.activeChoice.generate()) { + mc.textRenderer.textHandler.widthRetriever.getWidth(it, Style.EMPTY) + } + bookBuilder.writeBook() - val pages = ArrayList() - val filteredPages = ArrayList>() + bookCount++ + } - var pageIndex = 0 - var lineIndex = 0 - var lineWidth = 0.0f - val page = StringBuilder() + private sealed class GenerationMode( + name: String, + ) : Choice(name) { + override val parent: ChoiceConfigurable<*> = ModuleBookBot.generationMode - while (chars.hasNext()) { - val char = chars.nextInt().toChar() + val pages by int("Pages", 50, 0..100) - if (char == '\r' || char == '\n') { - page.append('\n') - lineWidth = 0.0f - lineIndex++ - } else { - val charWidth = widthRetriever.getWidth(char.code, Style.EMPTY) + abstract fun generate(): PrimitiveIterator.OfInt - if (lineWidth + charWidth > MAX_LINE_WIDTH) { - lineIndex++ - lineWidth = charWidth - appendLineBreak(page, lineIndex) - } else if (lineWidth == 0f && char == ' ') { - continue - } else { - lineWidth += charWidth - page.appendCodePoint(char.code) - } - } + object Random : GenerationMode("Random") { + private val asciiOnly by boolean("AsciiOnly", false) - if (lineIndex == MAX_LINES_PER_PAGE) { - addPageToBook(page, pages, filteredPages) - page.setLength(0) - pageIndex++ - lineIndex = 0 + private val allowSpace by boolean("AllowSpace", true) - if (pageIndex == generationMode.activeChoice.pages) { - break - } + override fun generate(): PrimitiveIterator.OfInt { + val origin = if (asciiOnly) 0x21 else 0x0800 + val bound = if (asciiOnly) 0x7E else 0x10FFFF - if (char != '\r' && char != '\n') { - page.appendCodePoint(char.code) - } + return random + .ints(origin, bound) + .filter { allowSpace || !Character.isWhitespace(it) } + .iterator() } } - - if (page.isNotEmpty() && pageIndex != generationMode.activeChoice.pages) { - addPageToBook(page, pages, filteredPages) - } - - writeBook(Sign.bookName.replace("%count%", bookCount.toString()), - filteredPages, pages) - - bookCount++ } - private fun appendLineBreak(page: StringBuilder, lineIndex: Int) { - page.append('\n') + private fun StringBuilder.appendLineBreak(lineIndex: Int) { + append('\n') if (lineIndex == MAX_LINES_PER_PAGE) { - page.appendCodePoint(' '.code) + append(' ') } } - private fun addPageToBook( - page: StringBuilder, - pages: MutableList, - filteredPages: MutableList> - ) { - filteredPages.add(RawFilteredPair.of(Text.of(page.toString()))) - pages.add(page.toString()) - } + private class BookBuilder { + private val title: String = Sign.bookName.replace("%count%", bookCount.toString()) + private val pageAmount: Int = generationMode.activeChoice.pages - private fun writeBook( - title: String, - filteredPages: ArrayList>, - pages: ArrayList - ) { - player.mainHandStack.set( - DataComponentTypes.WRITTEN_BOOK_CONTENT, - WrittenBookContentComponent( - RawFilteredPair.of(title), - player.gameProfile.name, - 0, - filteredPages, - true - ) - ) + private val pages = ArrayList(pageAmount) + private val filteredPages = ArrayList>(pageAmount) - player.networkHandler.sendPacket( - BookUpdateC2SPacket( - player.inventory.selectedSlot, - pages, - if (Sign.enabled) Optional.of(title) else Optional.empty() - ) - ) - } -} + @Suppress("detekt:CognitiveComplexMethod") + inline fun buildBookContent( + charGenerator: PrimitiveIterator.OfInt, + charWidthProvider: (charCode: Int) -> Float + ) { + var pageIndex = 0 + var lineIndex = 0 + var lineWidth = 0.0f + val page = StringBuilder() -abstract class GenerationMode( - name: String, -) : Choice(name) { - override val parent: ChoiceConfigurable<*> = ModuleBookBot.generationMode + while (charGenerator.hasNext()) { + val char = charGenerator.nextInt().toChar() - abstract val pages: Int + if (lineWidth == 0f && char == ' ') { + continue + } else if (char == '\r' || char == '\n') { + page.append('\n') + lineWidth = 0.0f + lineIndex++ + } else { + val charWidth = charWidthProvider(char.code) + + if (lineWidth + charWidth > MAX_LINE_WIDTH) { + lineIndex++ + lineWidth = charWidth + page.appendLineBreak(lineIndex) + } else { + lineWidth += charWidth + page.appendCodePoint(char.code) + } + } - abstract fun generate(): PrimitiveIterator.OfInt -} + if (lineIndex == MAX_LINES_PER_PAGE) { + this.addPage(page.toString()) + page.setLength(0) + pageIndex++ + lineIndex = 0 + + if (pageIndex >= pageAmount) { + break + } -object RandomGenerationMode : GenerationMode("Random") { - override val pages by int("Pages", 50, 0..100) + if (char != '\r' && char != '\n') { + page.append(char) + } + } + } - private val asciiOnly by boolean("AsciiOnly", false) + if (page.isNotEmpty() && pageIndex < pageAmount) { + this.addPage(page.toString()) + } + } - override fun generate(): PrimitiveIterator.OfInt { - val origin = if (asciiOnly) 0x21 else 0x0800 - val bound = if (asciiOnly) 0x7E else 0x10FFFF + fun addPage(page: String) { + filteredPages.add(RawFilteredPair.of(Text.literal(page))) + pages.add(page) + } - return ModuleBookBot.random - .ints(origin, bound) - .filter { !Character.isWhitespace(it) && it.toChar() != '\r' && it.toChar() != '\n' } - .iterator() + fun writeBook() { + player.mainHandStack.set( + DataComponentTypes.WRITTEN_BOOK_CONTENT, + WrittenBookContentComponent( + RawFilteredPair.of(title), + player.gameProfile.name, + 0, + filteredPages, + true + ) + ) + + player.networkHandler.sendPacket( + BookUpdateC2SPacket( + player.inventory.selectedSlot, + pages, + if (Sign.enabled) Optional.of(title) else Optional.empty() + ) + ) + } } } From c9fa6e0e2728d9cc55da9afd89d86d5895ff94bd Mon Sep 17 00:00:00 2001 From: MukjepScarlet <93977077+MukjepScarlet@users.noreply.github.com> Date: Wed, 8 Jan 2025 01:39:58 +0800 Subject: [PATCH 11/13] refactor(ChunkScanner): use flow and skip empty sections (#5174) --- .../liquidbounce/utils/block/ChunkScanner.kt | 169 ++++++++---------- .../utils/block/hole/HoleTracker.kt | 58 +++--- 2 files changed, 103 insertions(+), 124 deletions(-) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/ChunkScanner.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/ChunkScanner.kt index 50117efe7c7..5610e39353f 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/ChunkScanner.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/ChunkScanner.kt @@ -20,10 +20,7 @@ package net.ccbluex.liquidbounce.utils.block import it.unimi.dsi.fastutil.longs.LongOpenHashSet import kotlinx.coroutines.* -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.channels.ClosedReceiveChannelException -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.flow.MutableSharedFlow import net.ccbluex.liquidbounce.event.EventListener import net.ccbluex.liquidbounce.event.events.* import net.ccbluex.liquidbounce.event.handler @@ -31,25 +28,21 @@ import net.ccbluex.liquidbounce.features.module.MinecraftShortcuts import net.ccbluex.liquidbounce.utils.client.logger import net.ccbluex.liquidbounce.utils.kotlin.getValue import net.minecraft.block.BlockState -import net.minecraft.block.Blocks -import net.minecraft.util.Util import net.minecraft.util.math.BlockPos import net.minecraft.util.math.ChunkPos import net.minecraft.world.chunk.WorldChunk import java.util.concurrent.CopyOnWriteArrayList -import kotlin.coroutines.cancellation.CancellationException object ChunkScanner : EventListener, MinecraftShortcuts { + init { + ChunkScannerThread + } + private val subscribers = CopyOnWriteArrayList() private val loadedChunks = LongOpenHashSet() - private fun clearAllChunks() { - subscribers.forEach(BlockChangeSubscriber::clearAllChunks) - loadedChunks.clear() - } - @Suppress("unused") private val chunkLoadHandler = handler { event -> val chunk = world.getChunk(event.x, event.z) @@ -84,12 +77,9 @@ object ChunkScanner : EventListener, MinecraftShortcuts { @Suppress("unused") private val worldChangeHandler = handler { - clearAllChunks() - } - - @Suppress("unused") - private val disconnectHandler = handler { - clearAllChunks() + ChunkScannerThread.cancelCurrentJobs() + subscribers.forEach(BlockChangeSubscriber::clearAllChunks) + loadedChunks.clear() } fun subscribe(newSubscriber: BlockChangeSubscriber) { @@ -130,65 +120,50 @@ object ChunkScanner : EventListener, MinecraftShortcuts { * When the first request comes in, the dispatcher and the scope will be initialized, * and its parallelism cannot be modified */ - @OptIn(ExperimentalCoroutinesApi::class) - private val dispatcher = Util.getMainWorkerExecutor().asCoroutineDispatcher() + private val dispatcher = Dispatchers.Default .limitedParallelism((Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(2)) - private val scope = CoroutineScope(dispatcher + SupervisorJob()) - /** - * Shared cache for CoroutineScope + * The parent job for the current client world. + * All children will be cancelled on [WorldChangeEvent]. */ - private val mutable by ThreadLocal.withInitial(BlockPos::Mutable) + private val worldJob = SupervisorJob() + + private val scope = CoroutineScope(dispatcher + worldJob) - private const val CHANNEL_CAPACITY = 800 + private val eventFlow = MutableSharedFlow() - private var chunkUpdateChannel = Channel(capacity = CHANNEL_CAPACITY) + /** + * Shared cache for [scope] + */ + private val mutable by ThreadLocal.withInitial(BlockPos::Mutable) - private val channelRestartMutex = Mutex() + /** + * A standalone [Job] to dispatch all [UpdateRequest] from [eventFlow] + */ + private val collectorJob = scope.launch(Job()) { + eventFlow.collect { chunkUpdate -> + // Discard current request when world is null + if (mc.world == null) { + delay(50L) + return@collect + } - init { - // cyclic job, used to process tasks from channel - @Suppress("detekt:SwallowedException") - scope.launch { - var retrying = 0 - while (true) { + // Process the update request + launch { try { - val chunkUpdate = chunkUpdateChannel.receive() + when (chunkUpdate) { + is UpdateRequest.ChunkUpdateRequest -> scanChunk(chunkUpdate) - if (mc.world == null) { - // reset Channel (prevent sending) - channelRestartMutex.withLock { - chunkUpdateChannel.cancel() - chunkUpdateChannel = Channel(capacity = CHANNEL_CAPACITY) + is UpdateRequest.ChunkUnloadRequest -> subscribers.forEach { + it.clearChunk(chunkUpdate.x, chunkUpdate.z) } - // max delay = 30s (1s, 2s, 4s, ...) - delay((1000L shl retrying++).coerceAtMost(30000L)) - continue - } - - retrying = 0 - - // process the update request - launch { - when (chunkUpdate) { - is UpdateRequest.ChunkUpdateRequest -> scanChunk(chunkUpdate) - is UpdateRequest.ChunkUnloadRequest -> subscribers.forEach { - it.clearChunk(chunkUpdate.x, chunkUpdate.z) - } - - is UpdateRequest.BlockUpdateEvent -> subscribers.forEach { - it.recordBlock(chunkUpdate.blockPos, chunkUpdate.newState, cleared = false) - } + is UpdateRequest.BlockUpdateEvent -> subscribers.forEach { + it.recordBlock(chunkUpdate.blockPos, chunkUpdate.newState, cleared = false) } } - } catch (e: CancellationException) { - break // end loop if job has been canceled - } catch (e: ClosedReceiveChannelException) { - break // the channel is closed from outside (stopThread) } catch (e: Throwable) { - retrying++ logger.warn("Chunk update error", e) } } @@ -197,12 +172,17 @@ object ChunkScanner : EventListener, MinecraftShortcuts { fun enqueueChunkUpdate(request: UpdateRequest) { scope.launch { - channelRestartMutex.withLock { - chunkUpdateChannel.send(request) - } + eventFlow.emit(request) } } + /** + * Cancel all existing enqueue(emit) jobs and scanner jobs + */ + fun cancelCurrentJobs() { + worldJob.cancelChildren() + } + /** * Scans the chunks for a block */ @@ -213,39 +193,45 @@ object ChunkScanner : EventListener, MinecraftShortcuts { return } + val start = System.nanoTime() + val currentSubscriber = request.singleSubscriber?.let { listOf(it) } ?: subscribers - currentSubscriber.map { - scope.launch { - it.chunkUpdate(request.chunk.pos.x, request.chunk.pos.z) - } - }.joinAll() + when (currentSubscriber.size) { + 0 -> return + 1 -> currentSubscriber.first().chunkUpdate(chunk.pos.x, chunk.pos.z) + else -> currentSubscriber.map { + scope.launch { it.chunkUpdate(chunk.pos.x, chunk.pos.z) } + }.joinAll() + } // Contains all subscriber that want recordBlock called on a chunk update - val subscribersForRecordBlock = currentSubscriber.filter { it.shouldCallRecordBlockOnChunkUpdate } + val subscribersForRecordBlock = currentSubscriber.filter { + it.shouldCallRecordBlockOnChunkUpdate + }.toTypedArray() if (subscribersForRecordBlock.isEmpty()) { return } - val start = System.nanoTime() - val startX = chunk.pos.startX val startZ = chunk.pos.startZ - (chunk.bottomY..chunk.topYInclusive).map { y -> + /** + * @see WorldChunk.getBlockState + */ + (0..chunk.highestNonEmptySection).map { sectionIndex -> scope.launch { - /** - * @see WorldChunk.getBlockState - */ - val chunkSection = chunk.sectionArray.getOrNull((y shr 4) - (chunk.bottomY shr 4)) - - for (x in 0..15) { - for (z in 0..15) { - val blockState = chunkSection?.getBlockState(x, y and 15, z) ?: DEFAULT_BLOCK_STATE - - val pos = mutable.set(startX or x, y, startZ or z) - subscribersForRecordBlock.forEach { it.recordBlock(pos, blockState, cleared = true) } + val section = chunk.getSection(sectionIndex) + for (sectionY in 0..15) { + // index == (y >> 4) - (bottomY >> 4) + val y = (sectionIndex + (chunk.bottomY shr 4)) shl 4 or sectionY + for (x in 0..15) { + for (z in 0..15) { + val blockState = section.getBlockState(x, sectionY, z) + val pos = mutable.set(startX or x, y, startZ or z) + subscribersForRecordBlock.forEach { it.recordBlock(pos, blockState, cleared = true) } + } } } } @@ -255,21 +241,18 @@ object ChunkScanner : EventListener, MinecraftShortcuts { } fun stopThread() { - scope.cancel() - chunkUpdateChannel.close() + worldJob.cancel() + collectorJob.cancel() logger.info("Stopped Chunk Scanner Thread!") } sealed interface UpdateRequest { - @JvmRecord - data class ChunkUpdateRequest(val chunk: WorldChunk, val singleSubscriber: BlockChangeSubscriber? = null) : + class ChunkUpdateRequest(val chunk: WorldChunk, val singleSubscriber: BlockChangeSubscriber? = null) : UpdateRequest - @JvmRecord - data class ChunkUnloadRequest(val x: Int, val z: Int) : UpdateRequest + class ChunkUnloadRequest(val x: Int, val z: Int) : UpdateRequest - @JvmRecord - data class BlockUpdateEvent(val blockPos: BlockPos, val newState: BlockState) : UpdateRequest + class BlockUpdateEvent(val blockPos: BlockPos, val newState: BlockState) : UpdateRequest } } diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/hole/HoleTracker.kt b/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/hole/HoleTracker.kt index 06b3790f6f1..83f12e1ac3f 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/hole/HoleTracker.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/utils/block/hole/HoleTracker.kt @@ -19,17 +19,16 @@ package net.ccbluex.liquidbounce.utils.block.hole import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap +import net.ccbluex.liquidbounce.features.module.MinecraftShortcuts import net.ccbluex.liquidbounce.utils.block.ChunkScanner import net.ccbluex.liquidbounce.utils.block.Region import net.ccbluex.liquidbounce.utils.block.getState -import net.ccbluex.liquidbounce.utils.client.mc import net.ccbluex.liquidbounce.utils.kotlin.getValue import net.minecraft.block.Block import net.minecraft.block.BlockState import net.minecraft.registry.Registries import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Direction -import net.minecraft.world.chunk.Chunk import java.util.concurrent.ConcurrentSkipListSet private const val UNBREAKABLE = (-1).toByte() @@ -40,11 +39,11 @@ private const val BREAKABLE = 1.toByte() private typealias State = Byte private typealias BlockStateBuffer = Long2ByteOpenHashMap -object HoleTracker : ChunkScanner.BlockChangeSubscriber { +object HoleTracker : ChunkScanner.BlockChangeSubscriber, MinecraftShortcuts { val holes = ConcurrentSkipListSet() private val mutable by ThreadLocal.withInitial(BlockPos::Mutable) - private val fullSurroundings = setOf(Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.NORTH) + private val fullSurroundings = arrayOf(Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.NORTH) private val UNBREAKABLE_BLOCKS: Set by lazy { Registries.BLOCK.filterTo(hashSetOf()) { it.blastResistance >= 600 } } @@ -72,29 +71,35 @@ object HoleTracker : ChunkScanner.BlockChangeSubscriber { } @Suppress("detekt:CognitiveComplexMethod") - fun Region.cachedUpdate(chunk: Chunk? = null) { + fun Region.cachedUpdate() { val buffer = BlockStateBuffer(volume) + val mutableLocal = BlockPos.Mutable() + + val topY = world.topYInclusive - 2 + + val holesInRegion = if (holes.size >= 32) { + holes.subSet( + Hole(Hole.Type.ONE_ONE, Region.from(mutableLocal.set(start, -2, -2, -2))), true, + Hole(Hole.Type.ONE_ONE, Region.from(mutableLocal.set(endInclusive, 2, 2, 2))), true + ) + } else { + holes + } + // Only check positions in this chunk (pos is BlockPos.Mutable) forEach { pos -> - if (chunk != null && (pos.y <= chunk.bottomY || pos.y - 1 >= chunk.topYInclusive)) { + if (pos.y >= topY || holesInRegion.any { pos in it } || !buffer.checkSameXZ(pos)) { return@forEach } - if (holes.any { pos in it } || !buffer.checkSameXZ(pos)) { - return@forEach - } - - val surroundings = fullSurroundings.filterTo(HashSet(4, 1.0F)) { direction -> + val surroundings = fullSurroundings.filterTo(ArrayList(4)) { direction -> buffer.cache(mutable.set(pos, direction)) == UNBREAKABLE } when (surroundings.size) { // 1*1 - 4 -> holes += Hole( - Hole.Type.ONE_ONE, - Region.from(pos), - ) + 4 -> holes += Hole(Hole.Type.ONE_ONE, Region.from(pos)) // 1*2 3 -> { val airDirection = fullSurroundings.first { it !in surroundings } @@ -105,26 +110,20 @@ object HoleTracker : ChunkScanner.BlockChangeSubscriber { } val airOpposite = airDirection.opposite - val checkDirections = with(fullSurroundings.iterator()) { - Array(3) { - val value = next() - if (value == airOpposite) next() else value - } + var idx = 0 + val checkDirections = Array(3) { + val value = fullSurroundings[idx++] + if (value === airOpposite) fullSurroundings[idx++] else value } if (buffer.checkSurroundings(another, checkDirections)) { - holes += Hole( - Hole.Type.ONE_TWO, - Region(pos, another), - ) + holes += Hole(Hole.Type.ONE_TWO, Region(pos, another)) } } // 2*2 2 -> { val (direction1, direction2) = fullSurroundings.filterTo(ArrayList(2)) { it !in surroundings } - val mutableLocal = BlockPos.Mutable() - if (!buffer.checkState(mutableLocal.set(pos, direction1), direction1, direction2.opposite)) { return@forEach } @@ -137,10 +136,7 @@ object HoleTracker : ChunkScanner.BlockChangeSubscriber { return@forEach } - holes += Hole( - Hole.Type.TWO_TWO, - Region(pos, mutableLocal), - ) + holes += Hole(Hole.Type.TWO_TWO, Region(pos, mutableLocal)) } } } @@ -197,7 +193,7 @@ object HoleTracker : ChunkScanner.BlockChangeSubscriber { val region = Region.from(chunk) if (region.intersects(HoleManager.movableRegionScanner.currentRegion)) { invalidate(region) - region.cachedUpdate(chunk) + region.cachedUpdate() } } From be01b6bd7e0fa6f450ccbd9fe9ee89f420138732 Mon Sep 17 00:00:00 2001 From: Izuna <1zuna@ccbluex.net> Date: Tue, 7 Jan 2025 18:42:02 +0100 Subject: [PATCH 12/13] fix(Blur): disable blur on macOS (#5217) --- .../features/module/modules/render/ModuleHud.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/render/ModuleHud.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/render/ModuleHud.kt index 8329b19c58f..6308728e75e 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/render/ModuleHud.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/render/ModuleHud.kt @@ -20,7 +20,6 @@ package net.ccbluex.liquidbounce.features.module.modules.render import net.ccbluex.liquidbounce.config.types.Configurable import net.ccbluex.liquidbounce.config.types.Value -import net.ccbluex.liquidbounce.event.EventListener import net.ccbluex.liquidbounce.event.EventManager import net.ccbluex.liquidbounce.event.events.ScreenEvent import net.ccbluex.liquidbounce.event.events.SpaceSeperatedNamesChangeEvent @@ -40,6 +39,7 @@ import net.ccbluex.liquidbounce.utils.client.chat import net.ccbluex.liquidbounce.utils.client.inGame import net.ccbluex.liquidbounce.utils.client.markAsError import net.ccbluex.liquidbounce.utils.entity.RenderedEntities +import net.minecraft.client.MinecraftClient import net.minecraft.client.gui.screen.DisconnectedScreen /** @@ -67,7 +67,10 @@ object ModuleHud : ClientModule("HUD", Category.RENDER, state = true, hide = tru } val isBlurable - get() = blur && !(mc.options.hudHidden && mc.currentScreen == null) + get() = blur && !(mc.options.hudHidden && mc.currentScreen == null) && + // Only blur on Windows and Linux - Mac seems to have issues with it + // TODO: fix blur on macOS + !MinecraftClient.IS_SYSTEM_MAC init { tree(Configurable("In-built", components as MutableList>)) From 3ff66be0a866401ae4e4d7744ed84411ea1be9f7 Mon Sep 17 00:00:00 2001 From: Lished <116368352+L1shed@users.noreply.github.com> Date: Tue, 7 Jan 2025 18:48:35 +0100 Subject: [PATCH 13/13] fix(Reconnect): Remembers server resource-pack policy (#5197) Co-authored-by: izuna --- .../mixins/minecraft/gui/custom/MixinConnectScreen.java | 2 +- .../net/ccbluex/liquidbounce/event/events/GameEvents.kt | 3 ++- .../kotlin/net/ccbluex/liquidbounce/features/Reconnect.kt | 5 +++-- .../features/module/modules/misc/ModuleAntiStaff.kt | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/gui/custom/MixinConnectScreen.java b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/gui/custom/MixinConnectScreen.java index 6cd0fdf206a..bc7c064c1ed 100644 --- a/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/gui/custom/MixinConnectScreen.java +++ b/src/main/java/net/ccbluex/liquidbounce/injection/mixins/minecraft/gui/custom/MixinConnectScreen.java @@ -88,7 +88,7 @@ private void injectRender(DrawContext context, int mouseX, int mouseY, float del @Inject(method = "connect(Lnet/minecraft/client/MinecraftClient;Lnet/minecraft/client/network/ServerAddress;Lnet/minecraft/client/network/ServerInfo;Lnet/minecraft/client/network/CookieStorage;)V", at = @At("HEAD")) private void injectConnect(MinecraftClient client, ServerAddress address, ServerInfo info, CookieStorage cookieStorage, CallbackInfo ci) { this.serverAddress = address; - EventManager.INSTANCE.callEvent(new ServerConnectEvent(info.name, info.address)); + EventManager.INSTANCE.callEvent(new ServerConnectEvent(info)); } @ModifyConstant(method = "render", constant = @Constant(intValue = 50)) diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/event/events/GameEvents.kt b/src/main/kotlin/net/ccbluex/liquidbounce/event/events/GameEvents.kt index 3301f7d0edf..6c6a0684e09 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/event/events/GameEvents.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/event/events/GameEvents.kt @@ -26,6 +26,7 @@ import net.ccbluex.liquidbounce.integration.interop.protocol.event.WebSocketEven import net.ccbluex.liquidbounce.utils.client.Nameable import net.ccbluex.liquidbounce.utils.movement.DirectionalInput import net.minecraft.client.gui.screen.Screen +import net.minecraft.client.network.ServerInfo import net.minecraft.client.option.KeyBinding import net.minecraft.client.option.Perspective import net.minecraft.client.session.Session @@ -113,7 +114,7 @@ class SplashProgressEvent(val progress: Float, val isComplete: Boolean) : Event( @Nameable("serverConnect") @WebSocketEvent -class ServerConnectEvent(val serverName: String, val serverAddress: String) : Event() +class ServerConnectEvent(val serverInfo: ServerInfo) : Event() @Nameable("disconnect") @WebSocketEvent diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/Reconnect.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/Reconnect.kt index 3a3033a5b12..91a6a7086c6 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/Reconnect.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/Reconnect.kt @@ -38,8 +38,9 @@ object Reconnect : EventListener { private var lastServer: ServerInfo? = null - val handleServerConnect = handler { - lastServer = ServerInfo(it.serverName, it.serverAddress, ServerInfo.ServerType.OTHER) + @Suppress("unused") + private val handleServerConnect = handler { event -> + lastServer = event.serverInfo } /** diff --git a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleAntiStaff.kt b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleAntiStaff.kt index fb063e4d767..ebbcfdf16e0 100644 --- a/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleAntiStaff.kt +++ b/src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/misc/ModuleAntiStaff.kt @@ -82,7 +82,7 @@ object ModuleAntiStaff : ClientModule("AntiStaff", Category.MISC) { @Suppress("unused") val handleServerConnect = sequenceHandler { event -> - val address = event.serverAddress.dropPort().rootDomain() + val address = event.serverInfo.address.dropPort().rootDomain() if (serverStaffList.containsKey(address)) { return@sequenceHandler