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

Сериализация ItemStack в json

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

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

    NeMaster Новичок Пользователь

    Баллы:
    21
    Была пару лет назад схожая тема, но она не отвечает проблеме.

    Я хочу серилизовать ItemStack в jsonb поле БД постгреса.
    Известны ли какие то готовые близкие решения (я не нашёл)?

    Первая проблема с которой я столкнулся это то что сериализация сериализует только первый уровень вложенности свойств, т.е. сам текущий объект, а меты, зачары и не знаю что может быть ещё не сериализовано.

    Я сделал такой вариант сериализации

    Код:
        public JsonElement Serialize(Object obj) {
           Gson gson = new GsonBuilder().create();
    
           if (obj instanceof ConfigurationSerializable) {
               JsonObject json = new JsonObject();
                Map<String,Object> map = ((ConfigurationSerializable) obj).serialize();
                for (String key: map.keySet()) {
                    json.add(key, Serialize(map.get(key)));
                }
                return json;
           } else if (obj instanceof ImmutableMap) {
               JsonObject json = new JsonObject();
                for (Object key: ((ImmutableMap) obj).keySet()) {
                   json.add((String) key, Serialize(((ImmutableMap) obj).get(key)));
                }
                return json;
           } else {
               return new JsonPrimitive(gson.toJson(obj));
           }
        }
    Выглядит страшненько :) Как вы считаете на сколько это рабочий вариант?
    Одна проблема у него есть точно. Он все значения полей делает текстом. А на строки так ещё и кавычки дважды ставит.

     
  2. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    У предметов есть собственный прекрасный формат хранения - NBT. Причем можно использовать как бинарный формат, так и строковый (mojangson)
     
  3. alexandrage

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

    Баллы:
    173
    К чему этот костыль перевода yml в json? Что так yml что json все равно строка будет.
     
  4. Автор темы
    NeMaster

    NeMaster Новичок Пользователь

    Баллы:
    21
    Это не так. К json в постгресе можно будет применить sql запросы. yml удобен для хранеия в конфиг-файле.
    Я хочу уйти от конфиг файлов в сторону БД, мне так удобнее. Так появляется больше возможностей для работы с данными. В том числе на бэкенде веб-приложения. Игру можно ведь вынести за рамки только клиента в веб.
     
  5. Автор темы
    NeMaster

    NeMaster Новичок Пользователь

    Баллы:
    21
    Да, но на сколько мне известно никакие БД кроме нативно-майнкравтавских этот формат не использует. Постресс точно о таком формате не знает.
     
  6. Автор темы
    NeMaster

    NeMaster Новичок Пользователь

    Баллы:
    21
    С сериализацией вроде справился, обратный процесс пока не идёт.
    Код:
        public JsonElement Serialize(Object obj) {
           if (obj instanceof ConfigurationSerializable) {
               JsonObject json = new JsonObject();
                Map<String, Object> map = ((ConfigurationSerializable) obj).serialize();
                for (String key: map.keySet()) {
                    json.add(key, Serialize(map.get(key)));
                }
                return json;
           } else if (obj instanceof ImmutableMap) {
               JsonObject json = new JsonObject();
                for (Object key: ((ImmutableMap) obj).keySet()) {
                   json.add((String) key, Serialize(((ImmutableMap) obj).get(key)));
                }
                return json;
           } else {
               return gson.toJsonTree(obj);
           }
        }
    Пока сделал так
    Код:
        public ConfigurationSerializable Deserialize(String json) {
           Map<String, Object> map = gson.fromJson(json, new TypeToken<Map<String, Object>>(){}.getType());
           return ItemStack.deserialize(map);
        }
    Но конечно десериализуется только первый уровень, получается был меч с зачарами, а стал просто меч :)
    Вижу что там есть карты LinkedTreeMap вложены в корневую карту.
    Мне кажется надо десериализовывать начиная с наиболее глубоких уровней, заменяя карты готовыми объектами. Но у ConfigurationSerializable нет метода deserialize, я не понимаю.
    Друзья есть идеи как сделать десериализацию?
     

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