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

Помогите Проблема с перемещением добавленных серверов

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

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

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

    Баллы:
    61
    Имя в Minecraft:
    yanvsky_
    Код:
        private static void updateMenuDescriptions() {
            menu.clear();
    
            ItemStack glassPane = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 15);
            ItemMeta glassMeta = glassPane.getItemMeta();
            glassMeta.setDisplayName(" ");
            glassPane.setItemMeta(glassMeta);
    
            int[] slots = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 46, 47, 48, 50, 51, 52, 53};
    
            for (int slot : slots) {
                menu.setItem(slot, glassPane);
            }
    
            List<ConfigManager> availableServers = new ArrayList<>();
            List<ConfigManager> fullServers = new ArrayList<>();
    
            for (ConfigManager configManager : servers.values()) {
                int currentPlayers = configManager.getCurrentPlayers();
                if (currentPlayers < configManager.getMaxPlayers()) {
                    availableServers.add(configManager);
                } else {
                    fullServers.add(configManager);
                }
            }
    
            for (ConfigManager configManager : availableServers) {
                menu.setItem(configManager.getSlot(), createServerItem(configManager));
            }
    
            for (ConfigManager fullServer : fullServers) {
                boolean serverMoved = false;
                for (ConfigManager configManager : availableServers) {
                    if (!serverMoved && configManager.getSlot() != fullServer.getSlot()) {
                        menu.setItem(fullServer.getSlot(), createServerItem(configManager));
                        serverMoved = true;
                    }
                }
                if (!serverMoved) {
                    menu.setItem(fullServer.getSlot(), new ItemStack(Material.AIR));
                }
            }
    
            ItemStack backButton = new ItemStack(Material.ARROW);
            ItemMeta backButtonMeta = backButton.getItemMeta();
            backButtonMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', Main.getInstance().getConfig().getString("menu_other.back_bw.display_name")));
            backButton.setItemMeta(backButtonMeta);
            menu.setItem(49, backButton);
        }
    Когда один из добавленных мной серверов удаляется из-за превышения максимального онлайна, указанного в конфиге, и другие сервера перемещаются в его слот, то они стоят на своих слотах и на тех, на которые встали, но нужно сделать так, чтобы они переместились на слот, где они стояли раньше, будут временно удалены с этого слота, пока другие сервера не перестанут превышать максимальный указанный онлайн. В кратце - Я пытаюсь сделать динамические слоты
     
  2. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Формируешь список серверов, которые необходимо отобразить в данный момент.
    В цикле перебираешь этот список серверов, при этом инкрементишь переменную, отвечающую за слот. Таким образом, номера слотов теперь генерируются динамически.

    Можно на каждый сервер увеличивать значение не на 1, а на 2 - промежутки между предметами увеличатся.

    Если нужен какой-то более красивый специфический паттерн, то как вариант создать отдельный лист интеджеров, который будет хранить индексы всех слотов, где допустимо размещение предметов. При помощи счётчика из предыдущего варианта вычисляешь индекс, по нему получаешь номер слота из листа.

    Если пойти ещё дальше, то лист с индексами слотов можно заполнять не вручную, а "визуально" - для этого придется реализовать метод, позволяющий это делать. В качестве параметров принимать можно, допустим, массив строк. В этом случае формирование списка слотов будет происходить так:
    HTML:
    List<Integer> availableSlots = createSlotsList(
    "----*----",
    "---*-*---",
    "--*****--"
    );
    Так получишь номера слотов в форме Массонсского треугольника.
    Но смысл в такой фишке есть только тогда, когда делаешь кучу разных менюшек
     
  3. Автор темы
    yanvsky

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

    Баллы:
    61
    Имя в Minecraft:
    yanvsky_
    upload_2024-2-12_15-16-25.png upload_2024-2-12_15-16-31.png

    Когда сервер BW-1 превышает указанный максимальный онлайн, то происходит:
    upload_2024-2-12_15-18-2.png upload_2024-2-12_15-18-8.png
    BW-2 становится на место BW-1 и стоит также на своём указанном слоте, хотя временно должен оставаться только на слоте BW-1
     

    Вложения:

  4. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    При обновлении предметов очищай прежде все слоты, в которых могут быть стаки серверов.
    Если это не поможет, то, значит, в твоём листе доступных серверов BW2 повторяется два раза
     
  5. Автор темы
    yanvsky

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

    Баллы:
    61
    Имя в Minecraft:
    yanvsky_
    upload_2024-2-13_21-14-3.png
    У меня переносится bw2, а bw3 нет, ваще нужно, чтобы все добавленные сервера так перемещались


    Код:
        private static void updateMenuDescriptions() {
            menu.clear();
    
            for (int i = 0; i < menu.getSize(); i++) {
                menu.setItem(i, new ItemStack(Material.AIR));
            }
    
            ItemStack glassPane = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 15);
            ItemMeta glassMeta = glassPane.getItemMeta();
            glassMeta.setDisplayName("§a§lSweets§f§lCraft §b§lNetwork");
            glassPane.setItemMeta(glassMeta);
    
            int[] slots = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 17, 18, 26, 27, 35, 36, 44, 45, 46, 47, 48, 50, 51, 52, 53};
    
            for (int slot : slots) {
                menu.setItem(slot, glassPane);
            }
    
            List<ConfigManager> availableServers = new ArrayList<>();
            List<ConfigManager> fullServers = new ArrayList<>();
            List<Integer> usedSlots = new ArrayList<>();
    
            for (ConfigManager configManager : servers.values()) {
                int currentPlayers = configManager.getCurrentPlayers();
                if (currentPlayers < configManager.getMaxPlayers()) {
                    availableServers.add(configManager);
                } else {
                    fullServers.add(configManager);
                }
            }
    
            for (ConfigManager fullServer : fullServers) {
                boolean serverMoved = false;
                for (ConfigManager configManager : availableServers) {
                    if (!serverMoved && !usedSlots.contains(configManager.getSlot())) {
                        menu.setItem(fullServer.getSlot(), createServerItem(configManager));
                        usedSlots.add(configManager.getSlot());
                        serverMoved = true;
                    }
                }
                if (!serverMoved) {
                    menu.setItem(fullServer.getSlot(), new ItemStack(Material.AIR));
                }
            }
    
            for (ConfigManager configManager : availableServers) {
                if (!usedSlots.contains(configManager.getSlot())) {
                    menu.setItem(configManager.getSlot(), createServerItem(configManager));
                }
            }
    
            ItemStack backButton = new ItemStack(Material.ARROW);
            ItemMeta backButtonMeta = backButton.getItemMeta();
            backButtonMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', Main.getInstance().getConfig().getString("menu_other.back_bw.display_name")));
            backButton.setItemMeta(backButtonMeta);
            menu.setItem(49, backButton);
        }
     
    Последнее редактирование: 13 фев 2024
  6. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Ну так сделай, как я написал выше, и всё заработает
     
  7. Автор темы
    yanvsky

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

    Баллы:
    61
    Имя в Minecraft:
    yanvsky_
    Я так и сделал, не помогает. На последних скринах bw2 переносится на слот bw1, но другие добавленные сервера тоже должны перемещаться, к примеру bw3 должен перемещаться на слот bw2, а bw4 на bw3 и т.д
     
  8. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    У тебя в предыдущем посте в коде явно не тот алгоритм, который я тебе предложил.

    Почему списков несколько? Как минимум availableServers и fullServers.
    Зачем тебе булин serverMoved?
    Зачем тебе список usedSlots?
    Зачем тебе метод configManager.getSlot()?

    Это всё не не потребуется, если сделаешь, как я предлагал выше. Перечитай ещё раз
     
  9. Автор темы
    yanvsky

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

    Баллы:
    61
    Имя в Minecraft:
    yanvsky_
    У меня не только обработка в этом методе перемещения добавленных серверов.

    serverMoved отвечает за отслеживание того, был ли перемещен сервер в меню. Если сервер был перемещен на новую позицию, то serverMoved становится true.
    usedSlots представляет список слотов, которые уже используются в меню. Этот список обновляется при перемещении доступных серверов на места переполненных, чтобы избежать перезаписи других серверов на тех же слотах.
    configManager.getSlot() это слоты, благодаря которым должен отображаться добавленный сервер в меню.

    Как ты мне сказал, я сделал. Сверху я кидал последние скрины, это практически конец моей проблемы.
     
  10. Автор темы
    yanvsky

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

    Баллы:
    61
    Имя в Minecraft:
    yanvsky_
  11. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Ты явно не понял, что я предлагаю, иначе это всё тебе не понадобилось бы.
    Приведи код в порядок, и всё станет гораздо проще. Не нужно смешивать логику поиска подходящих серверов с логикой обновления инвентаря, раздели их хотя бы на разные методы. У тебя получится примерно это:
    PHP:
    private void updateMenuDescriptions(Inventory menu) {
        
    menu.clear();

        
    ItemStack borderItem createBorderItem();
        for (
    int borderSlot : new int[]{
            
    012345678,
            
    917,
            
    1826,
            
    2735,
            
    3644,
            
    454647484950515253
        
    }) {
            
    menu.setItem(borderSlotborderItem);
        }

        
    ItemStack backItem createBackItem();
        
    menu.setItem(49backItem);

        for (
    ServerInfo serverInfo getAvailableServers()) {
            
    int serverSlot menu.firstEmpty();
            
    ItemStack serverItem createServerItem(serverInfo);
            
    menu.setItem(serverSlotserverItem);
        }
    }

    private List<
    ServerInfogetAvailableServers() {
        List<
    ServerInfoavailableServers = new ArrayList<>();
        
    // TODO Тут проверяешь статус и онлайн и добавляешь в список только подходящие сервера
        
    return availableServers;
    }

    private 
    ItemStack createBackItem() {
        
    ItemStack result = new ItemStack(Material.ARROW);
        
    ItemMeta meta result.getItemMeta();
        
    meta.setDisplayName(ChatColor.translateAlternateColorCodes('&'Main.getInstance().getConfig().getString("menu_other.back_bw.display_name")));
        
    result.setItemMeta(meta);
        return 
    result;
    }

    private 
    ItemStack createBorderItem() {
        
    ItemStack result = new ItemStack(Material.STAINED_GLASS_PANE1, (short15);
        
    ItemMeta meta result.getItemMeta();
        
    meta.setDisplayName("§a§lSweets§f§lCraft §b§lNetwork");
        
    result.setItemMeta(meta);
        return 
    result;
    }

    private 
    ItemStack createServerItem(ServerInfo serverInfo) {
        
    ItemStack result = new ItemStack(Material.PAPER);
        
    ItemMeta meta result.getItemMeta();
        
    meta.setDisplayName(serverInfo.name);
        List<
    Stringlore = new ArrayList<>();
        
    lore.add("Статус: " serverInfo.status);
        
    lore.add("Карта: " serverInfo.map);
        
    lore.add("Онлайн: " serverInfo.currentOnline " из " serverInfo.maxOnline);
        
    meta.setLore(lore);
        
    result.setItemMeta(meta);
        return 
    result;
    }

    private static class 
    ServerInfo {
        private 
    String name;
        private 
    String status;
        private 
    String map;
        private 
    int currentOnline;
        private 
    int maxOnline;
    }
    Естественно, класс ServerInfo должен храниться не в классе инвентаря, а отдельно в подходящем пакете
     
    Последнее редактирование: 18 фев 2024

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