Skip to content

Commit b0995e7

Browse files
emyfopsbladekt
authored andcommitted
feat: static & dynamic delay mode
1 parent 5883c88 commit b0995e7

File tree

1 file changed

+81
-27
lines changed
  • common/src/main/kotlin/com/lambda/module/modules/network

1 file changed

+81
-27
lines changed
Lines changed: 81 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,120 @@
11
package com.lambda.module.modules.network
22

3+
import com.lambda.context.SafeContext
34
import com.lambda.event.events.PacketEvent
5+
import com.lambda.event.events.RenderEvent
46
import com.lambda.event.listener.SafeListener.Companion.listener
57
import com.lambda.module.Module
68
import com.lambda.module.tag.ModuleTag
79
import com.lambda.threading.runConcurrent
810
import com.lambda.threading.runGameScheduled
11+
import com.lambda.util.PacketUtils.handlePacketSilently
12+
import com.lambda.util.PacketUtils.sendPacketSilently
913
import kotlinx.coroutines.delay
10-
import net.minecraft.network.ClientConnection
14+
import net.minecraft.network.listener.ClientPacketListener
15+
import net.minecraft.network.listener.ServerPacketListener
1116
import net.minecraft.network.packet.Packet
1217
import net.minecraft.network.packet.c2s.common.KeepAliveC2SPacket
18+
import java.util.concurrent.ConcurrentLinkedDeque
1319

1420
object PacketDelay : Module(
1521
name = "PacketDelay",
1622
description = "Delays packets client-side & server-side.",
1723
defaultTags = setOf(ModuleTag.NETWORK),
1824
) {
25+
private val mode by setting("Mode", Mode.STATIC)
1926
private val networkScope by setting("Network Scope", Direction.BOTH)
2027
private val packetScope by setting("Packet Scope", PacketType.ANY)
2128
private val inboundDelay by setting("Inbound Delay", 250L, 0L..5000L, 10L, unit = "ms") { networkScope != Direction.OUTBOUND }
2229
private val outboundDelay by setting("Outbound Delay", 250L, 0L..5000L, 10L, unit = "ms") { networkScope != Direction.INBOUND }
2330

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-
}
31+
private var outboundPool = ConcurrentLinkedDeque<Packet<out ServerPacketListener>>()
32+
private var inboundPool = ConcurrentLinkedDeque<Packet<out ClientPacketListener>>()
33+
private var outboundLastUpdate = 0L
34+
private var inboundLastUpdate = 0L
3435

3536
init {
36-
listener<PacketEvent.Receive.Pre>(Int.MIN_VALUE) { event ->
37-
if (!connection.connection.isOpen) return@listener
37+
listener<RenderEvent.World> {
38+
if (mode != Mode.STATIC) return@listener
39+
40+
flushPools(System.currentTimeMillis())
41+
}
42+
43+
listener<PacketEvent.Send.Pre>(Int.MIN_VALUE) { event ->
3844
if (!packetScope.filter(event.packet)) return@listener
39-
event.cancel()
4045

41-
runConcurrent {
42-
delay(inboundDelay)
43-
runGameScheduled {
44-
if (connection.connection.packetListener?.accepts(event.packet) == false) return@runGameScheduled
46+
when (mode) {
47+
Mode.STATIC -> {
48+
outboundPool.add(event.packet)
49+
event.cancel()
50+
}
4551

46-
ClientConnection.handlePacket(event.packet, connection.connection.packetListener)
47-
connection.connection.packetsReceivedCounter++
52+
Mode.PULSE -> {
53+
runConcurrent {
54+
delay(outboundDelay)
55+
runGameScheduled {
56+
connection.sendPacketSilently(event.packet)
57+
}
58+
}
59+
event.cancel()
4860
}
4961
}
5062
}
5163

52-
listener<PacketEvent.Send.Pre>(Int.MIN_VALUE) { event ->
53-
if (!connection.connection.isOpen) return@listener
64+
listener<PacketEvent.Receive.Pre>(Int.MIN_VALUE) { event ->
5465
if (!packetScope.filter(event.packet)) return@listener
66+
67+
when (mode) {
68+
Mode.STATIC -> {
69+
inboundPool.add(event.packet)
70+
event.cancel()
71+
}
72+
73+
Mode.PULSE -> {
74+
runConcurrent {
75+
delay(inboundDelay)
76+
runGameScheduled {
77+
connection.handlePacketSilently(event.packet)
78+
}
79+
}
80+
event.cancel()
81+
}
82+
}
83+
5584
event.cancel()
85+
}
86+
87+
onDisable {
88+
flushPools(System.currentTimeMillis())
89+
}
90+
}
91+
92+
private fun SafeContext.flushPools(time: Long) {
93+
if (time - outboundLastUpdate >= outboundDelay) {
94+
while (outboundPool.isNotEmpty()) {
95+
outboundPool.poll().let { packet ->
96+
connection.sendPacketSilently(packet)
97+
}
98+
}
99+
100+
outboundLastUpdate = time
101+
}
56102

57-
runConcurrent {
58-
delay(outboundDelay)
59-
runGameScheduled {
60-
connection.connection.send(event.packet, null)
61-
connection.connection.packetsSentCounter++
103+
if (time - inboundLastUpdate >= inboundDelay) {
104+
while (inboundPool.isNotEmpty()) {
105+
inboundPool.poll().let { packet ->
106+
connection.handlePacketSilently(packet)
62107
}
63108
}
109+
110+
inboundLastUpdate = time
64111
}
65112
}
113+
114+
enum class Mode { STATIC, PULSE, }
115+
enum class Direction { BOTH, INBOUND, OUTBOUND }
116+
enum class PacketType(val filter: (Packet<*>) -> Boolean) {
117+
ANY({ true }),
118+
KEEP_ALIVE({ it is KeepAliveC2SPacket })
119+
}
66120
}

0 commit comments

Comments
 (0)