Upload folder via GUI - src
This commit is contained in:
@@ -2,12 +2,15 @@ package net.viper.statusapibridge;
|
|||||||
|
|
||||||
import net.milkbowl.vault.economy.Economy;
|
import net.milkbowl.vault.economy.Economy;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
@@ -25,10 +28,17 @@ import java.util.concurrent.Executors;
|
|||||||
public class StatusAPIBridge extends JavaPlugin implements Listener {
|
public class StatusAPIBridge extends JavaPlugin implements Listener {
|
||||||
|
|
||||||
private Economy economy;
|
private Economy economy;
|
||||||
private String statusApiUrl;
|
private String statusApiUrl;
|
||||||
private int pushDelayTicks;
|
private int pushDelayTicks;
|
||||||
private int liveSyncIntervalTicks;
|
private int liveSyncIntervalTicks;
|
||||||
private final Map<UUID, Double> lastPushedBalance = new ConcurrentHashMap<>();
|
private int scoreboardSyncIntervalTicks;
|
||||||
|
|
||||||
|
private final Map<UUID, Double> lastPushedBalance = new ConcurrentHashMap<>();
|
||||||
|
private final Map<UUID, Double> lastPushedHealth = new ConcurrentHashMap<>();
|
||||||
|
private final Map<UUID, String> lastPushedCompass = new ConcurrentHashMap<>();
|
||||||
|
private final Map<UUID, String> lastPushedWorld = new ConcurrentHashMap<>();
|
||||||
|
private final Map<UUID, String> lastPushedData = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final ExecutorService httpExecutor = Executors.newSingleThreadExecutor(r -> {
|
private final ExecutorService httpExecutor = Executors.newSingleThreadExecutor(r -> {
|
||||||
Thread t = new Thread(r, "StatusAPIBridge-HTTP");
|
Thread t = new Thread(r, "StatusAPIBridge-HTTP");
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
@@ -38,9 +48,10 @@ public class StatusAPIBridge extends JavaPlugin implements Listener {
|
|||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
saveDefaultConfig();
|
saveDefaultConfig();
|
||||||
statusApiUrl = getConfig().getString("statusapi-url", "http://127.0.0.1:9191").trim();
|
statusApiUrl = getConfig().getString("statusapi-url", "http://127.0.0.1:9191").trim();
|
||||||
pushDelayTicks = getConfig().getInt("push-delay-ticks", 40);
|
pushDelayTicks = getConfig().getInt("push-delay-ticks", 40);
|
||||||
liveSyncIntervalTicks = Math.max(20, getConfig().getInt("live-sync-interval-ticks", 20));
|
liveSyncIntervalTicks = Math.max(20, getConfig().getInt("live-sync-interval-ticks", 20));
|
||||||
|
scoreboardSyncIntervalTicks = Math.max(20, getConfig().getInt("scoreboard-sync-interval-ticks", 20));
|
||||||
|
|
||||||
if (!setupEconomy()) {
|
if (!setupEconomy()) {
|
||||||
getLogger().warning("Vault/Economy nicht gefunden – Economy-Push deaktiviert.");
|
getLogger().warning("Vault/Economy nicht gefunden – Economy-Push deaktiviert.");
|
||||||
@@ -51,6 +62,9 @@ public class StatusAPIBridge extends JavaPlugin implements Listener {
|
|||||||
Bukkit.getPluginManager().registerEvents(this, this);
|
Bukkit.getPluginManager().registerEvents(this, this);
|
||||||
Bukkit.getScheduler().runTaskTimer(this, this::pushChangedBalancesForOnlinePlayers,
|
Bukkit.getScheduler().runTaskTimer(this, this::pushChangedBalancesForOnlinePlayers,
|
||||||
liveSyncIntervalTicks, liveSyncIntervalTicks);
|
liveSyncIntervalTicks, liveSyncIntervalTicks);
|
||||||
|
Bukkit.getScheduler().runTaskTimer(this, this::pushScoreboardData,
|
||||||
|
scoreboardSyncIntervalTicks, scoreboardSyncIntervalTicks);
|
||||||
|
|
||||||
getLogger().info("StatusAPIBridge gestartet. Ziel: " + statusApiUrl);
|
getLogger().info("StatusAPIBridge gestartet. Ziel: " + statusApiUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,70 +75,98 @@ public class StatusAPIBridge extends JavaPlugin implements Listener {
|
|||||||
|
|
||||||
private boolean setupEconomy() {
|
private boolean setupEconomy() {
|
||||||
if (getServer().getPluginManager().getPlugin("Vault") == null) return false;
|
if (getServer().getPluginManager().getPlugin("Vault") == null) return false;
|
||||||
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
|
RegisteredServiceProvider<Economy> rsp =
|
||||||
|
getServer().getServicesManager().getRegistration(Economy.class);
|
||||||
if (rsp == null) return false;
|
if (rsp == null) return false;
|
||||||
economy = rsp.getProvider();
|
economy = rsp.getProvider();
|
||||||
return economy != null;
|
return economy != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Events ─────────────────────────────────────────────────────────────────
|
// ── Events ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void onJoin(PlayerJoinEvent e) {
|
public void onJoin(PlayerJoinEvent e) {
|
||||||
Player player = e.getPlayer();
|
Player player = e.getPlayer();
|
||||||
// Welt sofort pushen
|
Bukkit.getScheduler().runTaskLater(this, () -> {
|
||||||
pushWorld(player.getUniqueId(), player.getName(), player.getWorld().getName());
|
if (!player.isOnline()) return;
|
||||||
// Economy verzögert pushen
|
if (economy != null) pushEconomy(player);
|
||||||
if (economy != null) {
|
pushPlayerScoreboardData(player);
|
||||||
Bukkit.getScheduler().runTaskLater(this, () -> {
|
}, pushDelayTicks);
|
||||||
if (player.isOnline()) pushEconomy(player);
|
|
||||||
}, pushDelayTicks);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void onQuit(PlayerQuitEvent e) {
|
public void onQuit(PlayerQuitEvent e) {
|
||||||
Player player = e.getPlayer();
|
Player player = e.getPlayer();
|
||||||
if (economy != null) {
|
UUID id = player.getUniqueId();
|
||||||
double balance = economy.getBalance(player);
|
if (economy != null) pushEconomyAsync(id, player.getName(), economy.getBalance(player));
|
||||||
pushEconomyAsync(player.getUniqueId(), player.getName(), balance);
|
lastPushedBalance.remove(id);
|
||||||
|
lastPushedHealth.remove(id);
|
||||||
|
lastPushedCompass.remove(id);
|
||||||
|
lastPushedWorld.remove(id);
|
||||||
|
lastPushedData.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onDamage(EntityDamageEvent e) {
|
||||||
|
if (!(e.getEntity() instanceof Player)) return;
|
||||||
|
Player player = (Player) e.getEntity();
|
||||||
|
Bukkit.getScheduler().runTaskLater(this,
|
||||||
|
() -> { if (player.isOnline()) pushHealthIfChanged(player); }, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onHeal(EntityRegainHealthEvent e) {
|
||||||
|
if (!(e.getEntity() instanceof Player)) return;
|
||||||
|
Player player = (Player) e.getEntity();
|
||||||
|
Bukkit.getScheduler().runTaskLater(this,
|
||||||
|
() -> { if (player.isOnline()) pushHealthIfChanged(player); }, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onMove(PlayerMoveEvent e) {
|
||||||
|
if (e.getFrom().getYaw() == e.getTo().getYaw()) return;
|
||||||
|
pushCompassIfChanged(e.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Periodische Tasks ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private void pushChangedBalancesForOnlinePlayers() {
|
||||||
|
if (economy == null) return;
|
||||||
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
double current = economy.getBalance(player);
|
||||||
|
Double last = lastPushedBalance.get(player.getUniqueId());
|
||||||
|
if (last == null || Math.abs(current - last) > 0.000001d)
|
||||||
|
pushEconomyAsync(player.getUniqueId(), player.getName(), current);
|
||||||
}
|
}
|
||||||
lastPushedBalance.remove(player.getUniqueId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
private void pushScoreboardData() {
|
||||||
public void onWorldChange(PlayerChangedWorldEvent e) {
|
double tps = getCurrentTps();
|
||||||
Player player = e.getPlayer();
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
pushWorld(player.getUniqueId(), player.getName(), player.getWorld().getName());
|
pushPlayerScoreboardData(player);
|
||||||
|
pushTpsAsync(player.getUniqueId(), tps);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── World-Push ─────────────────────────────────────────────────────────────
|
private void pushPlayerScoreboardData(Player player) {
|
||||||
|
pushHealthIfChanged(player);
|
||||||
private void pushWorld(UUID uuid, String name, String world) {
|
pushCompassIfChanged(player);
|
||||||
httpExecutor.execute(() -> {
|
pushWorldIfChanged(player);
|
||||||
try {
|
pushPlayerDataIfChanged(player);
|
||||||
String json = "{\"uuid\":\"" + uuid + "\",\"name\":\"" + escape(name)
|
|
||||||
+ "\",\"world\":\"" + escape(world) + "\"}";
|
|
||||||
sendPost(statusApiUrl + "/player/world", json);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
getLogger().warning("World-Push fehlgeschlagen fuer " + name + ": " + ex.getMessage());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Economy-Push ───────────────────────────────────────────────────────────
|
// ── Push-Methoden ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
public void pushEconomy(Player player) {
|
public void pushEconomy(Player player) {
|
||||||
double balance = economy.getBalance(player);
|
pushEconomyAsync(player.getUniqueId(), player.getName(), economy.getBalance(player));
|
||||||
pushEconomyAsync(player.getUniqueId(), player.getName(), balance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pushEconomyAsync(UUID uuid, String name, double balance) {
|
private void pushEconomyAsync(UUID uuid, String name, double balance) {
|
||||||
httpExecutor.execute(() -> {
|
httpExecutor.execute(() -> {
|
||||||
try {
|
try {
|
||||||
String json = "{\"uuid\":\"" + uuid + "\",\"name\":\"" + escape(name)
|
sendPost(statusApiUrl + "/economy/update",
|
||||||
+ "\",\"balance\":" + balance + "}";
|
"{\"uuid\":\"" + uuid + "\",\"name\":\"" + escapeName(name)
|
||||||
sendPost(statusApiUrl + "/economy/update", json);
|
+ "\",\"balance\":" + balance + "}");
|
||||||
lastPushedBalance.put(uuid, balance);
|
lastPushedBalance.put(uuid, balance);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
getLogger().warning("Economy-Push fehlgeschlagen fuer " + name + ": " + e.getMessage());
|
getLogger().warning("Economy-Push fehlgeschlagen fuer " + name + ": " + e.getMessage());
|
||||||
@@ -132,18 +174,127 @@ public class StatusAPIBridge extends JavaPlugin implements Listener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pushChangedBalancesForOnlinePlayers() {
|
private void pushHealthIfChanged(Player player) {
|
||||||
if (economy == null) return;
|
double health = player.getHealth();
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
Double last = lastPushedHealth.get(player.getUniqueId());
|
||||||
double current = economy.getBalance(player);
|
if (last != null && Math.abs(health - last) < 0.01) return;
|
||||||
Double last = lastPushedBalance.get(player.getUniqueId());
|
lastPushedHealth.put(player.getUniqueId(), health);
|
||||||
if (last == null || Math.abs(current - last) > 0.000001d) {
|
UUID uuid = player.getUniqueId(); String name = player.getName();
|
||||||
pushEconomyAsync(player.getUniqueId(), player.getName(), current);
|
httpExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
sendPost(statusApiUrl + "/scoreboard/health",
|
||||||
|
"{\"uuid\":\"" + uuid + "\",\"name\":\"" + escapeName(name)
|
||||||
|
+ "\",\"health\":" + health + "}");
|
||||||
|
} catch (Exception e) {
|
||||||
|
getLogger().warning("Health-Push fehlgeschlagen: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── HTTP ───────────────────────────────────────────────────────────────────
|
private void pushCompassIfChanged(Player player) {
|
||||||
|
// Rohen Yaw normalisieren auf 0..360 (0 = Süden, wie MC-Konvention)
|
||||||
|
float rawYaw = player.getLocation().getYaw();
|
||||||
|
float normYaw = ((rawYaw % 360) + 360) % 360;
|
||||||
|
String yawStr = String.format(java.util.Locale.US, "%.1f", normYaw);
|
||||||
|
|
||||||
|
// Nur senden wenn Änderung >= 0.5° – fein genug für 1-Grad-Slots
|
||||||
|
String lastStr = lastPushedCompass.get(player.getUniqueId());
|
||||||
|
if (lastStr != null) {
|
||||||
|
try {
|
||||||
|
float lastYaw = Float.parseFloat(lastStr);
|
||||||
|
float diff = Math.abs(normYaw - lastYaw);
|
||||||
|
if (diff > 180) diff = 360 - diff; // kürzester Bogenweg
|
||||||
|
if (diff < 0.5f) return;
|
||||||
|
} catch (NumberFormatException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPushedCompass.put(player.getUniqueId(), yawStr);
|
||||||
|
UUID uuid = player.getUniqueId(); String name = player.getName();
|
||||||
|
httpExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
sendPost(statusApiUrl + "/scoreboard/compass",
|
||||||
|
"{\"uuid\":\"" + uuid + "\",\"name\":\"" + escapeName(name)
|
||||||
|
+ "\",\"compass\":\"" + yawStr + "\"}");
|
||||||
|
} catch (Exception e) {
|
||||||
|
getLogger().warning("Compass-Push fehlgeschlagen: " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pushWorldIfChanged(Player player) {
|
||||||
|
String world = player.getWorld().getName();
|
||||||
|
if (world.equals(lastPushedWorld.get(player.getUniqueId()))) return;
|
||||||
|
lastPushedWorld.put(player.getUniqueId(), world);
|
||||||
|
UUID uuid = player.getUniqueId(); String name = player.getName();
|
||||||
|
httpExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
sendPost(statusApiUrl + "/player/world",
|
||||||
|
"{\"uuid\":\"" + uuid + "\",\"name\":\"" + escapeName(name)
|
||||||
|
+ "\",\"world\":\"" + escapeName(world) + "\"}");
|
||||||
|
} catch (Exception e) {
|
||||||
|
getLogger().warning("World-Push fehlgeschlagen: " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pushPlayerDataIfChanged(Player player) {
|
||||||
|
int x = player.getLocation().getBlockX();
|
||||||
|
int y = player.getLocation().getBlockY();
|
||||||
|
int z = player.getLocation().getBlockZ();
|
||||||
|
String gm = player.getGameMode().name();
|
||||||
|
int exp= player.getLevel();
|
||||||
|
int fd = player.getFoodLevel();
|
||||||
|
double sp = player.getWalkSpeed();
|
||||||
|
String wld= player.getWorld().getName();
|
||||||
|
String key = x+","+y+","+z+","+gm+","+exp+","+fd+","+String.format("%.2f",sp)+","+wld;
|
||||||
|
if (key.equals(lastPushedData.get(player.getUniqueId()))) return;
|
||||||
|
lastPushedData.put(player.getUniqueId(), key);
|
||||||
|
UUID uuid = player.getUniqueId();
|
||||||
|
String name = player.getName();
|
||||||
|
httpExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
sendPost(statusApiUrl + "/player/data",
|
||||||
|
"{\"uuid\":\"" + uuid + "\",\"name\":\"" + escapeName(name)
|
||||||
|
+ "\",\"x\":" + x
|
||||||
|
+ ",\"y\":" + y
|
||||||
|
+ ",\"z\":" + z
|
||||||
|
+ ",\"gamemode\":\"" + gm + "\""
|
||||||
|
+ ",\"exp\":" + exp
|
||||||
|
+ ",\"food\":" + fd
|
||||||
|
+ ",\"speed\":" + String.format(java.util.Locale.US, "%.4f", sp)
|
||||||
|
+ ",\"world\":\"" + escapeName(wld) + "\"}");
|
||||||
|
} catch (Exception e) {
|
||||||
|
getLogger().warning("PlayerData-Push fehlgeschlagen: " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pushTpsAsync(UUID uuid, double tps) {
|
||||||
|
httpExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
sendPost(statusApiUrl + "/scoreboard/tps",
|
||||||
|
"{\"uuid\":\"" + uuid + "\",\"tps\":" + tps + "}");
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Hilfsmethoden ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/** TPS – Paper-API zuerst, dann Spigot-Reflection-Fallback */
|
||||||
|
private double getCurrentTps() {
|
||||||
|
try {
|
||||||
|
double[] tps = (double[]) Bukkit.getServer().getClass()
|
||||||
|
.getMethod("getTPS").invoke(Bukkit.getServer());
|
||||||
|
return Math.min(20.0, tps[0]);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
try {
|
||||||
|
Object ms = Bukkit.getServer().getClass()
|
||||||
|
.getMethod("getServer").invoke(Bukkit.getServer());
|
||||||
|
double[] tps = (double[]) ms.getClass().getField("recentTps").get(ms);
|
||||||
|
return Math.min(20.0, tps[0]);
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
return 20.0;
|
||||||
|
}
|
||||||
|
|
||||||
private void sendPost(String urlStr, String json) throws Exception {
|
private void sendPost(String urlStr, String json) throws Exception {
|
||||||
URL url = new URL(urlStr);
|
URL url = new URL(urlStr);
|
||||||
@@ -155,18 +306,15 @@ public class StatusAPIBridge extends JavaPlugin implements Listener {
|
|||||||
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
|
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
|
||||||
byte[] body = json.getBytes(StandardCharsets.UTF_8);
|
byte[] body = json.getBytes(StandardCharsets.UTF_8);
|
||||||
conn.setRequestProperty("Content-Length", String.valueOf(body.length));
|
conn.setRequestProperty("Content-Length", String.valueOf(body.length));
|
||||||
try (OutputStream os = conn.getOutputStream()) {
|
try (OutputStream os = conn.getOutputStream()) { os.write(body); }
|
||||||
os.write(body);
|
|
||||||
}
|
|
||||||
int code = conn.getResponseCode();
|
int code = conn.getResponseCode();
|
||||||
if (code != 200) {
|
if (code != 200)
|
||||||
getLogger().warning("StatusAPI antwortete mit Code " + code + " fuer " + urlStr);
|
getLogger().warning("StatusAPI antwortete mit Code " + code + " fuer " + urlStr);
|
||||||
}
|
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String escape(String s) {
|
private String escapeName(String name) {
|
||||||
if (s == null) return "";
|
if (name == null) return "";
|
||||||
return s.replace("\\", "\\\\").replace("\"", "\\\"");
|
return name.replace("\\", "\\\\").replace("\"", "\\\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,9 @@ statusapi-url: "http://127.0.0.1:9191"
|
|||||||
# Wie viele Ticks nach dem Join wird die Balance gepusht? (20 Ticks = 1 Sekunde)
|
# Wie viele Ticks nach dem Join wird die Balance gepusht? (20 Ticks = 1 Sekunde)
|
||||||
push-delay-ticks: 40
|
push-delay-ticks: 40
|
||||||
|
|
||||||
# Live-Sync Intervall fuer Economy-Updates waehrend der Spieler online ist (mind. 20 Ticks = 1 Sekunde)
|
# Live-Sync Intervall fuer Economy-Updates waehrend der Spieler online ist (mind. 20 Ticks)
|
||||||
live-sync-interval-ticks: 20
|
live-sync-interval-ticks: 20
|
||||||
|
|
||||||
|
# Sync-Intervall fuer Scoreboard-Daten (Health, Compass, TPS, World) in Ticks (mind. 20)
|
||||||
|
# Compass und Health werden zusaetzlich event-basiert aktualisiert.
|
||||||
|
scoreboard-sync-interval-ticks: 20
|
||||||
|
|||||||
Reference in New Issue
Block a user