Skip to content
This repository was archived by the owner on Nov 28, 2025. It is now read-only.

Commit a1fa1aa

Browse files
authored
Merge pull request #138 from DockyardMC/feature/bandwith-monitor
Add a bandwidth counter server metric
2 parents f0e962f + ac94a44 commit a1fa1aa

File tree

22 files changed

+123
-48
lines changed

22 files changed

+123
-48
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ dependencies {
7373
implementation("com.google.guava:guava:33.3.1-jre")
7474
implementation("com.google.code.gson:gson:2.10.1")
7575
api("it.unimi.dsi:fastutil:8.5.13")
76-
api("cz.lukynka:kotlin-bindables:1.9")
76+
api("cz.lukynka:kotlin-bindables:2.0")
7777

7878
api("io.github.dockyardmc:spark-api:1.12-SNAPSHOT")
7979
api("io.github.dockyardmc:spark-common:1.12-SNAPSHOT")

src/main/kotlin/Main.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import io.github.dockyardmc.events.PlayerJoinEvent
77
import io.github.dockyardmc.player.Player
88
import io.github.dockyardmc.player.systems.GameMode
99
import io.github.dockyardmc.registry.registries.PotionEffectRegistry
10+
import io.github.dockyardmc.utils.DebugSidebar
1011

1112
fun suggestPotionEffects(player: Player): List<String> {
1213
return PotionEffectRegistry.potionEffects.keys.toList()
@@ -25,6 +26,7 @@ fun main() {
2526
player.permissions.add("dockyard.admin")
2627
player.permissions.add("dockyard.*")
2728
player.gameMode.value = GameMode.CREATIVE
29+
DebugSidebar.sidebar.viewers.add(player)
2830
}
2931

3032
Commands.add("/interaction") {
@@ -34,15 +36,15 @@ fun main() {
3436
interaction.width.value = 3f
3537
interaction.height.value = 3f
3638

37-
interaction.rightClickDispatcher.register { p ->
39+
interaction.rightClickDispatcher.subscribe { p ->
3840
p.sendMessage("<yellow>Right Click")
3941
}
4042

41-
interaction.leftClickDispatcher.register { p ->
43+
interaction.leftClickDispatcher.subscribe { p ->
4244
p.sendMessage("<yellow>Left Click")
4345
}
4446

45-
interaction.middleClickDispatcher.register { p ->
47+
interaction.middleClickDispatcher.subscribe { p ->
4648
p.sendMessage("<yellow>Middle Click")
4749
}
4850
}

src/main/kotlin/io/github/dockyardmc/apis/sidebar/Sidebar.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import cz.lukynka.bindables.BindableList
55
import io.github.dockyardmc.extentions.sendPacket
66
import io.github.dockyardmc.player.Player
77
import io.github.dockyardmc.protocol.packets.play.clientbound.*
8+
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
89
import java.util.*
910

1011
class Sidebar(builder: Sidebar.() -> Unit) {
1112

1213
val title: Bindable<String> = Bindable("")
1314
val viewers: BindableList<Player> = BindableList()
14-
private val innerLines: MutableMap<Int, SidebarLine> = mutableMapOf()
15+
private val innerLines: Int2ObjectOpenHashMap<SidebarLine> = Int2ObjectOpenHashMap()
1516
val lines get() = innerLines.toList()
1617

1718
private val objective = UUID.randomUUID().toString()
@@ -35,7 +36,7 @@ class Sidebar(builder: Sidebar.() -> Unit) {
3536
fun setGlobalLine(line: Int, value: String) {
3637
val before = innerLines[line] as GlobalSidebarLine?
3738
innerLines[line] = GlobalSidebarLine(value)
38-
if(before?.value != value) viewers.values.forEach { sendLinePacket(it, line) }
39+
if (before?.value != value) viewers.values.forEach { sendLinePacket(it, line) }
3940
}
4041

4142
fun setPlayerLine(line: Int, value: (Player) -> String) {
@@ -59,7 +60,7 @@ class Sidebar(builder: Sidebar.() -> Unit) {
5960
}
6061

6162
private fun getLine(line: Int, player: Player): String {
62-
val value = when(val it = innerLines[line]) {
63+
val value = when (val it = innerLines[line]) {
6364
is GlobalSidebarLine -> it.value
6465
is PersonalizedSidebarLine -> it.getValue(player)
6566
else -> ""

src/main/kotlin/io/github/dockyardmc/entity/InteractionEntity.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ class Interaction(location: Location): Entity(location) {
2020
val height: Bindable<Float> = bindablePool.provideBindable(1f)
2121
val responsive: Bindable<Boolean> = bindablePool.provideBindable(true)
2222

23-
val rightClickDispatcher: BindableDispatcher<Player> = bindablePool.provideBindableListener()
24-
val leftClickDispatcher: BindableDispatcher<Player> = bindablePool.provideBindableListener()
25-
val middleClickDispatcher: BindableDispatcher<Player> = bindablePool.provideBindableListener()
26-
val generalInteractionDispatcher: BindableDispatcher<Player> = bindablePool.provideBindableListener()
23+
val rightClickDispatcher: BindableDispatcher<Player> = bindablePool.provideBindableDispatcher()
24+
val leftClickDispatcher: BindableDispatcher<Player> = bindablePool.provideBindableDispatcher()
25+
val middleClickDispatcher: BindableDispatcher<Player> = bindablePool.provideBindableDispatcher()
26+
val generalInteractionDispatcher: BindableDispatcher<Player> = bindablePool.provideBindableDispatcher()
2727

2828
init {
2929
eventPool.on<PlayerInteractWithEntityEvent> { event ->

src/main/kotlin/io/github/dockyardmc/entity/ai/goals/RandomWalkAroundGoal.kt

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,10 @@ package io.github.dockyardmc.entity.ai.goals
33
import io.github.dockyardmc.entity.Entity
44
import io.github.dockyardmc.entity.ai.AIGoal
55
import io.github.dockyardmc.location.Location
6+
import io.github.dockyardmc.maths.randomInt
67
import io.github.dockyardmc.pathfinding.Navigator
78
import io.github.dockyardmc.pathfinding.PatheticPlatformDockyard.toPathPosition
89
import io.github.dockyardmc.pathfinding.PathfindingHelper
9-
import io.github.dockyardmc.registry.Sounds
10-
import io.github.dockyardmc.sounds.Sound
11-
import io.github.dockyardmc.maths.randomFloat
12-
import io.github.dockyardmc.maths.randomInt
1310

1411
class RandomWalkAroundGoal(override var entity: Entity, override var priority: Int, val navigator: Navigator) : AIGoal() {
1512

@@ -25,26 +22,23 @@ class RandomWalkAroundGoal(override var entity: Entity, override var priority: I
2522
hasFinishedWalking = false
2623
var locationToPathfindTo: Location? = null
2724
startingLocation.getBlocksInRadius(10).shuffled().forEach { location ->
28-
if(!PathfindingHelper.isTraversable(location.block, location)) return@forEach
25+
if (!PathfindingHelper.isTraversable(location.block, location)) return@forEach
2926
val start = entity.location.getBlockLocation().subtract(0, 1, 0).toPathPosition()
3027
val end = location.toPathPosition()
3128

3229
navigator.pathfinder.findPath(start, end, navigator.filters).thenAccept { result ->
33-
if(!result.successful()) return@thenAccept
30+
if (!result.successful()) return@thenAccept
3431
locationToPathfindTo = location
3532
}
3633
}
3734

38-
if(locationToPathfindTo == null) {
35+
if (locationToPathfindTo == null) {
3936
hasFinishedWalking = true
4037
return
4138
}
4239

4340
navigator.updatePathfindingPath(locationToPathfindTo!!)
44-
navigator.navigationNodeStepDispatcher.register {
45-
entity.playSoundToViewers(Sound(Sounds.ENTITY_RAVAGER_STEP, volume = 0.1f, pitch = randomFloat(1f, 1.3f)), entity.location)
46-
}
47-
navigator.navigationCompleteDispatcher.register {
41+
navigator.navigationCompleteDispatcher.subscribe {
4842
hasFinishedWalking = true
4943
}
5044
}

src/main/kotlin/io/github/dockyardmc/events/system/EventSystem.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ package io.github.dockyardmc.events.system
33
import io.github.dockyardmc.events.*
44
import io.github.dockyardmc.events.EventListener
55
import io.github.dockyardmc.utils.Disposable
6+
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
67
import java.util.*
78
import kotlin.reflect.KClass
89

910
abstract class EventSystem : Disposable {
1011
val eventMap = mutableMapOf<KClass<out Event>, HandlerList>()
1112
var filter = EventFilter.empty()
1213

13-
val children = mutableSetOf<EventSystem>()
14+
val children = ObjectOpenHashSet<EventSystem>()
1415
open var parent: EventSystem? = null
1516
internal set // assigning to this value will fuck everything, there is no point having it public.
1617
open var name: String = "eventsystem-${UUID.randomUUID().toString().substring(0..7)}"
@@ -53,7 +54,7 @@ abstract class EventSystem : Disposable {
5354
// we create a copy of the children array before running any handlers to
5455
// ensure that if any children are added in the following listeners,
5556
// we don't call the newly registered events
56-
val children = children.toTypedArray()
57+
val children = children.clone()
5758
eventMap[eventType]?.let { handlers ->
5859
handlers.listeners.forEach { executableEvent ->
5960
executableEvent.function.invoke(event)

src/main/kotlin/io/github/dockyardmc/maths/MathUtils.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package io.github.dockyardmc.maths
22

33
import com.google.common.primitives.Ints.min
44
import io.github.dockyardmc.location.Location
5-
import io.github.dockyardmc.utils.ChunkUtils.floor
5+
import io.github.dockyardmc.world.chunk.ChunkUtils.floor
66
import io.github.dockyardmc.maths.vectors.Vector3f
77
import java.io.File
88
import java.security.MessageDigest

src/main/kotlin/io/github/dockyardmc/protocol/decoders/PacketLengthDecoder.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package io.github.dockyardmc.protocol.decoders
33
import cz.lukynka.prettylog.LogType
44
import cz.lukynka.prettylog.log
55
import io.github.dockyardmc.extentions.readVarInt
6+
import io.github.dockyardmc.server.ServerMetrics
7+
import io.github.dockyardmc.utils.DataSizeCounter
68
import io.netty.buffer.ByteBuf
79
import io.netty.channel.ChannelHandlerContext
810
import io.netty.handler.codec.ByteToMessageDecoder
@@ -23,6 +25,9 @@ class PacketLengthDecoder : ByteToMessageDecoder() {
2325

2426
out.add(buffer.retainedSlice(buffer.readerIndex(), length))
2527
buffer.skipBytes(length)
28+
// +1 to account for the size byte that is not counted
29+
ServerMetrics.inboundBandwidth.add(length + 1, DataSizeCounter.Type.BYTE)
30+
ServerMetrics.totalBandwidth.add(length + 1, DataSizeCounter.Type.BYTE)
2631
}
2732

2833
override fun exceptionCaught(connection: ChannelHandlerContext, cause: Throwable) {

src/main/kotlin/io/github/dockyardmc/protocol/encoders/PacketLengthEncoder.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package io.github.dockyardmc.protocol.encoders
33
import cz.lukynka.prettylog.LogType
44
import cz.lukynka.prettylog.log
55
import io.github.dockyardmc.extentions.writeVarInt
6+
import io.github.dockyardmc.server.ServerMetrics
7+
import io.github.dockyardmc.utils.DataSizeCounter
68
import io.netty.buffer.ByteBuf
79
import io.netty.channel.ChannelHandlerContext
810
import io.netty.handler.codec.MessageToByteEncoder
@@ -11,8 +13,13 @@ class PacketLengthEncoder: MessageToByteEncoder<ByteBuf>() {
1113

1214
override fun encode(connection: ChannelHandlerContext, buffer: ByteBuf, out: ByteBuf) {
1315
try {
14-
out.writeVarInt(buffer.readableBytes())
16+
val size = buffer.readableBytes()
17+
out.writeVarInt(size)
1518
out.writeBytes(buffer)
19+
20+
// +1 to account for the size byte that is not counted
21+
ServerMetrics.outboundBandwidth.add(size + 1, DataSizeCounter.Type.BYTE)
22+
ServerMetrics.totalBandwidth.add(size + 1, DataSizeCounter.Type.BYTE)
1623
} catch (exception: Exception) {
1724
log("There was an error while encoding packet length", LogType.ERROR)
1825
log(exception)

src/main/kotlin/io/github/dockyardmc/protocol/packets/play/clientbound/ClientboundChunkDataPacket.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package io.github.dockyardmc.protocol.packets.play.clientbound
22

33
import io.github.dockyardmc.extentions.*
44
import io.github.dockyardmc.protocol.packets.ClientboundPacket
5-
import io.github.dockyardmc.utils.ChunkUtils
5+
import io.github.dockyardmc.world.chunk.ChunkUtils
66
import io.github.dockyardmc.utils.writeMSNBT
77
import io.github.dockyardmc.world.Light
88
import io.github.dockyardmc.world.block.BlockEntity

0 commit comments

Comments
 (0)