This commit is contained in:
rattatwinko
2025-04-26 15:19:44 +02:00
commit 4731a659b9
23 changed files with 486 additions and 0 deletions

10
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Environment-dependent path to Maven home directory
/mavenHomeManager.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

13
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="server_info" />
</profile>
</annotationProcessing>
</component>
</project>

7
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/kotlin" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

30
.idea/jarRepositories.xml generated Normal file
View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="sonatype" />
<option name="name" value="sonatype" />
<option name="url" value="https://oss.sonatype.org/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="papermc-repo" />
<option name="name" value="papermc-repo" />
<option name="url" value="https://repo.papermc.io/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

6
.idea/kotlinc.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="2.2.0-Beta1" />
</component>
</project>

14
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_24" default="true" project-jdk-name="openjdk-24" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/server_info.iml" filepath="$PROJECT_DIR$/server_info.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.server_info</groupId>
<artifactId>server_info</artifactId>
<name>server_info</name>
<version>1.0-SNAPSHOT</version>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<defaultGoal>clean package</defaultGoal>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>${java.version}</jvmTarget>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>papermc-repo</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.21.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kotlin.version>2.2.0-Beta1</kotlin.version>
<java.version>21</java.version>
</properties>
</project>

87
pom.xml Normal file
View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.server_info</groupId>
<artifactId>server_info</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>server_info</name>
<properties>
<java.version>21</java.version>
<kotlin.version>2.2.0-Beta1</kotlin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<defaultGoal>clean package</defaultGoal>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>${java.version}</jvmTarget>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>papermc-repo</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.21.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</project>

13
server_info.iml Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>PAPER</platformType>
</autoDetectTypes>
<projectReimportVersion>1</projectReimportVersion>
</configuration>
</facet>
</component>
</module>

View File

@@ -0,0 +1,187 @@
package org.server_info.server_info
import net.kyori.adventure.text.Component
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import org.bukkit.plugin.java.JavaPlugin
import org.bukkit.scheduler.BukkitRunnable
import java.lang.management.ManagementFactory
import java.text.DecimalFormat
class Server_info : JavaPlugin() {
private var lastTickTime = System.currentTimeMillis()
private var tickCount = 0
private val tickTimeList = ArrayList<Long>()
private var tps = 20.0
private val df = DecimalFormat("#.##")
override fun onEnable() {
// Register command
getCommand("serverinfo")?.setExecutor(ServerInfoCommand(this))
// Start server info collectors
startTPSCalculation()
startTabListUpdater()
logger.info("ServerInfo plugin has been enabled!")
}
override fun onDisable() {
logger.info("ServerInfo plugin has been disabled!")
}
private fun startTPSCalculation() {
// Better TPS calculation method with moving average
object : BukkitRunnable() {
override fun run() {
tickCount++
val now = System.currentTimeMillis()
val elapsed = now - lastTickTime
lastTickTime = now
// Store data point - time per tick in ms
// Only add if we've gone through at least one tick to avoid startup anomalies
if (tickCount > 1) {
tickTimeList.add(elapsed)
}
// Keep only the last 600 data points (30 seconds at 20 TPS)
while (tickTimeList.size > 600) {
tickTimeList.removeAt(0)
}
// Calculate average tick time and TPS if we have data
if (tickTimeList.isNotEmpty()) {
val avgTickTime = tickTimeList.average()
tps = 1000.0 / avgTickTime
// Clamp TPS between 0 and 20
if (tps > 20.0) tps = 20.0
if (tps < 0.0) tps = 0.0
}
}
}.runTaskTimer(this, 1L, 1L) // Run every tick
}
private fun startTabListUpdater() {
object : BukkitRunnable() {
override fun run() {
updateTabList()
}
}.runTaskTimer(this, 20L, 20L) // Update every second
}
private fun updateTabList() {
val header = getTabListHeader()
val footer = getTabListFooter()
for (player in Bukkit.getOnlinePlayers()) {
player.sendPlayerListHeaderAndFooter(header, footer)
}
}
private fun getTabListHeader(): Component {
val serverName = server.name
return Component.text("§6§l$serverName\n§r§7Online players: §f${server.onlinePlayers.size}/${server.maxPlayers}")
}
private fun getTabListFooter(): Component {
// Memory information
val runtime = Runtime.getRuntime()
val maxMemory = runtime.maxMemory() / (1024 * 1024)
val allocatedMemory = runtime.totalMemory() / (1024 * 1024)
val freeMemory = runtime.freeMemory() / (1024 * 1024)
val usedMemory = allocatedMemory - freeMemory
// CPU usage
val osBean = ManagementFactory.getOperatingSystemMXBean()
var cpuLoad = osBean.systemLoadAverage
if (cpuLoad < 0) {
cpuLoad = osBean.availableProcessors * ManagementFactory.getThreadMXBean().threadCount / 100.0
}
val tpsColor = when {
tps >= 18.0 -> "§2" // Dark green
tps >= 15.0 -> "§e" // Yellow
else -> "§c" // Red
}
return Component.text(
"\n§7RAM: §f${usedMemory}MB / ${maxMemory}MB" +
"\n§7CPU: §f${df.format(cpuLoad)}%" +
"\n§7TPS: $tpsColor${df.format(tps)}"
)
}
fun getServerInfo(): String {
val info = StringBuilder()
// Memory information
val runtime = Runtime.getRuntime()
val maxMemory = runtime.maxMemory() / (1024 * 1024)
val allocatedMemory = runtime.totalMemory() / (1024 * 1024)
val freeMemory = runtime.freeMemory() / (1024 * 1024)
val usedMemory = allocatedMemory - freeMemory
// CPU usage
val osBean = ManagementFactory.getOperatingSystemMXBean()
var cpuLoad = osBean.systemLoadAverage
if (cpuLoad < 0) {
cpuLoad = osBean.availableProcessors * ManagementFactory.getThreadMXBean().threadCount / 100.0
}
// Format server info using string templates
info.append("§6===== SERVER INFO =====\n")
info.append("§aRAM Usage: §f${usedMemory}MB / ${allocatedMemory}MB\n")
info.append("§aMax RAM: §f${maxMemory}MB\n")
info.append("§aCPU Load: §f${df.format(cpuLoad)}%\n") // Added % sign
info.append("§aTPS: ${formatTPS(tps)}\n")
return info.toString()
}
private fun formatTPS(tps: Double): String {
return when {
tps >= 18.0 -> "§2${df.format(tps)}" // Dark green
tps >= 15.0 -> "§e${df.format(tps)}" // Yellow
else -> "§c${df.format(tps)}" // Red
}
}
fun getPingForPlayer(player: Player): Int {
return try {
// Get player ping using reflection
val entityPlayer = player.javaClass.getMethod("getHandle").invoke(player)
val pingField = entityPlayer.javaClass.getField("ping")
pingField.getInt(entityPlayer)
} catch (e: Exception) {
logger.warning("Failed to get ping for player: ${e.message}")
-1
}
}
// Command executor inner class
private inner class ServerInfoCommand(private val plugin: Server_info) : CommandExecutor {
override fun onCommand(sender: CommandSender, cmd: Command, label: String, args: Array<out String>): Boolean {
if (cmd.name.equals("serverinfo", ignoreCase = true)) {
// Send server info
sender.sendMessage(plugin.getServerInfo())
// If the sender is a player, show their ping
if (sender is Player) {
val ping = plugin.getPingForPlayer(sender)
sender.sendMessage("§aYour Ping: §f${ping}ms")
}
return true
}
return false
}
}
}

View File

@@ -0,0 +1,15 @@
name: ServerInfo
version: 1.0-SNAPSHOT
main: org.server_info.server_info.Server_info
api-version: 1.19
description: Displays server performance metrics
commands:
serverinfo:
description: Shows server performance metrics
usage: /<command>
aliases: [sinfo, si]
permission: serverinfo.use
permissions:
serverinfo.use:
description: Allows using the serverinfo command
default: true

Binary file not shown.

15
target/classes/plugin.yml Normal file
View File

@@ -0,0 +1,15 @@
name: ServerInfo
version: 1.0-SNAPSHOT
main: org.server_info.server_info.Server_info
api-version: 1.19
description: Displays server performance metrics
commands:
serverinfo:
description: Shows server performance metrics
usage: /<command>
aliases: [sinfo, si]
permission: serverinfo.use
permissions:
serverinfo.use:
description: Allows using the serverinfo command
default: true

View File

@@ -0,0 +1,3 @@
artifactId=server_info
groupId=org.server_info
version=1.0-SNAPSHOT

Binary file not shown.

Binary file not shown.