Upload folder via GUI - src
This commit is contained in:
@@ -9,6 +9,7 @@ import net.viper.status.modules.antibot.AntiBotModule;
|
|||||||
import net.viper.status.modules.network.NetworkInfoModule;
|
import net.viper.status.modules.network.NetworkInfoModule;
|
||||||
import net.viper.status.modules.AutoMessage.AutoMessageModule;
|
import net.viper.status.modules.AutoMessage.AutoMessageModule;
|
||||||
import net.viper.status.modules.customcommands.CustomCommandModule;
|
import net.viper.status.modules.customcommands.CustomCommandModule;
|
||||||
|
import net.viper.status.modules.serverswitcher.ServerSwitcherModule;
|
||||||
import net.viper.status.stats.PlayerStats;
|
import net.viper.status.stats.PlayerStats;
|
||||||
import net.viper.status.stats.StatsModule;
|
import net.viper.status.stats.StatsModule;
|
||||||
import net.viper.status.modules.verify.VerifyModule;
|
import net.viper.status.modules.verify.VerifyModule;
|
||||||
@@ -87,6 +88,7 @@ public class StatusAPI extends Plugin implements Runnable {
|
|||||||
moduleManager.registerModule(new NetworkInfoModule());
|
moduleManager.registerModule(new NetworkInfoModule());
|
||||||
moduleManager.registerModule(new AutoMessageModule());
|
moduleManager.registerModule(new AutoMessageModule());
|
||||||
moduleManager.registerModule(new CustomCommandModule());
|
moduleManager.registerModule(new CustomCommandModule());
|
||||||
|
moduleManager.registerModule(new ServerSwitcherModule());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class<?> forumBridge = Class.forName("net.viper.status.modules.forum.ForumBridgeModule");
|
Class<?> forumBridge = Class.forName("net.viper.status.modules.forum.ForumBridgeModule");
|
||||||
|
|||||||
@@ -1193,7 +1193,9 @@ public class ChatModule implements Module, Listener {
|
|||||||
String player, String suffix, String message) {
|
String player, String suffix, String message) {
|
||||||
String serverColor = config.getServerColor(server);
|
String serverColor = config.getServerColor(server);
|
||||||
String serverDisplay = config.getServerDisplay(server);
|
String serverDisplay = config.getServerDisplay(server);
|
||||||
String coloredServer = translateColors(serverColor + serverDisplay + "&r");
|
// Nur den Servernamen-Teil vorübersetzen damit &#RRGGBB im Display-Namen
|
||||||
|
// korrekt sitzt; der Rest wird am Ausgabepunkt via translateColors() übersetzt.
|
||||||
|
String coloredServer = serverColor + serverDisplay + "&r";
|
||||||
|
|
||||||
return format
|
return format
|
||||||
.replace("{server}", coloredServer)
|
.replace("{server}", coloredServer)
|
||||||
@@ -1299,7 +1301,7 @@ public class ChatModule implements Module, Listener {
|
|||||||
private BaseComponent[] buildClickableMessage(String msgId, String formatted, String senderName) {
|
private BaseComponent[] buildClickableMessage(String msgId, String formatted, String senderName) {
|
||||||
ComponentBuilder builder = new ComponentBuilder("");
|
ComponentBuilder builder = new ComponentBuilder("");
|
||||||
|
|
||||||
builder.append(ChatColor.translateAlternateColorCodes('&', formatted),
|
builder.append(translateColors(formatted),
|
||||||
ComponentBuilder.FormatRetention.NONE)
|
ComponentBuilder.FormatRetention.NONE)
|
||||||
.event((ClickEvent) null)
|
.event((ClickEvent) null)
|
||||||
.event((HoverEvent) null);
|
.event((HoverEvent) null);
|
||||||
|
|||||||
@@ -0,0 +1,273 @@
|
|||||||
|
package net.viper.status.modules.serverswitcher;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
|
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||||
|
import net.md_5.bungee.api.chat.HoverEvent;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.event.TabCompleteEvent;
|
||||||
|
import net.md_5.bungee.api.plugin.Command;
|
||||||
|
import net.md_5.bungee.api.plugin.Listener;
|
||||||
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
import net.viper.status.module.Module;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class ServerSwitcherModule implements Module {
|
||||||
|
|
||||||
|
private static final String CONFIG_FILE = "serverswitcher.properties";
|
||||||
|
|
||||||
|
private Plugin plugin;
|
||||||
|
private boolean enabled = true;
|
||||||
|
private String permission = "serverswitcher.use";
|
||||||
|
private String commandName = "go";
|
||||||
|
private List<String> aliases = new ArrayList<>(Arrays.asList("wechsel", "switch"));
|
||||||
|
private List<String> serverWhitelist = new ArrayList<>();
|
||||||
|
|
||||||
|
private String colorHeader = "&8&m---&r &6&lServer-Menue &8&m---";
|
||||||
|
private String colorEntry = "&7>> &e";
|
||||||
|
private String colorOnline = "&a";
|
||||||
|
private String colorOffline = "&c";
|
||||||
|
private String colorSelf = "&7(Aktuell)";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "ServerSwitcherModule";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
ensureConfigExists();
|
||||||
|
loadConfig();
|
||||||
|
|
||||||
|
if (!enabled) {
|
||||||
|
plugin.getLogger().info("[ServerSwitcherModule] Deaktiviert.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] aliasArray = aliases.toArray(new String[0]);
|
||||||
|
ProxyServer.getInstance().getPluginManager().registerCommand(plugin,
|
||||||
|
new GoCommand(commandName, permission, aliasArray));
|
||||||
|
ProxyServer.getInstance().getPluginManager().registerListener(plugin,
|
||||||
|
new GoTabListener());
|
||||||
|
|
||||||
|
plugin.getLogger().info("[ServerSwitcherModule] Aktiviert. Command: /" + commandName
|
||||||
|
+ " | Aliases: " + aliases + " | Permission: " + permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable(Plugin plugin) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureConfigExists() {
|
||||||
|
File target = new File(plugin.getDataFolder(), CONFIG_FILE);
|
||||||
|
if (target.exists()) return;
|
||||||
|
if (!plugin.getDataFolder().exists()) plugin.getDataFolder().mkdirs();
|
||||||
|
|
||||||
|
String defaults =
|
||||||
|
"# ServerSwitcherModule Konfiguration\n" +
|
||||||
|
"serverswitcher.enabled=true\n\n" +
|
||||||
|
"serverswitcher.command=go\n" +
|
||||||
|
"serverswitcher.aliases=wechsel,switch\n" +
|
||||||
|
"serverswitcher.permission=serverswitcher.use\n\n" +
|
||||||
|
"# Optionale Whitelist (leer = alle BungeeCord-Server)\n" +
|
||||||
|
"# Beispiel: serverswitcher.servers=lobby,citybuild,survival\n" +
|
||||||
|
"serverswitcher.servers=\n\n" +
|
||||||
|
"serverswitcher.color.header=&8&m---&r &6&lServer-Menü &8&m---\n" +
|
||||||
|
"serverswitcher.color.entry=&7>> &e\n" +
|
||||||
|
"serverswitcher.color.online=&a\n" +
|
||||||
|
"serverswitcher.color.offline=&c\n" +
|
||||||
|
"serverswitcher.color.self=&7(Aktuell)\n";
|
||||||
|
|
||||||
|
try (OutputStream out = new FileOutputStream(target)) {
|
||||||
|
out.write(defaults.getBytes(StandardCharsets.UTF_8));
|
||||||
|
} catch (Exception e) {
|
||||||
|
plugin.getLogger().warning("[ServerSwitcherModule] Konnte " + CONFIG_FILE + " nicht erstellen: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadConfig() {
|
||||||
|
File file = new File(plugin.getDataFolder(), CONFIG_FILE);
|
||||||
|
if (!file.exists()) return;
|
||||||
|
|
||||||
|
Properties props = new Properties();
|
||||||
|
try (FileInputStream fis = new FileInputStream(file)) {
|
||||||
|
props.load(new InputStreamReader(fis, StandardCharsets.UTF_8));
|
||||||
|
} catch (Exception e) {
|
||||||
|
plugin.getLogger().warning("[ServerSwitcherModule] Fehler beim Laden: " + e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enabled = Boolean.parseBoolean(props.getProperty("serverswitcher.enabled", "true"));
|
||||||
|
commandName = props.getProperty("serverswitcher.command", "go").trim();
|
||||||
|
permission = props.getProperty("serverswitcher.permission", "serverswitcher.use").trim();
|
||||||
|
|
||||||
|
aliases.clear();
|
||||||
|
for (String a : props.getProperty("serverswitcher.aliases", "wechsel,switch").split(",")) {
|
||||||
|
String t = a.trim();
|
||||||
|
if (!t.isEmpty()) aliases.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
serverWhitelist.clear();
|
||||||
|
for (String s : props.getProperty("serverswitcher.servers", "").split(",")) {
|
||||||
|
String t = s.trim().toLowerCase();
|
||||||
|
if (!t.isEmpty()) serverWhitelist.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
colorHeader = props.getProperty("serverswitcher.color.header", colorHeader);
|
||||||
|
colorEntry = props.getProperty("serverswitcher.color.entry", colorEntry);
|
||||||
|
colorOnline = props.getProperty("serverswitcher.color.online", colorOnline);
|
||||||
|
colorOffline = props.getProperty("serverswitcher.color.offline", colorOffline);
|
||||||
|
colorSelf = props.getProperty("serverswitcher.color.self", colorSelf);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getServerList() {
|
||||||
|
if (!serverWhitelist.isEmpty()) return new ArrayList<>(serverWhitelist);
|
||||||
|
List<String> list = new ArrayList<>(ProxyServer.getInstance().getServers().keySet());
|
||||||
|
list.sort(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String c(String text) {
|
||||||
|
return ChatColor.translateAlternateColorCodes('&', text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String capitalize(String s) {
|
||||||
|
if (s == null || s.isEmpty()) return s;
|
||||||
|
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Command ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private class GoCommand extends Command {
|
||||||
|
|
||||||
|
GoCommand(String name, String permission, String[] aliases) {
|
||||||
|
super(name, permission.isEmpty() ? null : permission, aliases);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String[] args) {
|
||||||
|
if (!(sender instanceof ProxiedPlayer)) {
|
||||||
|
sender.sendMessage(c("&cDieser Befehl ist nur für Spieler verfügbar."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||||
|
|
||||||
|
if (args.length >= 1) {
|
||||||
|
String target = args[0].trim();
|
||||||
|
ServerInfo server = null;
|
||||||
|
for (Map.Entry<String, ServerInfo> entry : ProxyServer.getInstance().getServers().entrySet()) {
|
||||||
|
if (entry.getKey().equalsIgnoreCase(target)) {
|
||||||
|
server = entry.getValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server == null) {
|
||||||
|
player.sendMessage(c("&cServer &e" + args[0] + " &cnicht gefunden."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.getServer() != null
|
||||||
|
&& player.getServer().getInfo().getName().equalsIgnoreCase(server.getName())) {
|
||||||
|
player.sendMessage(c("&7Du bist bereits auf &e" + server.getName() + "&7."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.sendMessage(c("&7Verbinde mit &e" + server.getName() + "&7..."));
|
||||||
|
player.connect(server);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendServerMenu(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendServerMenu(ProxiedPlayer player) {
|
||||||
|
player.sendMessage(c(colorHeader));
|
||||||
|
|
||||||
|
for (String serverName : getServerList()) {
|
||||||
|
ServerInfo info = ProxyServer.getInstance().getServerInfo(serverName);
|
||||||
|
if (info == null) continue;
|
||||||
|
|
||||||
|
boolean isCurrent = player.getServer() != null
|
||||||
|
&& player.getServer().getInfo().getName().equalsIgnoreCase(serverName);
|
||||||
|
int count = info.getPlayers().size();
|
||||||
|
|
||||||
|
TextComponent line = new TextComponent(c(colorEntry));
|
||||||
|
TextComponent btn = new TextComponent(c((isCurrent ? colorOffline : colorOnline) + capitalize(serverName)));
|
||||||
|
|
||||||
|
if (!isCurrent) {
|
||||||
|
btn.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
|
||||||
|
"/" + commandName + " " + serverName));
|
||||||
|
btn.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
|
||||||
|
new ComponentBuilder(c("&7Klicken zum Verbinden\n&7Online: &a" + count + " Spieler")).create()));
|
||||||
|
}
|
||||||
|
|
||||||
|
line.addExtra(btn);
|
||||||
|
line.addExtra(new TextComponent(c(" &8(&7" + count + " online&8)")));
|
||||||
|
if (isCurrent) line.addExtra(new TextComponent(c(" " + colorSelf)));
|
||||||
|
|
||||||
|
player.sendMessage(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.sendMessage(c("&8&m----------------------------"));
|
||||||
|
player.sendMessage(c("&7Tipp: &e/" + commandName + " <Server> &7für direkten Wechsel"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Tab-Completion ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
public class GoTabListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onTabComplete(TabCompleteEvent event) {
|
||||||
|
String cursor = event.getCursor();
|
||||||
|
if (cursor == null) return;
|
||||||
|
|
||||||
|
String lower = cursor.toLowerCase();
|
||||||
|
boolean matches = lower.startsWith("/" + commandName.toLowerCase() + " ");
|
||||||
|
if (!matches) {
|
||||||
|
for (String alias : aliases) {
|
||||||
|
if (lower.startsWith("/" + alias.toLowerCase() + " ")) {
|
||||||
|
matches = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!matches) return;
|
||||||
|
|
||||||
|
if (event.getSender() instanceof ProxiedPlayer) {
|
||||||
|
ProxiedPlayer p = (ProxiedPlayer) event.getSender();
|
||||||
|
if (!permission.isEmpty() && !p.hasPermission(permission)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spaceIdx = cursor.indexOf(' ');
|
||||||
|
String input = spaceIdx >= 0 ? cursor.substring(spaceIdx + 1).toLowerCase() : "";
|
||||||
|
|
||||||
|
List<String> suggestions = new ArrayList<>();
|
||||||
|
for (String server : getServerList()) {
|
||||||
|
if (server.toLowerCase().startsWith(input)) suggestions.add(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
event.getSuggestions().clear();
|
||||||
|
event.getSuggestions().addAll(suggestions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,9 +17,9 @@ server-colors:
|
|||||||
skyblock:
|
skyblock:
|
||||||
color: "&b"
|
color: "&b"
|
||||||
display: "SkyBlock"
|
display: "SkyBlock"
|
||||||
creative:
|
citybuild:
|
||||||
color: "&#A020E8"
|
color: "&#A020E8"
|
||||||
display: "Creative"
|
display: "CityBuild"
|
||||||
minigames:
|
minigames:
|
||||||
color: "&e"
|
color: "&e"
|
||||||
display: "MiniGames"
|
display: "MiniGames"
|
||||||
|
|||||||
@@ -176,6 +176,12 @@ commands:
|
|||||||
description: Report schliessen (Admin)
|
description: Report schliessen (Admin)
|
||||||
usage: /reportclose <ID>
|
usage: /reportclose <ID>
|
||||||
|
|
||||||
|
# ── ServerSwitcherModule ──────────────────────────────────
|
||||||
|
go:
|
||||||
|
description: Schneller Serverwechsel ueber Chat-Menue oder direkt
|
||||||
|
usage: /go [servername]
|
||||||
|
aliases: [wechsel, switch]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
# ── StatusAPI Core ────────────────────────────────────────
|
# ── StatusAPI Core ────────────────────────────────────────
|
||||||
statusapi.update.notify:
|
statusapi.update.notify:
|
||||||
@@ -263,3 +269,8 @@ permissions:
|
|||||||
commandblocker.admin:
|
commandblocker.admin:
|
||||||
description: CommandBlocker verwalten (/cb)
|
description: CommandBlocker verwalten (/cb)
|
||||||
default: op
|
default: op
|
||||||
|
|
||||||
|
# ── ServerSwitcherModule ──────────────────────────────────
|
||||||
|
serverswitcher.use:
|
||||||
|
description: Zugriff auf /go (Schneller Serverwechsel)
|
||||||
|
default: false
|
||||||
|
|||||||
Reference in New Issue
Block a user