Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Стартап Помощь начинающим. Как создавать, сохранять и считывать конфиг файлы.

lakninispe

Ньюби
Баллы
1
Новичкам в программировании бывает порой сложно понять сами принципы построения тех или иных объектов при создании плагинов. Помощь профессионалов бывает часто такой, что новички ещё хуже потом путаются. Вот представьте малыш первый раз в первый класс, научите меня математике? И учитель начинает его закидывать функциями, операндами, аргументами. А слабо понять, что ему необходимо сначала все на счетных палочках объяснить? Моя цель просто и наглядно объяснить, как работать с конфигами. В помощь начинающим, тем кто ломает голову, как же работать с конфигами, принцип создания и использования, выкладываю простенький код с комментами для создания, сохранения и использования конфиг файлов.
Данный демонстрационный проект это готовый плагин заготовка для работы с конфигами.
При старте сервера создается папка плагина и в ней 3 конфиг файла. Из них 2 файла просто копируются из самого плагина, а 3 файл создается со строкой и текстом при запуске или перезагрузке сервера. Во всех трех файлах в папке плагина можете добавить текст или значение
после строк String: Wert: Command: Значение вводится через пробел.
Пример: String: blablabla Wert: Tatata Command: gegegege
Если после повторного перезапуска сервера вы увидите эти значения в консоли, значит всё ОК!

Создайте проект, создайте в нем пакет we и в нем главный класс Main. Создайте в проекте 2 конфиг файла config.yml и conf.yml В файле config.yml создайте строку Wert: В файле conf.yml создайте строку String:
Сохраните файлы. Скопируйте мой код целиком в класс Main предварительно очистив его. Скомпилируйте проект в папку сервера и запустите просто консоль сервера, после создания папки плагина с конфигами, откройте каждый файл через NotePad++ и введите значения как описано выше, сохраните конфиги, перезапустите сервер и посмотрите в консоли введенные вами значения. Если вы увидели их там, то значит считывание прошло успешно. Изучите мой код подробно, он с комментариями, там доходчиво написано, что, зачем и почему
PHP:
package we;

import java.io.File;
import java.util.logging.Logger;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;



public class Main extends JavaPlugin implements Listener{

 

//**Код регистрации статической переменной - _Log - для вывода в консоль**/
public static final Logger _log  = Logger.getLogger("Minecraft");





//**В этом коде переменная - fileConfig - для доп. конфиг файла conf.yml**/
public File file = new File(getDataFolder() + File.separator + "conf.yml");
public FileConfiguration fileConfig = YamlConfiguration.loadConfiguration(file);
//**В этом коде переменная - fileConfig - для доп. конфиг файла conf.yml**/

 



//**В этом коде переменная - fileConfig2 - для доп. конфиг файла custom.yml**/
public File file2 = new File(getDataFolder() + File.separator + "custom.yml");
public FileConfiguration fileConfig2 = YamlConfiguration.loadConfiguration(file2);
//**В этом коде переменная - fileConfig2 - для доп. конфиг файла custom.yml**/





//**В этом коде переменная - conf - для доп. конфиг файла config.yml**/
FileConfiguration conf = getConfig();


 

 
//**public void onEnable(){==========================================================**/
public void onEnable(){
 

//**Этот код просто для дополнительных возможностей,  для консоли, или для слушания событий в этом классе  **/
 Bukkit.getConsoleSender().sendMessage(ChatColor.BLUE + "[ProjectSna] <===> Starting Plugin......"); //Для отображения в консоли сервера
 Bukkit.getPluginManager().registerEvents(this , this);


 
//**Этот код я применил лишь для быстрого теста чтения конфигов в консоли сервера **/
_log.info("Wert: " + conf.getString("Wert"));//**Строка считывания из основного конфиг файла config.yml**/
_log.info("String: " + fileConfig.getString("String"));//**Строка считывания из доп. конфиг файла conf.yml**/
_log.info("Command: " + fileConfig2.getString("Command"));//** Строка считывания из доп. конфиг файла custom.yml**/
 
 
 
 
 
 
 //**Здесь мы будем выполнять копирование существующих в  проекте конфигов в папку плагина**/

//**Создаем условие копирования  существующего доп. конфиг файла - conf.yml**/
 if (!this.file.exists() ) {    //**Если файла не существует**/
 saveResource("conf.yml", true); //**То копирование при запуске  сервера доп.  конфиг файла conf.yml**/
 }

 
 saveDefaultConfig();    //**Это код для копирование при запуске сервера основного конфиг файла config.yml**/
 
 
 
 
 
 
 
 //**Здесь мы будем создавать новый конфиг со строкой при запуске сервера  - custom.yml - **/
 
 //**Создаем условие создания нового конфиг файла - custom.yml**/
 
  if (!this.file2.exists() ) {    //**Если файла не существует**/
  this.fileConfig2.set("Command","data" ); //** То присваиваем переменной Config2 -данные со строкой Command- и значением -data**/
    saveCfg();    //** Сохраняем данные из переменной в конфиг custom.yml  **/
// к строке saveCfg();  Мы создаем метод, см. ниже
    }

 

 
}




//**Метод сохранения файла custom.yml**/
private void saveCfg() {
    try {                          //**Если вылетает ошибка Exception**/
        fileConfig2.save(file2);     //**При данном коде**/
    } catch (Exception e) {        //**То обрабатываем её**/
        e.printStackTrace();        //**Метод обработки исключений**/
    }
 
}
 

}
PHP:
Если вам необходимо считывать данные с конфигов, просто подставляйте вот эти переменные:

    conf.getString("Wert")
    fileConfig.getString("String")
    fileConfig2.getString("Command")

  Пример использования:

  p.sendMessage("blabla"); //Это просто текст
  p.sendMessage(fileConfig.getString("String")); // А это текст из вашего конфига

  Пример использования с условием:

  @EventHandler
  public void onCmd(PlayerCommandPreprocessEvent e) {
  Player p = e.getPlayer();
  String cmd = e.getMessage().replace("/", "").split("\\s+")[0];

 // Если вводимая команда совпадает с значением строки - String-  конфига- 1
  if(cmd.equalsIgnoreCase(fileConfig.getString("String"))){

 // То выводим в чат сообщение - (значение текст из строки -  Command-  конфига 2
  p.sendMessage(fileConfig2.getString("Command"));
  e.setCancelled(true); //Запрещаем все остальные действия и сообщения

  Если вам нужно добавить строки в конфиге custom.yml  , который создается у нас при запуске или перезапуске сервера,  то просто добавьте в этом плагине

  this.fileConfig2.set("Command","data" );
  this.fileConfig2.set("Command2","data" );
  this.fileConfig2.set("Command3","data" );

Если нужно создать подстроку, то делайте так:

this.fileConfig2.set("Command.string1","data" );
после Command ставите точку и string1    где string1  это подстрока

пример в конфиге:
Command:
   string1:

Это действует  для всех конфигов!



 

Но для других конфигов, которые просто копируются, нужно просто открыть их в
проекте и добавить нужные строки вручную, в соответствии с содержимым вашего
проекта, затем скомпилировать проект и все.
Важно знать, что как вы уже заметили, что в этом коде есть метод, который
разрешает копирование, перезапись или создание конфигов только после проверки
условия на их существование в папке плагина. Если они отсутствуют, произойдет
копирование существующих, или создание новых конфигов, если они есть в папке
плагина, то ничего происходить не будет. Так, если вы ввели какие то значения
в конфиг файлы, то пока эти файлы вы сами не удалили случайно иди намеренно,
то ваши данные не будут затронуты или обнулены после рестарта сервера.
Секция множественных путей
Пример конфигурации:

Код:
Configurations:
  string1: "MyText"
  string2: "YouText"
Имя «MyText» - это раздел «string1», который из раздела «Configurations:». Чтобы получить доступ к внутренним путям нашего файла, мы используем простой «.». Как способ сказать, что мы хотим следующий раздел. Итак, для нас, чтобы получить доступ к «MyText», мы должны вначале войти в раздел Configurations: а затем в подраздел string1: Это дело достается следующим образом:
Код:
config.getString("Configurations.string1");

Плагин Config.yml
Пример конфигурации:
У вас может быть файл config.yml, который загружается непосредственно из вашего файла jar. Он должен быть добавлен в папку вашего проекта, так же, как файл plugin.yml.
В этом файле у вас есть значения по умолчанию для вашей конфигурации


Код:
Configurations:
  string1: "MyText"
  string2: "YouText"
Пример файла конфигурации должен быть добавлен в папку проекта.
Чтобы загрузить файл конфигурации по умолчанию в папку вашего плагина, в ваш onEnable () должен быть добавлен следующий код:
Код:
saveDefaultConfig();
Это сделает ваш файл config.yml из проекта конфигурационным файлом вашего плагина и добавит его в папку вашего плагина.
Оттуда вы можете получить доступ к своему конфигурационному файлу из любого места, используя ваш экземпляр плагина, вот этот код:
Код:
JavaPlugin plugin;
FileConfiguration config = plugin.getConfig();
Оттуда мы можем получить доступ ко всему, что было установлено в конфигурации плагина.
Примечание. Файл конфигурации по умолчанию может иметь свои значения, если пользователь хочет отредактировать файл config.yml, сгенерированный в папке.
Код:
String Name = config.getString("Configurations.string1");
List<String> Name2 =  config.getStringList("Configurations.string2");






 
Последнее редактирование:
Я - говнокодер, но такой бы ху-ни не написал.
 
Чтобы не быть голословным, я попытаюсь привести пример ненужного кода(по крайней мере для меня):
1)
//**СОЗДАЁМ УСЛОВИЕ СОЗДАНИЯ НОВОГО КОНФИГ ФАЙЛА - conf.yml**/
if (!this.file.exists() ) { //**ЕСЛИ ФАЙЛА НЕ СУЩЕСТВУЕТ**/
saveResource("conf.yml", true); //**КОПИРОВАНИЕ ПРИ ЗАПУСКЕ СЕРВ. ДОП. КОНФИГ ФАЙЛА conf.yml**/
}
else if (this.file.exists()) return; //**ИНАЧЕ ЕСЛИ ФАЙЛ СУЩЕСТВУЕТ, ТО НИЧЕГО НЕ ДЕЛАЕМ**/

saveDefaultConfig(); //**КОПИРОВАНИЕ ПРИ ЗАПУСКЕ СЕРВ. ОСН. КОНФИГ ФАЙЛА config.yml**/
Зачем тебе ретурнить else? Если условие не выполнится, то оно просто пролетит мимо, и ничего не произойдет.
Код:
//Мой вариант:
if(!file.exists()) saveResource("conf.yml", true); //Можно оставить место для скобок, мне так даже удобнее, но было лень.
2)
if (!this.file2.exists() ) { //**ЕСЛИ ФАЙЛА НЕ СУЩЕСТВУЕТ**/
this.fileConfig2.set("Command","data" ); //** ТО СОЗДАЕМ ФАЙЛ И СТРОКУ В НЕМ -Command- СО ЗНАЧЕНИЕМ -data в - custom.yml**/
saveCfg(); //** (К ЭТОЙ СТРОЧКЕ СОЗДАЕМ МЕТОД. СМ. НИЖЕ) CОХРАНЯЕМ custom.yml в ПАПКЕ ПЛАГИНА**/
}
else if (this.file2.exists()) return;
Вот это вообще полная чушь. Если файла нет - то записываем в него строку, если есть - ретурним.
Относительно твоего кода, это должно выглядить как-то так:
Код:
if(file2.exists()) {
fileConfig2.set("Govnocod", "Mnogo govnocoda");
saveCfg();
}
Ну а еще, много грамматических и пунктуационных ошибок. А, ну и еще Caps Lock тут был лишним.
Возможно, тут больше ошибок, это тебе скажут опытные кодеры, а не я.
 
Чтобы не быть голословным, я попытаюсь привести пример ненужного кода
Спасибо за полезные подсказки! Я ценю критику, но только полезную! А в целом это отлично работает, это же не готовый плагин, это просто пример для понимания процессов для новичков!
Возможно может у меня где то коменты не на месте стоят, но реально оно отлично работает и создает файлы и строки все которые нужны, и все работает так, как там написано, а else и return никогда лишним не бывает, всегда предпочитаю подстраховаться, тогда это для чего придумано? Везде же оно применяется в довольно приличных плагинах.
Возможно вы поторопились с выводами там, где проверка я же написал ТО СОЗДАЕМ ФАЙЛ И СТРОКУ В НЕМ, данные в fileConfig2.set это как бы записывается в переменную, то есть в память, а ниже код saveCfg(); сохраняет из этой переменной в файл.
а вы исказили это, видать невнимательно смотрели, но я признаюсь что комент не совсем верно воткнул, а в общем то файл создается и сторока в нем тоже.
 
Последнее редактирование:
Возможно вы поторопились с выводами там, где проверка я же написал ТО СОЗДАЕМ ФАЙЛ И СТРОКУ В НЕМ, данные в fileConfig2.set это как бы записывается в переменную, то есть в память, а ниже код saveCfg(); сохраняет из этой переменной в файл.
а вы исказили это, видать невнимательно смотрели, но я признаюсь что комент не совсем верно воткнул, а в общем то файл создается и сторока в нем тоже.
Вот здесь, возможно, и ошибся, т.к. теоретически он не должен создать файл, должно было вылететь исключение IOException, но я не проверял, поэтому не факт, что я прав.
 
а else и return никогда лишним не бывает, всегда предпочитаю подстраховаться, тогда это для чего придумано?
идиот чтоли

это так здорово, когда ньюби, ничего не понимающие в программировании, пишут туториалы и считают себя умными
 
А, вот еще, что можно изменить.
Чтобы не использовать постоянно File.separator, можно файл получать так:
new File(getDataFolder(), "название_файла.формат");
 
Тема очень востребованная для новичков в этом деле, был бы рад, если кто продолжит тему или создаст новую с таким же подробным описанием, например иные варианты кода работы с конфигами, желательно в таком же доходчивом формате, им нужно все разжевать.
 
Мой вариант.
PHP:
package com.demkom58.config;

import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.logging.Level;

public class CustomConfig {
    private FileConfiguration config = null;
    private File configFile = null;
    private final Plugin p;
    private final String name;

    public CustomConfig (Plugin p, String name) {
        this.p = p;
        this.name = name;
    }

    public void reloadConfig() {
        if (configFile == null) {
            configFile = new File(p.getDataFolder(), name+".yml");
        }
        config = YamlConfiguration.loadConfiguration(configFile);

        Reader defConfigStream = new InputStreamReader(p.getResource(name+".yml"));
        if (defConfigStream != null) {
            YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
            config.setDefaults(defConfig);
        }
    }

    public FileConfiguration getConfig() {
        if (config == null) {
            reloadConfig();
        }
        return config;
    }

    public void saveConfig() {
        if (config == null || configFile == null) {
            return;
        }
        try {
            getConfig().save(configFile);
        } catch (IOException ex) {
            p.getLogger().log(Level.SEVERE, "Could not save config to " + configFile, ex);
        }
    }
    public void saveDefaultConfig() {
        if (configFile == null) {
            configFile = new File(p.getDataFolder(), name+".yml");
        }
        if (!configFile.exists()) {
            p.saveResource(name+".yml", false);
        }
    }
}
 
Мой вариант.
PHP:
package com.demkom58.config;

import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.logging.Level;

public class CustomConfig {
    private FileConfiguration config = null;
    private File configFile = null;
    private final Plugin p;
    private final String name;

    public CustomConfig (Plugin p, String name) {
        this.p = p;
        this.name = name;
    }

    public void reloadConfig() {
        if (configFile == null) {
            configFile = new File(p.getDataFolder(), name+".yml");
        }
        config = YamlConfiguration.loadConfiguration(configFile);

        Reader defConfigStream = new InputStreamReader(p.getResource(name+".yml"));
        if (defConfigStream != null) {
            YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
            config.setDefaults(defConfig);
        }
    }

    public FileConfiguration getConfig() {
        if (config == null) {
            reloadConfig();
        }
        return config;
    }

    public void saveConfig() {
        if (config == null || configFile == null) {
            return;
        }
        try {
            getConfig().save(configFile);
        } catch (IOException ex) {
            p.getLogger().log(Level.SEVERE, "Could not save config to " + configFile, ex);
        }
    }
    public void saveDefaultConfig() {
        if (configFile == null) {
            configFile = new File(p.getDataFolder(), name+".yml");
        }
        if (!configFile.exists()) {
            p.saveResource(name+".yml", false);
        }
    }
}
К чему такой костыль Reader defConfigStream = new InputStreamReader(p.getResource(name+".yml"));?
Когда есть готовый метод this.plugin.saveResource(name + ".yml", false);
И вообще тут много лишнего.
 
К чему такой костыль Reader defConfigStream = new InputStreamReader(p.getResource(name+".yml"));?
Когда есть готовый метод this.plugin.saveResource(name + ".yml", false);
И вообще тут много лишнего.
Хз, давно его сделал и юзаю, мне норм.
Конечно его можно улучшить...
 
Последнее редактирование:
Наконец то хоть кто-то данную тему выложил сюда! Спасибо автору! Иначе нигде никто не объясняет толком, народ очень скуп на это дело. В инете рылся, везде громоздкий код и сложно разобрать потом у себя в проекте!
Сколько времени угрохал, а оно оказывается все так просто.
 

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

Назад
Верх