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

Помогите Нагрузка на сервер

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

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

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

    Баллы:
    68
    Предположим, делаем такой плагин:
    Стив пошёл в отпуск. Идёт по полю/лесу. На ходу автоматически рвёт цветочки, пинает грибы...
    Уход в отпуск игрок оформляет командой: /отпуск on
    Возврат из отпуска соответственно: /отпуск off
    Также возможен отзыв игрока из отпуска при логоуте и таймауте.
    При уходе в отпуск очередного игрока пополняется массив-список "отпускников".
    При возврате из отпуска игрок из списка вычёркивается.
    Чтобы оформить пинание грибов и срыв цветов регистрируем обработчик события onMove.

    И вот тут возникает вопрос.
    Обработчик будет вызываться при каждом движении каждого игрока, что, подозреваю, будет притормаживать сервер. Тем более, как минимум, в начале обработчика будет проверяться список "отпускников", нужно ли для этого игрока проверять наличие цветов/грибов в шаговой доступности.

    Так вот сам вопрос: имеется ли возможность отключать и снова включать обработчик?
    Обработчик регистрируется при загрузке сервера. Потом вроде имеется возможность сделать setCancelled для него, чтобы сервер больше не вызывал его. Но я не нашёл возможности снова его включить. А так бы включать его только если игрок пошёл в отпуск и отключать, когда ни одного игрока нет в списке "отпускников".
    Возможно я не так понимаю физику процесса, но думаю, свою мысль донёс доступно. :)
    Или не стоит этим заморачиваться и не такая уж и нагрузка это?

    И попутно, чтобы не плодить темы. Есть ли какой-то штатный класс в буккитAPI, который инициализирует клик ПКМ? Т.е. полностью: клик ПКМ по указанному блоку с указанной стороны, проверка, что находится в руке, выполнение соответствующего действия (установка факела, блока, переключение переключателя и пр.) и при необходимости производились бы действия с инвентарём в руке (уменьшение количества или подобное).
    Вариант с block.setType() не нравится, так как не учитывается [не]возможность установки данного блока в конкретном месте. В итоге возможна установка блока в воздухе. Или надо самостоятельно анализировать окружающую среду. :-(
    Смотрел в сторону setUseItemInHand & useItemInHand, как и setUseInteractedBlock, но не уловил, можно ли воспользоваться ими. Если, да, то хотелось бы пример.
     
  2. Хостинг MineCraft
    <
  3. Ission

    Ission Старожил Девелопер Пользователь

    Баллы:
    173
    Skype:
    lokivava
    На счёт нагрузки не буду ничего говорить. Всё же это зависит от ситуации и конкретный случай для меня не самый ясный, но да, PlayerMoveEvent не лучший вариант.
    Обработчики можно включать и выключать когда вздумается, для этого каждого события есть статичный метод getHandlerList(), от которого можно вызвать unregister(Listener).
    Если я правильно понял, то требуется универсальнео событие, нет, такого события нет. У события PlayerInteractEvent можно при помощи getAction() проверить куда и какой кнопкой ткнул игрок(ЛКМ/ПКМ, на воздух/на блок). Всё же написали вы несколько скомкано и суть второго вопроса понять не удалось.
     
  4. Автор темы
    tuder

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

    Баллы:
    68
    Угу. Если можно отключать, буду копать.

    По второму вопросу. Нужно не отловить событие, а эмулировать его.
    Например, игрок встал на определённую локацию с рубином в руке, при этом плагин эмулирует нажатие ПКМ на каком-то блоке(скажем выключателе/рычаге) в удалении от игрока. После чего обнулит количество рубинов в руке. С последним нет проблем, в отличии от первого. Или аналогично с факелом в руке. Факел должен установиться на блок с каким-то координатами и количество факелов у игрока уменьшится. Только без интеракта от игрока, а "само собой". Встал куда-то - ПКМ сработал.
     
  5. LaoTheLizard

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

    Баллы:
    103
    Skype:
    sgp_the_controller
    Похоже, речь идет о костыле 80 уровня.
     
  6. Ission

    Ission Старожил Девелопер Пользователь

    Баллы:
    173
    Skype:
    lokivava
    В таком случае я могу предложить следующий вариант, как рабочий. Отслеживать положение игроков в текущем мире раз в 1 секунду, если находится в нужной точке, то использовать setblock от Block или update от BlockState. Если нужно так же бросать соответствующее событие.
     
  7. Автор темы
    tuder

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

    Баллы:
    68
    Мммм?
    Я делаю так:
    Код:
    Block b = world.getBlockAt(loc);
    b.setType(id);
    
    Про это речь?

    Но при этом не проверяется корректность установки блока. Возможна замена блока в воздухе. При ПКМ блок земли в воздух не установишь. При setType по координатам - легко. :-(
    Приходится проверять самому, что под местом установки не воздух или не жидкость...
    Код:
    loc.setY(loc.getY() - 1);
    Material ground = w.getBlockAt(loc).getType();
    
    Поэтому и хотелось бы воспользоваться готовым типовым классом установки блока, а не мастерить костыль 80-го уровня. :) Но похоже такого таки нет?

    Здесь: org.bukkit.block.Block я не вижу setblock...

    И ышо. Заметил, что когда делаю setType("RED_ROSE"), то устанавливаются случайным образом совершенно разные цветочки. :cool: Различие в метаданных?
    getData()/SetData()
    Deprecated. Magic value
    Gets/Sets the metadata for this block

    Но это Deprecated. Как быть? Что взамен?
     
  8. serega6531

    serega6531 Старожил Девелопер Пользователь

    Баллы:
    173
    Skype:
    shkurovs
    Deprecated абсолютно ни на что не влияет. Они никогда не будут удалены.
     
  9. Den_Abr

    Den_Abr Старожил Девелопер Пользователь

    Баллы:
    173
    Skype:
    Den_Abr
    Имя в Minecraft:
    Den_Abr
    Ничего, так как Deprecated были отмечены все подобные методы. Разработчики буккита планировали переходить на новую систему id/data, но не успели, т.к. буккит умер.
     
  10. Автор темы
    tuder

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

    Баллы:
    68
    Косяк свой я понял. Для установки блока я использовал только тип блока, а не весь Item.
    Код:
    Block b = world.getBlockAt(loc);
    Material id = player.getItemInHand().getType();
    b.setType(id);
    
    Но не могу найти, как блоку присвоить все данные.
    Скажем
    ItemStack id =player.getItemInHand();
    b.setType( id.getType()); // проходит без проблем
    b.setData( id.getData()); // это Idea не пропускает. :-( setData в блок не может применяться.

    В общем, вытаскиваю с помощью
    getData() из дубовых досок в руке:
    GENERIC UP WOOD(0)
    а из еловых досок
    REDWOOD UP WOOD(1)
    Как мне это применить к устанавливаемому блоку?
     
  11. CraftCoder

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

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    b.setDurability(ТУТ ЧИСЛО КОТОРОЕ ПОСЛЕ ДВОИТОЧИЯ).
     
  12. Автор темы
    tuder

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

    Баллы:
    68
    Ээээ? :confused: У блока нет такого метода. Только у итемов.
    И вообще, при чём тут прочность? Если мне надо задать вид досок: берёза/дуб/сосна...
     
  13. serega6531

    serega6531 Старожил Девелопер Пользователь

    Баллы:
    173
    Skype:
    shkurovs
    Это логика баккита, не пытайтесь понять её.
     
  14. Автор темы
    tuder

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

    Баллы:
    68
  15. JustBlender

    JustBlender Старожил Девелопер Пользователь

    Баллы:
    123
    Skype:
    justblender
    Имя в Minecraft:
    JustBlender
    b.setData(id.getData().getData());
     
  16. Автор темы
    tuder

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

    Баллы:
    68
    Вау. Интересно. :)
    Но второй getDate тоже будет Deprecated.

    Выкрутил уже решение всё же через Durability:
    Код:
    ItemStack id =player.getItemInHand();
    short md = id.getDurability();
    
    b.setType( id.getType());
    b.setData((byte) md);
    
     

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