Помогите Работа с BukkitRunnable

Hittcliff

Активный участник
Пользователь
Баллы
66
Имя в Minecraft
Relion128
Мне нужно дабы код:

Код:
                    if (b.getX() > valueX[rec] && b.getX() < valueXX[rec]) {
                        if (b.getY() > valueY[rec] && b.getY() < valueYY[rec]) {
                            if (b.getZ() > valueZ[rec] && b.getZ() < valueZZ[rec]) {

                                tested(event, array[rec]);
                            }
                        }
                        rec++;
                    }

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



Код:
        int timer = Integer.parseInt(getConfig().getString("array.time")) * 20;

        new BukkitRunnable() {

            int rec = 0;
            int rec3 = Integer.parseInt(getConfig().getString("array.value"));

            List<String> list = config.getStringList("array.dir");
            String[] array = list.toArray(new String[0]);

            @Override
            public void run() {

                if (rec == rec3 || rec > rec3) {

                    rec = 0;
                } else {

                    // Позиция 1
                    int[] valueX = new int[rec3];
                    valueX[rec] = Integer.parseInt(getConfig().getString("swarp." + array[rec] + ".x: " + "pos1"));

                    int[] valueY = new int[rec3];
                    valueY[rec] = Integer.parseInt(getConfig().getString("swarp." + array[rec] + ".y: " + "pos1"));

                    int[] valueZ = new int[rec3];
                    valueZ[rec] = Integer.parseInt(getConfig().getString("swarp." + array[rec] + ".z: " + "pos1"));

                    // Позиция 2
                    int[] valueXX = new int[rec3];
                    valueXX[rec] = Integer.parseInt(getConfig().getString("swarp." + array[rec] + ".x: " + "pos2"));

                    int[] valueYY = new int[rec3];
                    valueYY[rec] = Integer.parseInt(getConfig().getString("swarp." + array[rec] + ".y: " + "pos2"));

                    int[] valueZZ = new int[rec3];
                    valueZZ[rec] = Integer.parseInt(getConfig().getString("swarp." + array[rec] + ".z: " + "pos2"));
                    Location b = player.getLocation();

                    if (b.getX() > valueX[rec] && b.getX() < valueXX[rec]) { //От сюда
                        if (b.getY() > valueY[rec] && b.getY() < valueYY[rec]) {
                            if (b.getZ() > valueZ[rec] && b.getZ() < valueZZ[rec]) {

                                tested(event, array[rec]);
                            }
                        }
                        rec++;
                    } //До сюда нужно делать задержку, дабы он работал с другой задержкой... Эта работает раз в 60 секунд..
                }
            }
        }.runTaskTimer(this, 0L, timer); //Эта допустим работает раз в 3 секунды..
Я пытался делить на классы, но суть такова, что код выше в любом случае обращается каждые 3 секунды, хотя мне нужно чтобы он делал это с задержкой в 60 секунд.


Для примера tested к которому обращается код выше:

Код:
 public void tested(PlayerJoinEvent event, String vois) {
        Player player = event.getPlayer();
        player.sendMessage(ChatColor.BLUE + "[DCore]: Вы на территорий: " + vois);
    }

Ах да, почему я просто не укажу основному циклу 60 секунд? Да просто потому, что он каждые 3 секунды ищет игрока, и если находит то должен выполнять действие с задержкой, например запускается песня, и дабы это песня каждые 3 секунды снова - снова - снова не включалась, нужно чтобы была задержка в цикле.
 
Повторюсь. Я Java изучаю совсем недавно, так что за криворукость кода прошу не писать, со временем научу по уму делать. В конце концов все мы начинали с чего-то)
 
Тут есть к чему ещё придраться, но по теме -- тут, как мне кажется, есть проблемы с логикой.
Конфиг постоянно обновляется? Зачем его так часть перечитывать (каждые 60 или 3 секунды)?
Мешанина из чтения конфига и применением чего-то, ещё и разбить на два таймера, жесть.
Прочитай весь конфиг заранее, и запускай таймер только на 3 секунды.
 
Окей, если у тебя в конфиге список кубических территорий, которые могут меняться, и ты хочешь раз в N времени проверять, какие игроки в каких локациях, делай так:
1. при загрузке плагина читай список территорий в память.
2. при изменении территории сохраняй весь список в конфиг.
3. у тебя уже будет под рукой список актуальных территорий, по которому можно итерироваться в обработчике события, и перечитывать ничего не нужно будет. Оставляешь таймер по игроку и всё. А лучше один на всех.
 
Суть такова, что при заходе игрока на сервер
Окей, если у тебя в конфиге список кубических территорий, которые могут меняться, и ты хочешь раз в N времени проверять, какие игроки в каких локациях, делай так:
1. при загрузке плагина читай список территорий в память.
2. при изменении территории сохраняй весь список в конфиг.
3. у тебя уже будет под рукой список актуальных территорий, по которому можно итерироваться в обработчике события, и перечитывать ничего не нужно будет. Оставляешь таймер по игроку и всё. А лучше один на всех.


А как примерно сей процесс реализовать?
 
Я могу записать видео в котором покажу что да как работает сейчас, просто для демонстраций сразу и покажу чего я пытаюсь добиться.
 
Окей, если у тебя в конфиге список кубических территорий, которые могут меняться, и ты хочешь раз в N времени проверять, какие игроки в каких локациях, делай так:
1. при загрузке плагина читай список территорий в память.
2. при изменении территории сохраняй весь список в конфиг.
3. у тебя уже будет под рукой список актуальных территорий, по которому можно итерироваться в обработчике события, и перечитывать ничего не нужно будет. Оставляешь таймер по игроку и всё. А лучше один на всех.
 
В видео я более конкретно указал что требуется, запись с первого дубля, просто подключил микро и начал запись. Сорян за херовую дикцию)
 
swarp:
Boss:
'x: pos1': '-214'
'y: pos1': '40'
'z: pos1': '44'
'x: pos2': '-194'
'y: pos2': '44'
'z: pos2': '63'
'sound:': piano.music
'category:': master
'sound-time:': '255' //Длительность
'sound-volume:': '1'
Boss2:
'x: pos1': '-215'
'y: pos1': '41'
'z: pos1': '87'
'x: pos2': '-195'
'y: pos2': '45'
'z: pos2': '106'
'sound:': attack.play
'category:': master
'sound-time:': '14' //Длительность
'sound-volume:': '1'
array:
value: 2 //Количество данных в массиве
dir:
- Boss
- Boss2
 
Посмотрел.
Читаем СРАЗУ весь конфиг в память (HashMap, например). Потом работаем только с памятью.
При входе игрока следим за PlayerJoinEvent. Также не забываем про телепортирование (эвент не помню).
Потом с помощью PlayerMoveEvent следим за игроком.

При входе на территорию играем музыку и стартуем таймер на повторное проигрывание. Перед повтором чекаем, где игрок находится.
 
Спасибо за подробное изложение, проблема стала понятнее.
Извиняюсь за паузу, отвлёкся, сейчас вникну в детали и постараюсь дать советы.
 
Спасибо за подробное изложение, проблема стала понятнее.
Извиняюсь за паузу, отвлёкся, сейчас вникну в детали и постараюсь дать советы.
Буду очень признателен! 🙂
 
Посмотрел.
Читаем СРАЗУ весь конфиг в память (HashMap, например). Потом работаем только с памятью.
При входе игрока следим за PlayerJoinEvent. Также не забываем про телепортирование (эвент не помню).
Потом с помощью PlayerMoveEvent следим за игроком.

При входе на территорию играем музыку и стартуем таймер на повторное проигрывание. Перед повтором чекаем, где игрок находится.
Я пока что не умею работать с ХэшМэпом. Я немного не понял смысла ваших советов, простите. ☹️
 
Я пока что не умею работать с ХэшМэпом. Я немного не понял смысла ваших советов, простите. ☹️
Вот как вариант для обзора, а дальше десятки их на хабре.
1. при загрузке плагина читай список территорий в память.
2. при изменении территории сохраняй весь список в конфиг.
Посмотрел.
Читаем СРАЗУ весь конфиг в память (HashMap, например). Потом работаем только с памятью.
Вот это тут сразу однозначно. Я бы ещё выделил территорию в класс, назовём для простоты изложения
Java:
public class Area {

    public String name;

    public long x1;
    public long y1;
    public long z1;
    public long x2;
    public long y2;
    public long z2;

    public String sound;
    public String category;
    public int soundDuration;
    public double soundVolume;
}
Храним их, да, например в ассоциативном массиве, вполне HashMap нас устроит.
Java:
Map<String, Area> areas = new HashMap<>(); // В теле класса плагина, или где-нибудь ещё.
Пишем пару методов, чтения всех территорий из файлов, и записи их туда же.
Насколько я понял, в конфиге array.value и array.dir используются для определения сохранённых территорий, это не нужно, для получения этих данных уже есть методы у конфига.

Далее, что делать с игроками.
Нужно реагировать на три события (на самом деле может быть чуть больше) — вход, движение и выход.
Ещё нам нужен список игроков, которые "двигались". Я в своё время написал маленький класс и юзал его в разных плагинах. Можешь смело скопипастить себе. У него фактически один метод getMovedPlayersAsync(), вернёт список игроков, которые "двигались" с прошлого запроса.
И один таймер, например на 3 секунды.
Таймер будет делать два действия.
Первое — проверять список "переместившихся игроков", и для них определять, находятся ли они в какой либо зоне, или нет. Если сейчас в зоне, и был в ней (опишем ниже), пропускаем. Если ни в одной из зон, и раньше не был, тоже пропускаем. Далее соответственно либо добавляем, либо удаляем из этой зоны (ниже).
Когда список игроков внутри каждой зоны сформирован, вторая часть работы таймера - проверить, не пора ли запустить для них действие.
Для того, чтобы хранить связку Игрок - Зона, в которой он находится в данный момент, можно воспользоваться ещё одним ассоциативным массивом.
 
Последнее редактирование:
Когда начинал писать текст, в голове была более серьезная реализация именно обработки игрока внутри зоны, но когда дописал, понял, что надо тебе чуть попроще, поэтому будет вариант чуть более нагружающий сервер, но легче реализуемый.

Итак, у нас есть список пар игрок-зона, и нам нужно для игрока проигрывать в цикле мелодию (или делать какое-то другое действие) раз в M секунд. В основном таймере, который "наблюдает" за посещением зон игроками, в момент Добавления игрока в зону (например, playersPerAreas.put(player, area)) вызываем ещё один метод — создание таймера проигрывания мелодии area.sound с периодом area.soundDuration * 20.
В теле метода run этого таймера первым делом проверяем, содержится ли всё ещё игрок в карте playersPerAreas.get(player).equals(area). Если нет — отменяем себя вообще и выходим из метода. Если да -- просто играем мелодию. Код короткий и понятный.
Ну в общем-то это всё.

Если нужна будет более серьёзная помощь, я буду онлайн минут через 30.
 
Когда начинал писать текст, в голове была более серьезная реализация именно обработки игрока внутри зоны, но когда дописал, понял, что надо тебе чуть попроще, поэтому будет вариант чуть более нагружающий сервер, но легче реализуемый.

Итак, у нас есть список пар игрок-зона, и нам нужно для игрока проигрывать в цикле мелодию (или делать какое-то другое действие) раз в M секунд. В основном таймере, который "наблюдает" за посещением зон игроками, в момент Добавления игрока в зону (например, playersPerAreas.put(player, area)) вызываем ещё один метод — создание таймера проигрывания мелодии area.sound с периодом area.soundDuration * 20.
В теле метода run этого таймера первым делом проверяем, содержится ли всё ещё игрок в карте playersPerAreas.get(player).equals(area). Если нет — отменяем себя вообще и выходим из метода. Если да -- просто играем мелодию. Код короткий и понятный.
Ну в общем-то это всё.

Если нужна будет более серьёзная помощь, я буду онлайн минут через 30.
Огосики, сколько информаций сразу наплыло.. аж глаза разбегаются.
 
Z
Когда начинал писать текст, в голове была более серьезная реализация именно обработки игрока внутри зоны, но когда дописал, понял, что надо тебе чуть попроще, поэтому будет вариант чуть более нагружающий сервер, но легче реализуемый.

Итак, у нас есть список пар игрок-зона, и нам нужно для игрока проигрывать в цикле мелодию (или делать какое-то другое действие) раз в M секунд. В основном таймере, который "наблюдает" за посещением зон игроками, в момент Добавления игрока в зону (например, playersPerAreas.put(player, area)) вызываем ещё один метод — создание таймера проигрывания мелодии area.sound с периодом area.soundDuration * 20.
В теле метода run этого таймера первым делом проверяем, содержится ли всё ещё игрок в карте playersPerAreas.get(player).equals(area). Если нет — отменяем себя вообще и выходим из метода. Если да -- просто играем мелодию. Код короткий и понятный.
Ну в общем-то это всё.

Если нужна будет более серьёзная помощь, я буду онлайн минут через 30.
Я понимаю что сейчас я крайне туплю, но насчёт первой части я понял. Таймер который отвечает за отслеживанием игрока:

Код:
new BukkitRunnable() {       
@Override
            public void run() {

          //По твоей инструкций тут должен быть вызов метода создание таймера. Но ведь если он уже в таймере, то с каждым циклом в ЭТОМ таймере повторно и повторно будет запускаться таймер который кнутри первого...
            }
        }.runTaskTimer(this, 0L, timer); //Эта допустим работает раз в 3 секунды..

Прости, очень сильно пока туплю с Java)
 
Там, где комментарий, должно быть условие, что таймер для игрока будет создавать только в том случае, если он попал в зону, в которой не был ранее.
 
f
Там, где комментарий, должно быть условие, что таймер для игрока будет создавать только в том случае, если он попал в зону, в которой не был ранее.
Т.е за пределами таймера создать переменную, которую изменить в таймере и проверять if?

Код:
new BukkitRunnable() {      
@Override
           public void run() {
              if (b.getX() > valueX[rec] && b.getX() < valueXX[rec]) {
                       if (b.getY() > valueY[rec] && b.getY() < valueYY[rec]) {
                           if (b.getZ() > valueZ[rec] && b.getZ() < valueZZ[rec]) {
                                 ...

                           }
                       }
                   }
            }
       }.runTaskTimer(this, 0L, timer);
 
Последнее редактирование:
Назад
Верх