mirror of
https://github.com/plexusorg/Module-HTTPD.git
synced 2026-06-04 00:56:54 +00:00
compiles again
This commit is contained in:
+8
-3
@@ -2,11 +2,11 @@ plugins {
|
||||
java
|
||||
`maven-publish`
|
||||
idea
|
||||
id("dev.plex.module") version "1.1"
|
||||
id("dev.plex.module") version "1.2"
|
||||
}
|
||||
|
||||
group = "dev.plex"
|
||||
version = "1.7"
|
||||
version = "2.0"
|
||||
description = "Module-HTTPD"
|
||||
|
||||
repositories {
|
||||
@@ -25,10 +25,15 @@ repositories {
|
||||
}
|
||||
|
||||
maven {
|
||||
name = "codemc"
|
||||
url = uri("https://repo.codemc.io/repository/maven-public/")
|
||||
}
|
||||
}
|
||||
|
||||
plexModule {
|
||||
includeRepository("codemc")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.projectlombok:lombok:1.18.46")
|
||||
annotationProcessor("org.projectlombok:lombok:1.18.46")
|
||||
@@ -84,4 +89,4 @@ publishing {
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ public class PlayerActionServlet extends HttpServlet
|
||||
|
||||
final boolean kick = action.equals("ban") || action.equals("tempban");
|
||||
final PunishmentRequest toApply = punishment;
|
||||
HTTPDModule.plexApi().scheduler().runSync(() ->
|
||||
HTTPDModule.plexApi().scheduler().runGlobal(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -135,8 +135,11 @@ public class PlayerActionServlet extends HttpServlet
|
||||
Player online = Bukkit.getPlayer(uuid);
|
||||
if (online != null)
|
||||
{
|
||||
try { online.kick(Component.text("You have been banned: " + toApply.reason())); }
|
||||
catch (Throwable t) { t.printStackTrace(); }
|
||||
HTTPDModule.plexApi().scheduler().runEntity(online, () ->
|
||||
{
|
||||
try { online.kick(Component.text("You have been banned: " + toApply.reason())); }
|
||||
catch (Throwable t) { t.printStackTrace(); }
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -156,24 +159,27 @@ public class PlayerActionServlet extends HttpServlet
|
||||
|
||||
Log.log(ipAddress + " (xf:" + staff.username() + ") issued " + action + " on " + target.name() + " (" + uuid + ")" + (slot == null || slot.isBlank() ? "" : " slot " + slot));
|
||||
|
||||
HTTPDModule.plexApi().scheduler().runSync(() ->
|
||||
HTTPDModule.plexApi().scheduler().runGlobal(() ->
|
||||
{
|
||||
Player online = Bukkit.getPlayer(uuid);
|
||||
if (online == null) return;
|
||||
PlayerInventory inv = online.getInventory();
|
||||
if ("clear-inventory".equals(action))
|
||||
HTTPDModule.plexApi().scheduler().runEntity(online, () ->
|
||||
{
|
||||
inv.clear();
|
||||
inv.setArmorContents(null);
|
||||
inv.setItemInOffHand(null);
|
||||
online.updateInventory();
|
||||
return;
|
||||
}
|
||||
if ("clear-selected".equals(action))
|
||||
{
|
||||
clearSlot(inv, slot);
|
||||
online.updateInventory();
|
||||
}
|
||||
PlayerInventory inv = online.getInventory();
|
||||
if ("clear-inventory".equals(action))
|
||||
{
|
||||
inv.clear();
|
||||
inv.setArmorContents(null);
|
||||
inv.setItemInOffHand(null);
|
||||
online.updateInventory();
|
||||
return;
|
||||
}
|
||||
if ("clear-selected".equals(action))
|
||||
{
|
||||
clearSlot(inv, slot);
|
||||
online.updateInventory();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
response.sendRedirect("/player/" + uuid);
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.plex.request.impl;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import dev.plex.HTTPDModule;
|
||||
import jakarta.servlet.AsyncContext;
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -10,7 +11,6 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -60,10 +60,11 @@ public final class PlayerInventoryBroadcaster
|
||||
}
|
||||
|
||||
private final Map<UUID, Set<Subscriber>> subscribers = new ConcurrentHashMap<>();
|
||||
private final Map<UUID, String> cachedPayloads = new ConcurrentHashMap<>();
|
||||
private final AtomicInteger subscriberCount = new AtomicInteger();
|
||||
|
||||
private ScheduledExecutorService executor;
|
||||
private BukkitTask refreshTask;
|
||||
private ScheduledTask refreshTask;
|
||||
private int maxConnections = 32;
|
||||
|
||||
private PlayerInventoryBroadcaster() {}
|
||||
@@ -84,7 +85,7 @@ public final class PlayerInventoryBroadcaster
|
||||
|
||||
try
|
||||
{
|
||||
refreshTask = (BukkitTask)HTTPDModule.plexApi().scheduler().runTimer(this::tick, 0L, REFRESH_TICKS);
|
||||
refreshTask = HTTPDModule.plexApi().scheduler().runGlobalTimer(this::tick, 1L, REFRESH_TICKS);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
@@ -121,6 +122,7 @@ public final class PlayerInventoryBroadcaster
|
||||
}
|
||||
}
|
||||
subscribers.clear();
|
||||
cachedPayloads.clear();
|
||||
subscriberCount.set(0);
|
||||
}
|
||||
|
||||
@@ -160,12 +162,10 @@ public final class PlayerInventoryBroadcaster
|
||||
|
||||
public String currentPayload(UUID uuid)
|
||||
{
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
if (p == null) return "{\"online\":false}";
|
||||
return buildPayload(p);
|
||||
return cachedPayloads.getOrDefault(uuid, "{\"online\":false}");
|
||||
}
|
||||
|
||||
// Runs on the Bukkit main thread.
|
||||
// Runs on the global region and schedules per-player snapshots on entity schedulers.
|
||||
private void tick()
|
||||
{
|
||||
if (subscribers.isEmpty()) return;
|
||||
@@ -174,29 +174,54 @@ public final class PlayerInventoryBroadcaster
|
||||
Set<Subscriber> set = entry.getValue();
|
||||
if (set.isEmpty()) continue;
|
||||
UUID uuid = entry.getKey();
|
||||
String json;
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player == null)
|
||||
{
|
||||
publish(uuid, set, "{\"online\":false}");
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
json = (p == null) ? "{\"online\":false}" : buildPayload(p);
|
||||
ScheduledTask task = HTTPDModule.plexApi().scheduler().runEntity(player, () ->
|
||||
{
|
||||
String json;
|
||||
try
|
||||
{
|
||||
json = buildPayload(player);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
json = "{\"online\":false}";
|
||||
}
|
||||
publish(uuid, set, json);
|
||||
});
|
||||
if (task == null)
|
||||
{
|
||||
publish(uuid, set, "{\"online\":false}");
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
json = "{\"online\":false}";
|
||||
publish(uuid, set, "{\"online\":false}");
|
||||
}
|
||||
final String frame = "data: " + json + "\n\n";
|
||||
ScheduledExecutorService exec = executor;
|
||||
if (exec == null) return;
|
||||
for (Subscriber sub : set)
|
||||
}
|
||||
}
|
||||
|
||||
private void publish(UUID uuid, Set<Subscriber> set, String json)
|
||||
{
|
||||
cachedPayloads.put(uuid, json);
|
||||
final String frame = "data: " + json + "\n\n";
|
||||
ScheduledExecutorService exec = executor;
|
||||
if (exec == null) return;
|
||||
for (Subscriber sub : set)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
exec.execute(() -> writeFrame(uuid, sub, frame));
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
drop(uuid, sub);
|
||||
}
|
||||
exec.execute(() -> writeFrame(uuid, sub, frame));
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
drop(uuid, sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.plex.request.impl;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import dev.plex.HTTPDModule;
|
||||
import jakarta.servlet.AsyncContext;
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -11,7 +12,6 @@ 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.scheduler.BukkitTask;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -22,6 +22,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@@ -51,7 +52,7 @@ public final class PlayersBroadcaster
|
||||
private volatile String cachedStaffFrame = "{\"players\":[],\"max\":0}";
|
||||
|
||||
private ScheduledExecutorService executor;
|
||||
private BukkitTask refreshTask;
|
||||
private ScheduledTask refreshTask;
|
||||
private Listener listener;
|
||||
private int maxConnections = 32;
|
||||
|
||||
@@ -83,7 +84,7 @@ public final class PlayersBroadcaster
|
||||
|
||||
try
|
||||
{
|
||||
refreshTask = (BukkitTask)HTTPDModule.plexApi().scheduler().runTimer(this::refreshAndBroadcast, 0L, REFRESH_TICKS);
|
||||
refreshTask = HTTPDModule.plexApi().scheduler().runGlobalTimer(this::refreshAndBroadcast, 1L, REFRESH_TICKS);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
@@ -157,32 +158,94 @@ public final class PlayersBroadcaster
|
||||
{
|
||||
List<Player> online = new ArrayList<>(Bukkit.getOnlinePlayers());
|
||||
int max = Bukkit.getMaxPlayers();
|
||||
String publicJson = buildPublicPayload(online, max);
|
||||
String staffJson = buildStaffPayload(online, max);
|
||||
cachedPublicFrame = publicJson;
|
||||
cachedStaffFrame = staffJson;
|
||||
|
||||
ScheduledExecutorService exec = executor;
|
||||
if (exec == null || subscribers.isEmpty()) return;
|
||||
|
||||
final String publicFrame = "data: " + publicJson + "\n\n";
|
||||
final String staffFrame = "data: " + staffJson + "\n\n";
|
||||
for (Subscriber sub : subscribers)
|
||||
if (online.isEmpty())
|
||||
{
|
||||
final String frame = sub.staff ? staffFrame : publicFrame;
|
||||
publish(List.of(), List.of(), max);
|
||||
return;
|
||||
}
|
||||
|
||||
AtomicReferenceArray<Map<String, Object>> publicPlayers = new AtomicReferenceArray<>(online.size());
|
||||
AtomicReferenceArray<Map<String, Object>> staffPlayers = new AtomicReferenceArray<>(online.size());
|
||||
AtomicInteger remaining = new AtomicInteger(online.size());
|
||||
for (int i = 0; i < online.size(); i++)
|
||||
{
|
||||
final int index = i;
|
||||
Player player = online.get(i);
|
||||
try
|
||||
{
|
||||
exec.execute(() -> writeFrame(sub, frame));
|
||||
ScheduledTask task = HTTPDModule.plexApi().scheduler().runEntity(player, () ->
|
||||
{
|
||||
try
|
||||
{
|
||||
publicPlayers.set(index, buildPublicPlayer(player));
|
||||
staffPlayers.set(index, buildStaffPlayer(player));
|
||||
}
|
||||
catch (Throwable ignored) {}
|
||||
finally
|
||||
{
|
||||
if (remaining.decrementAndGet() == 0)
|
||||
{
|
||||
publish(compact(publicPlayers), compact(staffPlayers), max);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (task == null && remaining.decrementAndGet() == 0)
|
||||
{
|
||||
publish(compact(publicPlayers), compact(staffPlayers), max);
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
catch (Throwable ignored)
|
||||
{
|
||||
dropSubscriber(sub);
|
||||
if (remaining.decrementAndGet() == 0)
|
||||
{
|
||||
publish(compact(publicPlayers), compact(staffPlayers), max);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
private void publish(List<Map<String, Object>> publicPlayers, List<Map<String, Object>> staffPlayers, int max)
|
||||
{
|
||||
String publicJson = buildPayload(publicPlayers, max);
|
||||
String staffJson = buildPayload(staffPlayers, max);
|
||||
cachedPublicFrame = publicJson;
|
||||
cachedStaffFrame = staffJson;
|
||||
|
||||
ScheduledExecutorService exec = executor;
|
||||
if (exec == null || subscribers.isEmpty()) return;
|
||||
|
||||
final String publicFrame = "data: " + publicJson + "\n\n";
|
||||
final String staffFrame = "data: " + staffJson + "\n\n";
|
||||
for (Subscriber sub : subscribers)
|
||||
{
|
||||
final String frame = sub.staff ? staffFrame : publicFrame;
|
||||
try
|
||||
{
|
||||
exec.execute(() -> writeFrame(sub, frame));
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
dropSubscriber(sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Map<String, Object>> compact(AtomicReferenceArray<Map<String, Object>> players)
|
||||
{
|
||||
List<Map<String, Object>> result = new ArrayList<>(players.length());
|
||||
for (int i = 0; i < players.length(); i++)
|
||||
{
|
||||
Map<String, Object> player = players.get(i);
|
||||
if (player != null)
|
||||
{
|
||||
result.add(player);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void writeFrame(Subscriber sub, String frame)
|
||||
{
|
||||
try
|
||||
@@ -213,7 +276,7 @@ public final class PlayersBroadcaster
|
||||
if (!refreshScheduled.compareAndSet(false, true)) return;
|
||||
try
|
||||
{
|
||||
HTTPDModule.plexApi().scheduler().runLater(() ->
|
||||
HTTPDModule.plexApi().scheduler().runGlobalLater(() ->
|
||||
{
|
||||
refreshScheduled.set(false);
|
||||
refreshAndBroadcast();
|
||||
@@ -225,49 +288,34 @@ public final class PlayersBroadcaster
|
||||
}
|
||||
}
|
||||
|
||||
private String buildPublicPayload(List<Player> online, int max)
|
||||
private String buildPayload(List<Map<String, Object>> players, int max)
|
||||
{
|
||||
List<Map<String, Object>> players = new ArrayList<>();
|
||||
for (Player p : online)
|
||||
{
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
m.put("uuid", p.getUniqueId().toString());
|
||||
m.put("name", p.getName());
|
||||
try { m.put("world", p.getWorld() != null ? p.getWorld().getName() : ""); }
|
||||
catch (Throwable ignored) { m.put("world", ""); }
|
||||
int ping = 0;
|
||||
try { ping = p.getPing(); } catch (Throwable ignored) {}
|
||||
m.put("ping", ping);
|
||||
players.add(m);
|
||||
}
|
||||
Map<String, Object> root = new LinkedHashMap<>();
|
||||
root.put("players", players);
|
||||
root.put("max", max);
|
||||
return new GsonBuilder().serializeNulls().create().toJson(root);
|
||||
}
|
||||
|
||||
private String buildStaffPayload(List<Player> online, int max)
|
||||
private Map<String, Object> buildPublicPlayer(Player p)
|
||||
{
|
||||
List<Map<String, Object>> players = new ArrayList<>();
|
||||
for (Player p : online)
|
||||
{
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
m.put("uuid", p.getUniqueId().toString());
|
||||
m.put("name", p.getName());
|
||||
try { m.put("world", p.getWorld() != null ? p.getWorld().getName() : ""); }
|
||||
catch (Throwable ignored) { m.put("world", ""); }
|
||||
try { m.put("op", p.isOp()); } catch (Throwable ignored) { m.put("op", false); }
|
||||
try { m.put("gamemode", p.getGameMode().name()); }
|
||||
catch (Throwable ignored) { m.put("gamemode", ""); }
|
||||
int ping = 0;
|
||||
try { ping = p.getPing(); } catch (Throwable ignored) {}
|
||||
m.put("ping", ping);
|
||||
players.add(m);
|
||||
}
|
||||
Map<String, Object> root = new LinkedHashMap<>();
|
||||
root.put("players", players);
|
||||
root.put("max", max);
|
||||
return new GsonBuilder().serializeNulls().create().toJson(root);
|
||||
Map<String, Object> m = new LinkedHashMap<>();
|
||||
m.put("uuid", p.getUniqueId().toString());
|
||||
m.put("name", p.getName());
|
||||
try { m.put("world", p.getWorld() != null ? p.getWorld().getName() : ""); }
|
||||
catch (Throwable ignored) { m.put("world", ""); }
|
||||
int ping = 0;
|
||||
try { ping = p.getPing(); } catch (Throwable ignored) {}
|
||||
m.put("ping", ping);
|
||||
return m;
|
||||
}
|
||||
|
||||
private Map<String, Object> buildStaffPlayer(Player p)
|
||||
{
|
||||
Map<String, Object> m = buildPublicPlayer(p);
|
||||
try { m.put("op", p.isOp()); } catch (Throwable ignored) { m.put("op", false); }
|
||||
try { m.put("gamemode", p.getGameMode().name()); }
|
||||
catch (Throwable ignored) { m.put("gamemode", ""); }
|
||||
return m;
|
||||
}
|
||||
|
||||
private final class PlayersListener implements Listener
|
||||
|
||||
@@ -3,9 +3,9 @@ package dev.plex.request.impl;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import dev.plex.HTTPDModule;
|
||||
import jakarta.servlet.AsyncContext;
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.management.ManagementFactory;
|
||||
@@ -52,7 +52,7 @@ public final class StatsBroadcaster
|
||||
System.currentTimeMillis() - ManagementFactory.getRuntimeMXBean().getUptime();
|
||||
|
||||
private ScheduledExecutorService executor;
|
||||
private BukkitTask bukkitTask;
|
||||
private ScheduledTask bukkitTask;
|
||||
private ScheduledFuture<?> broadcastTask;
|
||||
|
||||
private int maxConnections = 32;
|
||||
@@ -77,7 +77,7 @@ public final class StatsBroadcaster
|
||||
|
||||
try
|
||||
{
|
||||
bukkitTask = (BukkitTask)HTTPDModule.plexApi().scheduler().runTimer(this::sampleBukkit, 0L, 40L);
|
||||
bukkitTask = HTTPDModule.plexApi().scheduler().runGlobalTimer(this::sampleBukkit, 1L, 40L);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Module-HTTPD
|
||||
version: 1.7
|
||||
version: 2.0
|
||||
description: HTTPD server for Plex
|
||||
main: dev.plex.HTTPDModule
|
||||
apiCompatibility: 1
|
||||
Reference in New Issue
Block a user