|
| 1 | +package com.lambda.module.modules.network |
| 2 | + |
| 3 | +import com.lambda.event.events.PacketEvent |
| 4 | +import com.lambda.event.listener.SafeListener.Companion.listener |
| 5 | +import com.lambda.module.Module |
| 6 | +import com.lambda.module.tag.ModuleTag |
| 7 | +import com.lambda.threading.runConcurrent |
| 8 | +import com.lambda.threading.runGameScheduled |
| 9 | +import kotlinx.coroutines.delay |
| 10 | +import net.minecraft.network.ClientConnection |
| 11 | +import net.minecraft.network.packet.Packet |
| 12 | +import net.minecraft.network.packet.c2s.common.KeepAliveC2SPacket |
| 13 | + |
| 14 | +object PacketDelay : Module( |
| 15 | + name = "PacketDelay", |
| 16 | + description = "Delays packets client-side & server-side.", |
| 17 | + defaultTags = setOf(ModuleTag.NETWORK), |
| 18 | +) { |
| 19 | + private val networkScope by setting("Network Scope", Direction.BOTH) |
| 20 | + private val packetScope by setting("Packet Scope", PacketType.ANY) |
| 21 | + private val inboundDelay by setting("Inbound Delay", 250L, 0L..5000L, 10L, unit = "ms") { networkScope != Direction.OUTBOUND } |
| 22 | + private val outboundDelay by setting("Outbound Delay", 250L, 0L..5000L, 10L, unit = "ms") { networkScope != Direction.INBOUND } |
| 23 | + |
| 24 | + enum class Direction { |
| 25 | + BOTH, |
| 26 | + INBOUND, |
| 27 | + OUTBOUND |
| 28 | + } |
| 29 | + |
| 30 | + enum class PacketType(val filter: (Packet<*>) -> Boolean) { |
| 31 | + ANY({ true }), |
| 32 | + KEEP_ALIVE({ it is KeepAliveC2SPacket }) |
| 33 | + } |
| 34 | + |
| 35 | + init { |
| 36 | + listener<PacketEvent.Receive.Pre>(Int.MIN_VALUE) { event -> |
| 37 | + if (!connection.connection.isOpen) return@listener |
| 38 | + if (!packetScope.filter(event.packet)) return@listener |
| 39 | + event.cancel() |
| 40 | + |
| 41 | + runConcurrent { |
| 42 | + delay(inboundDelay) |
| 43 | + runGameScheduled { |
| 44 | + if (connection.connection.packetListener?.accepts(event.packet) == false) return@runGameScheduled |
| 45 | + |
| 46 | + ClientConnection.handlePacket(event.packet, connection.connection.packetListener) |
| 47 | + connection.connection.packetsReceivedCounter++ |
| 48 | + } |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + listener<PacketEvent.Send.Pre>(Int.MIN_VALUE) { event -> |
| 53 | + if (!connection.connection.isOpen) return@listener |
| 54 | + if (!packetScope.filter(event.packet)) return@listener |
| 55 | + event.cancel() |
| 56 | + |
| 57 | + runConcurrent { |
| 58 | + delay(outboundDelay) |
| 59 | + runGameScheduled { |
| 60 | + connection.connection.send(event.packet, null) |
| 61 | + connection.connection.packetsSentCounter++ |
| 62 | + } |
| 63 | + } |
| 64 | + } |
| 65 | + } |
| 66 | +} |
0 commit comments