Войти или зарегистрироваться

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

  • Автор темы Автор темы DPOH-VAR
  • Дата начала Дата начала

DPOH-VAR

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

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

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

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

Подключаю к теме fromgate
Это был бы хороший активатор для ReActions и событие для VarScript
 
Хм... слушай, а как "тикает" время? Было бы хорошо создать событие на основе механизма тиканья.

Можно просто в тик осуществлять проверку времени. Единственное, если "ни тиком раньше ни тиком позже" - при лагах можно полночь и пропустить.
Или нет? Если это будет реально каждый тик, то время не пропустим - даже если какие-то тики "растянулись"?

По второму - нужно рассчитать 24000 тиков оставшихся до полуночи от текущего времени. Сутки измеряются именно в тиках? Если да, то это будет нормальный метод, но нужно действительно отслеживать корректировку по времени.
 
Хм... слушай, а как "тикает" время? Было бы хорошо создать событие на основе механизма тиканья.
тик - это дискретизация игрового времени. Время в игре измеряется с помощью тиков (вектор скорости - это блок/тик, время задержки у рипитеров, скорость роста кактуса и др.)
Когда сервер лагает - тики идут чуть медленнее. Как только лаги прошли - тики ускоряются и догоняют время. Но тики никогда не пропускаются.

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

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

Второй способ отпадает, т.к. нет события WorldTimeChangeEvent

Все сводится к ежетиковому перебору зарегистрированных задач.
Может, все-таки подобное где-то уже было реализовано?
 
Когда сервер лагает - тики идут чуть медленнее. Как только лаги прошли - тики ускоряются и догоняют время. Но тики никогда не пропускаются.
При фризе более 2 секунд выполнится лишь 40 тиков.

Второй способ отпадает, т.к. нет события WorldTimeChangeEvent
Буквально 5 минут на модификацию и у Вас будет такой эвент.
Если не хотите модифицировать ядро, то можно, например, запустить повторяющийся, синхронизированный BukkitScheduler с задержкой в один тик и работать на нем, все просто.
 
При фризе более 2 секунд выполнится лишь 40 тиков.


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

Тоже придерживаюсь мнения что последний вариант - лучший. Не нужно городить модификации и тд.
В случае с синхронизированным таском будет всё работать на ура. Если сервер повиснет - повиснет и таск)
 
Можно создать новую ежетиковую синхронизированную задачу, которая будет сверять текущее время с ближайшим зарегистрированным моментом времени и во время соответствия вычислять новый ближайший момент и вызывать событие, которое мы будем обрабатывать, как и любое стандартное.
 
Думаю, для того, чтобы затрачивать меньше ресурсов.
Можно сделать функцию, которая будет уменьшать кол-во пропускаемых тиков, при приближении к заданному числу.
Т.е. Допустим мы поставили ивент на 20к-ный тик.
время 1к. Следующая проверка 200 тиков. И с приближением шаг уменьшается.
Ресурсоемкость такой программы относительно уменьшена, т.к. она фактически стоит в режиме ожидания.
Тики - переводим в настоящую еденицу времени - и вводим нужные константы.
В случае изменения времени - время либо приближается к заданному, либо отдаляется - взависимости от чего шаг либо уменьшается - либо увеличивается;)
 
Думаю, для того, чтобы затрачивать меньше ресурсов.
Можно сделать функцию, которая будет уменьшать кол-во пропускаемых тиков, при приближении к заданному числу.
Т.е. Допустим мы поставили ивент на 20к-ный тик.
время 1к. Следующая проверка 200 тиков. И с приближением шаг уменьшается.
Ресурсоемкость такой программы относительно уменьшена, т.к. она фактически стоит в режиме ожидания.
Тики - переводим в настоящую еденицу времени - и вводим нужные константы.
В случае изменения времени - время либо приближается к заданному, либо отдаляется - взависимости от чего шаг либо уменьшается - либо увеличивается;)
  1. И зачем поднимать доисторическую тему?
  2. Лучше проверять тики в отдельном потоке.
 
Ололо.
В произвольный момент (onEnable, например), посмотреть, какое сейчас время в мире, и запланировать исполнение через разницу до полуночи. Можно сразу repeatable запланировать, с частотой = суткам.
Единственное, что сейчас ядра пропускают тики при сильной загрузке, и я не уверен, что пропущенные тики будут учтены в планировщике.
 
Ололо.
В произвольный момент (onEnable, например), посмотреть, какое сейчас время в мире, и запланировать исполнение через разницу до полуночи. Можно сразу repeatable запланировать, с частотой = суткам.
Единственное, что сейчас ядра пропускают тики при сильной загрузке, и я не уверен, что пропущенные тики будут учтены в планировщике.
Меняем время. Профит.
 
В общем, программист сам должен выбрать баланс между точностью полночи и затрачиваемыми ресурсами.
 
Назад
Верх