Upload folder via GUI - StatusAPIBridge

This commit is contained in:
Git Manager GUI
2026-05-07 21:55:53 +02:00
parent 39e86e4292
commit 3b2218e37e
4 changed files with 253 additions and 0 deletions

66
StatusAPIBridge/pom.xml Normal file
View File

@@ -0,0 +1,66 @@
<?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>net.viper</groupId>
<artifactId>StatusAPIBridge</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>vault-repo</id>
<url>https://nexus.hc.to/content/repositories/pub_releases/</url>
</repository>
</repositories>
<dependencies>
<!-- Spigot API -->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.21-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- Vault -->
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>StatusAPIBridge</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,172 @@
package net.viper.statusapibridge;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class StatusAPIBridge extends JavaPlugin implements Listener {
private Economy economy;
private String statusApiUrl;
private int pushDelayTicks;
private int liveSyncIntervalTicks;
private final Map<UUID, Double> lastPushedBalance = new ConcurrentHashMap<>();
private final ExecutorService httpExecutor = Executors.newSingleThreadExecutor(r -> {
Thread t = new Thread(r, "StatusAPIBridge-HTTP");
t.setDaemon(true);
return t;
});
@Override
public void onEnable() {
saveDefaultConfig();
statusApiUrl = getConfig().getString("statusapi-url", "http://127.0.0.1:9191").trim();
pushDelayTicks = getConfig().getInt("push-delay-ticks", 40);
liveSyncIntervalTicks = Math.max(20, getConfig().getInt("live-sync-interval-ticks", 20));
if (!setupEconomy()) {
getLogger().warning("Vault/Economy nicht gefunden Economy-Push deaktiviert.");
} else {
getLogger().info("Vault Economy gefunden: " + economy.getName());
}
Bukkit.getPluginManager().registerEvents(this, this);
Bukkit.getScheduler().runTaskTimer(this, this::pushChangedBalancesForOnlinePlayers,
liveSyncIntervalTicks, liveSyncIntervalTicks);
getLogger().info("StatusAPIBridge gestartet. Ziel: " + statusApiUrl);
}
@Override
public void onDisable() {
httpExecutor.shutdownNow();
}
private boolean setupEconomy() {
if (getServer().getPluginManager().getPlugin("Vault") == null) return false;
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
if (rsp == null) return false;
economy = rsp.getProvider();
return economy != null;
}
// ── Events ─────────────────────────────────────────────────────────────────
@EventHandler(priority = EventPriority.MONITOR)
public void onJoin(PlayerJoinEvent e) {
Player player = e.getPlayer();
// Welt sofort pushen
pushWorld(player.getUniqueId(), player.getName(), player.getWorld().getName());
// Economy verzögert pushen
if (economy != null) {
Bukkit.getScheduler().runTaskLater(this, () -> {
if (player.isOnline()) pushEconomy(player);
}, pushDelayTicks);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onQuit(PlayerQuitEvent e) {
Player player = e.getPlayer();
if (economy != null) {
double balance = economy.getBalance(player);
pushEconomyAsync(player.getUniqueId(), player.getName(), balance);
}
lastPushedBalance.remove(player.getUniqueId());
}
@EventHandler(priority = EventPriority.MONITOR)
public void onWorldChange(PlayerChangedWorldEvent e) {
Player player = e.getPlayer();
pushWorld(player.getUniqueId(), player.getName(), player.getWorld().getName());
}
// ── World-Push ─────────────────────────────────────────────────────────────
private void pushWorld(UUID uuid, String name, String world) {
httpExecutor.execute(() -> {
try {
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 ───────────────────────────────────────────────────────────
public void pushEconomy(Player player) {
double balance = economy.getBalance(player);
pushEconomyAsync(player.getUniqueId(), player.getName(), balance);
}
private void pushEconomyAsync(UUID uuid, String name, double balance) {
httpExecutor.execute(() -> {
try {
String json = "{\"uuid\":\"" + uuid + "\",\"name\":\"" + escape(name)
+ "\",\"balance\":" + balance + "}";
sendPost(statusApiUrl + "/economy/update", json);
lastPushedBalance.put(uuid, balance);
} catch (Exception e) {
getLogger().warning("Economy-Push fehlgeschlagen fuer " + name + ": " + e.getMessage());
}
});
}
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);
}
}
}
// ── HTTP ───────────────────────────────────────────────────────────────────
private void sendPost(String urlStr, String json) throws Exception {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setConnectTimeout(3000);
conn.setReadTimeout(3000);
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
byte[] body = json.getBytes(StandardCharsets.UTF_8);
conn.setRequestProperty("Content-Length", String.valueOf(body.length));
try (OutputStream os = conn.getOutputStream()) {
os.write(body);
}
int code = conn.getResponseCode();
if (code != 200) {
getLogger().warning("StatusAPI antwortete mit Code " + code + " fuer " + urlStr);
}
conn.disconnect();
}
private String escape(String s) {
if (s == null) return "";
return s.replace("\\", "\\\\").replace("\"", "\\\"");
}
}

View File

@@ -0,0 +1,8 @@
# URL der BungeeCord StatusAPI (kein Slash am Ende)
statusapi-url: "http://127.0.0.1:9191"
# Wie viele Ticks nach dem Join wird die Balance gepusht? (20 Ticks = 1 Sekunde)
push-delay-ticks: 40
# Live-Sync Intervall fuer Economy-Updates waehrend der Spieler online ist (mind. 20 Ticks = 1 Sekunde)
live-sync-interval-ticks: 20

View File

@@ -0,0 +1,7 @@
name: StatusAPIBridge
version: 1.0.0
main: net.viper.statusapibridge.StatusAPIBridge
api-version: 1.21
description: Sendet Vault-Economy-Daten an die BungeeCord StatusAPI
authors: [Viper]
softdepend: [Vault]