Определение количества блоков над игроком

Версия Minecraft
1.12.2
Добавил новый атрибут для игрока. Для постоянного его изменения (по аналогии с стандартным игровым голодом) мне понадобилось добавить переменную (float) radModifier, которая по умолчанию равна 1.0F, и которая должна уменьшаться на 30% с каждым найденным над игроком блоком (проще говоря, мне надо узнать количество плотных блоков над игроком) Для этого я воспользовался циклом "for". Но при наличии этого цикла в коде игра просто виснет, когда я пытаюсь войти в любой мир, а консоль говорит, что я пытаюсь выполнить слишком много операций за короткий промежуток времени. Есть ли какая-нибудь альтернатива моему способу (которая не будет заставлять игру виснуть)? Код ивента, логи и скрин ниже (Краш игры не происходит, клиент приходится закрывать насильно)screenshot.png).
Java:
@SubscribeEvent
    public static void onPlayerUpdate(LivingEvent.LivingUpdateEvent event) {

        float radModifier = 1.0F;

        if (event.getEntityLiving() instanceof EntityPlayer) {

            EntityPlayer player = (EntityPlayer) event.getEntityLiving();
            BlockPos pos = new BlockPos(player);
            boolean isSafe = false;

            if (player.ticksExisted % 60 == 0 && player.dimension == 0 && !player.capabilities.isCreativeMode) {

                for (int i = 1; i < 9; i++) {
                    BlockPos posF = pos.up(i);
                    if (player.world.getBlockState(posF) != Blocks.AIR) {

                        radModifier = radModifier - (radModifier / 100 * 30);
                        isSafe = true;
                        i = 1;

                    }
                    if (i == 8) {
                        if (!isSafe) {
                            radModifier = 1.0F;
                        }
                        break;
                    }

                }

                if (getRad(player) != 0 && getRad(player) != 199) {
                    increaseRad(player, radModifier - 0.3F);
                    saveRadToNBT(player);
                }
            }
        }

    }
[12:19:34] [Server thread/INFO] [minecraft/MinecraftServer]: Player734 joined the game
[12:19:39] [pool-2-thread-1/WARN] [mojang/YggdrasilMinecraftSessionService]: Couldn't look up profile properties for com.mojang.authlib.GameProfile@6eb42e56[id=3f66a67c-db6c-36b7-b762-d7a40c17883b,name=Player734,properties={},legacy=false]
com.mojang.authlib.exceptions.AuthenticationException: The client has sent too many requests within a certain amount of time
at com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService.makeRequest(YggdrasilAuthenticationService.java:79) ~[YggdrasilAuthenticationService.class:?]
at com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService.fillGameProfile(YggdrasilMinecraftSessionService.java:180) [YggdrasilMinecraftSessionService.class:?]
at com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService$1.load(YggdrasilMinecraftSessionService.java:60) [YggdrasilMinecraftSessionService$1.class:?]
at com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService$1.load(YggdrasilMinecraftSessionService.java:57) [YggdrasilMinecraftSessionService$1.class:?]
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3716) [guava-21.0.jar:?]
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2424) [guava-21.0.jar:?]
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2298) [guava-21.0.jar:?]
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2211) [guava-21.0.jar:?]
at com.google.common.cache.LocalCache.get(LocalCache.java:4154) [guava-21.0.jar:?]
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4158) [guava-21.0.jar:?]
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:5147) [guava-21.0.jar:?]
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:5153) [guava-21.0.jar:?]
at com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService.fillProfileProperties(YggdrasilMinecraftSessionService.java:170) [YggdrasilMinecraftSessionService.class:?]
at net.minecraft.client.Minecraft.getProfileProperties(Minecraft.java:3181) [Minecraft.class:?]
at net.minecraft.client.resources.SkinManager$3.run(SkinManager.java:138) [SkinManager$3.class:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_181]
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) [?:1.8.0_181]
at java.util.concurrent.FutureTask.run(FutureTask.java) [?:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_181]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_181]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_181]
 
Решение
Java:
@Mod.EventBusSubscriber(modid = MainClass.MODID)
public class RadiationHandler {

    private static Thread kek = null;
    
    public static float getRadMax(EntityPlayer player) {

        return (float) player.getEntityAttribute(PropRegistry.RAD_MAX).getAttributeValue();

    }

    public static float getRad(EntityPlayer player) {

        return player.getDataManager().get(PropRegistry.RAD);

    }

    public static void increaseRad(EntityPlayer player, float value) {

        player.getDataManager().set(PropRegistry.RAD, MathHelper.clamp(getRad(player) - value, 0.0F, getRadMax(player)));
    }

    public static void setRad(EntityPlayer player, float value) {

        player.getDataManager().set(PropRegistry.RAD...
68
1
7
Java:
@Mod.EventBusSubscriber(modid = MainClass.MODID)
public class RadiationHandler {

    private static Thread kek = null;
    
    public static float getRadMax(EntityPlayer player) {

        return (float) player.getEntityAttribute(PropRegistry.RAD_MAX).getAttributeValue();

    }

    public static float getRad(EntityPlayer player) {

        return player.getDataManager().get(PropRegistry.RAD);

    }

    public static void increaseRad(EntityPlayer player, float value) {

        player.getDataManager().set(PropRegistry.RAD, MathHelper.clamp(getRad(player) - value, 0.0F, getRadMax(player)));
    }

    public static void setRad(EntityPlayer player, float value) {

        player.getDataManager().set(PropRegistry.RAD, MathHelper.clamp(value, 0.0F, getRadMax(player)));
    }

    private static void saveRadToNBT(EntityPlayer player) {

        player.getEntityData().setFloat(MainClass.MODID + ":rad", getRad(player));
    }

    private static float loadRadFromNBT(EntityPlayer player) {

        return player.getEntityData().hasKey(MainClass.MODID + ":rad") ?
                player.getEntityData().getFloat(MainClass.MODID + ":rad") : getRadMax(player);
    }

    @SubscribeEvent
    public static void onPlayerLogIn(PlayerEvent.PlayerLoggedInEvent event) {

        setRad(event.player, loadRadFromNBT(event.player));
    }

    @SideOnly(Side.SERVER)
    @SubscribeEvent
    public static void onPlayerLogOut(PlayerEvent.PlayerLoggedOutEvent event) {

        saveRadToNBT(event.player);
    }


    @SubscribeEvent
    public static void onPlayerUpdate(LivingEvent.LivingUpdateEvent event) {
        if(kek == null || kek.getState() == Thread.State.TERMINATED){
            kek = new Kek(event);
            kek.start();
        }
    }


    private static class Kek extends Thread{
        LivingEvent.LivingUpdateEvent event;

        public Kek(LivingEvent.LivingUpdateEvent event){
            this.event = event;
        }


        @Override
        public void run(){
            float radModifier = 1.0F;

            if (event.getEntityLiving() instanceof EntityPlayer) {

                EntityPlayer player = (EntityPlayer) event.getEntityLiving();
                BlockPos pos = new BlockPos(player);
                boolean isSafe = false;

                if (player.ticksExisted % 60 == 0 && player.dimension == 0 && !player.capabilities.isCreativeMode) {

                    for (int i = 1; i < 9; i++) {
                        BlockPos posF = pos.up(i);
                        if (player.world.getBlockState(posF) != Blocks.AIR) {

                            radModifier = radModifier - (radModifier / 100 * 30);
                            isSafe = true;
                            i = 1;

                        }
                        if (i == 8) {
                            if (!isSafe) {
                                radModifier = 1.0F;
                            }
                            break;
                        }

                    }

                    if (getRad(player) != 0 && getRad(player) != 199) {
                        increaseRad(player, radModifier - 0.3F);
                        saveRadToNBT(player);
                    }
                }
            }
        }
    }
}
 
private static class Kek extends Thread...
При использовании такого кода игра продолжает выдавать "The client has sent too many requests within a certain amount of time" , но при этом мир работает нормально, а вот radModifier не отнимается от начального показателя.
 
68
1
7
The client has sent too many requests within a certain amount of time
Не удивительно наверно :D, сделайте тест:
ПЕРЕД циклом объявите переменную:
Java:
long old;
ПЕРЕД
Java:
BlockPos posF = pos.up(i);
добавьте
Java:
old = System.currentTimeMillis();
В самом конце цикла:
Java:
System.out.println(System.currentTimeMillis() - old);
Узнаете сколько millis занимает одна итерация цикла. Возможно (скорее всего), итерация занимает маленькое кол-во времени, а это значит что вы очень часто вызываете
Java:
pos.up(i);
и
Java:
player.world.getBlockState(posF)
 
68
1
7
О чём я писал выше:

Java:
                    ...
                    if(...){

                    long old ;

                    for (int i = 1; i < 9; i++) {

                        old = System.currentTimeMillis();

                        BlockPos posF = pos.up(i);
                        if (player.world.getBlockState(posF) != Blocks.AIR) {

                            radModifier = radModifier - (radModifier / 100 * 30);
                            isSafe = true;
                            i = 1;

                        }
                        if (i == 8) {
                            if (!isSafe) {
                                radModifier = 1.0F;
                            }
                            break;
                        }

                        System.out.println(System.currentTimeMillis() - old);
                    }
                    
                    if(...){...}
 
68
1
7
Если всё правильно работает, выходит вы 1000+ итераций цикла выполняете за секунду :D
Можно искусственно замедлить его, напишите перед
Java:
System.out.println(System.currentTimeMillis() - old);
Java:
Thread.sleep(200); //millis
Что тогда выводится в консоль?

0 подозрительно :unsure:
 
68
1
7
(судя по всему, это была все та же ошибка)
Сейчас 5 итераций в секунду. Можете ещё увеличить задержку, посмотреть что будет, возможно эта ошибка не из-за этого вылетает. Но куда-то надо будет впереть задержку, ибо нет смысла так часто проверять воздух, ибо игрок не может так быстро бегать. Скорее всего ошибка не тут
 
68
1
7
Так астооооп
У вас ошибка в проверке же. "Blocks.AIR" AIR же не enum, почему вы проверяете его через !=? Это же объекты, ссылочный тип, все дела. Как хорошо вы знаете Java? Попробуйте проверять через equals. Или я не шарю? *Дополнил* шарю же
 
68
1
7
Полное цитирование предыдущего сообщения запрещено
Я и вправду пропустил это) Спасибо). Помимо исправления этого я также добавил задержку в 3000 millis , но, хоть теперь скрипт начал подавать признаки жизни, ошибка почему то все равно возникает. Она вроде как не вредит особо, но ее наличие угнетает. Есть идеи, в чем проблема? Я про эту ошибку, если что "The client has sent too many requests within a certain amount of time" .
 
Сверху