Upload via GUI (85 Dateien)

This commit is contained in:
2026-11-11 00:38:32 +00:00
parent 7cc38d7c0f
commit 68dee989ee
4 changed files with 92 additions and 46 deletions
@@ -107,60 +107,80 @@ public class ScoreboardModule implements Module, Listener {
player.setScoreboard(board);
}
// Altes Objective entfernen
Objective oldObj = board.getObjective("lobby");
if (oldObj != null) oldObj.unregister();
// Alle alten Zeilen-Teams sicher entfernen (großzügige Obergrenze)
for (int i = 0; i < Math.max(lines.size() + 5, 32); i++) {
Team old = board.getTeam("line_" + i);
if (old != null) old.unregister();
// Falls ein anderes Plugin dem Spieler ein fremdes Board gesetzt hat: zurückholen
if (player.getScoreboard() != board) {
player.setScoreboard(board);
}
// Paper 1.21: Objective mit Component-Titel registrieren
String translatedTitle = translate(player, title);
Objective obj = board.registerNewObjective(
"lobby",
Criteria.DUMMY,
// ---------------------------------------------------------
// FLACKER-FIX: Nichts mehr löschen und neu aufbauen.
// Objective und Teams bleiben bestehen, es wird nur geändert,
// was sich wirklich geändert hat. So werden keine unnötigen
// Pakete gesendet und das Scoreboard flackert nicht.
// ---------------------------------------------------------
net.kyori.adventure.text.Component titleComponent =
net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
.legacySection()
.deserialize(translatedTitle)
);
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
.deserialize(translate(player, title));
// Zahlen global für dieses Objective ausblenden (Paper 1.20.4+ API)
obj.numberFormat(NumberFormat.blank());
Objective obj = board.getObjective("lobby");
if (obj == null) {
obj = board.registerNewObjective("lobby", Criteria.DUMMY, titleComponent);
// Zahlen global für dieses Objective ausblenden (Paper 1.20.4+ API)
obj.numberFormat(NumberFormat.blank());
} else if (!titleComponent.equals(obj.displayName())) {
obj.displayName(titleComponent);
}
if (obj.getDisplaySlot() != DisplaySlot.SIDEBAR) {
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
}
for (int i = 0; i < lines.size(); i++) {
String lineText = translate(player, lines.get(i));
// Eindeutiger unsichtbarer Entry pro Zeile via Farb-Code
String entry = ChatColor.values()[i % ChatColor.values().length].toString()
+ ChatColor.RESET;
String entry = lineEntry(i);
// getTeam statt registerNewTeam — verhindert "already in use" Fehler
Team team = board.getTeam("line_" + i);
if (team == null) team = board.registerNewTeam("line_" + i);
team.getEntries().forEach(team::removeEntry);
team.addEntry(entry);
// Text aufteilen falls länger als 64 Zeichen
if (lineText.length() > 64) {
team.setPrefix(lineText.substring(0, 64));
team.setSuffix(lineText.substring(64, Math.min(lineText.length(), 128)));
} else {
team.setPrefix(lineText);
team.setSuffix("");
if (!team.hasEntry(entry)) {
team.getEntries().forEach(team::removeEntry);
team.addEntry(entry);
}
// Score setzen + Zahl pro Eintrag zusätzlich ausblenden
// Text aufteilen falls länger als 64 Zeichen
String prefix;
String suffix;
if (lineText.length() > 64) {
prefix = lineText.substring(0, 64);
suffix = lineText.substring(64, Math.min(lineText.length(), 128));
} else {
prefix = lineText;
suffix = "";
}
if (!prefix.equals(team.getPrefix())) team.setPrefix(prefix);
if (!suffix.equals(team.getSuffix())) team.setSuffix(suffix);
// Score nur setzen, wenn er sich geändert hat oder neu ist
org.bukkit.scoreboard.Score score = obj.getScore(entry);
score.setScore(lines.size() - i);
score.numberFormat(NumberFormat.blank());
int wanted = lines.size() - i;
if (!score.isScoreSet() || score.getScore() != wanted) {
score.setScore(wanted);
score.numberFormat(NumberFormat.blank());
}
}
// Kein player.setScoreboard(board) nötig, da wir das Objekt 'board'
// direkt verändert haben, das der Spieler bereits hat.
// Zeilen entfernen, die nicht mehr gebraucht werden (z. B. Wechsel Default <-> Owner)
for (int i = lines.size(); i < 32; i++) {
Team old = board.getTeam("line_" + i);
if (old == null) continue;
board.resetScores(lineEntry(i));
old.unregister();
}
}
private String lineEntry(int i) {
return ChatColor.values()[i % ChatColor.values().length].toString() + ChatColor.RESET;
}
// --- Methoden für den /nexus sb Befehl ---
@@ -39,7 +39,7 @@ public class SecurityModule implements Module, Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onAsyncLogin(AsyncPlayerPreLoginEvent event) {
FileConfiguration config = plugin.getConfig();
FileConfiguration config = getSecurityConfig();
UUID uuid = event.getUniqueId();
String ip = event.getAddress().getHostAddress();
@@ -48,8 +48,9 @@ public class SecurityModule implements Module, Listener {
return; // Teammitglieder dürfen immer drauf
}
boolean vpnEnabled = config.getBoolean("security.vpn-blocker.enabled", true);
boolean countryEnabled = config.getBoolean("security.country-blocker.enabled", true);
// Standard: aus, wenn nichts konfiguriert ist (kein ungewolltes Kicken)
boolean vpnEnabled = config.getBoolean("security.vpn-blocker.enabled", false);
boolean countryEnabled = config.getBoolean("security.country-blocker.enabled", false);
if (!vpnEnabled && !countryEnabled) return;
@@ -69,11 +70,12 @@ public class SecurityModule implements Module, Listener {
// 2. VPN / Proxy Check
if (vpnEnabled) {
boolean isProxy = (boolean) json.get("proxy");
boolean isHosting = (boolean) json.get("hosting");
boolean isProxy = Boolean.TRUE.equals(json.get("proxy"));
boolean isHosting = Boolean.TRUE.equals(json.get("hosting"));
if (isProxy || isHosting) {
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER,
colorize(config.getString("security.vpn-blocker.kick-message")));
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER,
colorize(config.getString("security.vpn-blocker.kick-message",
"&cVPN und Proxies sind auf diesem Server nicht erlaubt!")));
return;
}
}
@@ -110,6 +112,21 @@ public class SecurityModule implements Module, Listener {
return user != null && user.getCachedData().getPermissionData().checkPermission("nexuslobby.security.bypass").asBoolean();
}
/**
* Die Security-Einstellungen stehen in der settings.yml (nicht in der config.yml).
* Fallback auf die config.yml, falls das Settings-Modul noch nicht bereit ist.
*/
private FileConfiguration getSecurityConfig() {
try {
var module = plugin.getLobbySettingsModule();
if (module != null && module.getSettingsConfig() != null) {
return module.getSettingsConfig();
}
} catch (Exception ignored) {
}
return plugin.getConfig();
}
private String colorize(String s) {
return s == null ? "" : s.replace("&", "§");
}
@@ -9,7 +9,9 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryClickEvent;
@@ -71,7 +73,10 @@ public class ServerSwitcherListener implements Listener, CommandExecutor {
return true;
}
@EventHandler
// LOWEST: Wir reagieren als Erste. So können andere Plugins (z. B. der Navigations-Stab
// von WorldEdit, der standardmäßig ein Kompass ist und beim Klick teleportiert)
// den Klick nicht mehr verarbeiten.
@EventHandler(priority = EventPriority.LOWEST)
public void onCompassClick(PlayerInteractEvent e) {
Player p = e.getPlayer();
@@ -79,8 +84,12 @@ public class ServerSwitcherListener implements Listener, CommandExecutor {
if (!(e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK
|| e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK)) return;
openServerGUI(p);
// Klick komplett sperren, bevor andere Plugins ihn sehen
e.setUseItemInHand(Event.Result.DENY);
e.setUseInteractedBlock(Event.Result.DENY);
e.setCancelled(true);
openServerGUI(p);
}
private void openServerGUI(Player p) {
+1 -1
View File
@@ -1,6 +1,6 @@
name: NexusLobby
main: de.nexuslobby.NexusLobby
version: "2.0"
version: "2.1"
api-version: "1.21"
author: M_Viper
description: Modular Lobby Plugin with an invisible Particle-Parkour system.