Помогите [1.19.2] Опять neverlessy, опять инвентари :(

neverlessy

Новичок
Пользователь
Баллы
21
Имя в Minecraft
neverlessy
У меня есть инвентарь, при открытии в лор записываю значение перменной bool из yaml конфигурации..

PHP:
config.getBoolean("chat.request.local")

При открытии инвентаря создается обьект типа FileConfiguration, в который пихается мой файл

PHP:
private static FileConfiguration config;
...
    public ChatSettingsMenu(Player player) {
        this.inventory = Bukkit.createInventory(this, 9 * 3, "Настройки чата");
        this.config = YamlConfiguration.loadConfiguration(new File("plugins//Lithium//players//" + player.getUniqueId() + ".yml"));
        addItemsToInventory(player);

        player.openInventory(getInventory());
    }

Затем при нажатии на определенный слот пытаюсь изменить значение и обновить инвентарь. Ничего не происходит, никаких ошибок. Listener зареган в мейн классе

PHP:
    @EventHandler
    public void onInventoryClickEvent(InventoryClickEvent event) {
        Inventory inv = event.getInventory();
        Player player = (Player) event.getWhoClicked();
        if(inv.getHolder() instanceof ChatSettingsMenu) {
            if(event.getRawSlot() == 11) {
                config.set("chat.request.local", Boolean.valueOf(false));
                player.updateInventory();
            }
            event.setCancelled(true);
        }
    }

Как регаются ивенты у меня:
upload_2022-11-2_17-42-35.png
upload_2022-11-2_17-42-59.png

Вообщем не могу изменить переменную.
 
да, когда учил джаву я больше всего шароебился во время лекций по коллекциям и работой с файлами :)
 
А что именно должно происходить? Изменение настройки уже в файле конфига? Тогда FileConfiguration#save(File).
 
Но все равно updateInventory не работает, т.е если заново открыть инвентарь - значение поменяется, но сразу при нажатии - нет
Предположу, что addItemsToInventory у тебя отвечает за заполнение инвентаря. Он у тебя ведь только при создании инвентаря вызывается? Соответственно, нужно повторно перед updateInventory.
 
Предположу, что addItemsToInventory у тебя отвечает за заполнение инвентаря. Он у тебя ведь только при создании инвентаря вызывается? Соответственно, нужно повторно перед updateInventory.
Так и делаю. Не работает
 
Судя по всему, Player#updateInventory() не влияет на инвентари, кроме инвентаря непосредственно игрока, так что толку от метода не много.
Мне кажется, дело в том, что происходит это все в InventoryClickEvent, и при этом он отменяется. Думаю, стоит попробовать отложить обновление предметов меню на тик.
 
Судя по всему, Player#updateInventory() не влияет на инвентари, кроме инвентаря непосредственно игрока, так что толку от метода не много.
Мне кажется, дело в том, что происходит это все в InventoryClickEvent, и при этом он отменяется. Думаю, стоит попробовать отложить обновление предметов меню на тик.
Не, все равно что-то не то. Щас буду заново все делать по другому
 
Дебаг, смотри что где и когда выводит, так придёшь к ответу.
 
Вопрос к знатокам, как будет правильней поступить.

Делать HashMap<UUID, Inventory> или
HashMap<UUID, ArrayList<Inventory>>, видел такие реализации. Не могу понять для чего, в майнкрафте же игрок может открыть максимум 1 инвентарь?
 
Ну вообщем сделал вот так. Вроде если разные игроки используют - все нормально. Сделайте ревью и скажите что тут не так и какие могут быть проблемы.

PHP:
public class ChatSettingsMenu implements Listener, InventoryHolder {

    private Inventory inventory;

    private int[] borders = new int[] {0,1,2,3,4,5,6,7,8,9,10,16,17,18,19,20,21,22,23,24,25,26};
    private static HashMap<UUID, Inventory> menusOpen = new HashMap<UUID, Inventory>();

    public ChatSettingsMenu(Player player) {
        this.inventory = Bukkit.createInventory(null, 9 * 3, "Настройка чата");

        setItemClot(new ItemStack(Material.BLACK_STAINED_GLASS_PANE), 5);

        menusOpen.put(player.getUniqueId(), getInventory());
        player.openInventory(menusOpen.get(player.getUniqueId()));
    }

@EventHandler
public void onPlayerCloseInventory(InventoryCloseEvent event) {
    if(event.getInventory().getHolder() == menusOpen.get(event.getPlayer().getUniqueId()).getHolder()) {
        HashMap<UUID, Inventory> fuckConcurent = menusOpen;
        for(Map.Entry<UUID, Inventory> entry : fuckConcurent.entrySet()) {
            UUID key = entry.getKey();
            Inventory value = entry.getValue();
            if(key == event.getPlayer().getUniqueId()) {
                event.getPlayer().sendMessage(MessageTypes.SUCCESS.getPrefix() + "Удалил из hashmap игрока: §b" + Bukkit.getPlayer(key).getName());
                menusOpen.remove(event.getPlayer().getUniqueId());
            }
        }
    }
}
    public ChatSettingsMenu() {} // Конструктор заглушка для регистрации события в mainclass


    public void setItemClot(ItemStack stack, int slot) {
        this.inventory.setItem(slot, stack);
    }

    @EventHandler
    public void onInventoryClickEvent(InventoryClickEvent event) {
        if(event.getInventory().getHolder() == menusOpen.get(event.getWhoClicked().getUniqueId()).getHolder()) {
            switch (event.getRawSlot()) {
                case 5:
                    event.getWhoClicked().sendMessage("Вы нажали на слот 5! Добавляю вещь в инвентарь!");
                    event.getWhoClicked().getInventory().addItem(new ItemStack(Material.NETHERITE_SCRAP, 16));
                    break;
                default:
                    event.getWhoClicked().sendMessage("Вы нажали на другой слот!");
                    break;
            }
            event.setCancelled(true);
        }
    }

    @EventHandler
    public void onInventoryDragEvent(InventoryDragEvent event) {
        if(event.getInventory().getHolder() == menusOpen.get(event.getWhoClicked().getUniqueId()).getHolder()) {
            event.setCancelled(true);
        }
    }

    @NotNull
    @Override
    public Inventory getInventory() {
        return this.inventory;
    }
}
 
Последнее редактирование:
Ну вообщем сделал вот так. Вроде если разные игроки используют - все нормально. Сделайте ревью и скажите что тут не так и какие могут быть проблемы.

PHP:
public class ChatSettingsMenu implements Listener, InventoryHolder {

    private Inventory inventory;

    private int[] borders = new int[] {0,1,2,3,4,5,6,7,8,9,10,16,17,18,19,20,21,22,23,24,25,26};
    private static HashMap<UUID, Inventory> menusOpen = new HashMap<UUID, Inventory>();

    public ChatSettingsMenu(Player player) {
        this.inventory = Bukkit.createInventory(null, 9 * 3, "Настройка чата");

        setItemClot(new ItemStack(Material.BLACK_STAINED_GLASS_PANE), 5);

        menusOpen.put(player.getUniqueId(), getInventory());
        player.openInventory(menusOpen.get(player.getUniqueId()));
    }

@EventHandler
public void onPlayerCloseInventory(InventoryCloseEvent event) {
    if(event.getInventory().getHolder() == menusOpen.get(event.getPlayer().getUniqueId()).getHolder()) {
        HashMap<UUID, Inventory> fuckConcurent = menusOpen;
        for(Map.Entry<UUID, Inventory> entry : fuckConcurent.entrySet()) {
            UUID key = entry.getKey();
            Inventory value = entry.getValue();
            if(key == event.getPlayer().getUniqueId()) {
                event.getPlayer().sendMessage(MessageTypes.SUCCESS.getPrefix() + "Удалил из hashmap игрока: §b" + Bukkit.getPlayer(key).getName());
                menusOpen.remove(event.getPlayer().getUniqueId());
            }
        }
    }
}
    public ChatSettingsMenu() {} // Конструктор заглушка для регистрации события в mainclass


    public void setItemClot(ItemStack stack, int slot) {
        this.inventory.setItem(slot, stack);
    }

    @EventHandler
    public void onInventoryClickEvent(InventoryClickEvent event) {
        if(event.getInventory().getHolder() == menusOpen.get(event.getWhoClicked().getUniqueId()).getHolder()) {
            switch (event.getRawSlot()) {
                case 5:
                    event.getWhoClicked().sendMessage("Вы нажали на слот 5! Добавляю вещь в инвентарь!");
                    event.getWhoClicked().getInventory().addItem(new ItemStack(Material.NETHERITE_SCRAP, 16));
                    break;
                default:
                    event.getWhoClicked().sendMessage("Вы нажали на другой слот!");
                    break;
            }
            event.setCancelled(true);
        }
    }

    @EventHandler
    public void onInventoryDragEvent(InventoryDragEvent event) {
        if(event.getInventory().getHolder() == menusOpen.get(event.getWhoClicked().getUniqueId()).getHolder()) {
            event.setCancelled(true);
        }
    }

    @NotNull
    @Override
    public Inventory getInventory() {
        return this.inventory;
    }
}
Не критично, но интерфейс InventoryHolder у тебя не используется.
Обычно делают так: создают объект класса с этим интерфейсом и суют его в Bukkit.createInventory()
Т.к. UUID игрока можно сохранять прямо в этом объекте, не надо создавать никаких хранилищ инвентарей
Кроме того, запрет лишних действий с инвентарём можно сделать через проверку класса холдера
 
Не критично, но интерфейс InventoryHolder у тебя не используется.
Обычно делают так: создают объект класса с этим интерфейсом и суют его в Bukkit.createInventory()
Т.к. UUID игрока можно сохранять прямо в этом объекте, не надо создавать никаких хранилищ инвентарей
Кроме того, запрет лишних действий с инвентарём можно сделать через проверку класса холдера

ну тут еще ситуация такая, мне нужно будет иногда из вне удалять из некоторых интерфейсов игроков
сначала думал просто через getViewers, но решил через мапу
 
Назад
Верх