Soft-delete copy _trash/2026-05-07T19-39-23-130Z/src/main/java/net/viper/status/modules/commandblocker/CommandBlockerModule.java
This commit is contained in:
@@ -0,0 +1,245 @@
|
|||||||
|
package net.viper.status.modules.commandblocker;
|
||||||
|
|
||||||
|
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.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.event.ChatEvent;
|
||||||
|
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.StatusAPI;
|
||||||
|
import net.viper.status.module.Module;
|
||||||
|
import net.viper.status.ratelimit.GlobalRateLimitFramework;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
public class CommandBlockerModule implements Module, Listener {
|
||||||
|
|
||||||
|
private StatusAPI plugin;
|
||||||
|
private boolean enabled = true; // Standardmäßig aktiv
|
||||||
|
private String bypassPermission = "commandblocker.bypass"; // Standard Permission
|
||||||
|
|
||||||
|
private File file;
|
||||||
|
private Set<String> blocked = new HashSet<>();
|
||||||
|
private final GlobalRateLimitFramework rateLimiter = GlobalRateLimitFramework.getInstance();
|
||||||
|
|
||||||
|
private boolean commandRateLimitEnabled = true;
|
||||||
|
private long commandRateLimitWindowMs = 3000L;
|
||||||
|
private int commandRateLimitMaxActions = 8;
|
||||||
|
private long commandRateLimitBlockMs = 6000L;
|
||||||
|
private String commandRateLimitMessage = "&cZu viele Befehle in kurzer Zeit. Bitte warte kurz.";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "CommandBlockerModule";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable(Plugin plugin) {
|
||||||
|
if (!(plugin instanceof StatusAPI)) return; // Sicherheit
|
||||||
|
this.plugin = (StatusAPI) plugin;
|
||||||
|
|
||||||
|
// Datei laden
|
||||||
|
file = new File(this.plugin.getDataFolder(), "blocked-commands.yml");
|
||||||
|
loadFile();
|
||||||
|
|
||||||
|
// Listener registrieren
|
||||||
|
ProxyServer.getInstance().getPluginManager().registerListener(this.plugin, this);
|
||||||
|
|
||||||
|
// /cb Befehl registrieren
|
||||||
|
ProxyServer.getInstance().getPluginManager().registerCommand(this.plugin,
|
||||||
|
new net.md_5.bungee.api.plugin.Command("cb", "commandblocker.admin") {
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String[] args) {
|
||||||
|
handleCommand(sender, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.plugin.getLogger().info("[CommandBlocker] aktiviert (" + blocked.size() + " Commands).");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable(Plugin plugin) {
|
||||||
|
blocked.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onCommand(ChatEvent event) {
|
||||||
|
if (!enabled || !event.isCommand()) return;
|
||||||
|
|
||||||
|
if (!(event.getSender() instanceof ProxiedPlayer)) return;
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
|
||||||
|
|
||||||
|
if (player.hasPermission(bypassPermission)) return;
|
||||||
|
|
||||||
|
String msg = event.getMessage();
|
||||||
|
if (msg == null || msg.length() <= 1) return;
|
||||||
|
|
||||||
|
if (commandRateLimitEnabled) {
|
||||||
|
GlobalRateLimitFramework.Result result = rateLimiter.check(
|
||||||
|
"chat.command",
|
||||||
|
player.getUniqueId().toString(),
|
||||||
|
new GlobalRateLimitFramework.Rule(
|
||||||
|
true,
|
||||||
|
commandRateLimitWindowMs,
|
||||||
|
commandRateLimitMaxActions,
|
||||||
|
commandRateLimitBlockMs
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.isBlocked()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
player.sendMessage(ChatColor.translateAlternateColorCodes('&', commandRateLimitMessage));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String cmd = msg.substring(1).toLowerCase(Locale.ROOT);
|
||||||
|
String base = cmd.split(" ")[0];
|
||||||
|
|
||||||
|
if (blocked.contains(base)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
player.sendMessage(ChatColor.RED + "Dieser Befehl ist auf diesem Netzwerk blockiert.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleCommand(CommandSender sender, String[] args) {
|
||||||
|
if (args == null || args.length == 0) {
|
||||||
|
sender.sendMessage(ChatColor.YELLOW + "/cb add <command>");
|
||||||
|
sender.sendMessage(ChatColor.YELLOW + "/cb remove <command>");
|
||||||
|
sender.sendMessage(ChatColor.YELLOW + "/cb list");
|
||||||
|
sender.sendMessage(ChatColor.YELLOW + "/cb reload");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String action = args[0].toLowerCase();
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case "add":
|
||||||
|
if (args.length < 2) break;
|
||||||
|
blocked.add(args[1].toLowerCase());
|
||||||
|
saveFile();
|
||||||
|
sender.sendMessage(ChatColor.GREEN + "Command blockiert: " + args[1]);
|
||||||
|
break;
|
||||||
|
case "remove":
|
||||||
|
if (args.length < 2) break;
|
||||||
|
blocked.remove(args[1].toLowerCase());
|
||||||
|
saveFile();
|
||||||
|
sender.sendMessage(ChatColor.GREEN + "Command freigegeben: " + args[1]);
|
||||||
|
break;
|
||||||
|
case "list":
|
||||||
|
sender.sendMessage(ChatColor.GOLD + "Blockierte Commands:");
|
||||||
|
for (String c : blocked) {
|
||||||
|
sender.sendMessage(ChatColor.RED + "- " + c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "reload":
|
||||||
|
loadFile();
|
||||||
|
sender.sendMessage(ChatColor.GREEN + "CommandBlocker neu geladen.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sender.sendMessage(ChatColor.RED + "Unbekannter Unterbefehl.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadFile() {
|
||||||
|
try {
|
||||||
|
if (!file.exists()) {
|
||||||
|
File parent = file.getParentFile();
|
||||||
|
if (parent != null && !parent.exists()) parent.mkdirs();
|
||||||
|
file.createNewFile();
|
||||||
|
saveFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
Yaml yaml = new Yaml();
|
||||||
|
Map<String, Object> data = null;
|
||||||
|
FileInputStream fis = null;
|
||||||
|
try {
|
||||||
|
fis = new FileInputStream(file);
|
||||||
|
data = yaml.loadAs(fis, Map.class);
|
||||||
|
} finally {
|
||||||
|
if (fis != null) try { fis.close(); } catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
blocked.clear();
|
||||||
|
if (data != null && data.containsKey("blocked")) {
|
||||||
|
Object obj = data.get("blocked");
|
||||||
|
if (obj instanceof List) {
|
||||||
|
List list = (List) obj;
|
||||||
|
for (Object o : list) {
|
||||||
|
if (o != null) blocked.add(String.valueOf(o).toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data != null && data.containsKey("rate-limit")) {
|
||||||
|
Object rlObj = data.get("rate-limit");
|
||||||
|
if (rlObj instanceof Map) {
|
||||||
|
Map rl = (Map) rlObj;
|
||||||
|
commandRateLimitEnabled = parseBoolean(rl.get("enabled"), commandRateLimitEnabled);
|
||||||
|
commandRateLimitWindowMs = parseLong(rl.get("window-ms"), commandRateLimitWindowMs);
|
||||||
|
commandRateLimitMaxActions = (int) parseLong(rl.get("max-actions"), commandRateLimitMaxActions);
|
||||||
|
commandRateLimitBlockMs = parseLong(rl.get("block-ms"), commandRateLimitBlockMs);
|
||||||
|
Object msgObj = rl.get("message");
|
||||||
|
if (msgObj != null) {
|
||||||
|
commandRateLimitMessage = String.valueOf(msgObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (plugin != null) plugin.getLogger().severe("[CommandBlocker] Fehler beim Laden: " + e.getMessage());
|
||||||
|
else System.err.println("[CommandBlocker] Fehler beim Laden: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveFile() {
|
||||||
|
try {
|
||||||
|
Yaml yaml = new Yaml();
|
||||||
|
Map<String, Object> out = new LinkedHashMap<>();
|
||||||
|
out.put("blocked", new ArrayList<>(blocked));
|
||||||
|
|
||||||
|
Map<String, Object> rl = new LinkedHashMap<>();
|
||||||
|
rl.put("enabled", commandRateLimitEnabled);
|
||||||
|
rl.put("window-ms", commandRateLimitWindowMs);
|
||||||
|
rl.put("max-actions", commandRateLimitMaxActions);
|
||||||
|
rl.put("block-ms", commandRateLimitBlockMs);
|
||||||
|
rl.put("message", commandRateLimitMessage);
|
||||||
|
out.put("rate-limit", rl);
|
||||||
|
|
||||||
|
FileWriter fw = null;
|
||||||
|
try {
|
||||||
|
fw = new FileWriter(file);
|
||||||
|
yaml.dump(out, fw);
|
||||||
|
} finally {
|
||||||
|
if (fw != null) try { fw.close(); } catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (plugin != null) plugin.getLogger().severe("[CommandBlocker] Fehler beim Speichern: " + e.getMessage());
|
||||||
|
else System.err.println("[CommandBlocker] Fehler beim Speichern: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean parseBoolean(Object obj, boolean fallback) {
|
||||||
|
if (obj == null) return fallback;
|
||||||
|
return Boolean.parseBoolean(String.valueOf(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
private long parseLong(Object obj, long fallback) {
|
||||||
|
if (obj == null) return fallback;
|
||||||
|
try {
|
||||||
|
return Long.parseLong(String.valueOf(obj));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user