Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

Идея Ограничение блоков на чанк

Тема в разделе "Запросы на разработку плагинов", создана пользователем iLapMbDev, 18 дек 2014.

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

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

    Баллы:
    61
    Имя в Minecraft:
    JaceTwice
    Существует ли плагин, который ставит ограничение определенных блоков на чанк? Допустим, чтобы в одном чанке нельзя было ставить больше 6 солнечных панелей и т.п. Если есть, то подскажите название, а лучше поделитесь ссылочкой. Если нет, то кто смог бы написать, бесплатно или за денежное вознаграждение. Спасибо. Если что, выдел подобный плагин на wim.su, на старом Industrial.
     
  2. Хостинг MineCraft
    <
  3. LaoTheLizard

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

    Баллы:
    103
    Skype:
    sgp_the_controller
    Ради интереса сочинил на эту тему процедуру. Проверено - работает. Только не уверен, что нет более простого и элегантного способа это сделать. Интересует мнение специалистов.

    @EventHandler
    public void onSetBlock(BlockPlaceEvent event){
    Player p = event.getPlayer();
    Material limited = Material.GOLD_BLOCK; //лимитируемый блок
    Block set = event.getBlockPlaced();
    if(set.getType() != limited){ return; }
    int maxnumber = 10; // лимит количества таких блоков на чанк
    int number = 0;
    Chunk checkchunk = set.getLocation().getChunk();
    for (x = 0; x < 16; ){
    for (y = 0; y < 128; ){
    for (z = 0; z < 16; ){
    Material check = checkchunk.getBlock(x, y, z).getType();
    if(check.equals(limited)){number++;}
    //log.info(x + " " + y + " " + z + " : " + check.toString());
    z++;
    }
    y++;
    }
    x++;
    }
    if(number > maxnumber){event.setCancelled(true);p.sendMessage("Limit of this block exceed.");}
    }
     
    Последнее редактирование: 21 дек 2014
  4. Автор темы
    iLapMbDev

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

    Баллы:
    61
    Имя в Minecraft:
    JaceTwice
    Можешь оформить в полноценный рабочий плагин, желательно с конфигом (туда вносить блоки, и было бы не плохо ID)? Я заплачу.
     
  5. LaoTheLizard

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

    Баллы:
    103
    Skype:
    sgp_the_controller
    Стучи в скайп - может, договоримся.
     
  6. saharin94

    saharin94 Старожил Пользователь Заблокирован

    Баллы:
    173
    Skype:
    RikkiLooh
    Имя в Minecraft:
    RubukkitDniwe
    1. Высота чанка - 256
    2. Перебор 65536 (16x16x256) блоков при установке каждой пОнели неплохо нагрузит сервер.
     
  7. LaoTheLizard

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

    Баллы:
    103
    Skype:
    sgp_the_controller
    Согласен. Хотя перебор идет только при установке именно конкретного блока (конечно же, можно сделать не один, а набор блоков и лимитов). Ну, в общем, я попробовал на тестовом - вроде мгновенно считает. Не будут же они пытаться ставить эти блоки ежесекундно? Ну, возможно, в начале чуток переберут, а потом, "обжегшись" десяток раз, уже не будут постоянно пытаться поставить много блоков. И "нагрузка" будет достигать некоего пика лишь тогда, когда новички будут "учиться" местным особенностям.

    Тем не менее, я не спорю. Потому ранее спросил у аудитории, нет ли более изящного способа подсчитать количество определенных блоков в чанке.

    Разгрузить процесс можно, если слушать еще и ломание блоков. То есть, при достижении лимита блоков чанк вносить в некий список забаненных и в дальнейшем просто проверять, не входит ли чанк в этот список. А уже из этого списка убирать чанк тогда, когда сломан один лимитированный блок и в чанке их стало меньше максимума. Однако, спорный вопрос: что сильнее нагрузит сервер - дополнительный "слушатель" на ломание блоков или все-таки перебор всего чанка каждый раз, когда установлен блок определенного типа.

    P.S. И, кстати, у меня в коде высота чанка равна 128. Цифру я взял, руководствуясь этим: http://jd.bukkit.org/rb/doxygen/d6/d90/interfaceorg_1_1bukkit_1_1Chunk.html
    И, кстати, зря я так поступил. :) Проверил, изменил.

    Что ж, это натолкнуло меня на мысль, что в настройках неплохо бы указывать пределы отслеживания. Кому придет в голову ставить блоки выше 200, например? Ну и нефиг тогда проверять, правильно?

    Надо сказать, что автор наверняка неточно выразил свою мысль и на самом деле речь не о чанке, а о некотором объеме. В таком случае можно проверять не чанк, а просто некий куб пространства вокруг блока, с заданным "радиусом".
     
    Последнее редактирование: 21 дек 2014
  8. deadanykey

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

    Баллы:
    96
    Я бы шедулер подтянул, что ли
     
  9. Eugenie

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

    Баллы:
    21
    Имя в Minecraft:
    zn_soft
    "в одном чанке нельзя было ставить больше 6 солнечных панелей"
    а нельзя это просто контролировать при установке блоков ?.. просто считать/хранить в базе их и запрещать в случае чего ... будет время реализую покажу, но пока не вижу применения этому плагину
     
  10. CraftCoder

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

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Проблема в том, что при подсчете будет не хилая нагрузочка.
     
  11. Eugenie

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

    Баллы:
    21
    Имя в Minecraft:
    zn_soft
    с какого перепугу ?

    вы меня не поняли !

    реализуется так (под рукой эклипса нет поэтому могу насчет методов классов/интерфейсов баккита ошибаться):
    public HashMap<Chunk,HashMap<Block,int>> КоличестваБлоковВЧанках;
    затем в методе события
    onBlockPlace(event){
    ВЧанке = КоличестваБлоковВЧанках.Get(event.getPlayer().getLocation().getChunk());
    int i = ВЧанке.Get(event.getBlock());
    i++;
    if(i>6)p.SendMessage("ЭЭЭЭ низя больше 6 блоков "+event.getBlock().GetName());
    ВЧанке.Set(event.getBlock(),i);

    }

    никаких циклов !
    все делается за одну итерацию
    ненужно пересчитывать весь чанк , зачем ? в задаче этого не упоминалось !
    единственное что эту структуру придется сериализовать, сохранять и загружать при перезапуске сервера
    причем такая структура будет небольшой (декартово произведение блоков на "тронутые" чанки) если ориентироваться в ограничениях на один блок то еще проще и меньше
    единственно что я б всетаки учел еще блокировку данных и использовал синхронизацию на случай если в одном чанке работают одновременно 10 человек и все одновременно поставят этот блок , но проблема решаема заменой HashMap на LinkedHashMap
     
    Последнее редактирование: 1 мар 2015
  12. CraftCoder

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

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Этот метод вызывает у меня сомнения насчет оптимальности использования ОЗУ. Но этот алгоритм можно использовать только при старте сервера, когда еще никто не ставил эти блоки.
     
  13. LaoTheLizard

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

    Баллы:
    103
    Skype:
    sgp_the_controller
    Поддерживаю.
     
  14. ptnk

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

    Баллы:
    173
    Java сама по себе вызывает сомнение насчёт оптимальности использования ОЗУ, поэтому не нужно про это писать. Мегабайтом больше/Мегабайтом меньше - ничего не поменяется.

    Всё что нужно для реализации данной проблемы - постепенно обходить чанки в различных тиках и вести подсчёт количества нужных блоков. Как только чанк будет считаться "расчитанным", то на таком чанке производим контроль изменения блоков: установка, ломание, взрывание. Никаких больших сложностей здесь нет, всё же здесь нужно - это правильная логика.

    p.s. для всех объектов bukkit'а лучше делать различные врапперы, а не пользоваться оригинальными объектами. Т.е. очень сомнительно пользоваться оригинальными Chunk/Block/Location, в особенности если нет понимания полной работы Контейнеров, хешфункции, equals, и нет уверенности, что адрес всегда будет один и тот же.
    Это единственное, в чём я увидел сомнение. Проще ChunkWrapper свой сделать, который будет иметь пару полей и переопределённые методы, чтобы можно было equals сделать с Chunk.
     
  15. Eugenie

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

    Баллы:
    21
    Имя в Minecraft:
    zn_soft
    насчет памяти скажу: сколько по вашему чанков "открывают" игроки всего? давайте прикинем, что игроки открыли мир 5000х5000 это будет всего 97656 чанков, если уж так беспокоиться за память то применить простой массив типа
    public int i[97656];
    и в коде из координат чанка высчитывать позицию в массиве с инкрементом в этом случае JVM использует всего 97656*sizeof(int)4 = 390624 байта или 381 килобайт озу... это много ? а если массив байт то вообще 96 килобайт ...
    по поводу использования лишь на свежих серверах , можно написать отдельную обработочку на любом языке которая "пробежит" за ночь по всем чанкам карты (вне сервера просто операция над файлами) и создаст базу заполнения (снимок сервера). либо и вправду постепенно обходить все чанки в параллельном потоке но это нагрузка на серв

    по поводу враперов я всеж не понял зачем, но звучит умно ) пожалуй возьму на заметку, тем более я новичек как в джаве так и в бакките , ранее на шарпе на плюсах писал :)
    правда пока не до конца понял зачем. Может из за того что неизвестно как реализована equals у класса в бакките?
     
  16. Shevchik

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

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Таки у Location есть equals, так что можно использовать его. А чанка точно нет, у блока вроде был.
    Проблема в контроле эвентами в том что ТС хочет на котёл, а там половину вещей эвентами не покрывается.
     
  17. ptnk

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

    Баллы:
    173
    Location отваливается в случае перезгрузки мира.
     
  18. Eugenie

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

    Баллы:
    21
    Имя в Minecraft:
    zn_soft
    что значит "отваливается" ? после перезагрузки меняются координаты или хэш меняется ?
     

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