General
Protocol 79
FantomProject
A
You
Paper
Защита сервера от Ddos атак, хакерских атак, инъекции, антивирус, античит.
ru
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