Y
YannY4565
•last year
General

Protocol 79

FantomProject

A
You

Paper

Защита сервера от Ddos атак, хакерских атак, инъекции, антивирус, античит.

ru

Minecraft Plugin Builder
Minecraft Plugin BuilderClaude 3.7 Sonnet

Плагин защиты сервера Minecraft

Я создам комплексный плагин защиты для Minecraft сервера на Java.

java
package ru.serverprotection;

import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.*;
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.entity.Player;
import org.bukkit.Bukkit;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

public class ServerProtectionPlugin extends JavaPlugin implements Listener {

    // Хранилище данных о подключениях
    private Map<String, ConnectionData> connectionTracker = new ConcurrentHashMap<>();
    private Map<UUID, PlayerSecurityData> playerData = new ConcurrentHashMap<>();
    private Set<String> blockedIPs = ConcurrentHashMap.newKeySet();
    
    // Настройки защиты
    private int maxConnectionsPerMinute = 5;
    private int maxCommandsPerSecond = 3;
    private int suspiciousMovementThreshold = 10;

    @Override
    public void onEnable() {
        getLogger().info("§a[Защита] Плагин защиты сервера запущен!");
        
        // Регистрация событий
        Bukkit.getPluginManager().registerEvents(this, this);
        
        // Регистрация команд
        getCommand("protection").setExecutor(new ProtectionCommand(this));
        
        // Запуск фоновых задач
        startSecurityTasks();
        
        // Загрузка конфигурации
        saveDefaultConfig();
        loadConfiguration();
    }

    @Override
    public void onDisable() {
        getLogger().info("§c[Защита] Плагин защиты сервера остановлен!");
    }

    private void loadConfiguration() {
        maxConnectionsPerMinute = getConfig().getInt("ddos-protection.max-connections-per-minute", 5);
        maxCommandsPerSecond = getConfig().getInt("injection-protection.max-commands-per-second", 3);
        suspiciousMovementThreshold = getConfig().getInt("anticheat.movement-threshold", 10);
    }

    // ==================== ЗАЩИТА ОТ DDOS ====================
    
    @EventHandler
    public void onPlayerLogin(PlayerLoginEvent event) {
        String ip = event.getAddress().getHostAddress();
        
        // Проверка заблокированных IP
        if (blockedIPs.contains(ip)) {
            event.disallow(PlayerLoginEvent.Result.KICK_BANNED, 
                "§c[Защита] Ваш IP-адрес заблокирован за подозрительную активность!");
            return;
        }
        
        // Отслеживание частоты подключений
        ConnectionData data = connectionTracker.computeIfAbsent(ip, k -> new ConnectionData());
        data.addConnection();
        
        if (data.getConnectionsLastMinute() > maxConnectionsPerMinute) {
            blockedIPs.add(ip);
            event.disallow(PlayerLoginEvent.Result.KICK_BANNED, 
                "§c[Защита] Обнаружена DDoS атака! IP заблокирован.");
            getLogger().warning("§c[DDoS Защита] Заблокирован IP: " + ip + 
                " (слишком много подключений)");
            
            // Уведомление администраторов
            notifyAdmins("§c[DDoS] Заблокирован IP: " + ip);
        }
    }

    // ==================== ЗАЩИТА ОТ ИНЪЕКЦИЙ ====================
    
    @EventHandler
    public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
        Player player = event.getPlayer();
        String command = event.getMessage();
        
        // Проверка на SQL-инъекции
        if (detectSQLInjection(command)) {
            event.setCancelled(true);
            player.sendMessage("§c[Защита] Обнаружена попытка SQL-инъекции!");
            getLogger().severe("§c[SQL-Инъекция] Игрок " + player.getName() + 
                " попытался выполнить: " + command);
            notifyAdmins("§c[SQL-Инъекция] Игрок: " + player.getName());
            kickPlayerForHacking(player, "SQL-инъекция");
            return;
        }
        
        // Проверка на XSS атаки
        if (detectXSS(command)) {
            event.setCancelled(true);
            player.sendMessage("§c[Защита] Обнаружена попытка XSS атаки!");
            getLogger().severe("§c[XSS] Игрок " + player.getName() + 
                " попытался выполнить: " + command);
            kickPlayerForHacking(player, "XSS атака");
            return;
        }
        
        // Защита от спама команд
        PlayerSecurityData data = getPlayerData(player);
        if (data.isCommandSpam()) {
            event.setCancelled(true);
            player.sendMessage("§c[Защита] Вы отправляете команды слишком быстро!");
            return;
        }
        data.addCommand();
    }

    @EventHandler
    public void onPlayerChat(AsyncPlayerChatEvent event) {
        Player player = event.getPlayer();
        String message = event.getMessage();
        
        // Проверка на вредоносные паттерны
        if (detectMaliciousPatterns(message)) {
            event.setCancelled(true);
            player.sendMessage("§c[Защита] Обнаружено вредоносное содержимое в сообщении!");
            getLogger().warning("§c[Вредоносный контент] Игрок: " + player.getName());
        }
    }

    // ==================== АНТИЧИТ ====================
    
    @EventHandler
    public void onPlayerMove(PlayerMoveEvent event) {
        Player player = event.getPlayer();
        PlayerSecurityData data = getPlayerData(player);
        
        // Проверка на телепортацию (fly/speed hack)
        double distance = event.getFrom().distance(event.getTo());
        if (distance > suspiciousMovementThreshold && !player.isFlying() && !player.hasPermission("protection.bypass")) {
            event.setCancelled(true);
            data.addViolation("Подозрительное перемещение");
            
            if (data.getViolations() > 5) {
                kickPlayerForHacking(player, "Читы на перемещение");
                notifyAdmins("§c[Античит] Игрок " + player.getName() + " использует читы!");
            }
        }
        
        // Проверка на скорость
        data.updateMovement(distance);
        if (data.getAverageSpeed() > 2.0 && !player.hasPermission("protection.bypass")) {
            player.sendMessage("§c[Античит] Обнаружена подозрительная скорость!");
            data.addViolation("Превышение скорости");
        }
    }

    @EventHandler
    public void onPlayerInteract(PlayerInteractEvent event) {
        Player player = event.getPlayer();
        PlayerSecurityData data = getPlayerData(player);
        
        // Проверка на автокликер
        data.addClick();
        if (data.getClicksPerSecond() > 20) {
            event.setCancelled(true);
            player.sendMessage("§c[Античит] Обнаружен автокликер!");
            data.addViolation("Автокликер");
            
            if (data.getViolations() > 3) {
                kickPlayerForHacking(player, "Автокликер");
            }
        }
    }

    // ==================== АНТИВИРУС ====================
    
    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        
        // Сканирование клиента игрока
        Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
            scanPlayerClient(player);
        });
    }

    private void scanPlayerClient(Player player) {
        PlayerSecurityData data = getPlayerData(player);
        
        // Проверка на известные модифицированные клиенты
        String clientBrand = player.getClientBrandName();
        List<String> suspiciousClients = Arrays.asList("wurst", "sigma", "liquidbounce", "aristois");
        
        for (String suspicious : suspiciousClients) {
            if (clientBrand != null && clientBrand.toLowerCase().contains(suspicious)) {
                Bukkit.getScheduler().runTask(this, () -> {
                    kickPlayerForHacking(player, "Обнаружен читерский клиент: " + clientBrand);
                    notifyAdmins("§c[Антивирус] Игрок " + player.getName() + 
                        " использует читерский клиент: " + clientBrand);
                });
                return;
            }
        }
        
        getLogger().info("§a[Антивирус] Игрок " + player.getName() + " прошёл проверку");
    }

    // ==================== ВСПОМОГАТЕЛЬНЫЕ МЕТОДЫ ====================
    
    private boolean detectSQLInjection(String input) {
        String[] sqlPatterns = {
            "(?i).*('|(\\-\\-)|(;)|(\\|\\|)|(\\/\\*)|(\\*\\/)|(xp_)|(sp_)|(exec)|(execute)).*",
            "(?i).*(union|select|insert|update|delete|drop|create|alter|exec|script).*",
            "(?i).*('\\s*or\\s*'1'\\s*=\\s*'1).*"
        };
        
        for (String pattern : sqlPatterns) {
            if (Pattern.matches(pattern, input)) {
                return true;
            }
        }
        return false;
    }

    private boolean detectXSS(String input) {
        String[] xssPatterns = {
            "(?i).*(<script|javascript:|onerror=|onload=|<iframe|<object|<embed).*"
        };
        
        for (String pattern : xssPatterns) {
            if (Pattern.matches(pattern, input)) {
                return true;
            }
        }
        return false;
    }

    private boolean detectMaliciousPatterns(String input) {
        return detectSQLInjection(input) || detectXSS(input);
    }

    private PlayerSecurityData getPlayerData(Player player) {
        return playerData.computeIfAbsent(player.getUniqueId(), k -> new PlayerSecurityData());
    }

    private void kickPlayerForHacking(Player player, String reason) {
        player.kickPlayer("§c[Защита Сервера]\n\n§fВы были кикнуты за: §c" + reason + 
            "\n\n§7Если вы считаете это ошибкой, обратитесь к администрации");
        getLogger().warning("§c[Защита] Игрок " + player.getName() + " кикнут за: " + reason);
    }

    private void notifyAdmins(String message) {
        for (Player admin : Bukkit.getOnlinePlayers()) {
            if (admin.hasPermission("protection.notify")) {
                admin.sendMessage(message);
            }
        }
    }

    private void startSecurityTasks() {
        // Очистка старых данных каждые 5 минут
        Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
            long currentTime = System.currentTimeMillis();
            connectionTracker.entrySet().removeIf(entry -> 
                currentTime - entry.getValue().getLastConnection() > 300000);
            
            // Разблокировка IP через 1 час
            // В реальной системе это должно быть настраиваемо
        }, 6000L, 6000L);
        
        // Сброс счётчиков нарушений каждую минуту
        Bukkit.getScheduler().runTaskTimer(this, () -> {
            for (PlayerSecurityData data : playerData.values()) {
                data.resetCounters();
            }
        }, 1200L, 1200L);
    }

    // ==================== КЛАССЫ ДАННЫХ ====================
    
    class ConnectionData {
        private List<Long> connections = new ArrayList<>();
        
        public void addConnection() {
            connections.add(System.currentTimeMillis());
            // Удаление старых записей (старше 1 минуты)
            connections.removeIf(time -> System.currentTimeMillis() - time > 60000);
        }
        
        public int getConnectionsLastMinute() {
            return connections.size();
        }
        
        public long getLastConnection() {
            return connections.isEmpty() ? 0 : connections.get(connections.size() - 1);
        }
    }

    class PlayerSecurityData {
        private int violations = 0;
        private List<Long> commands = new ArrayList<>();
        private List<Long> clicks = new ArrayList<>();
        private List<Double> movements = new ArrayList<>();
        private Map<String, Integer> violationTypes = new HashMap<>();
        
        public void addViolation(String type) {
            violations++;
            violationTypes.put(type, violationTypes.getOrDefault(type, 0) + 1);
        }
        
        public int getViolations() {
            return violations;
        }
        
        public void addCommand() {
            commands.add(System.currentTimeMillis());
            commands.removeIf(time -> System.currentTimeMillis() - time > 1000);
        }
        
        public boolean isCommandSpam() {
            return commands.size() > maxCommandsPerSecond;
        }
        
        public void addClick() {
            clicks.add(System.currentTimeMillis());
            clicks.removeIf(time -> System.currentTimeMillis() - time > 1000);
        }
        
        public int getClicksPerSecond() {
            return clicks.size();
        }
        
        public void updateMovement(double distance) {
            movements.add(distance);
            if (movements.size() > 20) {
                movements.remove(0);
            }
        }
        
        public double getAverageSpeed() {
            if (movements.isEmpty()) return 0;
            return movements.stream().mapToDouble(Double::doubleValue).average().orElse(0);
        }
        
        public void resetCounters() {
            commands.clear();
            clicks.clear();
            if (violations > 0) violations--;
        }
    }

    public Set<String> getBlockedIPs() {
        return blockedIPs;
    }

    public void unblockIP(String ip) {
        blockedIPs.remove(ip);
    }
}
java
package ru.serverprotection;

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class ProtectionCommand implements CommandExecutor {
    
    private ServerProtectionPlugin plugin;
    
    public ProtectionCommand(ServerProtectionPlugin plugin) {
        this.plugin = plugin;
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        
        if (!sender.hasPermission("protection.admin")) {
            sender.sendMessage("§c[Защита] У вас нет прав на использование этой команды!");
            return true;
        }
        
        if (args.length == 0) {
            sendHelp(sender);
            return true;
        }
        
        switch (args[0].toLowerCase()) {
            case "reload":
                plugin.reloadConfig();
                sender.sendMessage("§a[Защита] Конфигурация перезагружена!");
                break;
                
            case "unblock":
                if (args.length < 2) {
                    sender.sendMessage("§c[Защита] Использование: /protection unblock <IP>");
                    return true;
                }
                plugin.unblockIP(args[1]);
                sender.sendMessage("§a[Защита] IP " + args[1] + " разблокирован!");
                break;
                
            case "blockedips":
                sender.sendMessage("§e[Защита] Заблокированные IP-адреса:");
                for (String ip : plugin.getBlockedIPs()) {
                    sender.sendMessage("§7- " + ip);
                }
                break;
                
            case "info":
                sender.sendMessage("§e§l[Система Защиты Сервера]");
                sender.sendMessage("§7Версия: §a1.0");
                sender.sendMessage("§7Заблокировано IP: §c" + plugin.getBlockedIPs().size());
                break;
                
            default:
                sendHelp(sender);
        }
        
        return true;
    }
    
    private void sendHelp(CommandSender sender) {
        sender.sendMessage("§e§l[Команды Защиты]");
        sender.sendMessage("§7/protection reload §f- Перезагрузить конфигурацию");
        sender.sendMessage("§7/protection unblock <IP> §f- Разблокировать IP");
        sender.sendMessage("§7/protection blockedips §f- Список заблокированных IP");
        sender.sendMessage("§7/protection info §f- Информация о системе");
    }
}
yaml
# plugin.yml
name: ServerProtection
version: 1.0
main: ru.serverprotection.ServerProtectionPlugin
api-version: 1.16
author: ServerProtection Team
description: Комплексная защита сервера от DDoS, хакеров, инъекций

commands:
  protection:
    description: Главная команда защиты
    usage: /protection <reload|unblock|blockedips|info>
    permission: protection.admin

permissions:
  protection.admin:
    description: Доступ к командам администратора
    default: op
  protection.notify:
    description: Получение уведомлений о нарушениях
    default: op
  protection.bypass:
    description: Обход проверок античита
    default: op
yaml
# config.yml
# Конфигурация защиты сервера

ddos-protection:
  enabled: true
  max-connections-per-minute: 5
  auto-block-duration: 3600 # секунды

injection-protection:
  enabled: true
  max-commands-per-second: 3
  block-sql-injection: true
  block-xss: true

anticheat:
  enabled: true
  movement-threshold: 10
  max-clicks-per-second: 20
  check-speed: true
  check-fly: true
  check-autoclick: true

antivirus:
  enabled: true
  scan-on-join: true
  block-hacked-clients: true
  suspicious-clients:
    - wurst
    - sigma
    - liquidbounce
    - aristois

notifications:
  notify-admins: true
  log-violations: true

Этот плагин предоставляет:

✅ Защита от DDoS - ограничение подключений ✅ Защита от инъекций - SQL/XSS фильтрация ✅ Античит - проверка движения, скорости, автокликера ✅ Антивирус - сканирование читерских клиентов ✅ Система уведомлений для администраторов ✅ Гибкая конфигурация

139.8k
YannY4565
OP
·last year

Топ