Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Помогите Как сделать задержку на ивент для определенного игрока?

Статус
Закрыто для дальнейших ответов.

Нейн

Активный участник
Пользователь
Баллы
66
Имя в Minecraft
AmokDev
Доброго времени суток, ребят!

Я хочу сделать так, чтобы игрок мог использовать PlayerMoveEvent только раз в 30 секунд (нет, не чтобы не мог поворачивать или ходить, просто чтобы на стороне плагина ивент не активировался)

Можете пожалуйста подсказать, как это сделать правильно? Я попробовал сделать список с никами игроков, но что-то тема такая не продвинулась дальше (я не понял как сделать так, чтобы игрок удалялся из списка четко по времени :<)

Надеюсь на вашу помощь! :cry:
 
Храни в списке время добавления в список для каждого игрока (System.currentTimeMills()), при использовании - сравнивай с текущим временем и удаляй из списка, если прошло больше 30 секунд.
 
Храни в списке время добавления в список для каждого игрока (System.currentTimeMills()), при использовании - сравнивай с текущим временем и удаляй из списка, если прошло больше 30 секунд.
Только начал про это писать))

Да, вот будет как-то так:
HashMap<String, Long> playerMoveEventCooldown = new HashMap<>();

Когда игрок выполняет ивент, то:
1. Если игрока нет в map, добавить его:
Код:
playerMoveEventCooldown.put(player, System.currentTimeMills() + 30000)
и разрешить выполнение события.

2. Если игрок в map есть, то получить время из map. Если время из map >= System.currentTimeMills(), то перезаписать новое время в map (System.currentTimeMills() + 30000) и разрешить выполнения события.

3. Если игрок в списке есть и время из map < System.currentTimeMills(), то ничего не обновлять в map и сразу делать return; в коде.

Таким образом, в map будет храниться ник и время после которого будет разрешено использовать событие.
 
Только начал про это писать))

Да, вот будет как-то так:
HashMap<String, Long> playerMoveEventCooldown = new HashMap<>();

Когда игрок выполняет ивент, то:
1. Если игрока нет в map, добавить его:
Код:
playerMoveEventCooldown.put(player, System.currentTimeMills() + 30000)
и разрешить выполнение события.

2. Если игрок в map есть, то получить время из map. Если время из map >= System.currentTimeMills(), то перезаписать новое время в map (System.currentTimeMills() + 30000) и разрешить выполнения события.

3. Если игрок в списке есть и время из map < System.currentTimeMills(), то ничего не обновлять в map и сразу делать return; в коде.

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

Спасибо Вам огромное! Я хотел сделать аналогично, исходя из опыта в Python, но не понял как, ОГРОМНЕЙШАЯ Благодарность!
 
Только начал про это писать))

Да, вот будет как-то так:
HashMap<String, Long> playerMoveEventCooldown = new HashMap<>();

Когда игрок выполняет ивент, то:
1. Если игрока нет в map, добавить его:
Код:
playerMoveEventCooldown.put(player, System.currentTimeMills() + 30000)
и разрешить выполнение события.

2. Если игрок в map есть, то получить время из map. Если время из map >= System.currentTimeMills(), то перезаписать новое время в map (System.currentTimeMills() + 30000) и разрешить выполнения события.

3. Если игрок в списке есть и время из map < System.currentTimeMills(), то ничего не обновлять в map и сразу делать return; в коде.

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

Извиняюсь, возможно вопрос прозвучит очень глупо, но я не понимаю как сохранить переменную с HashMap так, чтобы она хранила в себе данные постоянно, а не перезаписывалась при новом вызове ивента. Я пробовал выставить ее глобально в классе Plugin.java , но это мне не помогло.

Обязательно ли сохранять в какой-то конфиг объект хешмапа или можно как-то более размуно это реализовать?

p.s Структура проекта такова:
2023-05-21-19-43-14.png
 
Я у себя для этого отдельный сервис завел: https://pastebin.com/EdmtVrAq
Из любой точки кода вызываю:

Код:
 if(cooldownService.cooldown(p, "global-chat", 5)) {
    // Делаем что-то, если на игрока не записано 5-ти секундной задержки по тегу 'global-chat'
}
 
Я у себя для этого отдельный сервис завел: https://pastebin.com/EdmtVrAq
Из любой точки кода вызываю:

Код:
 if(cooldownService.cooldown(p, "global-chat", 5)) {
    // Делаем что-то, если на игрока не записано 5-ти секундной задержки по тегу 'global-chat'
}

Простите, это не помогло решить мою проблему, я так и не понял как сохранить глобально мой HashMap :oops:
 
Если ты создал глобальную переменную (в классе вне метода) и занёс в нее какие-то значение а после их не удалял, то исчезнуть они могут только после перезагрузки плагина.

А лучше покажи код
 
Странно, вроде должно быть все нормально. Возможно из-за статики, Я не знаю, много слышал что из-за нее бывают проблемы. Не знаю, попробуй в классе слушателя создать глобальную Мапу не статическую и работай с ней, может поможет
 
Извиняюсь, возможно вопрос прозвучит очень глупо, но я не понимаю как сохранить переменную с HashMap так, чтобы она хранила в себе данные постоянно, а не перезаписывалась при новом вызове ивента. Я пробовал выставить ее глобально в классе Plugin.java , но это мне не помогло.
Не понял вопроса.
Если тебе нужно хранить данные между рестартами, тебе придется как-то хранить данные, будь то запись в конфиг, или ещё чего.
Если речь про то, что КД работает некорректно, убедись, что проходишь по всем шагам, описанным NuaN.
 
Не понял вопроса.
Если тебе нужно хранить данные между рестартами, тебе придется как-то хранить данные, будь то запись в конфиг, или ещё чего.
Если речь про то, что КД работает некорректно, убедись, что проходишь по всем шагам, описанным NuaN.

Я поместил хешмап в класс самого ивента и все нормально сохраняется, но теперь почему-то при сравнивании числа из списка игроков и System.currentTimeMills() все идет наперекосяк, будто эта часть кода напрочь пропускается.

p.s Мой код сравнения: https://pastebin.com/xxmyArH0
p.ss Player s = (Player) sender;
 
Ну во-первых, вместо == null используй Map#containsKey(или Map#contains, не помню точно), возможно срабатывает условие там где просто return.

Проверь какое из условий срабатывает
 
Проверь какое из условий срабатывает

Странно, почему-то срабатывает постоянно лишь условие ">"

Ну во-первых, вместо == null используй Map#containsKey(или Map#contains, не помню точно), возможно срабатывает условие там где просто return.
Нет, как раз-таки предметы бесконечно спавнятся и я не понимаю, почему же срабатывает именно условие ">", я уже отчаялся и попробовал ">=", но тут тоже пинок в спину :oops:

Мой мозг уже превратился в
imgonline-com-ua-Resize-xx-J3-D8-Xq-BJe-N7p-Kd.png
 
и я не понимаю, почему же срабатывает именно условие
Попробуй сделать дебаг, например, выводить значения из map и другие нужные переменные в чат или через System.out.println. Рано или поздно поймешь что не так работает. А просто гадать можно очень долго.
 
А зачем ты добавляешь в Мапу в условии, в котором значение из нее больше чем текущие миллисекунды? Мне кажется наоборот, там где меньше, там и нужно добавлять(ну, на самом деле я не очень понимаю вообще что ты делаешь, так что это лишь предположение)
 
значение из нее больше чем текущие миллисекунды?
Значение в мапе означает время, когда можно будет использовать ивент повторно. Поэтому к текущему времени прибавляем 30 сек. Это я так предложил, а вообще можно и по-другому реализовать.
 
Попробуй сделать дебаг, например, выводить значения из map и другие нужные переменные в чат или через System.out.println. Рано или поздно поймешь что не так работает. А просто гадать можно очень долго.

Сделал дебаг и почему-то постоянно срабатывает условие >=
https://pastebin.com/yPz7n1PX

Я окончательно запутался :rolleyes:

Ниже у меня есть щедуллер:
https://pastebin.com/KZPh0PDG
Сама логика кулдауна:
https://pastebin.com/qd4tmfPZ
 
Последнее редактирование:
Сделал дебаг и почему-то постоянно срабатывает условие >=
https://pastebin.com/yPz7n1PX

Я окончательно запутался :rolleyes:

Ниже у меня есть щедуллер:
https://pastebin.com/KZPh0PDG
Сама логика кулдауна:
https://pastebin.com/qd4tmfPZ
Судя по всему, в оригинальном алгоритме NuaN небольшая проблема, которая и у тебя отразилась. Когда значение из мапы больше текущего времени, ничего делать не нужно.
PHP:
Long untilMs = plrs.get(s.getName());
if (untilMs == null || untilMs < System.currentTimeMillis()) {
    s.sendMessage("Время кд ещё не назначено или уже прошло, можно запускать");
    plrs.put(s.getName(), System.currentTimeMillis() + 30000);
} else {
    s.sendMessage("Время кд ещё не прошло, нельзя");
}
В мапе у нас содержатся значения, до какого времени у нас кулдаун. currentTimeMillis выдает текущее время.
 
Судя по всему, в оригинальном алгоритме NuaN небольшая проблема, которая и у тебя отразилась. Когда значение из мапы больше текущего времени, ничего делать не нужно.
PHP:
Long untilMs = plrs.get(s.getName());
if (untilMs == null || untilMs < System.currentTimeMillis()) {
    s.sendMessage("Время кд ещё не назначено или уже прошло, можно запускать");
    plrs.put(s.getName(), System.currentTimeMillis() + 30000);
} else {
    s.sendMessage("Время кд ещё не прошло, нельзя");
}
В мапе у нас содержатся значения, до какого времени у нас кулдаун. currentTimeMillis выдает текущее время.
Спасибо огромное! Это серьезно сработало!!!
 
Статус
Закрыто для дальнейших ответов.

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

Назад
Верх