Подведи собственные итоги года совместно с YOUGAME и забери ценные призы! Перейти

Обход античита AutoTotem EXP 3.1

во первых паимоналетка, добавлю не сейчас, во вторых не удаляй, будет актив я сделаю

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


написать более нормальный чуть чатгпт, но обходит античиты
Можно настраивать его работу, задержки там и тд
Так же он более умный, ставит в приоритет тотем который находиться в слотах
а не в инвентаре = если закончились/нету в слоте, берет из инвентаря
короче если будет детектиться, могу скиднуть из вексайда, который перебрасывает из инвентаря в слоты

Ну, а так вроде отлично работает

Пожалуйста, авторизуйтесь для просмотра ссылки.








Код:
Expand Collapse Copy
@FunctionRegister(name = "AutoTotem", type = Category.Combat)
public class AutoTotem extends Function {
    @Override
    public String getDescription() {
        return "Автоматически берет тотем в руку";
    }

    private final SliderSetting healthThreshold = new SliderSetting("Здоровье", 6.0f, 1.0f, 20.0f, 0.5f);
    private final SliderSetting swapDelay = new SliderSetting("Задержка свапа", 150, 100, 500, 25);
    private final SliderSetting randomDelay = new SliderSetting("Случайная задержка", 25, 0, 100, 5);


    private final BooleanSetting returnItem = new BooleanSetting("Возвращать предмет", true);
    private final SliderSetting returnDelay = new SliderSetting("Задержка возврата", 2000, 1000, 5000, 250);
    private final BooleanSetting saveEnchanted = new BooleanSetting("Сохранять зачарованные", true);
    private final BooleanSetting preventBadSwap = new BooleanSetting("Умная замена", true);


    private final ModeListSetting threats = new ModeListSetting("Угрозы",
            new BooleanSetting("Кристаллы", true),
            new BooleanSetting("ТНТ", true),
            new BooleanSetting("Падение", true),
            new BooleanSetting("Низкое ХП", true));

    private final SliderSetting crystalRange = new SliderSetting("Дистанция кристаллов", 6.0f, 3.0f, 10.0f, 0.5f);
    private final SliderSetting fallDistance = new SliderSetting("Дистанция падения", 15.0f, 5.0f, 50.0f, 2.5f);


    private final StopWatch swapTimer = new StopWatch();
    private final StopWatch returnTimer = new StopWatch();
    private final StopWatch antiSpamTimer = new StopWatch();
    private final List<Integer> totemSlots = new ArrayList<>();

    private ItemStack previousOffhandItem = ItemStack.EMPTY;
    private int previousOffhandSlot = -1;
    private boolean totemActive = false;
    private boolean shouldReturn = false;
    private long lastSwapTime = 0;
    private int swapAttempts = 0;
    private boolean isSwapping = false;
    private boolean wasInDanger = false;

    public AutoTotem() {
        addSettings(healthThreshold, swapDelay, randomDelay, returnItem, returnDelay,
                saveEnchanted, preventBadSwap, threats, crystalRange, fallDistance);
    }

    @Subscribe
    private void onUpdate(EventUpdate event) {
        if (mc.player == null || mc.world == null) return;

        updateTotemSlots();

        boolean currentlyInDanger = isInDanger();


        if (currentlyInDanger && !hasTotemInOffhand()) {
            if (canSwapToTotem()) {
                handleTotemSwap();
            }
        }

        else if (!currentlyInDanger && shouldReturn && returnItem.get() &&
                returnTimer.isReached(getReturnDelay()) && !isSwapping) {
            handleItemReturn();
        }

        wasInDanger = currentlyInDanger;
    }

    @Subscribe
    private void onPacket(EventPacket event) {
        if (mc.player == null || mc.world == null) return;


        if (event.isReceive() && event.getPacket() instanceof SEntityStatusPacket packet) {
            if (packet.getOpCode() == 35 && packet.getEntity(mc.world) == mc.player) {
                onTotemActivated();
            }
        }
    }

    @Subscribe
    private void onSpawnEntity(EventSpawnEntity event) {
        if (!threats.getValueByName("Кристаллы").get()) return;
        if (mc.player == null || mc.world == null) return;

        Entity entity = event.getEntity();
        if (entity instanceof EnderCrystalEntity crystal) {
            if (mc.player.getDistance(crystal) <= crystalRange.get()) {
                // by wlayn3x
                if (!hasTotemInOffhand() && canSwapToTotem()) {
                    handleTotemSwap();
                }
            }
        }
    }

    private boolean canSwapToTotem() {

        return !totemSlots.isEmpty() &&
                !isSwapping &&
                antiSpamTimer.isReached(200) &&
                swapTimer.isReached(getRandomizedDelay()) &&
                System.currentTimeMillis() - lastSwapTime >= 300;
    }

    private boolean isInDanger() {
        return isLowHealth() || isDangerous() || isFalling();
    }

    private boolean isLowHealth() {
        if (!threats.getValueByName("Низкое ХП").get()) return false;

        float health = mc.player.getHealth();
        float absorption = mc.player.getAbsorptionAmount();


        if (mc.player.isPotionActive(Effects.ABSORPTION)) {
            health += absorption;
        }

        return health <= healthThreshold.get();
    }

    private boolean isDangerous() {
        if (mc.world == null) return false;

        // Проверка кристаллов
        if (threats.getValueByName("Кристаллы").get()) {
            for (Entity entity : mc.world.getAllEntities()) {
                if (isDangerousEntity(entity)) {
                    return true;
                }
            }
        }

        return false;
    }

    private boolean isDangerousEntity(Entity entity) {
        float distance = mc.player.getDistance(entity);

        if (entity instanceof EnderCrystalEntity && distance <= crystalRange.get()) {
            return true;
        }

        if (threats.getValueByName("ТНТ").get()) {
            if ((entity instanceof TNTEntity || entity instanceof TNTMinecartEntity)
                    && distance <= 8.0f) {
                return true;
            }
        }

        return false;
    }

    private boolean isFalling() {
        if (!threats.getValueByName("Падение").get()) return false;

        return mc.player.fallDistance >= fallDistance.get() &&
                !mc.player.isInWater() &&
                !mc.player.isElytraFlying() &&
                !mc.player.isOnGround();
    }

    private void handleTotemSwap() {
        if (totemSlots.isEmpty() || mc.currentScreen != null || isSwapping) return;

        int totemSlot = getBestTotemSlot();
        if (totemSlot == -1) return;

        isSwapping = true;

        try {

            if (!hasTotemInOffhand()) {
                ItemStack offhandItem = mc.player.getHeldItemOffhand();
                if (!offhandItem.isEmpty() && offhandItem.getItem() != Items.TOTEM_OF_UNDYING) {
                    previousOffhandItem = offhandItem.copy();
                    previousOffhandSlot = findItemInInventory(offhandItem);
                    shouldReturn = true;
                    returnTimer.reset();
                }
            }


            performSwap(totemSlot, 45);

            lastSwapTime = System.currentTimeMillis();
            swapTimer.reset();
            antiSpamTimer.reset();

        } finally {

            new Thread(() -> {
                try {
                    Thread.sleep(100);
                    isSwapping = false;
                } catch (InterruptedException ignored) {}
            }).start();
        }
    }

    private void handleItemReturn() {
        if (!shouldReturn || previousOffhandItem.isEmpty() || isSwapping) return;


        if (isInDanger()) return;


        if (!hasTotemInOffhand()) {
            shouldReturn = false;
            return;
        }

        isSwapping = true;

        try {
            int itemSlot = findItemInInventory(previousOffhandItem);
            if (itemSlot != -1) {
                performSwap(itemSlot, 45);
            } else {

                int emptySlot = findEmptySlot();
                if (emptySlot != -1) {
                    performSwap(emptySlot, 45);
                }
            }

            shouldReturn = false;
            previousOffhandItem = ItemStack.EMPTY;
            previousOffhandSlot = -1;
            antiSpamTimer.reset();

        } finally {
            new Thread(() -> {
                try {
                    Thread.sleep(100);
                    isSwapping = false;
                } catch (InterruptedException ignored) {}
            }).start();
        }
    }

    private void performSwap(int sourceSlot, int targetSlot) {
        if (sourceSlot == -1 || mc.currentScreen != null) return;

        int windowId = mc.player.container.windowId;
        int adjustedSourceSlot = sourceSlot < 9 ? sourceSlot + 36 : sourceSlot;

        try {

            mc.playerController.windowClick(windowId, adjustedSourceSlot, 0, ClickType.PICKUP, mc.player);
            Thread.sleep(50);
            mc.playerController.windowClick(windowId, targetSlot, 0, ClickType.PICKUP, mc.player);


            if (!mc.player.inventory.getItemStack().isEmpty()) {
                Thread.sleep(50);
                mc.playerController.windowClick(windowId, adjustedSourceSlot, 0, ClickType.PICKUP, mc.player);
            }

            mc.playerController.updateController();
        } catch (Exception e) {

        }
    }

    private void updateTotemSlots() {
        totemSlots.clear();

        for (int i = 0; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (isValidTotem(stack)) {
                totemSlots.add(i);
            }
        }
    }

    private boolean isValidTotem(ItemStack stack) {
        if (stack.getItem() != Items.TOTEM_OF_UNDYING) return false;


        if (saveEnchanted.get() && stack.isEnchanted()) {

            long normalTotems = totemSlots.stream()
                    .map(i -> mc.player.inventory.getStackInSlot(i))
                    .filter(s -> s.getItem() == Items.TOTEM_OF_UNDYING && !s.isEnchanted())
                    .count();

            return normalTotems == 0;
        }

        return true;
    }

    private int getBestTotemSlot() {
        if (totemSlots.isEmpty()) return -1;


        for (int slot : totemSlots) {
            ItemStack stack = mc.player.inventory.getStackInSlot(slot);
            if (!stack.isEnchanted()) {
                return slot;
            }
        }


        return totemSlots.get(0);
    }

    private boolean hasTotemInOffhand() {
        ItemStack offhandItem = mc.player.getHeldItemOffhand();
        return offhandItem.getItem() == Items.TOTEM_OF_UNDYING;
    }

    private int findItemInInventory(ItemStack targetStack) {
        for (int i = 0; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (ItemStack.areItemStacksEqual(stack, targetStack)) {
                return i;
            }
        }
        return -1;
    }

    private int findEmptySlot() {
        for (int i = 9; i < 36; i++) {
            if (mc.player.inventory.getStackInSlot(i).isEmpty()) {
                return i;
            }
        }
        return -1;
    }

    private long getRandomizedDelay() {
        long baseDelay = swapDelay.get().longValue();
        long randomOffset = ThreadLocalRandom.current().nextLong(0, randomDelay.get().longValue() + 1);
        return baseDelay + randomOffset;
    }

    private long getReturnDelay() {
        long baseDelay = returnDelay.get().longValue();
        long randomOffset = ThreadLocalRandom.current().nextLong(0, 100);
        return baseDelay + randomOffset;
    }

    private void onTotemActivated() {
        totemActive = true;
        shouldReturn = false;
        isSwapping = false;
        antiSpamTimer.reset();


        if (!totemSlots.isEmpty() && !hasTotemInOffhand()) {
            swapTimer.reset();
        }
    }

    private void reset() {
        totemSlots.clear();
        previousOffhandItem = ItemStack.EMPTY;
        previousOffhandSlot = -1;
        shouldReturn = false;
        totemActive = false;
        lastSwapTime = 0;
        swapAttempts = 0;
        isSwapping = false;
        wasInDanger = false;
        swapTimer.reset();
        returnTimer.reset();
        antiSpamTimer.reset();
    }

    @Override
    public boolean onEnable() {
        super.onEnable();
        if (mc.player != null && mc.world != null) {
            reset();
            return true;
        }
        return false;
    }

    @Override
    public void onDisable() {
        reset();
        super.onDisable();
    }
}
чел ти моя аватарка украсть
 
зачем нам этот высер, да даже в обычной блядской экспе его до адекватности довести дело 5 минут
"нам" :kekw: ты настолько легко б довел до адекватности за 5 минут, что аж не бежал бы на югейм спрашивать как фиксануть киллку
 
чел ти моя аватарка украсть

во первых паимоналетка, добавлю не сейчас, во вторых не удаляй, будет актив я сделаю

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


написать более нормальный чуть чатгпт, но обходит античиты
Можно настраивать его работу, задержки там и тд
Так же он более умный, ставит в приоритет тотем который находиться в слотах
а не в инвентаре = если закончились/нету в слоте, берет из инвентаря
короче если будет детектиться, могу скиднуть из вексайда, который перебрасывает из инвентаря в слоты

Ну, а так вроде отлично работает

Пожалуйста, авторизуйтесь для просмотра ссылки.








Код:
Expand Collapse Copy
@FunctionRegister(name = "AutoTotem", type = Category.Combat)
public class AutoTotem extends Function {
    @Override
    public String getDescription() {
        return "Автоматически берет тотем в руку";
    }

    private final SliderSetting healthThreshold = new SliderSetting("Здоровье", 6.0f, 1.0f, 20.0f, 0.5f);
    private final SliderSetting swapDelay = new SliderSetting("Задержка свапа", 150, 100, 500, 25);
    private final SliderSetting randomDelay = new SliderSetting("Случайная задержка", 25, 0, 100, 5);


    private final BooleanSetting returnItem = new BooleanSetting("Возвращать предмет", true);
    private final SliderSetting returnDelay = new SliderSetting("Задержка возврата", 2000, 1000, 5000, 250);
    private final BooleanSetting saveEnchanted = new BooleanSetting("Сохранять зачарованные", true);
    private final BooleanSetting preventBadSwap = new BooleanSetting("Умная замена", true);


    private final ModeListSetting threats = new ModeListSetting("Угрозы",
            new BooleanSetting("Кристаллы", true),
            new BooleanSetting("ТНТ", true),
            new BooleanSetting("Падение", true),
            new BooleanSetting("Низкое ХП", true));

    private final SliderSetting crystalRange = new SliderSetting("Дистанция кристаллов", 6.0f, 3.0f, 10.0f, 0.5f);
    private final SliderSetting fallDistance = new SliderSetting("Дистанция падения", 15.0f, 5.0f, 50.0f, 2.5f);


    private final StopWatch swapTimer = new StopWatch();
    private final StopWatch returnTimer = new StopWatch();
    private final StopWatch antiSpamTimer = new StopWatch();
    private final List<Integer> totemSlots = new ArrayList<>();

    private ItemStack previousOffhandItem = ItemStack.EMPTY;
    private int previousOffhandSlot = -1;
    private boolean totemActive = false;
    private boolean shouldReturn = false;
    private long lastSwapTime = 0;
    private int swapAttempts = 0;
    private boolean isSwapping = false;
    private boolean wasInDanger = false;

    public AutoTotem() {
        addSettings(healthThreshold, swapDelay, randomDelay, returnItem, returnDelay,
                saveEnchanted, preventBadSwap, threats, crystalRange, fallDistance);
    }

    @Subscribe
    private void onUpdate(EventUpdate event) {
        if (mc.player == null || mc.world == null) return;

        updateTotemSlots();

        boolean currentlyInDanger = isInDanger();


        if (currentlyInDanger && !hasTotemInOffhand()) {
            if (canSwapToTotem()) {
                handleTotemSwap();
            }
        }

        else if (!currentlyInDanger && shouldReturn && returnItem.get() &&
                returnTimer.isReached(getReturnDelay()) && !isSwapping) {
            handleItemReturn();
        }

        wasInDanger = currentlyInDanger;
    }

    @Subscribe
    private void onPacket(EventPacket event) {
        if (mc.player == null || mc.world == null) return;


        if (event.isReceive() && event.getPacket() instanceof SEntityStatusPacket packet) {
            if (packet.getOpCode() == 35 && packet.getEntity(mc.world) == mc.player) {
                onTotemActivated();
            }
        }
    }

    @Subscribe
    private void onSpawnEntity(EventSpawnEntity event) {
        if (!threats.getValueByName("Кристаллы").get()) return;
        if (mc.player == null || mc.world == null) return;

        Entity entity = event.getEntity();
        if (entity instanceof EnderCrystalEntity crystal) {
            if (mc.player.getDistance(crystal) <= crystalRange.get()) {
                // by wlayn3x
                if (!hasTotemInOffhand() && canSwapToTotem()) {
                    handleTotemSwap();
                }
            }
        }
    }

    private boolean canSwapToTotem() {

        return !totemSlots.isEmpty() &&
                !isSwapping &&
                antiSpamTimer.isReached(200) &&
                swapTimer.isReached(getRandomizedDelay()) &&
                System.currentTimeMillis() - lastSwapTime >= 300;
    }

    private boolean isInDanger() {
        return isLowHealth() || isDangerous() || isFalling();
    }

    private boolean isLowHealth() {
        if (!threats.getValueByName("Низкое ХП").get()) return false;

        float health = mc.player.getHealth();
        float absorption = mc.player.getAbsorptionAmount();


        if (mc.player.isPotionActive(Effects.ABSORPTION)) {
            health += absorption;
        }

        return health <= healthThreshold.get();
    }

    private boolean isDangerous() {
        if (mc.world == null) return false;

        // Проверка кристаллов
        if (threats.getValueByName("Кристаллы").get()) {
            for (Entity entity : mc.world.getAllEntities()) {
                if (isDangerousEntity(entity)) {
                    return true;
                }
            }
        }

        return false;
    }

    private boolean isDangerousEntity(Entity entity) {
        float distance = mc.player.getDistance(entity);

        if (entity instanceof EnderCrystalEntity && distance <= crystalRange.get()) {
            return true;
        }

        if (threats.getValueByName("ТНТ").get()) {
            if ((entity instanceof TNTEntity || entity instanceof TNTMinecartEntity)
                    && distance <= 8.0f) {
                return true;
            }
        }

        return false;
    }

    private boolean isFalling() {
        if (!threats.getValueByName("Падение").get()) return false;

        return mc.player.fallDistance >= fallDistance.get() &&
                !mc.player.isInWater() &&
                !mc.player.isElytraFlying() &&
                !mc.player.isOnGround();
    }

    private void handleTotemSwap() {
        if (totemSlots.isEmpty() || mc.currentScreen != null || isSwapping) return;

        int totemSlot = getBestTotemSlot();
        if (totemSlot == -1) return;

        isSwapping = true;

        try {

            if (!hasTotemInOffhand()) {
                ItemStack offhandItem = mc.player.getHeldItemOffhand();
                if (!offhandItem.isEmpty() && offhandItem.getItem() != Items.TOTEM_OF_UNDYING) {
                    previousOffhandItem = offhandItem.copy();
                    previousOffhandSlot = findItemInInventory(offhandItem);
                    shouldReturn = true;
                    returnTimer.reset();
                }
            }


            performSwap(totemSlot, 45);

            lastSwapTime = System.currentTimeMillis();
            swapTimer.reset();
            antiSpamTimer.reset();

        } finally {

            new Thread(() -> {
                try {
                    Thread.sleep(100);
                    isSwapping = false;
                } catch (InterruptedException ignored) {}
            }).start();
        }
    }

    private void handleItemReturn() {
        if (!shouldReturn || previousOffhandItem.isEmpty() || isSwapping) return;


        if (isInDanger()) return;


        if (!hasTotemInOffhand()) {
            shouldReturn = false;
            return;
        }

        isSwapping = true;

        try {
            int itemSlot = findItemInInventory(previousOffhandItem);
            if (itemSlot != -1) {
                performSwap(itemSlot, 45);
            } else {

                int emptySlot = findEmptySlot();
                if (emptySlot != -1) {
                    performSwap(emptySlot, 45);
                }
            }

            shouldReturn = false;
            previousOffhandItem = ItemStack.EMPTY;
            previousOffhandSlot = -1;
            antiSpamTimer.reset();

        } finally {
            new Thread(() -> {
                try {
                    Thread.sleep(100);
                    isSwapping = false;
                } catch (InterruptedException ignored) {}
            }).start();
        }
    }

    private void performSwap(int sourceSlot, int targetSlot) {
        if (sourceSlot == -1 || mc.currentScreen != null) return;

        int windowId = mc.player.container.windowId;
        int adjustedSourceSlot = sourceSlot < 9 ? sourceSlot + 36 : sourceSlot;

        try {

            mc.playerController.windowClick(windowId, adjustedSourceSlot, 0, ClickType.PICKUP, mc.player);
            Thread.sleep(50);
            mc.playerController.windowClick(windowId, targetSlot, 0, ClickType.PICKUP, mc.player);


            if (!mc.player.inventory.getItemStack().isEmpty()) {
                Thread.sleep(50);
                mc.playerController.windowClick(windowId, adjustedSourceSlot, 0, ClickType.PICKUP, mc.player);
            }

            mc.playerController.updateController();
        } catch (Exception e) {

        }
    }

    private void updateTotemSlots() {
        totemSlots.clear();

        for (int i = 0; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (isValidTotem(stack)) {
                totemSlots.add(i);
            }
        }
    }

    private boolean isValidTotem(ItemStack stack) {
        if (stack.getItem() != Items.TOTEM_OF_UNDYING) return false;


        if (saveEnchanted.get() && stack.isEnchanted()) {

            long normalTotems = totemSlots.stream()
                    .map(i -> mc.player.inventory.getStackInSlot(i))
                    .filter(s -> s.getItem() == Items.TOTEM_OF_UNDYING && !s.isEnchanted())
                    .count();

            return normalTotems == 0;
        }

        return true;
    }

    private int getBestTotemSlot() {
        if (totemSlots.isEmpty()) return -1;


        for (int slot : totemSlots) {
            ItemStack stack = mc.player.inventory.getStackInSlot(slot);
            if (!stack.isEnchanted()) {
                return slot;
            }
        }


        return totemSlots.get(0);
    }

    private boolean hasTotemInOffhand() {
        ItemStack offhandItem = mc.player.getHeldItemOffhand();
        return offhandItem.getItem() == Items.TOTEM_OF_UNDYING;
    }

    private int findItemInInventory(ItemStack targetStack) {
        for (int i = 0; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (ItemStack.areItemStacksEqual(stack, targetStack)) {
                return i;
            }
        }
        return -1;
    }

    private int findEmptySlot() {
        for (int i = 9; i < 36; i++) {
            if (mc.player.inventory.getStackInSlot(i).isEmpty()) {
                return i;
            }
        }
        return -1;
    }

    private long getRandomizedDelay() {
        long baseDelay = swapDelay.get().longValue();
        long randomOffset = ThreadLocalRandom.current().nextLong(0, randomDelay.get().longValue() + 1);
        return baseDelay + randomOffset;
    }

    private long getReturnDelay() {
        long baseDelay = returnDelay.get().longValue();
        long randomOffset = ThreadLocalRandom.current().nextLong(0, 100);
        return baseDelay + randomOffset;
    }

    private void onTotemActivated() {
        totemActive = true;
        shouldReturn = false;
        isSwapping = false;
        antiSpamTimer.reset();


        if (!totemSlots.isEmpty() && !hasTotemInOffhand()) {
            swapTimer.reset();
        }
    }

    private void reset() {
        totemSlots.clear();
        previousOffhandItem = ItemStack.EMPTY;
        previousOffhandSlot = -1;
        shouldReturn = false;
        totemActive = false;
        lastSwapTime = 0;
        swapAttempts = 0;
        isSwapping = false;
        wasInDanger = false;
        swapTimer.reset();
        returnTimer.reset();
        antiSpamTimer.reset();
    }

    @Override
    public boolean onEnable() {
        super.onEnable();
        if (mc.player != null && mc.world != null) {
            reset();
            return true;
        }
        return false;
    }

    @Override
    public void onDisable() {
        reset();
        super.onDisable();
    }
}
я вроде бы все импортировал но не знаю что делать с @override? оно не импортируется, когда ставлю @Subscribe не работает авто тотем. ansoft_terpish дс мой помоги пожалуйста если не трудно, знаю что я лох и тд не умею пастить
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
во первых паимоналетка, добавлю не сейчас, во вторых не удаляй, будет актив я сделаю

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


написать более нормальный чуть чатгпт, но обходит античиты
Можно настраивать его работу, задержки там и тд
Так же он более умный, ставит в приоритет тотем который находиться в слотах
а не в инвентаре = если закончились/нету в слоте, берет из инвентаря
короче если будет детектиться, могу скиднуть из вексайда, который перебрасывает из инвентаря в слоты

Ну, а так вроде отлично работает

Пожалуйста, авторизуйтесь для просмотра ссылки.








Код:
Expand Collapse Copy
@FunctionRegister(name = "AutoTotem", type = Category.Combat)
public class AutoTotem extends Function {
    @Override
    public String getDescription() {
        return "Автоматически берет тотем в руку";
    }

    private final SliderSetting healthThreshold = new SliderSetting("Здоровье", 6.0f, 1.0f, 20.0f, 0.5f);
    private final SliderSetting swapDelay = new SliderSetting("Задержка свапа", 150, 100, 500, 25);
    private final SliderSetting randomDelay = new SliderSetting("Случайная задержка", 25, 0, 100, 5);


    private final BooleanSetting returnItem = new BooleanSetting("Возвращать предмет", true);
    private final SliderSetting returnDelay = new SliderSetting("Задержка возврата", 2000, 1000, 5000, 250);
    private final BooleanSetting saveEnchanted = new BooleanSetting("Сохранять зачарованные", true);
    private final BooleanSetting preventBadSwap = new BooleanSetting("Умная замена", true);


    private final ModeListSetting threats = new ModeListSetting("Угрозы",
            new BooleanSetting("Кристаллы", true),
            new BooleanSetting("ТНТ", true),
            new BooleanSetting("Падение", true),
            new BooleanSetting("Низкое ХП", true));

    private final SliderSetting crystalRange = new SliderSetting("Дистанция кристаллов", 6.0f, 3.0f, 10.0f, 0.5f);
    private final SliderSetting fallDistance = new SliderSetting("Дистанция падения", 15.0f, 5.0f, 50.0f, 2.5f);


    private final StopWatch swapTimer = new StopWatch();
    private final StopWatch returnTimer = new StopWatch();
    private final StopWatch antiSpamTimer = new StopWatch();
    private final List<Integer> totemSlots = new ArrayList<>();

    private ItemStack previousOffhandItem = ItemStack.EMPTY;
    private int previousOffhandSlot = -1;
    private boolean totemActive = false;
    private boolean shouldReturn = false;
    private long lastSwapTime = 0;
    private int swapAttempts = 0;
    private boolean isSwapping = false;
    private boolean wasInDanger = false;

    public AutoTotem() {
        addSettings(healthThreshold, swapDelay, randomDelay, returnItem, returnDelay,
                saveEnchanted, preventBadSwap, threats, crystalRange, fallDistance);
    }

    @Subscribe
    private void onUpdate(EventUpdate event) {
        if (mc.player == null || mc.world == null) return;

        updateTotemSlots();

        boolean currentlyInDanger = isInDanger();


        if (currentlyInDanger && !hasTotemInOffhand()) {
            if (canSwapToTotem()) {
                handleTotemSwap();
            }
        }

        else if (!currentlyInDanger && shouldReturn && returnItem.get() &&
                returnTimer.isReached(getReturnDelay()) && !isSwapping) {
            handleItemReturn();
        }

        wasInDanger = currentlyInDanger;
    }

    @Subscribe
    private void onPacket(EventPacket event) {
        if (mc.player == null || mc.world == null) return;


        if (event.isReceive() && event.getPacket() instanceof SEntityStatusPacket packet) {
            if (packet.getOpCode() == 35 && packet.getEntity(mc.world) == mc.player) {
                onTotemActivated();
            }
        }
    }

    @Subscribe
    private void onSpawnEntity(EventSpawnEntity event) {
        if (!threats.getValueByName("Кристаллы").get()) return;
        if (mc.player == null || mc.world == null) return;

        Entity entity = event.getEntity();
        if (entity instanceof EnderCrystalEntity crystal) {
            if (mc.player.getDistance(crystal) <= crystalRange.get()) {
                // by wlayn3x
                if (!hasTotemInOffhand() && canSwapToTotem()) {
                    handleTotemSwap();
                }
            }
        }
    }

    private boolean canSwapToTotem() {

        return !totemSlots.isEmpty() &&
                !isSwapping &&
                antiSpamTimer.isReached(200) &&
                swapTimer.isReached(getRandomizedDelay()) &&
                System.currentTimeMillis() - lastSwapTime >= 300;
    }

    private boolean isInDanger() {
        return isLowHealth() || isDangerous() || isFalling();
    }

    private boolean isLowHealth() {
        if (!threats.getValueByName("Низкое ХП").get()) return false;

        float health = mc.player.getHealth();
        float absorption = mc.player.getAbsorptionAmount();


        if (mc.player.isPotionActive(Effects.ABSORPTION)) {
            health += absorption;
        }

        return health <= healthThreshold.get();
    }

    private boolean isDangerous() {
        if (mc.world == null) return false;

        // Проверка кристаллов
        if (threats.getValueByName("Кристаллы").get()) {
            for (Entity entity : mc.world.getAllEntities()) {
                if (isDangerousEntity(entity)) {
                    return true;
                }
            }
        }

        return false;
    }

    private boolean isDangerousEntity(Entity entity) {
        float distance = mc.player.getDistance(entity);

        if (entity instanceof EnderCrystalEntity && distance <= crystalRange.get()) {
            return true;
        }

        if (threats.getValueByName("ТНТ").get()) {
            if ((entity instanceof TNTEntity || entity instanceof TNTMinecartEntity)
                    && distance <= 8.0f) {
                return true;
            }
        }

        return false;
    }

    private boolean isFalling() {
        if (!threats.getValueByName("Падение").get()) return false;

        return mc.player.fallDistance >= fallDistance.get() &&
                !mc.player.isInWater() &&
                !mc.player.isElytraFlying() &&
                !mc.player.isOnGround();
    }

    private void handleTotemSwap() {
        if (totemSlots.isEmpty() || mc.currentScreen != null || isSwapping) return;

        int totemSlot = getBestTotemSlot();
        if (totemSlot == -1) return;

        isSwapping = true;

        try {

            if (!hasTotemInOffhand()) {
                ItemStack offhandItem = mc.player.getHeldItemOffhand();
                if (!offhandItem.isEmpty() && offhandItem.getItem() != Items.TOTEM_OF_UNDYING) {
                    previousOffhandItem = offhandItem.copy();
                    previousOffhandSlot = findItemInInventory(offhandItem);
                    shouldReturn = true;
                    returnTimer.reset();
                }
            }


            performSwap(totemSlot, 45);

            lastSwapTime = System.currentTimeMillis();
            swapTimer.reset();
            antiSpamTimer.reset();

        } finally {

            new Thread(() -> {
                try {
                    Thread.sleep(100);
                    isSwapping = false;
                } catch (InterruptedException ignored) {}
            }).start();
        }
    }

    private void handleItemReturn() {
        if (!shouldReturn || previousOffhandItem.isEmpty() || isSwapping) return;


        if (isInDanger()) return;


        if (!hasTotemInOffhand()) {
            shouldReturn = false;
            return;
        }

        isSwapping = true;

        try {
            int itemSlot = findItemInInventory(previousOffhandItem);
            if (itemSlot != -1) {
                performSwap(itemSlot, 45);
            } else {

                int emptySlot = findEmptySlot();
                if (emptySlot != -1) {
                    performSwap(emptySlot, 45);
                }
            }

            shouldReturn = false;
            previousOffhandItem = ItemStack.EMPTY;
            previousOffhandSlot = -1;
            antiSpamTimer.reset();

        } finally {
            new Thread(() -> {
                try {
                    Thread.sleep(100);
                    isSwapping = false;
                } catch (InterruptedException ignored) {}
            }).start();
        }
    }

    private void performSwap(int sourceSlot, int targetSlot) {
        if (sourceSlot == -1 || mc.currentScreen != null) return;

        int windowId = mc.player.container.windowId;
        int adjustedSourceSlot = sourceSlot < 9 ? sourceSlot + 36 : sourceSlot;

        try {

            mc.playerController.windowClick(windowId, adjustedSourceSlot, 0, ClickType.PICKUP, mc.player);
            Thread.sleep(50);
            mc.playerController.windowClick(windowId, targetSlot, 0, ClickType.PICKUP, mc.player);


            if (!mc.player.inventory.getItemStack().isEmpty()) {
                Thread.sleep(50);
                mc.playerController.windowClick(windowId, adjustedSourceSlot, 0, ClickType.PICKUP, mc.player);
            }

            mc.playerController.updateController();
        } catch (Exception e) {

        }
    }

    private void updateTotemSlots() {
        totemSlots.clear();

        for (int i = 0; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (isValidTotem(stack)) {
                totemSlots.add(i);
            }
        }
    }

    private boolean isValidTotem(ItemStack stack) {
        if (stack.getItem() != Items.TOTEM_OF_UNDYING) return false;


        if (saveEnchanted.get() && stack.isEnchanted()) {

            long normalTotems = totemSlots.stream()
                    .map(i -> mc.player.inventory.getStackInSlot(i))
                    .filter(s -> s.getItem() == Items.TOTEM_OF_UNDYING && !s.isEnchanted())
                    .count();

            return normalTotems == 0;
        }

        return true;
    }

    private int getBestTotemSlot() {
        if (totemSlots.isEmpty()) return -1;


        for (int slot : totemSlots) {
            ItemStack stack = mc.player.inventory.getStackInSlot(slot);
            if (!stack.isEnchanted()) {
                return slot;
            }
        }


        return totemSlots.get(0);
    }

    private boolean hasTotemInOffhand() {
        ItemStack offhandItem = mc.player.getHeldItemOffhand();
        return offhandItem.getItem() == Items.TOTEM_OF_UNDYING;
    }

    private int findItemInInventory(ItemStack targetStack) {
        for (int i = 0; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (ItemStack.areItemStacksEqual(stack, targetStack)) {
                return i;
            }
        }
        return -1;
    }

    private int findEmptySlot() {
        for (int i = 9; i < 36; i++) {
            if (mc.player.inventory.getStackInSlot(i).isEmpty()) {
                return i;
            }
        }
        return -1;
    }

    private long getRandomizedDelay() {
        long baseDelay = swapDelay.get().longValue();
        long randomOffset = ThreadLocalRandom.current().nextLong(0, randomDelay.get().longValue() + 1);
        return baseDelay + randomOffset;
    }

    private long getReturnDelay() {
        long baseDelay = returnDelay.get().longValue();
        long randomOffset = ThreadLocalRandom.current().nextLong(0, 100);
        return baseDelay + randomOffset;
    }

    private void onTotemActivated() {
        totemActive = true;
        shouldReturn = false;
        isSwapping = false;
        antiSpamTimer.reset();


        if (!totemSlots.isEmpty() && !hasTotemInOffhand()) {
            swapTimer.reset();
        }
    }

    private void reset() {
        totemSlots.clear();
        previousOffhandItem = ItemStack.EMPTY;
        previousOffhandSlot = -1;
        shouldReturn = false;
        totemActive = false;
        lastSwapTime = 0;
        swapAttempts = 0;
        isSwapping = false;
        wasInDanger = false;
        swapTimer.reset();
        returnTimer.reset();
        antiSpamTimer.reset();
    }

    @Override
    public boolean onEnable() {
        super.onEnable();
        if (mc.player != null && mc.world != null) {
            reset();
            return true;
        }
        return false;
    }

    @Override
    public void onDisable() {
        reset();
        super.onDisable();
    }
}
И что тут изменено?
во первых паимоналетка, добавлю не сейчас, во вторых не удаляй, будет актив я сделаю

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


написать более нормальный чуть чатгпт, но обходит античиты
Можно настраивать его работу, задержки там и тд
Так же он более умный, ставит в приоритет тотем который находиться в слотах
а не в инвентаре = если закончились/нету в слоте, берет из инвентаря
короче если будет детектиться, могу скиднуть из вексайда, который перебрасывает из инвентаря в слоты

Ну, а так вроде отлично работает

Пожалуйста, авторизуйтесь для просмотра ссылки.








Код:
Expand Collapse Copy
@FunctionRegister(name = "AutoTotem", type = Category.Combat)
public class AutoTotem extends Function {
    @Override
    public String getDescription() {
        return "Автоматически берет тотем в руку";
    }

    private final SliderSetting healthThreshold = new SliderSetting("Здоровье", 6.0f, 1.0f, 20.0f, 0.5f);
    private final SliderSetting swapDelay = new SliderSetting("Задержка свапа", 150, 100, 500, 25);
    private final SliderSetting randomDelay = new SliderSetting("Случайная задержка", 25, 0, 100, 5);


    private final BooleanSetting returnItem = new BooleanSetting("Возвращать предмет", true);
    private final SliderSetting returnDelay = new SliderSetting("Задержка возврата", 2000, 1000, 5000, 250);
    private final BooleanSetting saveEnchanted = new BooleanSetting("Сохранять зачарованные", true);
    private final BooleanSetting preventBadSwap = new BooleanSetting("Умная замена", true);


    private final ModeListSetting threats = new ModeListSetting("Угрозы",
            new BooleanSetting("Кристаллы", true),
            new BooleanSetting("ТНТ", true),
            new BooleanSetting("Падение", true),
            new BooleanSetting("Низкое ХП", true));

    private final SliderSetting crystalRange = new SliderSetting("Дистанция кристаллов", 6.0f, 3.0f, 10.0f, 0.5f);
    private final SliderSetting fallDistance = new SliderSetting("Дистанция падения", 15.0f, 5.0f, 50.0f, 2.5f);


    private final StopWatch swapTimer = new StopWatch();
    private final StopWatch returnTimer = new StopWatch();
    private final StopWatch antiSpamTimer = new StopWatch();
    private final List<Integer> totemSlots = new ArrayList<>();

    private ItemStack previousOffhandItem = ItemStack.EMPTY;
    private int previousOffhandSlot = -1;
    private boolean totemActive = false;
    private boolean shouldReturn = false;
    private long lastSwapTime = 0;
    private int swapAttempts = 0;
    private boolean isSwapping = false;
    private boolean wasInDanger = false;

    public AutoTotem() {
        addSettings(healthThreshold, swapDelay, randomDelay, returnItem, returnDelay,
                saveEnchanted, preventBadSwap, threats, crystalRange, fallDistance);
    }

    @Subscribe
    private void onUpdate(EventUpdate event) {
        if (mc.player == null || mc.world == null) return;

        updateTotemSlots();

        boolean currentlyInDanger = isInDanger();


        if (currentlyInDanger && !hasTotemInOffhand()) {
            if (canSwapToTotem()) {
                handleTotemSwap();
            }
        }

        else if (!currentlyInDanger && shouldReturn && returnItem.get() &&
                returnTimer.isReached(getReturnDelay()) && !isSwapping) {
            handleItemReturn();
        }

        wasInDanger = currentlyInDanger;
    }

    @Subscribe
    private void onPacket(EventPacket event) {
        if (mc.player == null || mc.world == null) return;


        if (event.isReceive() && event.getPacket() instanceof SEntityStatusPacket packet) {
            if (packet.getOpCode() == 35 && packet.getEntity(mc.world) == mc.player) {
                onTotemActivated();
            }
        }
    }

    @Subscribe
    private void onSpawnEntity(EventSpawnEntity event) {
        if (!threats.getValueByName("Кристаллы").get()) return;
        if (mc.player == null || mc.world == null) return;

        Entity entity = event.getEntity();
        if (entity instanceof EnderCrystalEntity crystal) {
            if (mc.player.getDistance(crystal) <= crystalRange.get()) {
                // by wlayn3x
                if (!hasTotemInOffhand() && canSwapToTotem()) {
                    handleTotemSwap();
                }
            }
        }
    }

    private boolean canSwapToTotem() {

        return !totemSlots.isEmpty() &&
                !isSwapping &&
                antiSpamTimer.isReached(200) &&
                swapTimer.isReached(getRandomizedDelay()) &&
                System.currentTimeMillis() - lastSwapTime >= 300;
    }

    private boolean isInDanger() {
        return isLowHealth() || isDangerous() || isFalling();
    }

    private boolean isLowHealth() {
        if (!threats.getValueByName("Низкое ХП").get()) return false;

        float health = mc.player.getHealth();
        float absorption = mc.player.getAbsorptionAmount();


        if (mc.player.isPotionActive(Effects.ABSORPTION)) {
            health += absorption;
        }

        return health <= healthThreshold.get();
    }

    private boolean isDangerous() {
        if (mc.world == null) return false;

        // Проверка кристаллов
        if (threats.getValueByName("Кристаллы").get()) {
            for (Entity entity : mc.world.getAllEntities()) {
                if (isDangerousEntity(entity)) {
                    return true;
                }
            }
        }

        return false;
    }

    private boolean isDangerousEntity(Entity entity) {
        float distance = mc.player.getDistance(entity);

        if (entity instanceof EnderCrystalEntity && distance <= crystalRange.get()) {
            return true;
        }

        if (threats.getValueByName("ТНТ").get()) {
            if ((entity instanceof TNTEntity || entity instanceof TNTMinecartEntity)
                    && distance <= 8.0f) {
                return true;
            }
        }

        return false;
    }

    private boolean isFalling() {
        if (!threats.getValueByName("Падение").get()) return false;

        return mc.player.fallDistance >= fallDistance.get() &&
                !mc.player.isInWater() &&
                !mc.player.isElytraFlying() &&
                !mc.player.isOnGround();
    }

    private void handleTotemSwap() {
        if (totemSlots.isEmpty() || mc.currentScreen != null || isSwapping) return;

        int totemSlot = getBestTotemSlot();
        if (totemSlot == -1) return;

        isSwapping = true;

        try {

            if (!hasTotemInOffhand()) {
                ItemStack offhandItem = mc.player.getHeldItemOffhand();
                if (!offhandItem.isEmpty() && offhandItem.getItem() != Items.TOTEM_OF_UNDYING) {
                    previousOffhandItem = offhandItem.copy();
                    previousOffhandSlot = findItemInInventory(offhandItem);
                    shouldReturn = true;
                    returnTimer.reset();
                }
            }


            performSwap(totemSlot, 45);

            lastSwapTime = System.currentTimeMillis();
            swapTimer.reset();
            antiSpamTimer.reset();

        } finally {

            new Thread(() -> {
                try {
                    Thread.sleep(100);
                    isSwapping = false;
                } catch (InterruptedException ignored) {}
            }).start();
        }
    }

    private void handleItemReturn() {
        if (!shouldReturn || previousOffhandItem.isEmpty() || isSwapping) return;


        if (isInDanger()) return;


        if (!hasTotemInOffhand()) {
            shouldReturn = false;
            return;
        }

        isSwapping = true;

        try {
            int itemSlot = findItemInInventory(previousOffhandItem);
            if (itemSlot != -1) {
                performSwap(itemSlot, 45);
            } else {

                int emptySlot = findEmptySlot();
                if (emptySlot != -1) {
                    performSwap(emptySlot, 45);
                }
            }

            shouldReturn = false;
            previousOffhandItem = ItemStack.EMPTY;
            previousOffhandSlot = -1;
            antiSpamTimer.reset();

        } finally {
            new Thread(() -> {
                try {
                    Thread.sleep(100);
                    isSwapping = false;
                } catch (InterruptedException ignored) {}
            }).start();
        }
    }

    private void performSwap(int sourceSlot, int targetSlot) {
        if (sourceSlot == -1 || mc.currentScreen != null) return;

        int windowId = mc.player.container.windowId;
        int adjustedSourceSlot = sourceSlot < 9 ? sourceSlot + 36 : sourceSlot;

        try {

            mc.playerController.windowClick(windowId, adjustedSourceSlot, 0, ClickType.PICKUP, mc.player);
            Thread.sleep(50);
            mc.playerController.windowClick(windowId, targetSlot, 0, ClickType.PICKUP, mc.player);


            if (!mc.player.inventory.getItemStack().isEmpty()) {
                Thread.sleep(50);
                mc.playerController.windowClick(windowId, adjustedSourceSlot, 0, ClickType.PICKUP, mc.player);
            }

            mc.playerController.updateController();
        } catch (Exception e) {

        }
    }

    private void updateTotemSlots() {
        totemSlots.clear();

        for (int i = 0; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (isValidTotem(stack)) {
                totemSlots.add(i);
            }
        }
    }

    private boolean isValidTotem(ItemStack stack) {
        if (stack.getItem() != Items.TOTEM_OF_UNDYING) return false;


        if (saveEnchanted.get() && stack.isEnchanted()) {

            long normalTotems = totemSlots.stream()
                    .map(i -> mc.player.inventory.getStackInSlot(i))
                    .filter(s -> s.getItem() == Items.TOTEM_OF_UNDYING && !s.isEnchanted())
                    .count();

            return normalTotems == 0;
        }

        return true;
    }

    private int getBestTotemSlot() {
        if (totemSlots.isEmpty()) return -1;


        for (int slot : totemSlots) {
            ItemStack stack = mc.player.inventory.getStackInSlot(slot);
            if (!stack.isEnchanted()) {
                return slot;
            }
        }


        return totemSlots.get(0);
    }

    private boolean hasTotemInOffhand() {
        ItemStack offhandItem = mc.player.getHeldItemOffhand();
        return offhandItem.getItem() == Items.TOTEM_OF_UNDYING;
    }

    private int findItemInInventory(ItemStack targetStack) {
        for (int i = 0; i < 36; i++) {
            ItemStack stack = mc.player.inventory.getStackInSlot(i);
            if (ItemStack.areItemStacksEqual(stack, targetStack)) {
                return i;
            }
        }
        return -1;
    }

    private int findEmptySlot() {
        for (int i = 9; i < 36; i++) {
            if (mc.player.inventory.getStackInSlot(i).isEmpty()) {
                return i;
            }
        }
        return -1;
    }

    private long getRandomizedDelay() {
        long baseDelay = swapDelay.get().longValue();
        long randomOffset = ThreadLocalRandom.current().nextLong(0, randomDelay.get().longValue() + 1);
        return baseDelay + randomOffset;
    }

    private long getReturnDelay() {
        long baseDelay = returnDelay.get().longValue();
        long randomOffset = ThreadLocalRandom.current().nextLong(0, 100);
        return baseDelay + randomOffset;
    }

    private void onTotemActivated() {
        totemActive = true;
        shouldReturn = false;
        isSwapping = false;
        antiSpamTimer.reset();


        if (!totemSlots.isEmpty() && !hasTotemInOffhand()) {
            swapTimer.reset();
        }
    }

    private void reset() {
        totemSlots.clear();
        previousOffhandItem = ItemStack.EMPTY;
        previousOffhandSlot = -1;
        shouldReturn = false;
        totemActive = false;
        lastSwapTime = 0;
        swapAttempts = 0;
        isSwapping = false;
        wasInDanger = false;
        swapTimer.reset();
        returnTimer.reset();
        antiSpamTimer.reset();
    }

    @Override
    public boolean onEnable() {
        super.onEnable();
        if (mc.player != null && mc.world != null) {
            reset();
            return true;
        }
        return false;
    }

    @Override
    public void onDisable() {
        reset();
        super.onDisable();
    }
}
ну чекни свой мега крутой $$elfcode авто тотем на пт каком нибудь, тебя интейв нахуй пошлет из за ClickType.PICKUP, да и стопов у тебя нету, о обходе чего идет речь
 
И что тут изменено?

ну чекни свой мега крутой $$elfcode авто тотем на пт каком нибудь, тебя интейв нахуй пошлет из за ClickType.PICKUP, да и стопов у тебя нету, о обходе чего идет речь
проверял на рв, фт, даже на твоем лююимом простотрейнере на фс, спукитайме везде работает, не проверял лишь на холике, но сомневаюсь что там не работает, а ты позорник, не проверив пишешь про что то, я бы не сливал, если б его банило, не свапало или же кикало, тебе не привыкать писать хуже идти на югейм со своими знаниями, и писать ыыыы нахуй интейв пошлет, лив с форума
 
дай updateController в PlayerController пж
package net.minecraft.client.multiplayer;

import com.mojang.datafixers.util.Pair;
import im.expensive.Expensive;
import im.expensive.events.AttackEvent;
import im.expensive.functions.api.FunctionRegistry;
import im.expensive.functions.impl.combat.KillAura;
import im.expensive.functions.impl.player.NoInteract;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import net.minecraft.block.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SimpleSound;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.network.play.ClientPlayNetHandler;
import net.minecraft.client.util.ClientRecipeBook;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.passive.horse.AbstractHorseEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.FluidState;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.network.play.client.*;
import net.minecraft.stats.StatisticsManager;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.EntityRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.GameType;
import net.minecraft.world.World;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class PlayerController {
private static final Logger LOGGER = LogManager.getLogger();
private final Minecraft mc;
private final ClientPlayNetHandler connection;
private BlockPos currentBlock = new BlockPos(-1, -1, -1);
private ItemStack currentItemHittingBlock = ItemStack.EMPTY;
private float curBlockDamageMP;
private float stepSoundTickCounter;
private int blockHitDelay;
private boolean isHittingBlock;
private GameType currentGameType = GameType.SURVIVAL;
private GameType field_239166_k_ = GameType.NOT_SET;
private final Object2ObjectLinkedOpenHashMap<Pair<BlockPos, CPlayerDiggingPacket.Action>, Vector3d> unacknowledgedDiggingPackets = new Object2ObjectLinkedOpenHashMap<>();
private int currentPlayerItem;

public PlayerController(Minecraft mcIn, ClientPlayNetHandler netHandler) {
this.mc = mcIn;
this.connection = netHandler;
}

/**
* Sets player capabilities depending on current gametype. params: player
*/
public void setPlayerCapabilities(PlayerEntity player) {
this.currentGameType.configurePlayerCapabilities(player.abilities);
}

public void func_241675_a_(GameType p_241675_1_) {
this.field_239166_k_ = p_241675_1_;
}

/**
* Sets the game type for the player.
*/
public void setGameType(GameType type) {
if (type != this.currentGameType) {
this.field_239166_k_ = this.currentGameType;
}

this.currentGameType = type;
this.currentGameType.configurePlayerCapabilities(this.mc.player.abilities);
}

public boolean shouldDrawHUD() {
return this.currentGameType.isSurvivalOrAdventure();
}

public boolean onPlayerDestroyBlock(BlockPos pos) {
if (this.mc.player.blockActionRestricted(this.mc.world, pos, this.currentGameType)) {
return false;
} else {
World world = this.mc.world;
BlockState blockstate = world.getBlockState(pos);

if (!this.mc.player.getHeldItemMainhand().getItem().canPlayerBreakBlockWhileHolding(blockstate, world, pos,
this.mc.player)) {
return false;
} else {
Block block = blockstate.getBlock();

if ((block instanceof CommandBlockBlock || block instanceof StructureBlock
|| block instanceof JigsawBlock) && !this.mc.player.canUseCommandBlock()) {
return false;
} else if (blockstate.isAir()) {
return false;
} else {
block.onBlockHarvested(world, pos, blockstate, this.mc.player);
FluidState fluidstate = world.getFluidState(pos);
boolean flag = world.setBlockState(pos, fluidstate.getBlockState(), 11);

if (flag) {
block.onPlayerDestroy(world, pos, blockstate);
}

return flag;
}
}
}
}

/**
* Called when the player is hitting a block with an item.
*/
public boolean clickBlock(BlockPos loc, Direction face) {
if (this.mc.player.blockActionRestricted(this.mc.world, loc, this.currentGameType)) {
return false;
} else if (!this.mc.world.getWorldBorder().contains(loc)) {
return false;
} else {
if (this.currentGameType.isCreative()) {
BlockState blockstate = this.mc.world.getBlockState(loc);
this.mc.getTutorial().onHitBlock(this.mc.world, loc, blockstate, 1.0F);
this.sendDiggingPacket(CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, loc, face);
this.onPlayerDestroyBlock(loc);
this.blockHitDelay = 5;
} else if (!this.isHittingBlock || !this.isHittingPosition(loc)) {
if (this.isHittingBlock) {
this.sendDiggingPacket(CPlayerDiggingPacket.Action.ABORT_DESTROY_BLOCK, this.currentBlock, face);
}

BlockState blockstate1 = this.mc.world.getBlockState(loc);
this.mc.getTutorial().onHitBlock(this.mc.world, loc, blockstate1, 0.0F);
this.sendDiggingPacket(CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, loc, face);
boolean flag = !blockstate1.isAir();

if (flag && this.curBlockDamageMP == 0.0F) {
blockstate1.onBlockClicked(this.mc.world, loc, this.mc.player);
}

if (flag && blockstate1.getPlayerRelativeBlockHardness(this.mc.player, this.mc.player.world,
loc) >= 1.0F) {
this.onPlayerDestroyBlock(loc);
} else {
this.isHittingBlock = true;
this.currentBlock = loc;
this.currentItemHittingBlock = this.mc.player.getHeldItemMainhand();
this.curBlockDamageMP = 0.0F;
this.stepSoundTickCounter = 0.0F;
this.mc.world.sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock,
(int) (this.curBlockDamageMP * 10.0F) - 1);
}
}

return true;
}
}

/**
* Resets current block damage
*/
public void resetBlockRemoving() {
if (this.isHittingBlock) {
BlockState blockstate = this.mc.world.getBlockState(this.currentBlock);
this.mc.getTutorial().onHitBlock(this.mc.world, this.currentBlock, blockstate, -1.0F);
this.sendDiggingPacket(CPlayerDiggingPacket.Action.ABORT_DESTROY_BLOCK, this.currentBlock, Direction.DOWN);
this.isHittingBlock = false;
this.curBlockDamageMP = 0.0F;
this.mc.world.sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock, -1);
this.mc.player.resetCooldown();
}
}

public boolean onPlayerDamageBlock(BlockPos posBlock, Direction directionFacing) {
this.syncCurrentPlayItem();

if (this.blockHitDelay > 0) {
--this.blockHitDelay;
return true;
} else if (this.currentGameType.isCreative() && this.mc.world.getWorldBorder().contains(posBlock)) {
this.blockHitDelay = 5;
BlockState blockstate1 = this.mc.world.getBlockState(posBlock);
this.mc.getTutorial().onHitBlock(this.mc.world, posBlock, blockstate1, 1.0F);
this.sendDiggingPacket(CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, posBlock, directionFacing);
this.onPlayerDestroyBlock(posBlock);
return true;
} else if (this.isHittingPosition(posBlock)) {
BlockState blockstate = this.mc.world.getBlockState(posBlock);

if (blockstate.isAir()) {
this.isHittingBlock = false;
return false;
} else {
this.curBlockDamageMP += blockstate.getPlayerRelativeBlockHardness(this.mc.player, this.mc.player.world,
posBlock);

if (this.stepSoundTickCounter % 4.0F == 0.0F) {
SoundType soundtype = blockstate.getSoundType();
this.mc.getSoundHandler().play(new SimpleSound(soundtype.getHitSound(), SoundCategory.BLOCKS,
(soundtype.getVolume() + 1.0F) / 8.0F, soundtype.getPitch() * 0.5F, posBlock));
}

++this.stepSoundTickCounter;
this.mc.getTutorial().onHitBlock(this.mc.world, posBlock, blockstate,
MathHelper.clamp(this.curBlockDamageMP, 0.0F, 1.0F));

if (this.curBlockDamageMP >= 1.0F) {
this.isHittingBlock = false;
this.sendDiggingPacket(CPlayerDiggingPacket.Action.STOP_DESTROY_BLOCK, posBlock, directionFacing);
this.onPlayerDestroyBlock(posBlock);
this.curBlockDamageMP = 0.0F;
this.stepSoundTickCounter = 0.0F;
this.blockHitDelay = 5;
}

this.mc.world.sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock,
(int) (this.curBlockDamageMP * 10.0F) - 1);
return true;
}
} else {
return this.clickBlock(posBlock, directionFacing);
}
}

/**
* player reach distance = 4F
*/
public float getBlockReachDistance() {
return this.currentGameType.isCreative() ? 5.0F : 4.5F;
}

public void tick() {
this.syncCurrentPlayItem();

if (this.connection.getNetworkManager().isChannelOpen()) {
this.connection.getNetworkManager().tick();
} else {
this.connection.getNetworkManager().handleDisconnection();
}
}

private boolean isHittingPosition(BlockPos pos) {
ItemStack itemstack = this.mc.player.getHeldItemMainhand();
boolean flag = this.currentItemHittingBlock.isEmpty() && itemstack.isEmpty();

if (!this.currentItemHittingBlock.isEmpty() && !itemstack.isEmpty()) {
flag = itemstack.getItem() == this.currentItemHittingBlock.getItem()
&& ItemStack.areItemStackTagsEqual(itemstack, this.currentItemHittingBlock)
&& (itemstack.isDamageable() || itemstack.getDamage() == this.currentItemHittingBlock.getDamage());
}

return pos.equals(this.currentBlock) && flag;
}

/**
* Syncs the current player item with the server
*/
public void syncCurrentPlayItem() {
int i = this.mc.player.inventory.currentItem;

if (i != this.currentPlayerItem) {
this.currentPlayerItem = i;
this.connection.sendPacket(new CHeldItemChangePacket(this.currentPlayerItem));
}
}

public ActionResultType processRightClickBlock(ClientPlayerEntity p_217292_1_, ClientWorld p_217292_2_, Hand p_217292_3_,
BlockRayTraceResult p_217292_4_) {
this.syncCurrentPlayItem();
BlockPos blockpos = p_217292_4_.getPos();

if (!this.mc.world.getWorldBorder().contains(blockpos)) {
return ActionResultType.FAIL;
} else {
ItemStack itemstack = p_217292_1_.getHeldItem(p_217292_3_);

if (this.currentGameType == GameType.SPECTATOR) {
this.connection.sendPacket(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
return ActionResultType.SUCCESS;
} else {
FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
KillAura killAura = functionRegistry.getKillAura();
NoInteract noInteract = functionRegistry.getNoInteract();

boolean flag = !p_217292_1_.getHeldItemMainhand().isEmpty()
|| !p_217292_1_.getHeldItemOffhand().isEmpty();
boolean flag1 = p_217292_1_.isSecondaryUseActive() && flag;
boolean flag2 = noInteract.isState() && noInteract.allBlocks.get() || noInteract.isState() &&
noInteract.getBlocks().contains(p_217292_2_.getBlockState(p_217292_4_.getPos()).getBlockId())
|| killAura.getTarget() != null;
if (!flag2) {
if (!flag1) {
ActionResultType actionresulttype = p_217292_2_.getBlockState(blockpos)
.onBlockActivated(p_217292_2_, p_217292_1_, p_217292_3_, p_217292_4_);

if (actionresulttype.isSuccessOrConsume()) {
this.connection.sendPacket(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
return actionresulttype;
}
}
this.connection.sendPacket(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
}
if (!itemstack.isEmpty() && !p_217292_1_.getCooldownTracker().hasCooldown(itemstack.getItem())) {
ItemUseContext itemusecontext = new ItemUseContext(p_217292_1_, p_217292_3_, p_217292_4_);
ActionResultType actionresulttype1;

if (this.currentGameType.isCreative()) {
int i = itemstack.getCount();
actionresulttype1 = itemstack.onItemUse(itemusecontext);
itemstack.setCount(i);
} else {
actionresulttype1 = itemstack.onItemUse(itemusecontext);
}

return actionresulttype1;
} else {
return ActionResultType.PASS;
}
}
}
}

public ActionResultType processRightClick(PlayerEntity player, World worldIn, Hand hand) {
if (this.currentGameType == GameType.SPECTATOR) {
return ActionResultType.PASS;
} else {
this.syncCurrentPlayItem();
this.connection.sendPacket(new CPlayerTryUseItemPacket(hand));
ItemStack itemstack = player.getHeldItem(hand);

if (player.getCooldownTracker().hasCooldown(itemstack.getItem())) {
return ActionResultType.PASS;
} else {
int i = itemstack.getCount();
ActionResult<ItemStack> actionresult = itemstack.useItemRightClick(worldIn, player, hand);
ItemStack itemstack1 = actionresult.getResult();

if (itemstack1 != itemstack) {
player.setHeldItem(hand, itemstack1);
}

return actionresult.getType();
}
}
}

public ClientPlayerEntity createPlayer(ClientWorld worldIn, StatisticsManager statsManager,
ClientRecipeBook recipes) {
return this.func_239167_a_(worldIn, statsManager, recipes, false, false);
}

public ClientPlayerEntity func_239167_a_(ClientWorld p_239167_1_, StatisticsManager p_239167_2_,
ClientRecipeBook p_239167_3_, boolean p_239167_4_, boolean p_239167_5_) {
return new ClientPlayerEntity(this.mc, p_239167_1_, this.connection, p_239167_2_, p_239167_3_, p_239167_4_,
p_239167_5_);
}

private final AttackEvent event = new AttackEvent(null);

/**
* Attacks an entity
*/
public void attackEntity(PlayerEntity playerIn, Entity targetEntity) {
event.entity = targetEntity;
Expensive.getInstance().getEventBus().post(event);

this.syncCurrentPlayItem();

if (mc.player.serverSprintState && !mc.player.isInWater()) {
mc.player.connection.sendPacket(new CEntityActionPacket(mc.player, CEntityActionPacket.Action.STOP_SPRINTING));
}

this.connection.sendPacket(new CUseEntityPacket(targetEntity, playerIn.isSneaking()));

if (this.currentGameType != GameType.SPECTATOR) {
playerIn.attackTargetEntityWithCurrentItem(targetEntity);
playerIn.resetCooldown();
}
if (mc.player.serverSprintState && !mc.player.isInWater()) {
mc.player.connection.sendPacket(new CEntityActionPacket(mc.player, CEntityActionPacket.Action.START_SPRINTING));
}
}

/**
* Handles right clicking an entity, sends a packet to the server.
*/
public ActionResultType interactWithEntity(PlayerEntity player, Entity target, Hand hand) {
this.syncCurrentPlayItem();
this.connection.sendPacket(new CUseEntityPacket(target, hand, player.isSneaking()));
return this.currentGameType == GameType.SPECTATOR ? ActionResultType.PASS : player.interactOn(target, hand);
}

/**
* Handles right clicking an entity from the entities side, sends a packet to
* the server.
*/
public ActionResultType interactWithEntity(PlayerEntity player, Entity target, EntityRayTraceResult ray,
Hand hand) {
this.syncCurrentPlayItem();
Vector3d vector3d = ray.getHitVec().subtract(target.getPosX(), target.getPosY(), target.getPosZ());
this.connection.sendPacket(new CUseEntityPacket(target, hand, vector3d, player.isSneaking()));
return this.currentGameType == GameType.SPECTATOR ? ActionResultType.PASS
: target.applyPlayerInteraction(player, vector3d, hand);
}

/**
* Handles slot clicks, sends a packet to the server.
*/
public ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, PlayerEntity player) {
System.out.println(slotId);
short short1 = player.openContainer.getNextTransactionID(player.inventory);
ItemStack itemstack = player.openContainer.slotClick(slotId, mouseButton, type, player);
System.out.println(itemstack.getTag());
this.connection.sendPacket(new CClickWindowPacket(windowId, slotId, mouseButton, type, itemstack, short1));
return itemstack;
}

public void windowClickFixed(int windowId, int slotId, int mouseButton, ClickType type, PlayerEntity player, int timeWait) {
mc.player.windowClickMemory.add(new ClientPlayerEntity.WindowClickMemory(windowId, slotId, mouseButton, type, player, timeWait));
}

public void sendPlaceRecipePacket(int p_203413_1_, IRecipe<?> p_203413_2_, boolean p_203413_3_) {
this.connection.sendPacket(new CPlaceRecipePacket(p_203413_1_, p_203413_2_, p_203413_3_));
}

/**
* GuiEnchantment uses this during multiplayer to tell PlayerControllerMP to
* send a packet indicating the
* enchantment action the player has taken.
*/
public void sendEnchantPacket(int windowID, int button) {
this.connection.sendPacket(new CEnchantItemPacket(windowID, button));
}

/**
* Used in PlayerControllerMP to update the server with an ItemStack in a slot.
*/
public void sendSlotPacket(ItemStack itemStackIn, int slotId) {
if (this.currentGameType.isCreative()) {
this.connection.sendPacket(new CCreativeInventoryActionPacket(slotId, itemStackIn));
}
}

/**
* Sends a Packet107 to the server to drop the item on the ground
*/
public void sendPacketDropItem(ItemStack itemStackIn) {
if (this.currentGameType.isCreative() && !itemStackIn.isEmpty()) {
this.connection.sendPacket(new CCreativeInventoryActionPacket(-1, itemStackIn));
}
}

public void onStoppedUsingItem(PlayerEntity playerIn) {
this.syncCurrentPlayItem();
this.connection.sendPacket(
new CPlayerDiggingPacket(CPlayerDiggingPacket.Action.RELEASE_USE_ITEM, BlockPos.ZERO, Direction.DOWN));
playerIn.stopActiveHand();
}

public boolean gameIsSurvivalOrAdventure() {
return this.currentGameType.isSurvivalOrAdventure();
}

/**
* Checks if the player is not creative, used for checking if it should break a
* block instantly
*/
public boolean isNotCreative() {
return !this.currentGameType.isCreative();
}

/**
* returns true if player is in creative mode
*/
public boolean isInCreativeMode() {
return this.currentGameType.isCreative();
}

/**
* true for hitting entities far away.
*/
public boolean extendedReach() {
return this.currentGameType.isCreative();
}

/**
* Checks if the player is riding a horse, used to chose the GUI to open
*/
public boolean isRidingHorse() {
return this.mc.player.isPassenger() && this.mc.player.getRidingEntity() instanceof AbstractHorseEntity;
}

public boolean isSpectatorMode() {
return this.currentGameType == GameType.SPECTATOR;
}

public GameType func_241822_k() {
return this.field_239166_k_;
}

public GameType getCurrentGameType() {
return this.currentGameType;
}

/**
* Return isHittingBlock
*/
public boolean getIsHittingBlock() {
return this.isHittingBlock;
}

public void pickItem(int index) {
this.connection.sendPacket(new CPickItemPacket(index));
}

private void sendDiggingPacket(CPlayerDiggingPacket.Action action, BlockPos pos, Direction dir) {
ClientPlayerEntity clientplayerentity = this.mc.player;
this.unacknowledgedDiggingPackets.put(Pair.of(pos, action), clientplayerentity.getPositionVec());
this.connection.sendPacket(new CPlayerDiggingPacket(action, pos, dir));
}
public void updateController() {

this.syncCurrentPlayItem();

if (this.isHittingBlock) {
BlockState blockstate = this.mc.world.getBlockState(this.currentBlock);

if (blockstate.isAir()) {
this.isHittingBlock = false;
this.curBlockDamageMP = 0.0F;
this.mc.world.sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock, -1);
} else {
this.curBlockDamageMP += blockstate.getPlayerRelativeBlockHardness(this.mc.player, this.mc.player.world, this.currentBlock);

this.stepSoundTickCounter++;
if (this.stepSoundTickCounter % 4.0F == 0.0F) {
SoundType soundtype = blockstate.getSoundType();
this.mc.getSoundHandler().play(new SimpleSound(soundtype.getHitSound(), SoundCategory.BLOCKS,
(soundtype.getVolume() + 1.0F) / 8.0F, soundtype.getPitch() * 0.5F, this.currentBlock));
}

this.mc.getTutorial().onHitBlock(this.mc.world, this.currentBlock, blockstate, MathHelper.clamp(this.curBlockDamageMP, 0.0F, 1.0F));

if (this.curBlockDamageMP >= 1.0F) {
this.isHittingBlock = false;
this.sendDiggingPacket(CPlayerDiggingPacket.Action.STOP_DESTROY_BLOCK, this.currentBlock, Direction.UP);
this.onPlayerDestroyBlock(this.currentBlock);
this.curBlockDamageMP = 0.0F;
this.stepSoundTickCounter = 0.0F;
this.blockHitDelay = 5;
}

this.mc.world.sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1);
}
}
if (this.connection.getNetworkManager().isChannelOpen()) {
this.connection.getNetworkManager().tick();
} else {
this.connection.getNetworkManager().handleDisconnection();
}
}


public void acknowledgePlayerDiggingReceived(ClientWorld worldIn, BlockPos pos, BlockState blockIn,
CPlayerDiggingPacket.Action action, boolean successful) {
Vector3d vector3d = this.unacknowledgedDiggingPackets.remove(Pair.of(pos, action));
BlockState blockstate = worldIn.getBlockState(pos);

if ((vector3d == null || !successful
|| action != CPlayerDiggingPacket.Action.START_DESTROY_BLOCK && blockstate != blockIn)
&& blockstate != blockIn) {
worldIn.invalidateRegionAndSetBlock(pos, blockIn);
PlayerEntity playerentity = this.mc.player;

if (vector3d != null && worldIn == playerentity.world && playerentity.func_242278_a(pos, blockIn)) {
playerentity.func_242281_f(vector3d.x, vector3d.y, vector3d.z);
}
}

while (this.unacknowledgedDiggingPackets.size() >= 50) {
Pair<BlockPos, CPlayerDiggingPacket.Action> pair = this.unacknowledgedDiggingPackets.firstKey();
this.unacknowledgedDiggingPackets.removeFirst();
LOGGER.error("Too many unacked block actions, dropping " + pair);
}
}



}
 
package net.minecraft.client.multiplayer;

import com.mojang.datafixers.util.Pair;
import im.expensive.Expensive;
import im.expensive.events.AttackEvent;
import im.expensive.functions.api.FunctionRegistry;
import im.expensive.functions.impl.combat.KillAura;
import im.expensive.functions.impl.player.NoInteract;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import net.minecraft.block.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SimpleSound;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.network.play.ClientPlayNetHandler;
import net.minecraft.client.util.ClientRecipeBook;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.passive.horse.AbstractHorseEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.FluidState;
import net.minecraft.inventory.container.ClickType;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.network.play.client.*;
import net.minecraft.stats.StatisticsManager;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.EntityRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.GameType;
import net.minecraft.world.World;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class PlayerController {
private static final Logger LOGGER = LogManager.getLogger();
private final Minecraft mc;
private final ClientPlayNetHandler connection;
private BlockPos currentBlock = new BlockPos(-1, -1, -1);
private ItemStack currentItemHittingBlock = ItemStack.EMPTY;
private float curBlockDamageMP;
private float stepSoundTickCounter;
private int blockHitDelay;
private boolean isHittingBlock;
private GameType currentGameType = GameType.SURVIVAL;
private GameType field_239166_k_ = GameType.NOT_SET;
private final Object2ObjectLinkedOpenHashMap<Pair<BlockPos, CPlayerDiggingPacket.Action>, Vector3d> unacknowledgedDiggingPackets = new Object2ObjectLinkedOpenHashMap<>();
private int currentPlayerItem;

public PlayerController(Minecraft mcIn, ClientPlayNetHandler netHandler) {
this.mc = mcIn;
this.connection = netHandler;
}

/**
* Sets player capabilities depending on current gametype. params: player
*/
public void setPlayerCapabilities(PlayerEntity player) {
this.currentGameType.configurePlayerCapabilities(player.abilities);
}

public void func_241675_a_(GameType p_241675_1_) {
this.field_239166_k_ = p_241675_1_;
}

/**
* Sets the game type for the player.
*/
public void setGameType(GameType type) {
if (type != this.currentGameType) {
this.field_239166_k_ = this.currentGameType;
}

this.currentGameType = type;
this.currentGameType.configurePlayerCapabilities(this.mc.player.abilities);
}

public boolean shouldDrawHUD() {
return this.currentGameType.isSurvivalOrAdventure();
}

public boolean onPlayerDestroyBlock(BlockPos pos) {
if (this.mc.player.blockActionRestricted(this.mc.world, pos, this.currentGameType)) {
return false;
} else {
World world = this.mc.world;
BlockState blockstate = world.getBlockState(pos);

if (!this.mc.player.getHeldItemMainhand().getItem().canPlayerBreakBlockWhileHolding(blockstate, world, pos,
this.mc.player)) {
return false;
} else {
Block block = blockstate.getBlock();

if ((block instanceof CommandBlockBlock || block instanceof StructureBlock
|| block instanceof JigsawBlock) && !this.mc.player.canUseCommandBlock()) {
return false;
} else if (blockstate.isAir()) {
return false;
} else {
block.onBlockHarvested(world, pos, blockstate, this.mc.player);
FluidState fluidstate = world.getFluidState(pos);
boolean flag = world.setBlockState(pos, fluidstate.getBlockState(), 11);

if (flag) {
block.onPlayerDestroy(world, pos, blockstate);
}

return flag;
}
}
}
}

/**
* Called when the player is hitting a block with an item.
*/
public boolean clickBlock(BlockPos loc, Direction face) {
if (this.mc.player.blockActionRestricted(this.mc.world, loc, this.currentGameType)) {
return false;
} else if (!this.mc.world.getWorldBorder().contains(loc)) {
return false;
} else {
if (this.currentGameType.isCreative()) {
BlockState blockstate = this.mc.world.getBlockState(loc);
this.mc.getTutorial().onHitBlock(this.mc.world, loc, blockstate, 1.0F);
this.sendDiggingPacket(CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, loc, face);
this.onPlayerDestroyBlock(loc);
this.blockHitDelay = 5;
} else if (!this.isHittingBlock || !this.isHittingPosition(loc)) {
if (this.isHittingBlock) {
this.sendDiggingPacket(CPlayerDiggingPacket.Action.ABORT_DESTROY_BLOCK, this.currentBlock, face);
}

BlockState blockstate1 = this.mc.world.getBlockState(loc);
this.mc.getTutorial().onHitBlock(this.mc.world, loc, blockstate1, 0.0F);
this.sendDiggingPacket(CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, loc, face);
boolean flag = !blockstate1.isAir();

if (flag && this.curBlockDamageMP == 0.0F) {
blockstate1.onBlockClicked(this.mc.world, loc, this.mc.player);
}

if (flag && blockstate1.getPlayerRelativeBlockHardness(this.mc.player, this.mc.player.world,
loc) >= 1.0F) {
this.onPlayerDestroyBlock(loc);
} else {
this.isHittingBlock = true;
this.currentBlock = loc;
this.currentItemHittingBlock = this.mc.player.getHeldItemMainhand();
this.curBlockDamageMP = 0.0F;
this.stepSoundTickCounter = 0.0F;
this.mc.world.sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock,
(int) (this.curBlockDamageMP * 10.0F) - 1);
}
}

return true;
}
}

/**
* Resets current block damage
*/
public void resetBlockRemoving() {
if (this.isHittingBlock) {
BlockState blockstate = this.mc.world.getBlockState(this.currentBlock);
this.mc.getTutorial().onHitBlock(this.mc.world, this.currentBlock, blockstate, -1.0F);
this.sendDiggingPacket(CPlayerDiggingPacket.Action.ABORT_DESTROY_BLOCK, this.currentBlock, Direction.DOWN);
this.isHittingBlock = false;
this.curBlockDamageMP = 0.0F;
this.mc.world.sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock, -1);
this.mc.player.resetCooldown();
}
}

public boolean onPlayerDamageBlock(BlockPos posBlock, Direction directionFacing) {
this.syncCurrentPlayItem();

if (this.blockHitDelay > 0) {
--this.blockHitDelay;
return true;
} else if (this.currentGameType.isCreative() && this.mc.world.getWorldBorder().contains(posBlock)) {
this.blockHitDelay = 5;
BlockState blockstate1 = this.mc.world.getBlockState(posBlock);
this.mc.getTutorial().onHitBlock(this.mc.world, posBlock, blockstate1, 1.0F);
this.sendDiggingPacket(CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, posBlock, directionFacing);
this.onPlayerDestroyBlock(posBlock);
return true;
} else if (this.isHittingPosition(posBlock)) {
BlockState blockstate = this.mc.world.getBlockState(posBlock);

if (blockstate.isAir()) {
this.isHittingBlock = false;
return false;
} else {
this.curBlockDamageMP += blockstate.getPlayerRelativeBlockHardness(this.mc.player, this.mc.player.world,
posBlock);

if (this.stepSoundTickCounter % 4.0F == 0.0F) {
SoundType soundtype = blockstate.getSoundType();
this.mc.getSoundHandler().play(new SimpleSound(soundtype.getHitSound(), SoundCategory.BLOCKS,
(soundtype.getVolume() + 1.0F) / 8.0F, soundtype.getPitch() * 0.5F, posBlock));
}

++this.stepSoundTickCounter;
this.mc.getTutorial().onHitBlock(this.mc.world, posBlock, blockstate,
MathHelper.clamp(this.curBlockDamageMP, 0.0F, 1.0F));

if (this.curBlockDamageMP >= 1.0F) {
this.isHittingBlock = false;
this.sendDiggingPacket(CPlayerDiggingPacket.Action.STOP_DESTROY_BLOCK, posBlock, directionFacing);
this.onPlayerDestroyBlock(posBlock);
this.curBlockDamageMP = 0.0F;
this.stepSoundTickCounter = 0.0F;
this.blockHitDelay = 5;
}

this.mc.world.sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock,
(int) (this.curBlockDamageMP * 10.0F) - 1);
return true;
}
} else {
return this.clickBlock(posBlock, directionFacing);
}
}

/**
* player reach distance = 4F
*/
public float getBlockReachDistance() {
return this.currentGameType.isCreative() ? 5.0F : 4.5F;
}

public void tick() {
this.syncCurrentPlayItem();

if (this.connection.getNetworkManager().isChannelOpen()) {
this.connection.getNetworkManager().tick();
} else {
this.connection.getNetworkManager().handleDisconnection();
}
}

private boolean isHittingPosition(BlockPos pos) {
ItemStack itemstack = this.mc.player.getHeldItemMainhand();
boolean flag = this.currentItemHittingBlock.isEmpty() && itemstack.isEmpty();

if (!this.currentItemHittingBlock.isEmpty() && !itemstack.isEmpty()) {
flag = itemstack.getItem() == this.currentItemHittingBlock.getItem()
&& ItemStack.areItemStackTagsEqual(itemstack, this.currentItemHittingBlock)
&& (itemstack.isDamageable() || itemstack.getDamage() == this.currentItemHittingBlock.getDamage());
}

return pos.equals(this.currentBlock) && flag;
}

/**
* Syncs the current player item with the server
*/
public void syncCurrentPlayItem() {
int i = this.mc.player.inventory.currentItem;

if (i != this.currentPlayerItem) {
this.currentPlayerItem = i;
this.connection.sendPacket(new CHeldItemChangePacket(this.currentPlayerItem));
}
}

public ActionResultType processRightClickBlock(ClientPlayerEntity p_217292_1_, ClientWorld p_217292_2_, Hand p_217292_3_,
BlockRayTraceResult p_217292_4_) {
this.syncCurrentPlayItem();
BlockPos blockpos = p_217292_4_.getPos();

if (!this.mc.world.getWorldBorder().contains(blockpos)) {
return ActionResultType.FAIL;
} else {
ItemStack itemstack = p_217292_1_.getHeldItem(p_217292_3_);

if (this.currentGameType == GameType.SPECTATOR) {
this.connection.sendPacket(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
return ActionResultType.SUCCESS;
} else {
FunctionRegistry functionRegistry = Expensive.getInstance().getFunctionRegistry();
KillAura killAura = functionRegistry.getKillAura();
NoInteract noInteract = functionRegistry.getNoInteract();

boolean flag = !p_217292_1_.getHeldItemMainhand().isEmpty()
|| !p_217292_1_.getHeldItemOffhand().isEmpty();
boolean flag1 = p_217292_1_.isSecondaryUseActive() && flag;
boolean flag2 = noInteract.isState() && noInteract.allBlocks.get() || noInteract.isState() &&
noInteract.getBlocks().contains(p_217292_2_.getBlockState(p_217292_4_.getPos()).getBlockId())
|| killAura.getTarget() != null;
if (!flag2) {
if (!flag1) {
ActionResultType actionresulttype = p_217292_2_.getBlockState(blockpos)
.onBlockActivated(p_217292_2_, p_217292_1_, p_217292_3_, p_217292_4_);

if (actionresulttype.isSuccessOrConsume()) {
this.connection.sendPacket(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
return actionresulttype;
}
}
this.connection.sendPacket(new CPlayerTryUseItemOnBlockPacket(p_217292_3_, p_217292_4_));
}
if (!itemstack.isEmpty() && !p_217292_1_.getCooldownTracker().hasCooldown(itemstack.getItem())) {
ItemUseContext itemusecontext = new ItemUseContext(p_217292_1_, p_217292_3_, p_217292_4_);
ActionResultType actionresulttype1;

if (this.currentGameType.isCreative()) {
int i = itemstack.getCount();
actionresulttype1 = itemstack.onItemUse(itemusecontext);
itemstack.setCount(i);
} else {
actionresulttype1 = itemstack.onItemUse(itemusecontext);
}

return actionresulttype1;
} else {
return ActionResultType.PASS;
}
}
}
}

public ActionResultType processRightClick(PlayerEntity player, World worldIn, Hand hand) {
if (this.currentGameType == GameType.SPECTATOR) {
return ActionResultType.PASS;
} else {
this.syncCurrentPlayItem();
this.connection.sendPacket(new CPlayerTryUseItemPacket(hand));
ItemStack itemstack = player.getHeldItem(hand);

if (player.getCooldownTracker().hasCooldown(itemstack.getItem())) {
return ActionResultType.PASS;
} else {
int i = itemstack.getCount();
ActionResult<ItemStack> actionresult = itemstack.useItemRightClick(worldIn, player, hand);
ItemStack itemstack1 = actionresult.getResult();

if (itemstack1 != itemstack) {
player.setHeldItem(hand, itemstack1);
}

return actionresult.getType();
}
}
}

public ClientPlayerEntity createPlayer(ClientWorld worldIn, StatisticsManager statsManager,
ClientRecipeBook recipes) {
return this.func_239167_a_(worldIn, statsManager, recipes, false, false);
}

public ClientPlayerEntity func_239167_a_(ClientWorld p_239167_1_, StatisticsManager p_239167_2_,
ClientRecipeBook p_239167_3_, boolean p_239167_4_, boolean p_239167_5_) {
return new ClientPlayerEntity(this.mc, p_239167_1_, this.connection, p_239167_2_, p_239167_3_, p_239167_4_,
p_239167_5_);
}

private final AttackEvent event = new AttackEvent(null);

/**
* Attacks an entity
*/
public void attackEntity(PlayerEntity playerIn, Entity targetEntity) {
event.entity = targetEntity;
Expensive.getInstance().getEventBus().post(event);

this.syncCurrentPlayItem();

if (mc.player.serverSprintState && !mc.player.isInWater()) {
mc.player.connection.sendPacket(new CEntityActionPacket(mc.player, CEntityActionPacket.Action.STOP_SPRINTING));
}

this.connection.sendPacket(new CUseEntityPacket(targetEntity, playerIn.isSneaking()));

if (this.currentGameType != GameType.SPECTATOR) {
playerIn.attackTargetEntityWithCurrentItem(targetEntity);
playerIn.resetCooldown();
}
if (mc.player.serverSprintState && !mc.player.isInWater()) {
mc.player.connection.sendPacket(new CEntityActionPacket(mc.player, CEntityActionPacket.Action.START_SPRINTING));
}
}

/**
* Handles right clicking an entity, sends a packet to the server.
*/
public ActionResultType interactWithEntity(PlayerEntity player, Entity target, Hand hand) {
this.syncCurrentPlayItem();
this.connection.sendPacket(new CUseEntityPacket(target, hand, player.isSneaking()));
return this.currentGameType == GameType.SPECTATOR ? ActionResultType.PASS : player.interactOn(target, hand);
}

/**
* Handles right clicking an entity from the entities side, sends a packet to
* the server.
*/
public ActionResultType interactWithEntity(PlayerEntity player, Entity target, EntityRayTraceResult ray,
Hand hand) {
this.syncCurrentPlayItem();
Vector3d vector3d = ray.getHitVec().subtract(target.getPosX(), target.getPosY(), target.getPosZ());
this.connection.sendPacket(new CUseEntityPacket(target, hand, vector3d, player.isSneaking()));
return this.currentGameType == GameType.SPECTATOR ? ActionResultType.PASS
: target.applyPlayerInteraction(player, vector3d, hand);
}

/**
* Handles slot clicks, sends a packet to the server.
*/
public ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, PlayerEntity player) {
System.out.println(slotId);
short short1 = player.openContainer.getNextTransactionID(player.inventory);
ItemStack itemstack = player.openContainer.slotClick(slotId, mouseButton, type, player);
System.out.println(itemstack.getTag());
this.connection.sendPacket(new CClickWindowPacket(windowId, slotId, mouseButton, type, itemstack, short1));
return itemstack;
}

public void windowClickFixed(int windowId, int slotId, int mouseButton, ClickType type, PlayerEntity player, int timeWait) {
mc.player.windowClickMemory.add(new ClientPlayerEntity.WindowClickMemory(windowId, slotId, mouseButton, type, player, timeWait));
}

public void sendPlaceRecipePacket(int p_203413_1_, IRecipe<?> p_203413_2_, boolean p_203413_3_) {
this.connection.sendPacket(new CPlaceRecipePacket(p_203413_1_, p_203413_2_, p_203413_3_));
}

/**
* GuiEnchantment uses this during multiplayer to tell PlayerControllerMP to
* send a packet indicating the
* enchantment action the player has taken.
*/
public void sendEnchantPacket(int windowID, int button) {
this.connection.sendPacket(new CEnchantItemPacket(windowID, button));
}

/**
* Used in PlayerControllerMP to update the server with an ItemStack in a slot.
*/
public void sendSlotPacket(ItemStack itemStackIn, int slotId) {
if (this.currentGameType.isCreative()) {
this.connection.sendPacket(new CCreativeInventoryActionPacket(slotId, itemStackIn));
}
}

/**
* Sends a Packet107 to the server to drop the item on the ground
*/
public void sendPacketDropItem(ItemStack itemStackIn) {
if (this.currentGameType.isCreative() && !itemStackIn.isEmpty()) {
this.connection.sendPacket(new CCreativeInventoryActionPacket(-1, itemStackIn));
}
}

public void onStoppedUsingItem(PlayerEntity playerIn) {
this.syncCurrentPlayItem();
this.connection.sendPacket(
new CPlayerDiggingPacket(CPlayerDiggingPacket.Action.RELEASE_USE_ITEM, BlockPos.ZERO, Direction.DOWN));
playerIn.stopActiveHand();
}

public boolean gameIsSurvivalOrAdventure() {
return this.currentGameType.isSurvivalOrAdventure();
}

/**
* Checks if the player is not creative, used for checking if it should break a
* block instantly
*/
public boolean isNotCreative() {
return !this.currentGameType.isCreative();
}

/**
* returns true if player is in creative mode
*/
public boolean isInCreativeMode() {
return this.currentGameType.isCreative();
}

/**
* true for hitting entities far away.
*/
public boolean extendedReach() {
return this.currentGameType.isCreative();
}

/**
* Checks if the player is riding a horse, used to chose the GUI to open
*/
public boolean isRidingHorse() {
return this.mc.player.isPassenger() && this.mc.player.getRidingEntity() instanceof AbstractHorseEntity;
}

public boolean isSpectatorMode() {
return this.currentGameType == GameType.SPECTATOR;
}

public GameType func_241822_k() {
return this.field_239166_k_;
}

public GameType getCurrentGameType() {
return this.currentGameType;
}

/**
* Return isHittingBlock
*/
public boolean getIsHittingBlock() {
return this.isHittingBlock;
}

public void pickItem(int index) {
this.connection.sendPacket(new CPickItemPacket(index));
}

private void sendDiggingPacket(CPlayerDiggingPacket.Action action, BlockPos pos, Direction dir) {
ClientPlayerEntity clientplayerentity = this.mc.player;
this.unacknowledgedDiggingPackets.put(Pair.of(pos, action), clientplayerentity.getPositionVec());
this.connection.sendPacket(new CPlayerDiggingPacket(action, pos, dir));
}
public void updateController() {

this.syncCurrentPlayItem();

if (this.isHittingBlock) {
BlockState blockstate = this.mc.world.getBlockState(this.currentBlock);

if (blockstate.isAir()) {
this.isHittingBlock = false;
this.curBlockDamageMP = 0.0F;
this.mc.world.sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock, -1);
} else {
this.curBlockDamageMP += blockstate.getPlayerRelativeBlockHardness(this.mc.player, this.mc.player.world, this.currentBlock);

this.stepSoundTickCounter++;
if (this.stepSoundTickCounter % 4.0F == 0.0F) {
SoundType soundtype = blockstate.getSoundType();
this.mc.getSoundHandler().play(new SimpleSound(soundtype.getHitSound(), SoundCategory.BLOCKS,
(soundtype.getVolume() + 1.0F) / 8.0F, soundtype.getPitch() * 0.5F, this.currentBlock));
}

this.mc.getTutorial().onHitBlock(this.mc.world, this.currentBlock, blockstate, MathHelper.clamp(this.curBlockDamageMP, 0.0F, 1.0F));

if (this.curBlockDamageMP >= 1.0F) {
this.isHittingBlock = false;
this.sendDiggingPacket(CPlayerDiggingPacket.Action.STOP_DESTROY_BLOCK, this.currentBlock, Direction.UP);
this.onPlayerDestroyBlock(this.currentBlock);
this.curBlockDamageMP = 0.0F;
this.stepSoundTickCounter = 0.0F;
this.blockHitDelay = 5;
}

this.mc.world.sendBlockBreakProgress(this.mc.player.getEntityId(), this.currentBlock, (int)(this.curBlockDamageMP * 10.0F) - 1);
}
}
if (this.connection.getNetworkManager().isChannelOpen()) {
this.connection.getNetworkManager().tick();
} else {
this.connection.getNetworkManager().handleDisconnection();
}
}


public void acknowledgePlayerDiggingReceived(ClientWorld worldIn, BlockPos pos, BlockState blockIn,
CPlayerDiggingPacket.Action action, boolean successful) {
Vector3d vector3d = this.unacknowledgedDiggingPackets.remove(Pair.of(pos, action));
BlockState blockstate = worldIn.getBlockState(pos);

if ((vector3d == null || !successful
|| action != CPlayerDiggingPacket.Action.START_DESTROY_BLOCK && blockstate != blockIn)
&& blockstate != blockIn) {
worldIn.invalidateRegionAndSetBlock(pos, blockIn);
PlayerEntity playerentity = this.mc.player;

if (vector3d != null && worldIn == playerentity.world && playerentity.func_242278_a(pos, blockIn)) {
playerentity.func_242281_f(vector3d.x, vector3d.y, vector3d.z);
}
}

while (this.unacknowledgedDiggingPackets.size() >= 50) {
Pair<BlockPos, CPlayerDiggingPacket.Action> pair = this.unacknowledgedDiggingPackets.firstKey();
this.unacknowledgedDiggingPackets.removeFirst();
LOGGER.error("Too many unacked block actions, dropping " + pair);
}
}



}
друг ну ты молодец, помог ему!
 

Похожие темы

Назад
Сверху Снизу