Upload files to "src/main/java/com/wulliestudio/tab"

This commit is contained in:
2025-11-30 06:53:55 +00:00
commit 0f13c65415

View File

@@ -0,0 +1,108 @@
package com.wulliestudio.tab;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.text.DecimalFormat;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class TabPlugin extends JavaPlugin {
private final DecimalFormat tpsFormat = new DecimalFormat("#0.0");
private long enableMillis;
@Override
public void onEnable() {
saveDefaultConfig();
// record plugin enable time (server uptime from onEnable)
this.enableMillis = System.currentTimeMillis();
long interval = Math.max(1L, getConfig().getLong("update-interval-ticks", 20L));
// Folia global region scheduler for UI updates (safe for TAB)
Bukkit.getGlobalRegionScheduler().runAtFixedRate(
this,
task -> updateAllPlayersTab(),
1L,
interval
);
getLogger().info("FoliaTab enabled (Folia-safe). Update interval: " + interval + " ticks");
}
@Override
public void onDisable() {
getLogger().info("FoliaTab disabled.");
}
private void updateAllPlayersTab() {
double tps = getTPS();
String tpsFormatted = tpsFormat.format(tps);
List<String> headerLines = getConfig().getStringList("header");
List<String> footerLines = getConfig().getStringList("footer");
String serverName = getConfig().getString("server-name", "Minecraft Server");
for (Player player : Bukkit.getOnlinePlayers()) {
String headerRaw = String.join("\n", headerLines);
String footerRaw = String.join("\n", footerLines);
headerRaw = applyPlaceholders(headerRaw, player, serverName, tpsFormatted);
footerRaw = applyPlaceholders(footerRaw, player, serverName, tpsFormatted);
Component header = LegacyComponentSerializer.legacyAmpersand().deserialize(headerRaw);
Component footer = LegacyComponentSerializer.legacyAmpersand().deserialize(footerRaw);
// Send header/footer (Folia-safe from global region scheduler)
try {
player.sendPlayerListHeaderAndFooter(header, footer);
} catch (NoSuchMethodError e) {
// Fallback to separate methods if available
try {
player.sendPlayerListHeader(header);
player.sendPlayerListFooter(footer);
} catch (Throwable t) {
getLogger().warning("Failed to set header/footer for " + player.getName() + ": " + t.getMessage());
}
} catch (Throwable t) {
getLogger().warning("Failed to set header/footer for " + player.getName() + ": " + t.getMessage());
}
}
}
private String applyPlaceholders(String input, Player player, String serverName, String tps) {
return input
.replace("%server_name%", serverName)
.replace("%tps%", tps)
.replace("%ping%", String.valueOf(player.getPing()))
.replace("%player_name%", player.getName())
.replace("%uptime%", formatUptime(System.currentTimeMillis() - enableMillis));
}
private String formatUptime(long millis) {
long seconds = TimeUnit.MILLISECONDS.toSeconds(millis);
long days = seconds / 86_400;
seconds %= 86_400;
long hours = seconds / 3_600;
seconds %= 3_600;
long minutes = seconds / 60;
seconds %= 60;
return String.format("%02d:%02d:%02d:%02d", days, hours, minutes, seconds);
}
private double getTPS() {
try {
double[] tpsArr = Bukkit.getServer().getTPS();
if (tpsArr != null && tpsArr.length > 0) return tpsArr[0];
} catch (Throwable ignored) { }
return 20.0;
}
}