1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите "Error occurred while enabling""

Тема в разделе "Разработка плагинов для новичков", создана пользователем cradles, 6 янв 2024.

  1. Автор темы
    cradles

    cradles Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Mattgyve1990
    здравствуйте, пытаюсь сделать плагин на регенерацию территории, но при запуске плагина на сервере происходит такая ошибка:

    Код:
    [19:57:03] [Server thread/INFO]: [MArenas] Enabling MArenas v1.0.0
    [19:57:04] [Server thread/INFO]: [MArenas] §aPlugin has Enabled
    [19:57:04] [Server thread/ERROR]: Error occurred while enabling MArenas v1.0.0 (Is it up to date?)
    java.lang.NullPointerException: null
        at java.util.Objects.requireNonNull(Unknown Source) ~[?:?]
        at me.matt.marenas.MArenas.onEnable(MArenas.java:31) ~[MArenas.jar:?]
        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:281) ~[paper-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at io.papermc.paper.plugin.manager.PaperPluginInstanceManager.enablePlugin(PaperPluginInstanceManager.java:189) ~[paper-1.20.1.jar:git-Paper-196]
        at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.enablePlugin(PaperPluginManagerImpl.java:104) ~[paper-1.20.1.jar:git-Paper-196]
        at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:507) ~[paper-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.craftbukkit.v1_20_R1.CraftServer.enablePlugin(CraftServer.java:642) ~[paper-1.20.1.jar:git-Paper-196]
        at org.bukkit.craftbukkit.v1_20_R1.CraftServer.enablePlugins(CraftServer.java:553) ~[paper-1.20.1.jar:git-Paper-196]
        at net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:635) ~[paper-1.20.1.jar:git-Paper-196]
        at net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:434) ~[paper-1.20.1.jar:git-Paper-196]
        at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:308) ~[paper-1.20.1.jar:git-Paper-196]
        at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1100) ~[paper-1.20.1.jar:git-Paper-196]
        at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:317) ~[paper-1.20.1.jar:git-Paper-196]
        at java.lang.Thread.run(Unknown Source) ~[?:?]
    [19:57:04] [Server thread/INFO]: [MArenas] Disabling MArenas v1.0.0
    [19:57:04] [Server thread/INFO]: [MArenas] §cPlugin has Disabled

    MArenas (main class):
    Код:
    package me.matt.marenas;
    
    import me.matt.marenas.command.ZoneManager;
    import me.matt.marenas.command.ZoneRegenerator;
    import me.matt.marenas.command.ZoneSelection;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.event.Listener;
    import org.bukkit.ChatColor;
    import org.bukkit.plugin.java.JavaPlugin;
    import me.matt.marenas.command.MACommand;
    import me.matt.marenas.command.Zone;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.Objects;
    import java.util.logging.Level;
    
    public final class MArenas extends JavaPlugin implements Listener {
        private FileConfiguration config;
    
        @Override
        public void onEnable() {
            loadConfig();
            getLogger().info(ChatColor.GREEN + "Plugin has Enabled");
            ZoneManager zoneManager = new ZoneManager(this);
            ZoneSelection zoneSelection = new ZoneSelection(zoneManager);
            ZoneRegenerator zoneRegenerator = new ZoneRegenerator(this, zoneManager);
    
            getServer().getPluginManager().registerEvents(zoneSelection, this);
            Objects.requireNonNull(getCommand("ma")).setExecutor(new MACommand(zoneManager));
        }
    
        @Override
        public void onDisable() {
            saveConfig();
            getLogger().info(ChatColor.RED + "Plugin has Disabled");
        }
    
        private void loadConfig() {
            File configFile = new File(getDataFolder(), "config.yml");
            if (!configFile.exists()) {
                saveDefaultConfig();
            }
            config = YamlConfiguration.loadConfiguration(configFile);
        }
    
        public void saveConfig() {
            File configFile = new File(getDataFolder(), "config.yml");
            try {
                config.save(configFile);
            } catch (IOException e) {
                getLogger().log(Level.SEVERE, "Could not save config to " + configFile, e);
            }
        }
    }
    MACommand:
    Код:
    package me.matt.marenas.command;
    
    import me.matt.marenas.command.Zone;
    import me.matt.marenas.command.ZoneManager;
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    
    public class MACommand implements CommandExecutor {
        private final ZoneManager zoneManager;
    
        public MACommand(ZoneManager zoneManager) {
            this.zoneManager = zoneManager;
        }
    
        @Override
        public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
            if (!(sender instanceof Player)) {
                sender.sendMessage(ChatColor.RED + "Команда доступна только для игроков");
                return true;
            }
    
            Player player = (Player) sender;
    
            if (args.length == 0) {
                player.sendMessage(ChatColor.RED + "Используйте /ma help для получения списка команд");
                return true;
            }
    
            switch (args[0].toLowerCase()) {
                case "create":
                    if (args.length < 2) {
                        player.sendMessage(ChatColor.RED + "Используйте /ma create <название зоны>");
                        return true;
                    }
    
                    String name = args[1];
                    if (zoneManager.getZones().containsKey(name)) {
                        player.sendMessage(ChatColor.RED + "Зона с таким именем уже существует");
                        return true;
                    }
    
                    Zone zone = new Zone(name, player.getWorld(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ());
                    zoneManager.addZone(zone);
                    player.sendMessage(ChatColor.GREEN + "Зона " + name + " успешно создана");
                    break;
    
                case "delete":
                    if (args.length < 2) {
                        player.sendMessage(ChatColor.RED + "Используйте /ma delete <название зоны>");
                        return true;
                    }
    
                    String zoneName = args[1];
                    if (!zoneManager.getZones().containsKey(zoneName)) {
                        player.sendMessage(ChatColor.RED + "Зона с таким именем не найдена");
                        return true;
                    }
    
                    zoneManager.getZones().remove(zoneName);
                    player.sendMessage(ChatColor.GREEN + "Зона " + zoneName + " успешно удалена");
                    break;
    
                case "list":
                    player.sendMessage(ChatColor.YELLOW + "Список зон:");
                    for (Zone z : zoneManager.getZones().values()) {
                        player.sendMessage(ChatColor.YELLOW + "- " + z.getName());
                    }
                    break;
    
                default:
                    player.sendMessage(ChatColor.RED + "Неизвестная команда. Используйте /ma help для получения списка команд");
                    break;
            }
    
            return true;
        }
    }
    Zone:
    Код:
    package me.matt.marenas.command;
    
    import org.bukkit.World;
    
    public class Zone {
        private final String name;
        private final World world;
        private final int x1, y1, z1, x2, y2, z2;
    
        public Zone(String name, World world, int x1, int y1, int z1, int x2, int y2, int z2) {
            this.name = name;
            this.world = world;
            this.x1 = Math.min(x1, x2);
            this.y1 = Math.min(y1, y2);
            this.z1 = Math.min(z1, z2);
            this.x2 = Math.max(x1, x2);
            this.y2 = Math.max(y1, y2);
            this.z2 = Math.max(z1, z2);
        }
    
        public String getName() {
            return name;
        }
    
        public World getWorld() {
            return world;
        }
    
        public int getX1() {
            return x1;
        }
    
        public int getY1() {
            return y1;
        }
    
        public int getZ1() {
            return z1;
        }
    
        public int getX2() {
            return x2;
        }
    
        public int getY2() {
            return y2;
        }
    
        public int getZ2() {
            return z2;
        }
    }
    
    
    Код:
    package me.matt.marenas.command;
    
    import org.bukkit.World;
    
    public class Zone {
        private final String name;
        private final World world;
        private final int x1, y1, z1, x2, y2, z2;
    
        public Zone(String name, World world, int x1, int y1, int z1, int x2, int y2, int z2) {
            this.name = name;
            this.world = world;
            this.x1 = Math.min(x1, x2);
            this.y1 = Math.min(y1, y2);
            this.z1 = Math.min(z1, z2);
            this.x2 = Math.max(x1, x2);
            this.y2 = Math.max(y1, y2);
            this.z2 = Math.max(z1, z2);
        }
    
        public String getName() {
            return name;
        }
    
        public World getWorld() {
            return world;
        }
    
        public int getX1() {
            return x1;
        }
    
        public int getY1() {
            return y1;
        }
    
        public int getZ1() {
            return z1;
        }
    
        public int getX2() {
            return x2;
        }
    
        public int getY2() {
            return y2;
        }
    
        public int getZ2() {
            return z2;
        }
    }
    
    
    ZoneManager:
    Код:
    package me.matt.marenas.command;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.World;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockState;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.plugin.java.JavaPlugin;
    import me.matt.marenas.MArenas;
    import org.bukkit.scheduler.BukkitTask;
    
    import java.io.*;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.logging.Level;
    
    public class ZoneManager {
        private final JavaPlugin plugin;
        private final Map<String, Zone> zones = new HashMap<>();
        private final BukkitTask regenTask;
    
        public ZoneManager(JavaPlugin plugin) {
            this.plugin = plugin;
            this.regenTask = Bukkit.getScheduler().runTaskTimer(plugin, this::regenerateZones, 20L * 60 * 30, 20L * 60 * 30);
        }
    
        public void addZone(Zone zone) {
            zones.put(zone.getName(), zone);
        }
    
        public Map<String, Zone> getZones() {
            return zones;
        }
    
        private void regenerateZones() {
            for (Zone zone : zones.values()) {
                World world = zone.getWorld();
                int x1 = zone.getX1();
                int y1 = zone.getY1();
                int z1 = zone.getZ1();
                int x2 = zone.getX2();
                int y2 = zone.getY2();
                int z2 = zone.getZ2();
    
                // Загружаем сохраненные блоки из файла
                File blocksFile = new File(plugin.getDataFolder(), zone.getName() + ".dat");
                if (!blocksFile.exists()) {
                    plugin.getLogger().warning("Файл блоков для зоны " + zone.getName() + " не найден");
                    continue;
                }
    
                Map<Location, BlockState> originalBlocks = new HashMap<>();
                try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(blocksFile))) {
                    originalBlocks = (Map<Location, BlockState>) in.readObject();
                } catch (IOException | ClassNotFoundException e) {
                    plugin.getLogger().log(Level.SEVERE, "Ошибка чтения файла блоков для зоны " + zone.getName(), e);
                    continue;
                }
    
                // Восстанавливаем сохраненные блоки в зоне
                for (Map.Entry<Location, BlockState> entry : originalBlocks.entrySet()) {
                    Location location = entry.getKey();
                    BlockState state = entry.getValue();
                    Block block = location.getBlock();
                    state.update(true, false);
                }
            }
        }
    
        public void stop() {
            regenTask.cancel();
        }
    }
    ZoneRegenerator:
    Код:
    package me.matt.marenas.command;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.World;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockState;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.scheduler.BukkitTask;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.logging.Level;
    
    public class ZoneRegenerator {
        private final ZoneManager zoneManager;
        private final JavaPlugin plugin;
        private final BukkitTask regenTask;
    
        public ZoneRegenerator(JavaPlugin plugin, ZoneManager zoneManager) {
            this.plugin = plugin;
            this.zoneManager = zoneManager;
            this.regenTask = Bukkit.getScheduler().runTaskTimer(plugin, this::regenerateZones, 20L * 60 * 30, 20L * 60 * 30);
        }
    
        public void stop() {
            regenTask.cancel();
        }
    
        private void regenerateZones() {
            for (Zone zone : zoneManager.getZones().values()) {
                World world = zone.getWorld();
                int x1 = zone.getX1();
                int y1 = zone.getY1();
                int z1 = zone.getZ1();
                int x2 = zone.getX2();
                int y2 = zone.getY2();
                int z2 = zone.getZ2();
    
                Map<Location, BlockState> originalBlocks = new HashMap<>();
                for (int x = x1; x <= x2; x++) {
                    for (int y = y1; y <= y2; y++) {
                        for (int z = z1; z <= z2; z++) {
                            Location location = new Location(world, x, y, z);
                            Block block = location.getBlock();
                            BlockState state = block.getState();
                            originalBlocks.put(location, state);
                        }
                    }
                }
    
                File blocksFile = new File(plugin.getDataFolder(), zone.getName() + ".dat");
                try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(blocksFile))) {
                    out.writeObject(originalBlocks);
                } catch (IOException e) {
                    plugin.getLogger().log(Level.SEVERE, "Error saving blocks for zone " + zone.getName(), e);
                }
    
                FileConfiguration config = YamlConfiguration.loadConfiguration(blocksFile);
                for (String key : config.getKeys(false)) {
                    Location location = (Location) config.get(key + ".location");
                    BlockState state = (BlockState) config.get(key + ".state");
                    state.update(true, false);
                }
            }
        }
    }
    Надеюсь на помощь форума, ибо идей как чинить у меня уже нет..
     
  2. Автор темы
    cradles

    cradles Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Mattgyve1990
    ZoneSelection:
    Код:
    package me.matt.marenas.command;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.World;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockFace;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.*********ventory.ItemStack;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.scheduler.BukkitRunnable;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    import org.bukkit.event.Listener;
    import org.bukkit.ChatColor;
    
    public class ZoneSelection implements Listener {
        private final ZoneManager zoneManager;
    
        private final Map<UUID, Location> firstPoints = new HashMap<>();
        private final Map<UUID, Location> secondPoints = new HashMap<>();
    
        public ZoneSelection(ZoneManager zoneManager) {
            this.zoneManager = zoneManager;
        }
    
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent event) {
            Player player = event.getPlayer();
            ItemStack item = event.getItem();
            if (item == null || item.getType() != Material.GOLDEN_SHOVEL) {
                return;
            }
    
            if (!player.hasPermission("myplugin.selectzone")) {
                player.sendMessage(ChatColor.RED + "You do not have permission to select zones.");
                return;
            }
    
            Block block = event.getClickedBlock();
            if (block == null) {
                return;
            }
    
            UUID playerId = player.getUniqueId();
            Location location = block.getLocation();
    
            if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
                firstPoints.put(playerId, location);
                player.sendMessage(ChatColor.GREEN + "First point set to " + location.getBlockX() + ", " + location.getBlockY() + ", " + location.getBlockZ() + ".");
            } else if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                secondPoints.put(playerId, location);
                player.sendMessage(ChatColor.GREEN + "Second point set to " + location.getBlockX() + ", " + location.getBlockY() + ", " + location.getBlockZ() + ".");
            }
    
            if (firstPoints.containsKey(playerId) && secondPoints.containsKey(playerId)) {
                Location first = firstPoints.get(playerId);
                Location second = secondPoints.get(playerId);
                World world = first.getWorld();
                int x1 = first.getBlockX();
                int y1 = first.getBlockY();
                int z1 = first.getBlockZ();
                int x2 = second.getBlockX();
                int y2 = second.getBlockY();
                int z2 = second.getBlockZ();
                String name = "zone" + (zoneManager.getZones().size() + 1);
                Zone zone = new Zone(name, world, x1, y1, z1, x2, y2, z2);
                zoneManager.addZone(zone);
                player.sendMessage(ChatColor.GREEN + "Zone " + name + " created.");
                firstPoints.remove(playerId);
                secondPoints.remove(playerId);
            }
        }
    }
    
     
  3. FeniksDEV

    FeniksDEV Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    Feniksovich
    Покажи plugin.yml, емае.
     
  4. Автор темы
    cradles

    cradles Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Mattgyve1990
    Код:
    name: MArenas
    version: '1.0.0'
    main: me.matt.marenas.MArenas
    api-version: '1.20'
    authors: [Mattgyve1990]
    description: saves a certain allocated territory, and after a certain time restores it if it has been destroyed
    commands:
      ma:
        description: Main command for MArenas plugin
        usage: /<command> [create|delete|list]
        permission: marenas.use
    извиняюсь, забыл
     
  5. FeniksDEV

    FeniksDEV Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    Feniksovich
    В «ma» нигде нет кириллических букв, например?
     
  6. NuaN

    NuaN Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    NuaN
    Хм... очень интересно. Плагин почему-то не видит команду, хотя она есть...
    У меня пока что два варианта:
    1. Название команды слишком короткое или занято (хотя врядли)
    2. В plugin.yml, а именно в usage убрать разные символы (может из-за <>[|] плагин пропускает эту команду)
     
  7. Автор темы
    cradles

    cradles Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Mattgyve1990
    Код:
    name: MArenas
    version: '1.0.0'
    main: me.matt.marenas.MArenas
    api-version: '1.20'
    authors: [Mattgyve1990]
    description: saves a certain allocated territory, and after a certain time restores it if it has been destroyed
    commands:
      ma:
        description: Create, Delete, List for arenas
        usage: /command create delete list
        permission: marenas.use
    сделал так, не помогло:(
     
  8. Автор темы
    cradles

    cradles Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Mattgyve1990
    я не особо понял, в каком плане?
    есть например такое:
    Код:
      Map<Location, BlockState> originalBlocks = new HashMap<>();
                try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(blocksFile))) {
                    originalBlocks = (Map<Location, BlockState>) in.readObject();
                } catch (IOException | ClassNotFoundException e) {
                    plugin.getLogger().log(Level.SEVERE, "Ошибка чтения файла блоков для зоны " + zone.getName(), e);
                    continue;
                }
    и такое:

    Код:
                case "list":
                    player.sendMessage(ChatColor.YELLOW + "Список зон:");
                    for (Zone z : zoneManager.getZones().values()) {
                        player.sendMessage(ChatColor.YELLOW + "- " + z.getName());
                    }
                    break;
     
  9. FeniksDEV

    FeniksDEV Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    Feniksovich
    Нет, я не про код вовсе. Может быть в коде имя команды написано английскими буквами (латинскими): "ma", а в plugin.yml русскими (кириллическими): "mа" (здесь "a" – кириллическая). Нужно переписать в обоих местах название команды, убедившись, что используется английская раскладка.
    ---
    Впрочем, я сейчас и сам проверил (почему-то не догадался раньше :)) – в обоих местах буквы латинские, как нужно.

    Ну тогда попробуй открыть скомпилированный .jar каким-нибудь архиватором и посмотри, что находится в plugin.yml уже в нем.
     
  10. Автор темы
    cradles

    cradles Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Mattgyve1990
    открыл через winrar, зашел в файл и в прочем как должно быть так и есть:
    upload_2024-1-6_20-46-10.png
     
  11. FeniksDEV

    FeniksDEV Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    Feniksovich
    Ага, paper-plugin.yml. Ну тогда:
    «Paper plugins do not use the commands field to register commands. This means that you do not need to include all of your commands in the paper-plugin.yml file. Instead, you can register commands using the command map».
     
  12. Автор темы
    cradles

    cradles Участник Пользователь

    Баллы:
    31
    Имя в Minecraft:
    Mattgyve1990
    мне нужно регистрировать команду с помощью getCommandMap? верно?
     
  13. NuaN

    NuaN Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    NuaN
    Верно
     
  14. FeniksDEV

    FeniksDEV Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    Feniksovich
    Если хочется использовать новомодный paper-plugin.yml, то да (но это скорее всего потребует еще каких-нибудь изменений в коде).
     
  15. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Да не потребует особо.
    Правда менеджеры плагинов до сих пор не способны в рантайме перезагружать Paper-плагины. Но, к счастью, это особо часто и не нужно
     
  16. FeniksDEV

    FeniksDEV Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    Feniksovich
    PlugMan'ы всякие?) Зло жеж.
     
    Последнее редактирование: 6 янв 2024
  17. Dymeth

    Dymeth Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Не бывает в этом мире ни абсолютного добра, ни абсолютного зла.
    Когда на проде в пик онлайна плагин ведёт себя неадекватно - нет ничего лучше, чем просто его отгрузить или перезагрузить для хотфикса проблемы.
    С другой стороны, на тестовом сервере тоже бывает удобно выполнять горячую перезагрузку для применения новой версии или обновления конфига, если отдельной команды для этого нет.
    Естественно, в неумелых руках менеджеры плагинов приведут к проблемам. Но если пользоваться с умом, то пользы от этого всё же больше, чем вреда
     
  18. Кaктуc

    Кaктуc Участник Пользователь

    Баллы:
    36
    Имя в Minecraft:
    SniperAndTrapper
    та нормально
     

Поделиться этой страницей