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

Стартап Помощь новичкам и тем, кто мало писал плагины. (+ LifeHack'и)

Тема в разделе "Разработка плагинов для новичков", создана пользователем ANTI_GREEFER, 1 дек 2013.

  1. Deawilld

    Deawilld Участник Пользователь

    Баллы:
    36
    Имя в Minecraft:
    Deawilld
    Вообще-то не сам придумал, но спасибо, что побудил меня самому это протестить. Ты прав, все три способа одинаково быстрые. (0-1 ms)
     
  2. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Такие вещи изменяются в наносекундах и проверяются unit-тестами
     
  3. Deawilld

    Deawilld Участник Пользователь

    Баллы:
    36
    Имя в Minecraft:
    Deawilld
    Это я не умею проверять
     
  4. volk_alex

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

    Баллы:
    61
    Имя в Minecraft:
    volk_alex
    Иииии еще один вопросик...
    Имею ArmorStand_1 в переменной AS. Могу его менять, изменять, перемещать, удалять и т.д. и это отображается на сервере. Теперь я помещаю переменную AS в HashMap<String, Object> и сам HashMap помещаю в Metadata некоему ArmorStend_2. Затем при срабатывании определенных эвентов я беру мету ArmorStend_2.getMetadata.get(0).value и из неё вытаскиваю AS_1. Как будет вести себя сервер, если я попытаюсь что-то сделать с AS_1? Смогу ли я получить Location и вытащить мету из AS_1?
     
  5. Luminate_

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

    Баллы:
    76
    Имя в Minecraft:
    Luminate_
    Должно быть да.
     
  6. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Если всё так, как ты сказал - сможешь вытащить AS_1 и работать с ним, как и сразу после спауна, например.
    Более интересен вопрос, как ты собираешься помещать HashMap в метадату
     
  7. volk_alex

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

    Баллы:
    61
    Имя в Minecraft:
    volk_alex
    Так, как-как? Вот так:
    PHP:
    // Создаем контейнер для хранения переменных
    HashMap<StringObjectplayer_meta_set = new HashMap<>();
    // Запихиваем необходимые данные в контейнер
    player_meta_set.put("Ne", AS);
    player_meta_set.put("a"a);
    player_meta_set.put("stage"1);
    // Ради удобства создаем локальный экземпляр плагина
    Plugin plugin Bukkit.getPluginManager().getPlugin("FirstTestMinecarts");
    // На всякий противопожарный случай удолем мету с таким же именем
    player.removeMetadata("FTM_player_meta"plugin);
    // Зпихиваем данные в мету
    player.setMetadata("FTM_player_meta", new FixedMetadataValue(pluginplayer_meta_set));
    А забирать вот так:
    PHP:
    Player player event.getPlayer();

    //Проверка наличия у player FTM_player_meta и валидность меты
    if (player.hasMetadata("FTM_player_meta")&&(player.getMetadata("FTM_player_meta").get(0).value() instanceof HashMap)) {
        
        @
    SuppressWarnings("unchecked")
        
    HashMap<StringObjectplayer_meta_set = (HashMap<StringObject>) player.getMetadata("FTM_player_meta").get(0).value();
        
    //получим переменную stage ради примера
        
    Integer stage = (Integer) player_meta_set.get("stage");
        
        
    /*
         * какой-то код
         */
    }
    Правда мы должны наверняка знать, что в контейнере хранится именно то, что мы хотим получить. Но на случай если нет я обычно ловлю любой exception и удаляю мету FTM_player_meta
     
    Последнее редактирование: 7 сен 2019
  8. Jampire

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

    Баллы:
    173
    Skype:
    jampire-h
    Имя в Minecraft:
    Jampire
    метадата не особо подходит для хранения чего либо продолжительное время ибо после рестарта оно превратится в тыкву.
     
  9. alexandrage

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

    Баллы:
    173
    До рестарта сервера сможешь. Лучше юзай что то типо scoreboard.
     
  10. volk_alex

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

    Баллы:
    61
    Имя в Minecraft:
    volk_alex
    Ммм... Я не хочу использовать скорборды, т.к. к ней можно получить доступ из игры. К тому же я боюсь, что я не смогу сохранять объекты типа Location. Можно попробовать пихать в локальные файлы, а потом доставать их в глобальную переменную, но опять-таки, что будет с Entity и прочими Objects?
     
  11. alexandrage

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

    Баллы:
    173
    Без плагина там ничего не сделаешь из игры.
     
  12. volk_alex

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

    Баллы:
    61
    Имя в Minecraft:
    volk_alex
    Теперь я понял, что под scoreboards я понимал не то, что понимали Вы. Но этот вариант мне все равно не нравится. Т.к. сериализовывать объекты (например: Location), сохранять их как стринг, а затем доставать их из переменной и десериализировать обратно мне кажется неоправданно трудозатратным. Не уж-то в баките нет проще способа хранить объекты внутри энтити?
    Пока искал варианты решения вопроса, родилась идея хранить данные в глобальном HashMap<String, Object>, где String, это UUID конкретного арморСтенда. Но это означает, что все объекты, которые я хочу иметь на карте будут хранить данные в этой штуке. А это много данных. Считай, каждый мой арморСтенд будет хранить как минимум 4 переменных типа double и 2 объекта типа Location, которые сами по себе занимают ХЗ сколько, но думаю то же не мало (как минимум 5 double на x, y, z, pitch и yaw). Итого по скромным оценкам 9 * 8 байт = 75 байт (!) занимают данные только одного АС при их общем количестве от 100 и более.
    /* Можно было бы организовать хитрый механизм, который бы ловил ChunkLoadEvent и ChunkUnloadEvent и в зависимости от этого убирал бы или добавлял записи в мапу.. Но надо добавить в класс строку о чанке, в котором находится АС */
     
  13. alexandrage

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

    Баллы:
    173
    Ты сделал мой день. Достать строку это крайне тяжелая операция :D. Как только сервер вообще работает, бедняга. Там же миллион таких строк.
    От куда вы вообще берете такие "познания"?
     
  14. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Правильно мыслишь.
    Зачем строку? Можно хэш чанка. У каждого чанка свой хэш. Считать можно примерно так:
    PHP:
    public static int hash(Chunk chunk) {
        return 
    hash(chunk.getWorld(), chunk.getX(), chunk.getZ());
    }

    public static 
    int hash(World worldint chunkXint chunkZ) {
        return 
    world.hashCode() + 32765 chunkX 32767 chunkZ;
    }
    Этот же хеш можно будет использовать в качестве ключа в какой-нибудь мапе вида Map<Integer, Set<ArmorStandData>>
    Собственно, таким образом можно будет реализовать довольно быструю очистку информации при выгрузке чанка (дабы не перебирать все элементы).
     
  15. CoolBoy

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

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    Ого, отсыпь мне тоже.
    Это же тот самый тип людей, который борется за каждый байт памяти.
    (21 век блджад, 16 гб оперативы на пк это уже норма, но ноунеймы на форуме все ещё пытаются сохранить 10 байт памяти)

    А если серьезно, то начать можно с того, что Map хранит не объекты, а ссылки на них. Твой AC уже существует в памяти отдельно, а мапа по ключу будет лишь ссылаться на него.
    И на этом, пожалуй, можно и закончить.

    И вообще преждевременная оптимизация - это очень плохо. Начинать заниматься оптимизацией нужно только после возникновения проблем с ней.
     
  16. alexandrage

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

    Баллы:
    173
    Как он вообще не боится сервер запускать :D. Там же так много всего в нем. Голова опухнет.
     
  17. volk_alex

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

    Баллы:
    61
    Имя в Minecraft:
    volk_alex
    Н-да... Соглашусь. Фигню сморозил (не надо мне на ночь глядя давать слова писать). Однакож колличество информации все же вызывает у меня беспокойство, точнее количество операций записи/чтения, а так же операции сериализации и десериализации.
    Про занятие оптимизацией там, где этого не нужно - каюсь, грешен. Хочется сделать все сразу хорошо, чтоб ничего потом переделывать не пришлось. Хотя уже сейчас что-то из старого приходится переделывать. Я Вас понял и постараюсь больше такой ерундой без необходимости не заниматься, но не обещаю, потому что хочется :)
    Про хэш - мысль интересная, но для меня не подходит, т.к. в одном и том же чанке могут находится несколько АС. Я ещё не до конца понял сериализацию и в ближайшие недели планирую плотно заняться изучением этого вопроса и возможно найду для хеша применение.
    Спасибо большое за ваши ответы. Вы мне очень сильно помогаете двигаться вперёд :)
     
  18. alexandrage

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

    Баллы:
    173
    Ты похоже не понимаешь вообще как это работает. Причем тут твои сериализации и десериализации? Ты всего лишь работаешь с гетерами и сетерами.
     
  19. CoolBoy

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

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    Тут смысл в том, что пока ты эволюционируешь в плане кода - весь твой более-менее старый код будет казаться тебе говном. И если ты только начал этим заниматься - советую не пытаться сделать сразу идеально - не выйдет, просто из-за отсутствия опыта. Думаешь что написал идеально, а через год твой старый код будет для тебя казаться дырявым ведром из костылей. Тру стори.
     
  20. Dymeth

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

    Баллы:
    98
    Имя в Minecraft:
    Dymeth
    Я понимаю. Именно поэтому в моём прошлом ответе в качестве значения элемента мапы был указан не просто ArmorStandData, а Set<ArmorStandData>
     

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