1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

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

Тема в разделе "Разработка плагинов для новичков", создана пользователем Нейн, 21 май 2023.

Статус темы:
Закрыта.
  1. Автор темы
    Нейн

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

    Баллы:
    66
    Имя в Minecraft:
    AmokDev
    Доброго времени суток, ребят!

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

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

    Надеюсь на вашу помощь! :cry:
     
  2. MrAlexeiMK

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

    Баллы:
    66
    Имя в Minecraft:
    MrAlexeiMK
    Храни в списке время добавления в список для каждого игрока (System.currentTimeMills()), при использовании - сравнивай с текущим временем и удаляй из списка, если прошло больше 30 секунд.
     
  3. NuaN

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

    Баллы:
    96
    Имя в Minecraft:
    NuaN
    Только начал про это писать))

    Да, вот будет как-то так:
    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 будет храниться ник и время после которого будет разрешено использовать событие.
     
  4. Автор темы
    Нейн

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

    Баллы:
    66
    Имя в Minecraft:
    AmokDev
    Спасибо Вам огромное! Я хотел сделать аналогично, исходя из опыта в Python, но не понял как, ОГРОМНЕЙШАЯ Благодарность!
     
  5. Автор темы
    Нейн

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

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

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

    p.s Структура проекта такова:
    [​IMG]
     
  6. MrAlexeiMK

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

    Баллы:
    66
    Имя в Minecraft:
    MrAlexeiMK
    Я у себя для этого отдельный сервис завел: https://pastebin.com/EdmtVrAq
    Из любой точки кода вызываю:

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

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

    Баллы:
    66
    Имя в Minecraft:
    AmokDev
    Простите, это не помогло решить мою проблему, я так и не понял как сохранить глобально мой HashMap :oops:
     
  8. ReloGGrc

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

    Баллы:
    46
    Имя в Minecraft:
    ALis
    Если ты создал глобальную переменную (в классе вне метода) и занёс в нее какие-то значение а после их не удалял, то исчезнуть они могут только после перезагрузки плагина.

    А лучше покажи код
     
  9. Автор темы
    Нейн

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

    Баллы:
    66
    Имя в Minecraft:
    AmokDev
    https://pastebin.com/teVP5UsU

    Cтруктура проекта:
    [​IMG]
     
  10. ReloGGrc

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

    Баллы:
    46
    Имя в Minecraft:
    ALis
    Странно, вроде должно быть все нормально. Возможно из-за статики, Я не знаю, много слышал что из-за нее бывают проблемы. Не знаю, попробуй в классе слушателя создать глобальную Мапу не статическую и работай с ней, может поможет
     
  11. imDaniX

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

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
    Не понял вопроса.
    Если тебе нужно хранить данные между рестартами, тебе придется как-то хранить данные, будь то запись в конфиг, или ещё чего.
    Если речь про то, что КД работает некорректно, убедись, что проходишь по всем шагам, описанным NuaN.
     
  12. Автор темы
    Нейн

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

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

    p.s Мой код сравнения: https://pastebin.com/xxmyArH0
    p.ss Player s = (Player) sender;
     
  13. ReloGGrc

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

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

    Проверь какое из условий срабатывает
     
  14. Автор темы
    Нейн

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

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

    Нет, как раз-таки предметы бесконечно спавнятся и я не понимаю, почему же срабатывает именно условие ">", я уже отчаялся и попробовал ">=", но тут тоже пинок в спину :oops:

    Мой мозг уже превратился в [​IMG]
     
  15. NuaN

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

    Баллы:
    96
    Имя в Minecraft:
    NuaN
    Попробуй сделать дебаг, например, выводить значения из map и другие нужные переменные в чат или через System.out.println. Рано или поздно поймешь что не так работает. А просто гадать можно очень долго.
     
  16. ReloGGrc

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

    Баллы:
    46
    Имя в Minecraft:
    ALis
    А зачем ты добавляешь в Мапу в условии, в котором значение из нее больше чем текущие миллисекунды? Мне кажется наоборот, там где меньше, там и нужно добавлять(ну, на самом деле я не очень понимаю вообще что ты делаешь, так что это лишь предположение)
     
  17. NuaN

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

    Баллы:
    96
    Имя в Minecraft:
    NuaN
    Значение в мапе означает время, когда можно будет использовать ивент повторно. Поэтому к текущему времени прибавляем 30 сек. Это я так предложил, а вообще можно и по-другому реализовать.
     
  18. Автор темы
    Нейн

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

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

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

    Ниже у меня есть щедуллер:
    https://pastebin.com/KZPh0PDG
    Сама логика кулдауна:
    https://pastebin.com/qd4tmfPZ
     
    Последнее редактирование: 23 май 2023
  19. imDaniX

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

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
    Судя по всему, в оригинальном алгоритме 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 выдает текущее время.
     
  20. Автор темы
    Нейн

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

    Баллы:
    66
    Имя в Minecraft:
    AmokDev
    Спасибо огромное! Это серьезно сработало!!!
     
Статус темы:
Закрыта.

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