Bukkit Как изменить int в файле конфигурации, чтобы иметь возможность изменить его снова без перезагрузки (класс пользовательского файла конфигурации.))

Хорошо, поэтому я делаю пользовательскую функцию для своего сервера OP-Prison, одна из вещей, которые мне нужно сделать, это получить целое число из файла player.yml, проверить, является ли оно >= единицей, если это убрать единицу, сохраните его, а затем, если он все еще выше единицы, они могут повторять действие до тех пор, пока он не станет 0. Проблема связана с тем, что мне нужно перезапустить сервер, чтобы файл изменился, и даже когда я это сделаю, он только упадет на одно целое число за раз, прежде чем перезагружать его снова.

Код создания графического интерфейса:

Main main = Main.getPlugin(Main.class);

@SuppressWarnings("unused")
private FileControl fc;

@SuppressWarnings("unused")
private FileControl playerfc;

public static String inventoryname = Utils.chat(Main.pl.getFileControl().getConfig().getString("Backpacks.White.InventoryName"));

public List<Player> WhiteOpened = new ArrayList<>();

public static Inventory whiteBackpack(Player player) {
    Inventory whiteBackpack = Bukkit.createInventory(null, 27, (inventoryname));
    UUID uuid = player.getUniqueId();

    whiteBackpack.setItem(10,
            new ItemCreator(Material.INK_SACK).setData(8)
                    .setDisplayname(Utils.chat("&fCommon Packages &8» &f&l" + Main.pl.getPlayerFile().getConfig().getInt("Users." + uuid + ".Packages.Common")))
                    .getItem());

    return whiteBackpack;
}

Код для обновления элемента конфигурации + при нажатии Commonpackage:

@EventHandler
public void whiteBackpackInteract(InventoryClickEvent event) {

    Player player = (Player) event.getWhoClicked();
    UUID uuid = player.getUniqueId();
    ItemStack clicked = event.getCurrentItem();
    String title = event.getInventory().getName();

    if (title.equals(inventoryname)) {
        // Making it so that the item cannot be moved
        event.setCancelled(true); 

        if (clicked != null) {

            if (event.getSlot() == 10) {

                // Getting the user's common packages section in the config and checking if it is greater than or equal to 1.
                if (Main.pl.getPlayerFile().getConfig().getInt("Users." + uuid + ".Packages.Common") >= 1) { 

                    // Saving the user's common package section to 'currentCommon'
                    Integer currentCommon = Main.pl.getPlayerFile().getConfig().getInt("Users." + uuid + ".Packages.Common");

                    // Taking away one from 'currentCommon' and saving it to 'newCommon'
                    Integer newCommon = currentCommon - 1;

                    // Getting the 'players.yml' file
                    File file = new File(main.getDataFolder(), "players.yml");
                    FileConfiguration config = YamlConfiguration.loadConfiguration(file);

                    // Checking if the current common keys is greater than or equal to 1
                    if (currentCommon >= 1) {
                        try {

                            //Now, Here's where the error lies.
                            //Gets the player's common package count and sets it to the 'newCommon' count
                            config.set("Users." + uuid + ".Packages.Common", newCommon);
                            //Saves the players.yml file
                            config.save(file);

                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        // Updates the inventory they're currently in (Atleast it's meant to...)
                        player.updateInventory();
                        // Sends them a message (This is just for testing purposes, making sure it's working.)
                        player.sendMessage(Utils.chat("&8(&9Vexil&8) &fCommon Package"));
                    }
                }
            }
        }
    }
}

Если вам нужен какой-либо другой код, просто спросите, я с радостью предоставлю его вам.


person Askingg    schedule 09.07.2018    source источник


Ответы (2)


Прямо сейчас вам нужно перезапустить сервер, чтобы он сохранил данные в файл. Этого не должно происходить, поскольку вы вызываете метод config.save(file). Нижеследующее является просто предположением, но это единственная причина, которая, я думаю, может легко объяснить происходящее.

В объекте, возвращаемом getPlayerFile().getConfig(), вероятно, есть переменная, в которой хранится FileConfiguration. Эта переменная содержит все данные из файла players.yml. В вашем методе whiteBackpackInteract() вы загружаете данные заново. Затем вы продолжаете писать в этот НОВЫЙ FileConfiguration переменная, а не та, что хранится в getPlayerfile().getConfig(). Поскольку затем вы переходите к непосредственному сохранению в файл, переменные, хранящиеся в getPlayerfile().getConfig(), никогда не сообщаются о том, что вы изменили некоторые значения. Чтобы исправить это, вам нужно изменить следующее:

config.set("Users." + uuid + ".Packages.Common", newCommon);
config.save(file);

к этому:

Main.pl.getPlayerFile().getConfig().set("Users." + uuid + ".Packages.Common", newCommon);
Main.pl.getPlayerFile().getConfig().save(file);

а затем удалите эту строку кода:

FileConfiguration config = YamlConfiguration.loadConfiguration(file);

Это должно полностью решить вашу проблему. Если это не так, я бы порекомендовал не использовать пользовательский API конфигурации вашего друга, а вместо этого просто использовать встроенные. Использование стороннего кода, который вы не понимаете должным образом, может очень часто приводить к таким проблемам.

Ниже приведены не ошибки, а предложения по улучшению вашего кода:

  • Вы должны обязательно размещать свои комментарии ВЫШЕ или СПРАВА над кодом, который они описывают. Люди читают сверху вниз, поэтому комментарии (до того, как я внес предлагаемое редактирование в ваш пост) были ниже кода, который они описывают.
  • Как правило, вы хотите убедиться, что если код не нужно запускать, то это не так. Поскольку int newCommon не используется до тех пор, пока внутри этого оператора if, вы должны переместить его туда.
person Michael Ziluck    schedule 11.07.2018

Вы используете Main.getPlugin();

Теперь, хотя это не кажется такой уж плохой вещью, вы получаете неназначенную переменную, я понятия не имею, как это работает, но вы назначаете Main для Main. Есть два правильных способа получить основной класс.

Первый и, как правило, лучший способ — использовать внедрение зависимостей.

Итак, в основном,

public class Main extends JavaPlugin {

    @Override
    public void onEnable() {
        BackpackListener listener new Backpacklistener(this);
        getServer().getPluginManager().registerEvents(listener, this);
    }
}

public class BackpackListener implements Listener {
     private Main instance;
     private BackpackUtil util;

     public BackpackListener(Main instance) {
         this.instance = instance;
         util = new BackpackUtil();
     }

     @EventHandler
     public void onClick(InventoryClickEvent event) {
         //code
         util.whiteBackpack(instance);
     }
public class BackpackUtil {
    public Inventory whiteBackpack(Main instance) {
        FileConfiguration config = instance.getConfig();
        //Do things
        instance.saveConfig();
    }
}

Следующий способ, которым вы можете это сделать, менее оптимален и не одобряется, но все же является более простым вариантом.

public class Main() {
    public static Main instance;
    @Override
    public void onEnable() {
        instance = this;
    }
}

public class ConfigHelper() {
    Main instance = Main.instance;
    FileConfiguration config = instance.getConfig();
    //Do things
    instance.saveConfig();
}

Хорошо избавиться от привычки использовать второй метод (он называется синглтоном), потому что обычно основной класс изменяется или имеет несколько экземпляров и т. д., но с Spigot может быть только один основной экземпляр и один поток. .

person Big_Bad_E    schedule 27.07.2018