Сборки серверов

СливПлатные

Новые сообщения

Сейчас онлайн

  • worldhipe
  • RedLine134
  • JAHED2020
  • MrLemonleak
  • 4ak4ak
  • dragxwx
  • khasanovtimur
  • sweye
  • asdasdasdusad
  • scorgme
  • Postal_08
  • Fastaer
  • Black123
  • Keryesh4ka
  • whosthis
  • uszik
  • gi2l
  • Catilka
  • crazy_f0x
  • peha
  • Merfist_ZxcS
  • Maloy under
  • 123123asd
  • pizzatop444444
  • Shalostx
  • getfl000ry
  • Hoon8773
  • FuMeng
  • consers
  • Zigono
  • katze225
  • Sebsish
  • Karton
  • Spoty
  • wexternalka
  • undefined322
  • mygamingniki123312
  • xzzzzzz
  • dmitriy.kst2
  • SIMBAY
  • Vinsent
  • Qrdx
  • Kadzerai
  • Sqeeze
  • Jarvis20015
  • qaqiiii1
  • капец
  • MINE_EXE
  • miminttto
  • WhyZerVellasskx
  • cherry4ever
  • vetribel
  • Toibit
  • NightSide777
  • kasper_xui
  • WaffleFt
  • MilfXanter
  • Саня-ItzSancho
  • savenx
  • HauserGrim
  • KILLER42
  • PasToSmith1
  • xGodstolbik2
  • limonchikx
  • Hagito
  • sveralol
  • Lors1k
  • Henddy213456
  • vitaki
  • Felson
  • Rossek2
  • Атумикс1
  • IvanBiog_Petro
  • DandyMix123
  • sqworell
  • rauharu
  • Plazmaman
  • QAZWSX
  • kurumaq
  • politmake
  • Bogdan_Sopov
  • euj3ne
  • fr1z
  • kadoru1488
  • jimer
  • aXEDFSWQRS43SD56
  • kquan
  • bvvg

Помощь Помогите пж по созданию плагинов в майнкрафт (IDE Bukkit Paper, java)

Tanri
Вставляйте код/тексты файлов под код
У меня плагин на изменения времени роста семян и деревьев.
Кто знает как сделать так, что бы значения в cfg файле изменялись (например если есть "speed: 7d", то был рост растений семян пшеницы в 7 дней, а если изменить на 1d, то 1 день, так же с другими значениями делать все под конфиг)

config.yml:
# Значения, для конфига:
# id - Айди растения
# Все существующие id растений и семян: 295 (пшеница), 361 (тыква),
# Названия растений и семян на английском: wheat_seeds (пшеница), melon_seeds (тыква),
# speed - Скорость его роста
# droping - Это категория, в которой пишем что выпадает с собирания растений.
# remove - То, что вы хотите убрать при выпадении, когда растение вырастит
# add - То, что вы хотите добавить при выпадении, когда растение вырастит

Wheat_Seeds:
id: 295
speed: 7d
droping:
remove: wheat_seeds
Melon_Seeds:
id: 362
speed: 7d
droping:
remove: melon_seeds
Plant_growth.class:
package yt.tanr1.plant_growth;

import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockGrowEvent;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.HashMap;
import java.util.Map;

public class Plant_growth extends JavaPlugin implements Listener {

// Храним время роста для конкретного ID растения
private Map<Integer, Long> growthTimes = new HashMap<>();

// Константы
private final int WHEAT_ID = Material.WHEAT.getId(); // ID блоков пшеницы
private final long WHEAT_GROWTH_TIME = 16800; // Время роста в тиках (7 дней)

@Override
public void onEnable() {
getLogger().info(Color.ORANGE + "Plugin Enabled");
getServer().getPluginManager().registerEvents(this, this);

// Инициализируем время роста прямо в коде
growthTimes.put(WHEAT_ID, WHEAT_GROWTH_TIME);
}

@EventHandler
public void onPlantGrow(BlockGrowEvent event) {
int id = event.getBlock().getType().getId();
if (growthTimes.containsKey(id)) {
event.setCancelled(true); // Отменяем обычный рост
getServer().getScheduler().runTaskLater(this, () -> {
// Здесь логика для нового роста через заданный таймаут
// Например, чтобы пшеница выросла:
event.getBlock().setType(Material.WHEAT); // Убедитесь, что в этом месте вы используете правильный тип блока
}, growthTimes.get(id));
}
}

@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
int id = event.getBlock().getType().getId();

// Проверяем, является ли блок пшеницей
if (id == WHEAT_ID) {
event.setDropItems(false); // Отменить выпадение предметов при сборе пшеницы
}
}
}
 
Последнее редактирование модератором:
totoshka
Ответ от o1-preview:

Я вижу, что вы предоставили ваш текущий код класса Plant_growth. Ваша цель — сделать так, чтобы значения скорости роста растений считывались из файла конфигурации config.yml, и изменения в этом файле влияли на поведение плагина без необходимости переписывать код.

Давайте шаг за шагом модифицируем ваш код, чтобы достичь этого.


1. Считывание значений из конфигурации

В вашем методе onEnable() вам нужно загрузить значения из config.yml и заполнить ими growthTimes.

Шаги:

  • Убедитесь, что файл config.yml загружается при старте плагина.
  • Пройдитесь по каждому разделу в конфигурации и извлеките необходимые данные.
Java:
@Override
public void onEnable() {
    getLogger().info("Plugin Enabled");
    getServer().getPluginManager().registerEvents(this, this);

    // Загружаем конфигурацию
    saveDefaultConfig();
    reloadConfig();

    // Инициализируем время роста из конфигурации
    loadGrowthTimesFromConfig();
}

2. Метод для загрузки данных из конфигурации

Создадим метод loadGrowthTimesFromConfig(), который будет считывать данные из конфигурации и заполнять growthTimes.
Java:
private void loadGrowthTimesFromConfig() {
    for (String key : getConfig().getKeys(false)) {
        ConfigurationSection plantSection = getConfig().getConfigurationSection(key);
        if (plantSection != null) {
            int id = plantSection.getInt("id");
            String speedStr = plantSection.getString("speed");

            // Парсим значение скорости в тики
            long growthTicks = parseDurationToTicks(speedStr);

            // Сохраняем в карту
            growthTimes.put(id, growthTicks);
        }
    }
}

3. Парсинг значения скорости в тики

Реализуем метод parseDurationToTicks(String durationString) для преобразования строки вида "7d" в количество тиков.
Java:
public long parseDurationToTicks(String durationString) {
    durationString = durationString.toLowerCase().trim();
    long ticks = 0;

    try {
        if (durationString.endsWith("d")) {
            String numberPart = durationString.substring(0, durationString.length() - 1);
            ticks = Long.parseLong(numberPart) * 24 * 60 * 60 * 20; // 1 день = 1728000 тиков
        } else if (durationString.endsWith("h")) {
            String numberPart = durationString.substring(0, durationString.length() - 1);
            ticks = Long.parseLong(numberPart) * 60 * 60 * 20; // 1 час = 72000 тиков
        } else if (durationString.endsWith("m")) {
            String numberPart = durationString.substring(0, durationString.length() - 1);
            ticks = Long.parseLong(numberPart) * 60 * 20; // 1 минута = 1200 тиков
        } else if (durationString.endsWith("s")) {
            String numberPart = durationString.substring(0, durationString.length() - 1);
            ticks = Long.parseLong(numberPart) * 20; // 1 секунда = 20 тиков
        } else {
            // Если нет суффикса, считаем, что это тики
            ticks = Long.parseLong(durationString);
        }
    } catch (NumberFormatException e) {
        getLogger().warning("Неверный формат времени: " + durationString);
        ticks = 0;
    }

    return ticks;
}

4. Обновление обработчика событий роста

Теперь нам нужно обновить метод onPlantGrow, чтобы он корректно работал с новыми данными.
Java:
@EventHandler
public void onPlantGrow(BlockGrowEvent event) {
    int id = event.getBlock().getType().getId();
    if (growthTimes.containsKey(id)) {
        event.setCancelled(true); // Отменяем обычный рост
        long growthTime = growthTimes.get(id);

        getServer().getScheduler().runTaskLater(this, () -> {
            // Получаем следующий этап роста растения
            Block block = event.getBlock();
            Material nextStage = getNextGrowthStage(block.getType());

            if (nextStage != null) {
                block.setType(nextStage);
            }
        }, growthTime);
    }
}

5. Метод для определения следующей стадии роста

Вам потребуется метод getNextGrowthStage(Material currentStage), чтобы определить, какое растение поставить на следующей стадии роста.
Java:
private Material getNextGrowthStage(Material currentStage) {
    // Здесь вы можете определить логику перехода между стадиями роста
    // Например, для пшеницы можно использовать enum Material по стадиям роста
    // Однако в Bukkit API стадии роста растений обычно управляются с помощью данных блока (BlockData)

    // Пример для пшеницы:
    if (currentStage == Material.WHEAT) {
        // Получаем данные о росте
        Ageable ageable = (Ageable) currentStage.createBlockData();
        if (ageable.getAge() < ageable.getMaximumAge()) {
            ageable.setAge(ageable.getAge() + 1);
            return ageable.getMaterial();
        }
    }

    // Для других растений аналогично
    return null;
}

6. Обработка данных блока (BlockData)

Современный Bukkit API рекомендует использовать BlockData вместо устаревших методов. Мы можем обновить наш код, чтобы использовать BlockData для установки возраста растения.

Обновленный код обработчика события:


Java:
@EventHandler
public void onPlantGrow(BlockGrowEvent event) {
    Block block = event.getBlock();
    Material material = block.getType();
    int id = material.getId();

    if (growthTimes.containsKey(id)) {
        event.setCancelled(true); // Отменяем обычный рост
        long growthTime = growthTimes.get(id);

        getServer().getScheduler().runTaskLater(this, () -> {
            // Увеличиваем стадию роста
            BlockData data = block.getBlockData();

            if (data instanceof Ageable) {
                Ageable ageable = (Ageable) data;
                if (ageable.getAge() < ageable.getMaximumAge()) {
                    ageable.setAge(ageable.getAge() + 1);
                    block.setBlockData(ageable);
                }
            }
        }, growthTime);
    }
}

7. Обновление обработчика события разрушения блока

Если вы хотите управлять выпадением предметов при сборе урожая, вы можете использовать BlockBreakEvent и проверять стадии роста.
Java:
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
    Block block = event.getBlock();
    Material material = block.getType();
    int id = material.getId();

    if (growthTimes.containsKey(id)) {
        BlockData data = block.getBlockData();

        if (data instanceof Ageable) {
            Ageable ageable = (Ageable) data;

            if (ageable.getAge() < ageable.getMaximumAge()) {
                // Растение еще не созрело
                event.setDropItems(false); // Отменяем выпадение
                event.getPlayer().sendMessage("Растение еще не созрело!");
            } else {
                // Растение созрело, можно настроить выпадение предметов
                // Здесь можно использовать данные из конфигурации
            }
        }
    }
}

8. Обработка выпадения предметов при сборе урожая

Чтобы управлять тем, какие предметы выпадают при сборе урожая, используйте данные из раздела droping в конфигурации.
Java:
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
    Block block = event.getBlock();
    Material material = block.getType();
    int id = material.getId();

    if (growthTimes.containsKey(id)) {
        BlockData data = block.getBlockData();

        if (data instanceof Ageable) {
            Ageable ageable = (Ageable) data;

            if (ageable.getAge() < ageable.getMaximumAge()) {
                // Растение еще не созрело
                event.setDropItems(false);
                event.getPlayer().sendMessage("Растение еще не созрело!");
            } else {
                // Растение созрело
                event.setDropItems(false); // Отменяем стандартное выпадение

                // Получаем информацию о выпадении из конфигурации
                String key = getConfigKeyById(id);
                if (key != null) {
                    ConfigurationSection plantSection = getConfig().getConfigurationSection(key);
                    if (plantSection != null) {
                        ConfigurationSection dropSection = plantSection.getConfigurationSection("droping");

                        if (dropSection != null) {
                            // Удаляем предметы из списка remove
                            List<String> removeItems = dropSection.getStringList("remove");
                            // Добавляем предметы из списка add
                            List<String> addItems = dropSection.getStringList("add");

                            // Удаление предметов (если нужно)
                            // В вашем случае вы отменили стандартное выпадение, поэтому это может быть не нужно

                            // Добавление новых предметов
                            for (String itemName : addItems) {
                                Material dropMaterial = Material.getMaterial(itemName.toUpperCase());
                                if (dropMaterial != null) {
                                    block.getWorld().dropItemNaturally(block.getLocation(), new ItemStack(dropMaterial));
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
Метод для получения ключа конфигурации по ID
Java:
private String getConfigKeyById(int id) {
    for (String key : getConfig().getKeys(false)) {
        if (getConfig().getInt(key + ".id") == id) {
            return key;
        }
    }
    return null;
}

9. Корректировка файла конфигурации

Убедитесь, что ваш config.yml имеет правильную структуру.
YAML:
Wheat_Seeds:
  id: 59
  speed: 7d
  droping:
    remove:
      - wheat_seeds
    add:
      - wheat
Melon_Seeds:
  id: 105
  speed: 7d
  droping:
    remove:
      - melon_seeds
    add:
      - melon_slice
Примечание: Используйте правильные ID блоков и названия материалов. Например, для пшеницы в виде блока используется Material.WHEAT, который имеет ID 59, а для семян — Material.WHEAT_SEEDS.

10. Обновление устаревших методов

Обратите внимание, что метод getId() устарел. Лучше использовать Material напрямую или использовать NamespacedKey для идентификации материалов.

Замена:

Java:
private Map<Material, Long> growthTimes = new HashMap<>();
И везде, где вы используете ID, замените на Material.

Пример:

Java:
private void loadGrowthTimesFromConfig() {
    for (String key : getConfig().getKeys(false)) {
        ConfigurationSection plantSection = getConfig().getConfigurationSection(key);
        if (plantSection != null) {
            String materialName = plantSection.getString("material");
            Material material = Material.getMaterial(materialName.toUpperCase());

            if (material != null) {
                String speedStr = plantSection.getString("speed");
                long growthTicks = parseDurationToTicks(speedStr);
                growthTimes.put(material, growthTicks);
            } else {
                getLogger().warning("Неизвестный материал: " + materialName);
            }
        }
    }
}
И в обработчиках событий:
Java:
@EventHandler
public void onPlantGrow(BlockGrowEvent event) {
    Material material = event.getBlock().getType();

    if (growthTimes.containsKey(material)) {
        // Остальной код
    }
}

11. Полный обновленный код класса​

Java:
package yt.tanr1.plant_growth;

import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockGrowEvent;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Plant_growth extends JavaPlugin implements Listener {

    // Храним время роста для конкретного материала растения
    private Map<Material, Long> growthTimes = new HashMap<>();

    @Override
    public void onEnable() {
        getLogger().info("Plugin Enabled");
        getServer().getPluginManager().registerEvents(this, this);

        // Загружаем конфигурацию
        saveDefaultConfig();
        reloadConfig();

        // Инициализируем время роста из конфигурации
        loadGrowthTimesFromConfig();
    }

    private void loadGrowthTimesFromConfig() {
        for (String key : getConfig().getKeys(false)) {
            ConfigurationSection plantSection = getConfig().getConfigurationSection(key);
            if (plantSection != null) {
                String materialName = plantSection.getString("material");
                Material material = Material.getMaterial(materialName.toUpperCase());

                if (material != null) {
                    String speedStr = plantSection.getString("speed");
                    long growthTicks = parseDurationToTicks(speedStr);
                    growthTimes.put(material, growthTicks);
                } else {
                    getLogger().warning("Неизвестный материал: " + materialName);
                }
            }
        }
    }

    public long parseDurationToTicks(String durationString) {
        durationString = durationString.toLowerCase().trim();
        long ticks = 0;

        try {
            if (durationString.endsWith("d")) {
                String numberPart = durationString.substring(0, durationString.length() - 1);
                ticks = Long.parseLong(numberPart) * 24 * 60 * 60 * 20;
            } else if (durationString.endsWith("h")) {
                String numberPart = durationString.substring(0, durationString.length() - 1);
                ticks = Long.parseLong(numberPart) * 60 * 60 * 20;
            } else if (durationString.endsWith("m")) {
                String numberPart = durationString.substring(0, durationString.length() - 1);
                ticks = Long.parseLong(numberPart) * 60 * 20;
            } else if (durationString.endsWith("s")) {
                String numberPart = durationString.substring(0, durationString.length() - 1);
                ticks = Long.parseLong(numberPart) * 20;
            } else {
                ticks = Long.parseLong(durationString);
            }
        } catch (NumberFormatException e) {
            getLogger().warning("Неверный формат времени: " + durationString);
            ticks = 0;
        }

        return ticks;
    }

    @EventHandler
    public void onPlantGrow(BlockGrowEvent event) {
        Block block = event.getBlock();
        Material material = block.getType();

        if (growthTimes.containsKey(material)) {
            event.setCancelled(true); // Отменяем обычный рост
            long growthTime = growthTimes.get(material);

            new BukkitRunnable() {
                @Override
                public void run() {
                    BlockData data = block.getBlockData();

                    if (data instanceof Ageable) {
                        Ageable ageable = (Ageable) data;
                        if (ageable.getAge() < ageable.getMaximumAge()) {
                            ageable.setAge(ageable.getAge() + 1);
                            block.setBlockData(ageable);
                        }
                    }
                }
            }.runTaskLater(this, growthTime);
        }
    }

    @EventHandler
    public void onBlockBreak(BlockBreakEvent event) {
        Block block = event.getBlock();
        Material material = block.getType();

        if (growthTimes.containsKey(material)) {
            BlockData data = block.getBlockData();

            if (data instanceof Ageable) {
                Ageable ageable = (Ageable) data;

                if (ageable.getAge() < ageable.getMaximumAge()) {
                    event.setDropItems(false);
                    event.getPlayer().sendMessage("Растение еще не созрело!");
                } else {
                    event.setDropItems(false);

                    String key = getConfigKeyByMaterial(material);
                    if (key != null) {
                        ConfigurationSection plantSection = getConfig().getConfigurationSection(key);
                        if (plantSection != null) {
                            ConfigurationSection dropSection = plantSection.getConfigurationSection("droping");

                            if (dropSection != null) {
                                List<String> addItems = dropSection.getStringList("add");

                                for (String itemName : addItems) {
                                    Material dropMaterial = Material.getMaterial(itemName.toUpperCase());
                                    if (dropMaterial != null) {
                                        block.getWorld().dropItemNaturally(block.getLocation(), new ItemStack(dropMaterial));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private String getConfigKeyByMaterial(Material material) {
        for (String key : getConfig().getKeys(false)) {
            String materialName = getConfig().getString(key + ".material");
            if (materialName != null && material == Material.getMaterial(materialName.toUpperCase())) {
                return key;
            }
        }
        return null;
    }
}

12. Обновленный файл конфигурации​

YAML:
Wheat_Seeds:
  material: WHEAT
  speed: 7d
  droping:
    remove:
      - WHEAT_SEEDS
    add:
      - WHEAT
Melon_Seeds:
  material: MELON_STEM
  speed: 7d
  droping:
    remove:
      - MELON_SEEDS
    add:
      - MELON_SLICE

Примечания:
  • Используйте Material вместо ID. В современном Bukkit API рекомендуется использовать Material напрямую, так как ID могут меняться и устарели.
  • Обратите внимание на регистры. Названия материалов должны быть в верхнем регистре, чтобы метод Material.getMaterial() мог их распознать.
  • Проверьте доступность материалов. Убедитесь, что используемые материалы существуют в вашей версии сервера.
  • Используйте BlockData и Ageable. Это современные способы управления состояниями блоков в Bukkit API.
  • Обработка ошибок. Добавьте проверки и обработку возможных ошибок, чтобы избежать сбоев плагина.
  • Перезагрузка конфигурации. Если вы хотите менять конфигурацию без перезагрузки сервера, добавьте команду или механизм для перезагрузки конфигурации во время работы плагина.
 
ВерхНиз