1+ package io.github.dockyardmc.implementations.commands
2+
3+ import io.github.dockyardmc.DockyardServer
4+ import io.github.dockyardmc.commands.Commands
5+ import io.github.dockyardmc.commands.WorldArgument
6+ import io.github.dockyardmc.events.Events
7+ import io.github.dockyardmc.extentions.truncate
8+ import io.github.dockyardmc.player.PlayerManager
9+ import io.github.dockyardmc.profiler.profiler
10+ import io.github.dockyardmc.server.ServerMetrics
11+ import io.github.dockyardmc.utils.DataSizeCounter
12+ import io.github.dockyardmc.world.World
13+
14+ object DebugCommands {
15+
16+ fun register () {
17+
18+ Commands .add(" /debug_world" ) {
19+ addOptionalArgument(" world" , WorldArgument ())
20+ execute { ctx ->
21+ val world = getArgumentOrNull<World >(" world" ) ? : ctx.getPlayerOrThrow().world
22+
23+ ctx.sendMessage(" " )
24+ ctx.sendMessage(" <gray>Entities:" )
25+ ctx.sendMessage(" <dark_gray>◾ <gray>Total: <white>${world.entities.size} " )
26+ ctx.sendMessage(" <dark_gray>◾ <gray>Tickable: <white>${world.entities.filter { entity -> entity.tickable }.size} " )
27+ ctx.sendMessage(" <dark_gray>◾ <gray>Non-tickable: <white>${world.entities.filter { entity -> ! entity.tickable }.size} " )
28+ ctx.sendMessage(" <dark_gray>◾ <gray>AutoViewable: <white>${world.entities.filter { entity -> entity.autoViewable }.size} " )
29+ ctx.sendMessage(" <dark_gray>◾ <gray>Non-AutoViewable: <white>${world.entities.filter { entity -> ! entity.autoViewable }.size} " )
30+ ctx.sendMessage(" " )
31+ ctx.sendMessage(" <gray>Chunks:" )
32+ ctx.sendMessage(" <dark_gray>◾ <gray>Total: <white>${world.chunks.size} " )
33+ ctx.sendMessage(" <dark_gray>◾ <gray>Visible: <white>${world.chunks.filter { chunk -> chunk.value.viewers.isNotEmpty() }.size} " )
34+ ctx.sendMessage(" " )
35+ ctx.sendMessage(" <gray>Scheduler:" )
36+ ctx.sendMessage(" <dark_gray>◾ <gray>Running: <white>${! world.scheduler.paused.value} " )
37+ ctx.sendMessage(" <dark_gray>◾ <gray>Tickrate: <white>${world.scheduler.tickRate.value.inWholeMilliseconds} ms <gray>(${world.scheduler.mspt} mspt)" )
38+ ctx.sendMessage(" <dark_gray>◾ <gray>Tasks: <white>${world.scheduler.taskSize} " )
39+ ctx.sendMessage(" " )
40+ ctx.sendMessage(" <gray>World:" )
41+ ctx.sendMessage(" <dark_gray>◾ <gray>Event pool size: <white>${world.eventPool.eventList().size} " )
42+ ctx.sendMessage(" <dark_gray>◾ <gray>Bindable pool size: <white>${world.bindablePool.size} " )
43+ ctx.sendMessage(" <dark_gray>◾ <gray>Loaded: <white>${world.isLoaded.value} " )
44+ ctx.sendMessage(" <dark_gray>◾ <gray>Player Queue: <white>${world.playerJoinQueue.size} " )
45+ ctx.sendMessage(" <dark_gray>◾ <gray>Data Blocks: <white>${world.customDataBlocks.size} " )
46+ ctx.sendMessage(" " )
47+ }
48+ }
49+
50+ Commands .add(" /debug_events" ) {
51+ execute { ctx ->
52+ ctx.sendMessage(" " )
53+ ctx.sendMessage(Events .debugTree())
54+ ctx.sendMessage(" " )
55+ }
56+ }
57+
58+ Commands .add(" /forcegc" ) {
59+ execute { ctx ->
60+ val ms = profiler(" Force Collect GC" ) {
61+ System .gc()
62+ }
63+ ctx.sendMessage(" <gray>Ran GC in <white>${ms} <gray>ms" )
64+ }
65+ }
66+
67+ Commands .add(" /debug_network" ) {
68+ execute { ctx ->
69+ val dockyard = DockyardServer .instance.nettyServer
70+ val nettyThreadBoss = dockyard.bossGroup.executorCount()
71+ val nettyThreadWorker = dockyard.workerGroup.executorCount()
72+
73+ ctx.sendMessage(" " )
74+ ctx.sendMessage(" <gray>Netty:" )
75+ ctx.sendMessage(" <dark_gray>◾ <gray>Boss: <white>$nettyThreadBoss " )
76+ ctx.sendMessage(" <dark_gray>◾ <gray>Worker: <white>$nettyThreadWorker " )
77+ ctx.sendMessage(" <dark_gray>◾ <gray>Connections: <white>${PlayerManager .players.size} " )
78+ ctx.sendMessage(" " )
79+ ctx.sendMessage(" <gray>Network" )
80+ ctx.sendMessage(" <dark_gray>◾ <gray>Packets/Sec: <white>↑${ServerMetrics .packetsSentAverage} ↓${ServerMetrics .packetsReceivedAverage} " )
81+ ctx.sendMessage(" <dark_gray>◾ <gray>Bandwidth: <white>↑${ServerMetrics .outboundBandwidth.getSize(DataSizeCounter .Type .MEGABYTE )} mb ↓${ServerMetrics .inboundBandwidth.getSize(DataSizeCounter .Type .MEGABYTE )} mb" )
82+ ctx.sendMessage(" " )
83+ }
84+ }
85+
86+ Commands .add(" /debug_memory" ) {
87+ execute { ctx ->
88+ val runtime = Runtime .getRuntime()
89+ val message = buildString {
90+ append(" \n " )
91+ appendLine(" <gray>Memory Stats:" )
92+ appendLine(" <dark_gray>◾ <gray>Max memory: <white>${runtime.maxMemory() / 1024 / 1024 } MB" )
93+ appendLine(" <dark_gray>◾ <gray>Total memory: <white>${runtime.totalMemory() / 1024 / 1024 } MB" )
94+ appendLine(" <dark_gray>◾ <gray>Free memory: <white>${runtime.freeMemory() / 1024 / 1024 } MB" )
95+ appendLine(" <dark_gray>◾ <gray>Used memory: <white>${(runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024 } MB" )
96+ appendLine(" " )
97+ appendLine(" <gray>GC Stats:" )
98+ appendLine(" <dark_gray>◾ <gray>Available processors: <white>${runtime.availableProcessors()} " )
99+ appendLine(" <dark_gray>◾ <gray>Memory usage: <white>${ServerMetrics .memoryUsagePercent.truncate(1 )} %" )
100+ }
101+ ctx.sendMessage(message)
102+ }
103+ }
104+
105+ Commands .add(" /reloadchunks" ) {
106+ execute { ctx ->
107+ val player = ctx.getPlayerOrThrow()
108+ player.chunkViewSystem.lock.lock()
109+ player.chunkViewSystem.resendChunks()
110+ player.chunkViewSystem.lock.unlock()
111+ player.chunkViewSystem.update()
112+ player.sendMessage(" <gray>Reloaded your chunks!" )
113+ }
114+ }
115+
116+ Commands .add(" /reloadviewers" ) {
117+ execute { ctx ->
118+ val player = ctx.getPlayerOrThrow()
119+ player.entityViewSystem.lock.lock()
120+ player.entityViewSystem.clear()
121+ player.entityViewSystem.lock.unlock()
122+ player.entityViewSystem.tick()
123+ player.sendMessage(" <gray>Reloaded your viewers!" )
124+ }
125+ }
126+ }
127+ }
0 commit comments