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

Помогите Событие по времени суток в Bukkit

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

  1. Автор темы
    DPOH-VAR

    DPOH-VAR Старожил Пользователь

    Баллы:
    153
    Skype:
    dpohvar
    Прошу помощи в реализации такой фичи:
    выполнять определенное действие по времени в майнкрафте.
    Например, каждую полночь в мире World исполнять команду.
    Обязательное условие, чтобы команда исполнялась ровно в полночь, ни тиком раньше, ни позже.

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

    Вариант 2:
    Сутки длятся 24000 тиков. Поэтому можно запускать BukkitTask с периодом в 24000 тиков, и постоянно исполнять действие. Но вдруг кто изменит время? Тогда придется уничтожать BukkitTask, делать пересчет времени и потом запускать задачу снова. Это недостаток этого метода.

    Есть ли более простой способ?

    Подключаю к теме fromgate
    Это был бы хороший активатор для ReActions и событие для VarScript
     
  2. Хостинг MineCraft
    <
  3. Автор темы
    DPOH-VAR

    DPOH-VAR Старожил Пользователь

    Баллы:
    153
    Skype:
    dpohvar
    тик - это дискретизация игрового времени. Время в игре измеряется с помощью тиков (вектор скорости - это блок/тик, время задержки у рипитеров, скорость роста кактуса и др.)
    Когда сервер лагает - тики идут чуть медленнее. Как только лаги прошли - тики ускоряются и догоняют время. Но тики никогда не пропускаются.

    с помощью BukkitScheduler можно вклиниваться в каждый тик и выполнять что-то в нем. Это гарантирует, что каждый игровой тик будет нами обработан, и в игровых сутках наша задача запустится ровно 24000 раз.

    Все сводится к созданию одного сервиса, который будет манипулировать такими задачами.
    К примеру так:
    Код:
    EveryDayTask task = EveryDayService.register(runnable,18000,world);
    ...
    EveryDayService.unregister(task);
    или
    task.unregister();
    [DOUBLEPOST=1378311756,1378310948][/DOUBLEPOST]Второй способ отпадает, т.к. нет события WorldTimeChangeEvent

    Все сводится к ежетиковому перебору зарегистрированных задач.
    Может, все-таки подобное где-то уже было реализовано?
     
  4. gamelax

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

    Баллы:
    103
    Имя в Minecraft:
    gamelax
    При фризе более 2 секунд выполнится лишь 40 тиков.

    Буквально 5 минут на модификацию и у Вас будет такой эвент.[DOUBLEPOST=1378334133,1378333082][/DOUBLEPOST]Если не хотите модифицировать ядро, то можно, например, запустить повторяющийся, синхронизированный BukkitScheduler с задержкой в один тик и работать на нем, все просто.
     
  5. Jampire

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

    Баллы:
    173
    Skype:
    jampire-h
    Имя в Minecraft:
    Jampire
    Тоже придерживаюсь мнения что последний вариант - лучший. Не нужно городить модификации и тд.
    В случае с синхронизированным таском будет всё работать на ура. Если сервер повиснет - повиснет и таск)
     
  6. Ission

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

    Баллы:
    173
    Skype:
    lokivava
    Можно создать новую ежетиковую синхронизированную задачу, которая будет сверять текущее время с ближайшим зарегистрированным моментом времени и во время соответствия вычислять новый ближайший момент и вызывать событие, которое мы будем обрабатывать, как и любое стандартное.
     
    HoShiMin нравится это.
  7. ApaDoctor

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

    Баллы:
    103
    Думаю, для того, чтобы затрачивать меньше ресурсов.
    Можно сделать функцию, которая будет уменьшать кол-во пропускаемых тиков, при приближении к заданному числу.
    Т.е. Допустим мы поставили ивент на 20к-ный тик.
    время 1к. Следующая проверка 200 тиков. И с приближением шаг уменьшается.
    Ресурсоемкость такой программы относительно уменьшена, т.к. она фактически стоит в режиме ожидания.
    Тики - переводим в настоящую еденицу времени - и вводим нужные константы.
    В случае изменения времени - время либо приближается к заданному, либо отдаляется - взависимости от чего шаг либо уменьшается - либо увеличивается;)
     
  8. gamerforEA

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

    Баллы:
    143
    Skype:
    sk2000sk1
    Имя в Minecraft:
    gamerforEA_MCPC
    1. И зачем поднимать доисторическую тему?
    2. Лучше проверять тики в отдельном потоке.
     
  9. Reality_SC

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

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Ололо.
    В произвольный момент (onEnable, например), посмотреть, какое сейчас время в мире, и запланировать исполнение через разницу до полуночи. Можно сразу repeatable запланировать, с частотой = суткам.
    Единственное, что сейчас ядра пропускают тики при сильной загрузке, и я не уверен, что пропущенные тики будут учтены в планировщике.
     
  10. Dereku

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Меняем время. Профит.
     
  11. Reality_SC

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

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    В общем, программист сам должен выбрать баланс между точностью полночи и затрачиваемыми ресурсами.
     

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