Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TPS API and command #82

Merged
merged 1 commit into from
Mar 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/main/java/com/legacyminecraft/poseidon/Poseidon.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.legacyminecraft.poseidon;

import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.CraftServer;

import java.util.LinkedList;

public class Poseidon {

/**
* Returns a list of the server's TPS (Ticks Per Second) records for performance monitoring.
* The list contains Double values indicating the TPS at each second, ordered from most recent to oldest.
*
* @return LinkedList<Double> of TPS records.
*/
public static LinkedList<Double> getTpsRecords() {
return ((CraftServer) Bukkit.getServer()).getServer().getTpsRecords();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ private void write() {
generateConfigOption("message.player.join", "\u00A7e%player% joined the game.");
generateConfigOption("message.player.leave", "\u00A7e%player% left the game.");

//Optional Poseidon Commands
generateConfigOption("command.info", "This section allows you to enable or disable optional Poseidon commands. This is useful if you have a plugin that conflicts with a Poseidon command.");
generateConfigOption("command.tps.info", "Enables the /tps command to show the server's TPS for various intervals.");
generateConfigOption("command.tps.enabled", true);

//Tree Leave Destroy Blacklist
if (Boolean.valueOf(String.valueOf(getConfigOption("world.settings.block-tree-growth.enabled", true)))) {
if (String.valueOf(this.getConfigOption("world.settings.block-tree-growth.list", "")).trim().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.legacyminecraft.poseidon.commands;

import com.legacyminecraft.poseidon.Poseidon;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.VanillaCommand;

import java.util.LinkedList;
import java.util.LinkedHashMap;
import java.util.Map;

public class TPSCommand extends Command {

private final LinkedHashMap<String, Integer> intervals = new LinkedHashMap<>();

public TPSCommand(String name) {
super(name);
this.description = "Shows the server's TPS for various intervals";
this.usageMessage = "/tps";
this.setPermission("poseidon.command.tps");

// Define the intervals for TPS calculation
intervals.put("5s", 5);
intervals.put("30s", 30);
intervals.put("1m", 60);
intervals.put("5m", 300);
intervals.put("10m", 600);
intervals.put("15m", 900);
}

@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;

LinkedList<Double> tpsRecords = Poseidon.getTpsRecords();
StringBuilder message = new StringBuilder("§bServer TPS: ");

// Calculate and format TPS for each interval dynamically
for (Map.Entry<String, Integer> entry : intervals.entrySet()) {
double averageTps = calculateAverage(tpsRecords, entry.getValue());
message.append(formatTps(averageTps)).append(" (").append(entry.getKey()).append("), ");
}

// Remove the trailing comma and space
if (message.length() > 0) {
message.setLength(message.length() - 2);
}

sender.sendMessage(message.toString());
return true;
}

private double calculateAverage(LinkedList<Double> records, int seconds) {
int size = Math.min(records.size(), seconds);
if (size == 0) return 20.0;

double total = 0;
for (int i = 0; i < size; i++) {
total += records.get(i);
}
return total / size;
}

private String formatTps(double tps) {
String colorCode;
if (tps >= 19) {
colorCode = "§a";
} else if (tps >= 15) {
colorCode = "§e";
} else {
colorCode = "§c";
}
return colorCode + String.format("%.2f", tps);
}
}
30 changes: 30 additions & 0 deletions src/main/java/net/minecraft/server/MinecraftServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,16 @@ public void run() {
}
}

//Project Poseidon Start - Tick Update
private final LinkedList<Double> tpsRecords = new LinkedList<>();
private long lastTick = System.currentTimeMillis();
private int tickCount = 0;

public LinkedList<Double> getTpsRecords() {
return tpsRecords;
}
//Project Poseidon End - Tick Update

private void h() {
ArrayList arraylist = new ArrayList();
Iterator iterator = trackerList.keySet().iterator();
Expand Down Expand Up @@ -494,6 +504,26 @@ private void h() {

((CraftScheduler) this.server.getScheduler()).mainThreadHeartbeat(this.ticks); // CraftBukkit

//Project Poseidon Start - Tick Update
long currentTime = System.currentTimeMillis();
tickCount++;

//Check if a second has passed
if (currentTime - lastTick >= 1000) {
double tps = tickCount / ((currentTime - lastTick) / 1000.0);
tpsRecords.addFirst(tps);
if(tpsRecords.size() > 900) { //Don't keep more than 15 minutes of data
tpsRecords.removeLast();
}

tickCount = 0;
lastTick = currentTime;
}

//Project Poseidon End - Tick Update



for (j = 0; j < this.worlds.size(); ++j) { // CraftBukkit
// if (j == 0 || this.propertyManager.getBoolean("allow-nether", true)) { // CraftBukkit
WorldServer worldserver = this.worlds.get(j); // CraftBukkit
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/org/bukkit/command/SimpleCommandMap.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.bukkit.command;

import com.legacyminecraft.poseidon.PoseidonConfig;
import com.legacyminecraft.poseidon.commands.TPSCommand;
import org.bukkit.Server;
import org.bukkit.command.defaults.*;

Expand Down Expand Up @@ -43,10 +45,14 @@ public SimpleCommandMap(final Server server) {
}

private void setDefaultCommands(final Server server) {
register("poseidon", new PoseidonCommand("poseidon"));
register("bukkit", new VersionCommand("version"));
register("bukkit", new ReloadCommand("reload"));
register("bukkit", new PluginsCommand("plugins"));

//Poseidon Command
register("poseidon", new PoseidonCommand("poseidon"));
if (PoseidonConfig.getInstance().getConfigBoolean("command.tps.enabled"))
register("poseidon", new TPSCommand("tps"));
}

/**
Expand Down
Loading