From cb633fedbe35182e1f3013a9b5471dec2b686df0 Mon Sep 17 00:00:00 2001 From: mems01 <70612656+mems01@users.noreply.github.com> Date: Mon, 23 Oct 2023 00:24:55 +0300 Subject: [PATCH] Rewrote PingSpoof module. (#1449) This was tested on the Karhu test server and on servers that use the Polar anti-cheat. Spoofs ping more properly than before. --- .../module/modules/exploit/PingSpoof.kt | 79 ++++++++++++------- .../ccbluex/liquidbounce/utils/PacketUtils.kt | 2 +- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/main/java/net/ccbluex/liquidbounce/features/module/modules/exploit/PingSpoof.kt b/src/main/java/net/ccbluex/liquidbounce/features/module/modules/exploit/PingSpoof.kt index 8077c3378e2..d8ffd89dee0 100644 --- a/src/main/java/net/ccbluex/liquidbounce/features/module/modules/exploit/PingSpoof.kt +++ b/src/main/java/net/ccbluex/liquidbounce/features/module/modules/exploit/PingSpoof.kt @@ -7,66 +7,85 @@ package net.ccbluex.liquidbounce.features.module.modules.exploit import net.ccbluex.liquidbounce.event.EventTarget import net.ccbluex.liquidbounce.event.PacketEvent -import net.ccbluex.liquidbounce.event.UpdateEvent +import net.ccbluex.liquidbounce.event.TickEvent +import net.ccbluex.liquidbounce.event.WorldEvent import net.ccbluex.liquidbounce.features.module.Module import net.ccbluex.liquidbounce.features.module.ModuleCategory -import net.ccbluex.liquidbounce.utils.PacketUtils.sendPacket -import net.ccbluex.liquidbounce.utils.timing.TimeUtils.randomDelay +import net.ccbluex.liquidbounce.utils.PacketUtils.handlePacket import net.ccbluex.liquidbounce.value.IntegerValue import net.minecraft.network.Packet -import net.minecraft.network.play.client.C00PacketKeepAlive -import net.minecraft.network.play.client.C0FPacketConfirmTransaction -import net.minecraft.network.play.client.C16PacketClientStatus +import net.minecraft.network.play.server.S00PacketKeepAlive +import net.minecraft.network.play.server.S32PacketConfirmTransaction +import java.util.concurrent.ConcurrentHashMap object PingSpoof : Module("PingSpoof", ModuleCategory.EXPLOIT) { - private val maxDelayValue: IntegerValue = object : IntegerValue("MaxDelay", 1000, 0..5000) { - override fun onChange(oldValue: Int, newValue: Int) = newValue.coerceAtLeast(minDelay) + private val delay by object : IntegerValue("Delay", 500, 0..25000) { + override fun onChange(oldValue: Int, newValue: Int): Int { + reset() + + return newValue + } } - private val maxDelay by maxDelayValue - private val minDelay by object : IntegerValue("MinDelay", 500, 0..5000) { - override fun onChange(oldValue: Int, newValue: Int) = newValue.coerceAtMost(maxDelay) + private val packetQueue = ConcurrentHashMap, Pair>() - override fun isSupported() = !maxDelayValue.isMinimal() - } + private var cancelPackets = false - private val packetQueue = hashMapOf, Long>() + override fun onEnable() { + cancelPackets = true + } - override fun onDisable() = packetQueue.clear() + override fun onDisable() { + reset() + } - @EventTarget + // Ignore conditions must be true because there is always a chance packets could be received + // during module disable and the packet queue would not fetch the latest packet addition, therefore messing up the order + @EventTarget(ignoreCondition = true) fun onPacket(event: PacketEvent) { val packet = event.packet - if (mc.thePlayer == null) { + if (mc.thePlayer == null || !cancelPackets) { return } - if ((packet is C00PacketKeepAlive || packet is C16PacketClientStatus || packet is C0FPacketConfirmTransaction) && packet !in packetQueue) { + if (packet is S32PacketConfirmTransaction || packet is S00PacketKeepAlive) { event.cancelEvent() - synchronized(packetQueue) { - packetQueue[packet] = - System.currentTimeMillis() + randomDelay(minDelay, maxDelay) - } + // Use nano time for the registration time since there are chances + // the packets can be under the same milliseconds and mess up the order + packetQueue[packet] = System.currentTimeMillis() + delay to System.nanoTime() } } @EventTarget - fun onUpdate(event: UpdateEvent) { - var filtered: List> + fun onTick(event: TickEvent) { + sendPacketsByOrder(false) + } + + @EventTarget + fun onWorld(event: WorldEvent) { + packetQueue.clear() + } - synchronized(packetQueue) { - filtered = packetQueue.entries.filter { - it.value <= System.currentTimeMillis() - }.map { it.key } - } + private fun sendPacketsByOrder(all: Boolean) { + // Accept packets that have passed the requested delay, then sort by registration time + val filtered = packetQueue.filter { + all || it.value.first <= System.currentTimeMillis() + }.entries.sortedBy { it.value.second }.map { it.key } for (packet in filtered) { - sendPacket(packet) + handlePacket(packet) packetQueue.remove(packet) } } + private fun reset() { + sendPacketsByOrder(true) + + packetQueue.clear() + + cancelPackets = false + } } diff --git a/src/main/java/net/ccbluex/liquidbounce/utils/PacketUtils.kt b/src/main/java/net/ccbluex/liquidbounce/utils/PacketUtils.kt index 095b802e267..3850eb9f57a 100644 --- a/src/main/java/net/ccbluex/liquidbounce/utils/PacketUtils.kt +++ b/src/main/java/net/ccbluex/liquidbounce/utils/PacketUtils.kt @@ -59,7 +59,7 @@ object PacketUtils : MinecraftInstance() { fun sendPackets(vararg packets: Packet<*>, triggerEvents: Boolean = true) = packets.forEach { sendPacket(it, triggerEvents) } - fun handlePacket(packet: Packet?) = packet?.processPacket(mc.netHandler) + fun handlePacket(packet: Packet<*>?) = (packet as Packet).processPacket(mc.netHandler) val Packet<*>.type get() = when (this.javaClass.simpleName[0]) {