Вопрос Java Code - Как брать material для config.yml

LastClock

Пользователь
Сообщения
98
Создаю свой плагин на предметы (Т.к. в ExecutableItems много разной ненужной штуковин) и не понимаю как сделать так чтобы в config.yml брался предмет и плагин проверял его на наличие ошибок

Пример:
Форматирование (BB-код):
items:
  test:
    material: LEATHER_CHESTPLATE
Правильно работает

Форматирование (BB-код):
items:
  test:
    material: DIRG
Неправильно работает


Как сделать проверку на это и чтобы проверяло еще по версии? По версии имеется ввиду когда материал 1.18.2, а твоя версия сервера ниже, то пишет что материал не найден и просит переделать материал в конфигурации.

Надеюсь на вашу помощь
 
Чтобы проверить существует ли тип в ядре на котором запущен плагин, юзай что-то типо этого

Код:
        String materialName = config.getString...
        if (!EnumUtils.isValidEnum(Material.class, materialName)) {
            plugin.getLogger().info("Invalid material type: " + materialName);
        }
Спасибо, если сработает напишу
 
Java:
YamlConfiguration yamlConfiguration = // получение конфига

Material material = Material.STONE;

String materialName = yamlConfiguration.getString("material");
try {
    material = Material.valueOf(materialName)};
} catch (IllegalArgumentException e) {
    logger.warn("Материал " + materialName + " не существует");
}
 
Java:
YamlConfiguration yamlConfiguration = // получение конфига

Material material = Material.STONE;

String materialName = yamlConfiguration.getString("material");
try {
    material = Material.valueOf(materialName)};
} catch (IllegalArgumentException e) {
    logger.warn("Материал " + materialName + " не существует");
}
О спасибо великий дракоша, если сработает напишу
 
Лично я люблю пользоваться более универсальным методом. Можешь под себя подогнать и убрать дефолт значение и возвращать null
Java:
public interface EnumConstantResolver {
    static <T extends Enum<T>> T resolve(Object name, T def, Class<T> type) {
        if (!(name instanceof String s)) return def;
        T result;
        try {
            result = Enum.valueOf(type, s);
        } catch (IllegalArgumentException e) {
            Bukkit.getLogger().severe("Cannot resolve enum for type " + type + ". Input enum name: " + s);
            result = def;
        }
        return result;
    }
}

Java:
failParticle = EnumConstantResolver.resolve(section.get("particle.fail"), Particle.LAVA, Particle.class);
 
Лично я люблю пользоваться более универсальным методом. Можешь под себя подогнать и убрать дефолт значение и возвращать null
Java:
public interface EnumConstantResolver {
    static <T extends Enum<T>> T resolve(Object name, T def, Class<T> type) {
        if (!(name instanceof String s)) return def;
        T result;
        try {
            result = Enum.valueOf(type, s);
        } catch (IllegalArgumentException e) {
            Bukkit.getLogger().severe("Cannot resolve enum for type " + type + ". Input enum name: " + s);
            result = def;
        }
        return result;
    }
}

Java:
failParticle = EnumConstantResolver.resolve(section.get("particle.fail"), Particle.LAVA, Particle.class);
Можно обойтись без последнего аргумента, держу в курсе
 
Можно обойтись без последнего аргумента, держу в курсе
Конкретно у меня были моменты, когда в качестве дефолт значения надо было передавать null. Так что лично мне так удобнее было)
 
Java:
package ru.lastdev.lastitems.commands;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
import ru.lastdev.lastitems.utils.ColorUtil;
import ru.lastdev.lastitems.utils.ConfigUtil;

public class GiveCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length < 3) {
sender.sendMessage(ColorUtil.hex("&fИспользование: /lastitems give [ник] [предмет] [кол-во]"));
return true;
}
String nickname = args[0];
String itemKey = args[1];
String amountStr = args[2];
int amount;
try {
amount = Integer.parseInt(amountStr);
} catch (NumberFormatException e) {
sender.sendMessage(ColorUtil.hex("&fНекорректное количество: " + amountStr));
return true;
}
if (amount <= 0) {
sender.sendMessage(ColorUtil.hex("&fКоличество должно быть больше 0! Введите больше чем число " + args[2] + "!"));
return true;
}
ConfigUtil.ItemData itemData = ConfigUtil.itemdata.get(itemKey);
if (itemData == null) {
sender.sendMessage(ColorUtil.hex("&fПредмет '" + itemKey + "' не найден"));
return true;
}
Material material = Material.matchMaterial(itemData.material());
if (material == null) {
sender.sendMessage(ColorUtil.hex("&fНедопустимый материал: " + itemData.material()));
return true;
}
Player target = Bukkit.getPlayerExact(nickname);
if (target == null) {
sender.sendMessage(ColorUtil.hex("&fИгрок " + nickname + " не в сети"));
return true;
}
ItemStack item = new ItemStack(material, amount);
Map<Integer, ItemStack> leftover = target.getInventory().addItem(item);

if (leftover.isEmpty()) {
sender.sendMessage(ColorUtil.hex("&fУспешно выдано " + amount + "x " + itemKey));
} else {
sender.sendMessage(ColorUtil.hex("&fЧасть предметов не поместилась в инвентарь"));
}
return true;
}
}

написал вот так, спасибо всем кто помог тем что смог :)
 
Java:
package ru.lastdev.lastitems.commands;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
import ru.lastdev.lastitems.utils.ColorUtil;
import ru.lastdev.lastitems.utils.ConfigUtil;

public class GiveCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length < 3) {
sender.sendMessage(ColorUtil.hex("&fИспользование: /lastitems give [ник] [предмет] [кол-во]"));
return true;
}
String nickname = args[0];
String itemKey = args[1];
String amountStr = args[2];
int amount;
try {
amount = Integer.parseInt(amountStr);
} catch (NumberFormatException e) {
sender.sendMessage(ColorUtil.hex("&fНекорректное количество: " + amountStr));
return true;
}
if (amount <= 0) {
sender.sendMessage(ColorUtil.hex("&fКоличество должно быть больше 0! Введите больше чем число " + args[2] + "!"));
return true;
}
ConfigUtil.ItemData itemData = ConfigUtil.itemdata.get(itemKey);
if (itemData == null) {
sender.sendMessage(ColorUtil.hex("&fПредмет '" + itemKey + "' не найден"));
return true;
}
Material material = Material.matchMaterial(itemData.material());
if (material == null) {
sender.sendMessage(ColorUtil.hex("&fНедопустимый материал: " + itemData.material()));
return true;
}
Player target = Bukkit.getPlayerExact(nickname);
if (target == null) {
sender.sendMessage(ColorUtil.hex("&fИгрок " + nickname + " не в сети"));
return true;
}
ItemStack item = new ItemStack(material, amount);
Map<Integer, ItemStack> leftover = target.getInventory().addItem(item);

if (leftover.isEmpty()) {
sender.sendMessage(ColorUtil.hex("&fУспешно выдано " + amount + "x " + itemKey));
} else {
sender.sendMessage(ColorUtil.hex("&fЧасть предметов не поместилась в инвентарь"));
}
return true;
}
}

написал вот так, спасибо всем кто помог тем что смог :)
Почему бы сразу не хранить в ItemData материал?
 
Да ты видел что там под капотом ваще??? Тут наносекундами не принято разбрасываться
Какая блин нахрен разница, сколько времени будет преобразовываться строка из конфига в нужный тип данных? 0.0001 секунды или 0.0005 секунд... Все равно у тебя там не милионы строк конфига и делается это ровно 1 раз, при запуске
 
Назад
Сверху Снизу