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

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

Discussion in 'Разработка плагинов для новичков' started by tuder, Mar 11, 2015.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Но при этом не проверяется корректность установки блока. Возможна замена блока в воздухе. При ПКМ блок земли в воздух не установишь. При setType по координатам - легко. :-(
    Приходится проверять самому, что под местом установки не воздух или не жидкость...
    Code:
    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 Старожил Девелопер Пользователь

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

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

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

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

    Trophy Points:
    68
    Косяк свой я понял. Для установки блока я использовал только тип блока, а не весь Item.
    Code:
    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 Старожил Пользователь

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

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

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

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

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

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

    Trophy Points:
    68
  15. JustBlender

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

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

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

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

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

Share This Page