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

Помогите сериализовать предметы, полученные из инвентарей, и их списки

Тема в разделе "Разработка плагинов для новичков", создана пользователем ToBlEzZ, 13 июн 2022.

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

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

    Баллы:
    76
    Всем привет!
    Мне нужно сериализовать предметы, полученные из инвентарей, и их списки. Для этого использую gson, но у него возникают проблемы, если попадаются предметы из игры.
    Код:
    Unable to make field private volatile java.util.logging.Logger$ConfigurationData java.util.logging.Logger.config accessible: module java.logging does not "opens java.util.logging" to unnamed module @1d98260d
    С предметами, которые делаю в коде, никаких проблем нет и сериализируется все нормально.
    Код:
    ItemStack item = Inventory.getItem(slot); //Ошибка
    ItemStack item = Inventory.getItem(slot).clone(); //Тоже ошибка
    ItemStack item = new ItemStack(Material.*); //Нет ошибки
    Ни как не пойму почему так происходит. Единственное, додумался сделать костыль, но с ним в json попадает слишком много лишней информации
    Код:
    ItemStack items = Inventory.getItem(slot);
    ItemStack it = new ItemStack(item.getType(), item.getAmount());
    it.setItemMeta(item.getItemMeta());
    

    Код:
    "ITEM": {
            "type": "DEEPSLATE_REDSTONE_ORE",
            "amount": 2,
            "meta": {
              "repairCost": 0,
              "hideFlag": 0,
              "unbreakable": false,
              "damage": 0,
              "placeableKeys": [],
              "destroyableKeys": [],
              "unhandledTags": {},
              "persistentDataContainer": {
                "customDataTags": {},
                "registry": {
                  "CREATE_ADAPTER": {},
                  "adapters": {}
                },
                "adapterContext": {
                  "registry": {
                    "CREATE_ADAPTER": {},
                    "adapters": {}
                  }
                }
              },
              "version": 2865
            }
     
  2. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Покажи код, которым сериализуешь. И причём тут логирование - вообще неясно.
    На самом деле, из коробки есть только сериализация в yaml и binary.
    Я в своё время пытался сериализовать PostionEffect, на что получил ответ, что стандартными человеческими методами это невозможно. Подозреваю, что со стаками ситуация та же:
    upload_2022-6-14_22-2-20.png
     
  3. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Все верно, ибо там интерфейсы и нужно зарегать свои сериализаторы.
     
  4. imDaniX

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

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
    Тоже натыкался на такую надобность. На форуме спигота наткнулся на довольно развернутый ответ на тему. Ссылка из поста на его реализацию поломалась, но найти ещё можно.
     
  5. Автор темы
    ToBlEzZ

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

    Баллы:
    76
    Код:
    public static void save() throws IOException {
            try(Writer writer = new FileWriter(SCS.plugin.getDataFolder() + File.separator + "Items.json")){
                Gson gson = new GsonBuilder().setPrettyPrinting().create();
                gson.toJson(SCS.storage, writer);
            }
        }
     
  6. JavaSher

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

    Баллы:
    66
    Используй GsonBuilder#registerTypeHierarchyAdapter если хочешь реализовать метод сериализации/десериализации
    ConfigurationSerializable ниже:
    https://www.spigotmc.org/threads/configurationserializable-to-json-using-gson.467776/

    Либо если хочешь сам реализовать сериализацию/десериализацию имплементируй интерфейсы:
    JsonDeserializer<ТВОЙ_ОБЬЕКТ>, JsonSerializer<ТВОЙ_ОБЬЕКТ>.

    И дальше в методе serialize ты уже конвертируешь объект в json.
    Чаще всего создают JsonObject, записывают в него данные, к примеру:
    Код:
    @Override
    public JsonElement serialize(Location location, Type type, JsonSerializationContext jsonSerializationContext) {
    JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("world", location.getWorld().getName());
        jsonObject.addProperty("x", location.getX());
        jsonObject.addProperty("y", location.getY());
        jsonObject.addProperty("z", location.getZ());
        return jsonObject;
    }

    А в методе deserialize ты уже конвертируешь обратно JsonObject в свой объект:
    Код:
    @Override
    public Location deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
    JsonObject jsonObject = (JsonObject) json;
    JsonElement world = jsonObject.get("world");
    JsonElement x = jsonObject.get("x");
    JsonElement y = jsonObject.get("y");
    JsonElement z = jsonObject.get("z");
    
    World worldInstance = Bukkit.getWorld(world.getAsString());
    
    return new Location(worldInstance, x.getAsDouble(), y.getAsDouble(), z.getAsDouble());
    } 

    Естественно то что выше это всего лишь пример, не более.
    В идеале нужно делать проверку является ли как тут.

    И после создания этого ты должен использовать аннотацию на поле которое хочешь сериализовать @JsonAdapter(ТВОЙ_КЛАСС_(ДЕ)СЕРИАЛИЗАТОР), либо же используя метод Gson#registerTypeAdapter
     
    Последнее редактирование: 17 июн 2022

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