Подпишитесь на наш Telegram-канал, чтобы всегда быть в курсе важных обновлений! Перейти

Часть функционала Tploot SpookyTime / NightDLC

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
3 Июн 2024
Сообщения
16
Реакции
0
Выберите загрузчик игры
  1. Прочие моды
ss - нету т.к это дефолтный тп лут на сс. Сам выходит сам заходит на анку. Сразу говорю, это не моё говно мне это скинули
tploot:
Expand Collapse Copy
package dev.wh1tew1ndows.client.managers.module.impl.movement;

import dev.wh1tew1ndows.client.api.events.orbit.EventHandler;
import dev.wh1tew1ndows.client.managers.events.player.MotionEvent;
import dev.wh1tew1ndows.client.managers.events.player.UpdateEvent;
import dev.wh1tew1ndows.client.managers.module.Category;
import dev.wh1tew1ndows.client.managers.module.Module;
import dev.wh1tew1ndows.client.managers.module.ModuleInfo;
import dev.wh1tew1ndows.client.managers.module.impl.misc.Notifications;

import dev.wh1tew1ndows.client.managers.module.settings.impl.BooleanSetting;
import dev.wh1tew1ndows.client.managers.module.settings.impl.ModeSetting;
import dev.wh1tew1ndows.client.managers.module.settings.impl.SliderSetting;
import dev.wh1tew1ndows.client.utils.player.PlayerUtil;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Items;
import net.minecraft.network.play.client.CEntityActionPacket;
import net.minecraft.network.play.client.CPlayerPacket;
import net.minecraft.scoreboard.ScoreObjective;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.ArmorMaterial;
import net.minecraft.item.ItemStack;

import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Getter
@Accessors(fluent = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
@ModuleInfo(name = "TPLoot", category = Category.MOVEMENT, desc = "Автоматический сбор лута с убитых игроков")
public class TPLoot extends Module {

    public final ModeSetting mode = new ModeSetting(this, "Режим", "Игроки", "Предметы");
    public final SliderSetting followSpeed = new SliderSetting(this, "Скорость следования", 0.2F, 0.1F, 20.F, 1.00F);
    public final SliderSetting lootRadius = new SliderSetting(this, "Радиус лута", 10.0F, 3.0F, 15.0F, 0.5F);
    public final SliderSetting waitTime = new SliderSetting(this, "Время ожидания", 3.0F, 0.0F, 10.0F, 0.5F);
    public final SliderSetting itemRadius = new SliderSetting(this, "Радиус предметов", 20.0F, 5.0F, 50.0F, 1.0F);
    public final BooleanSetting safeMode = new BooleanSetting(this, "Безопасный режим", true);
    public final SliderSetting maxFreeHeight = new SliderSetting(this, "Макс. высота препятствия", 6.0F, 1.0F, 10.0F, 1.0F);
    public final BooleanSetting returnToHub = new BooleanSetting(this, "Возврат в хаб", true);
    public final BooleanSetting autoDisable = new BooleanSetting(this, "Авто выключение", true);
    public final BooleanSetting filterEnabled = new BooleanSetting(this, "Фильтр игроков", false);
    public final BooleanSetting filterTotemOffhand = new BooleanSetting(this, "Тотем в левой руке", true).setVisible(() -> filterEnabled.getValue());
    public final BooleanSetting filterHeadOffhand = new BooleanSetting(this, "Голова в левой руке", true).setVisible(() -> filterEnabled.getValue());
    public final BooleanSetting filterDiamondArmor = new BooleanSetting(this, "Алмазная броня", false).setVisible(() -> filterEnabled.getValue());
    public final BooleanSetting filterNetheriteArmor = new BooleanSetting(this, "Незеритовая броня", false).setVisible(() -> filterEnabled.getValue());

    double initialHeight;
    PlayerEntity targetPlayer;
    Vector3d deathPosition;

    Vector3d lootPosition;
    long targetDisappearedTime;
    long lootCollectionStartTime;
    boolean waitingForLoot;
    boolean hasLooted;
    boolean collectingLoot;
    int initialInventorySize;
    boolean teleportedToDeathPoint;
    ItemEntity targetItem;

    // Для работы с хабом и аренами
    boolean hubCommandSent = false;
    boolean anCommandSent = false;
    long hubCommandTime = 0;
    String arenaNumber = null;

    LootState state = LootState.IDLE;

    private enum LootState {
        IDLE,
        SEARCHING_PLAYER,
        FOLLOWING_PLAYER,
        WAITING_FOR_LOOT,
        LOOTING,
        SEARCHING_ITEM,
        LOOTING_ITEM
    }

    @Override
    public void onEnable() {
        super.onEnable();
        if (mc.player == null) return;

        // Устанавливаем дефолтное значение maxFreeHeight в зависимости от безопасного режима
        if (safeMode.getValue()) {
            maxFreeHeight.set(3.0F);
        }

        initialHeight = mc.player.getPosY();
        targetPlayer = null;
        deathPosition = null;
        lootPosition = null;
        targetDisappearedTime = 0;
        lootCollectionStartTime = 0;
        waitingForLoot = false;
        hasLooted = false;
        collectingLoot = false;
        initialInventorySize = 0;
        teleportedToDeathPoint = false;
        targetItem = null;
        hubCommandSent = false;
        anCommandSent = false;
        hubCommandTime = 0;
        arenaNumber = null;
        state = mode.is("Игроки") ? LootState.SEARCHING_PLAYER : LootState.SEARCHING_ITEM;
    }

    @Override
    public void onDisable() {
        super.onDisable();
        resetState();
        sendActionBar("§7TPLoot деактивирован");
    }

    @EventHandler
    public void onUpdate(UpdateEvent e) {
        if (mc.player == null || mc.world == null) return;

        // Обработка команд хаба и арены
        if (hubCommandSent && !anCommandSent) {
            long elapsed = System.currentTimeMillis() - hubCommandTime;
            if (elapsed > 1000) { // Ждем 1 секунду после /hub
                if (arenaNumber != null) {
                    mc.player.sendChatMessage("/an" + arenaNumber);
                    sendActionBar("§aВозврат на арену " + arenaNumber);
                    anCommandSent = true;

                    // Выключаем модуль после команды /an
                    if (autoDisable.getValue()) {
                        new Thread(() -> {
                            try {
                                Thread.sleep(500);
                                mc.execute(() -> {
                                    if (this.isEnabled()) {
                                        toggle();
                                    }
                                });
                            } catch (InterruptedException ex) {
                                ex.printStackTrace();
                            }
                        }).start();
                    }
                } else {
                    // Если номер арены не найден, просто выключаем модуль
                    if (autoDisable.getValue()) {
                        toggle();
                    }
                }
            }
            return;
        }

        switch (state) {
            case SEARCHING_PLAYER:
                findTargetPlayer();
                break;
            case FOLLOWING_PLAYER:
                followTargetPlayer();
                break;
            case WAITING_FOR_LOOT:
                checkForLoot();
                break;
            case LOOTING:
                checkLootCollection();
                break;
            case SEARCHING_ITEM:
                findTargetItem();
                break;
            case LOOTING_ITEM:
                checkItemLootCollection();
                break;
        }
    }

    @EventHandler
    public void onMotion(MotionEvent e) {
        if (state == LootState.FOLLOWING_PLAYER && targetPlayer != null) {
            moveTowardsTarget();
        }
    }

    // ========== РЕЖИМ "ИГРОКИ" ==========

    private void findTargetPlayer() {
        List<PlayerEntity> validPlayers = mc.world.getPlayers().stream()
                .filter(player -> player != mc.player)
                .filter(player -> !player.isSpectator())
                .filter(player -> player.isAlive())
                .filter(player -> player.getPosY() < 109)
                .filter(player -> PlayerUtil.isNameValid(player.getName().getString()))
                .filter(player -> mc.player.getDistance(player) < 50)
                .filter(this::isPlayerMatchesFilter)
                .sorted(Comparator.comparingDouble(p -> p.getHealth()))
                .collect(Collectors.toList());

        if (!validPlayers.isEmpty()) {
            PlayerEntity newTarget = validPlayers.get(0);
            if (newTarget != targetPlayer) {
                targetPlayer = newTarget;
                deathPosition = targetPlayer.getPositionVec();
            } else {
                targetPlayer = newTarget;
            }
            deathPosition = targetPlayer.getPositionVec();
            state = LootState.FOLLOWING_PLAYER;
            sendActionBar("§aЦель найдена: §f" + targetPlayer.getName().getString());
        }
    }

    private void followTargetPlayer() {
        if (targetPlayer == null) {
            state = LootState.SEARCHING_PLAYER;
            return;
        }

        if (!targetPlayer.isAlive() || targetPlayer.getHealth() <= 0 || !mc.world.getPlayers().contains(targetPlayer)) {
            deathPosition = targetPlayer.getPositionVec();
            targetDisappearedTime = System.currentTimeMillis();
            waitingForLoot = true;
            if (mc.player != null && deathPosition != null) {
                mc.player.setMotion(0.0, mc.player.getMotion().y, 0.0);
            }
            state = LootState.WAITING_FOR_LOOT;
            sendActionBar("§eЦель умерла, ожидание лута...");
            return;
        }

        deathPosition = targetPlayer.getPositionVec();

        if (targetPlayer.getPosY() >= 109 || !PlayerUtil.isNameValid(targetPlayer.getName().getString())) {
            targetPlayer = null;
            state = LootState.SEARCHING_PLAYER;
            sendActionBar("§cЦель потеряна, поиск новой...");
        }
    }

    private boolean isPlayerMatchesFilter(PlayerEntity player) {
        if (!filterEnabled.getValue()) {
            return true;
        }

        boolean matched = false;

        ItemStack offhand = player.getHeldItemOffhand();

        if (filterTotemOffhand.getValue()) {
            if (!offhand.isEmpty() && offhand.getItem() == Items.TOTEM_OF_UNDYING && offhand.isEnchanted()) {
                matched = true;
            }
        }

        if (filterHeadOffhand.getValue()) {
            if (!offhand.isEmpty() && offhand.getItem() == Items.PLAYER_HEAD) {
                matched = true;
            }
        }

        if (filterDiamondArmor.getValue() || filterNetheriteArmor.getValue()) {
            if (hasRequiredArmor(player)) {
                matched = true;
            }
        }

        return matched;
    }

    private boolean hasRequiredArmor(PlayerEntity player) {
        boolean hasDiamond = false;
        boolean hasNetherite = false;

        for (ItemStack armorStack : player.getArmorInventoryList()) {
            if (armorStack.isEmpty() || !(armorStack.getItem() instanceof ArmorItem)) {
                continue;
            }

            ArmorItem armorItem = (ArmorItem) armorStack.getItem();
            ArmorMaterial material = (ArmorMaterial) armorItem.getArmorMaterial();

            if (material == ArmorMaterial.DIAMOND) {
                hasDiamond = true;
            } else if (material == ArmorMaterial.NETHERITE) {
                hasNetherite = true;
            }
        }

        if (filterDiamondArmor.getValue() && hasDiamond) {
            return true;
        }

        if (filterNetheriteArmor.getValue() && hasNetherite) {
            return true;
        }

        return false;
    }

    private void moveTowardsTarget() {
        if (targetPlayer == null || deathPosition == null) return;

        double targetX = deathPosition.x;
        double targetZ = deathPosition.z;

        double deltaX = targetX - mc.player.getPosX();
        double deltaZ = targetZ - mc.player.getPosZ();
        double distance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ);

        if (distance > 1.0) {
            double moveX = (deltaX / distance) * followSpeed.getValue();
            double moveZ = (deltaZ / distance) * followSpeed.getValue();

            mc.player.setMotion(moveX, mc.player.getMotion().y, moveZ);

            if (Math.abs(mc.player.getPosY() - initialHeight) > 0.5) {
                double yDiff = initialHeight - mc.player.getPosY();
                mc.player.setMotion(mc.player.getMotion().x, yDiff * 0.1, mc.player.getMotion().z);
            }
        } else {
            mc.player.setMotion(0, mc.player.getMotion().y, 0);
        }
    }

    private void checkForLoot() {
        if (!waitingForLoot || deathPosition == null) return;

        long elapsedTime = System.currentTimeMillis() - targetDisappearedTime;
        int waitSeconds = (int) waitTime.getValue().intValue();

        if (elapsedTime < waitSeconds * 1000) {
            int secondsLeft = waitSeconds - (int) (elapsedTime / 1000);
            sendActionBar("§eОжидание лута... " + secondsLeft + "с");
            return;
        }

        if (!teleportedToDeathPoint) {
            findLootPosition();
            if (lootPosition != null) {
                // Проверка безопасного режима
                if (safeMode.getValue() && !isStrictlyAboveTeleportPoint(lootPosition)) {
                    sendActionBar("§c[Безопасный режим] Не находитесь прямо над точкой лута!");
                    if (returnToHub.getValue()) {
                        returnToHub();
                    } else {
                        state = LootState.SEARCHING_PLAYER;
                    }
                    return;
                }

                if (isAboveTeleportPoint(lootPosition)) {
                    teleportToLootPosition();
                    teleportedToDeathPoint = true;
                    lootCollectionStartTime = System.currentTimeMillis();
                    initialInventorySize = countInventoryItems();
                    sendActionBar("§aТелепортация к луту...");
                    state = LootState.LOOTING;
                } else {
                    sendActionBar("§cНе над точкой лута! Подойдите ближе по X/Z");
                }
            } else {
                sendActionBar("§cЛут не найден" + (returnToHub.getValue() ? ", возврат в хаб..." : ""));
                if (returnToHub.getValue()) {
                    returnToHub();
                } else {
                    state = LootState.SEARCHING_PLAYER;
                }
            }
        }
    }

    // ========== РЕЖИМ "ПРЕДМЕТЫ" ==========

    private void findTargetItem() {
        ItemEntity bestItem = null;
        double bestDistance = Double.MAX_VALUE;

        for (net.minecraft.entity.Entity entity : mc.world.getAllEntities()) {
            if (entity instanceof ItemEntity) {
                ItemEntity item = (ItemEntity) entity;
                if (item.getPosY() < 109 && isItemEntityValid(item)) {
                    double distance = mc.player.getDistance(item);

                    if (distance <= itemRadius.getValue() && distance < bestDistance) {
                        bestDistance = distance;
                        bestItem = item;
                    }
                }
            }
        }

        if (bestItem != null) {
            targetItem = bestItem;
            lootPosition = new Vector3d(
                    bestItem.getPosX(),
                    bestItem.getPosY(),
                    bestItem.getPosZ()
            );

            // Проверка безопасного режима
            if (safeMode.getValue() && !isStrictlyAboveTeleportPoint(lootPosition)) {
                sendActionBar("§c[Безопасный режим] Не находитесь прямо над предметом!");
                targetItem = null;
                lootPosition = null;
                return;
            }

            if (isAboveTeleportPoint(lootPosition)) {
                sendActionBar("§aНайден предмет, телепортация...");
                teleportToLootPosition();
                lootCollectionStartTime = System.currentTimeMillis();
                initialInventorySize = countInventoryItems();
                state = LootState.LOOTING_ITEM;
            } else {
                sendActionBar("§cНе над точкой предмета! Подойдите ближе по X/Z");
                targetItem = null;
                lootPosition = null;
            }
        } else {
            sendActionBar("§cПредметы не найдены в радиусе " + itemRadius.getValue() + " блоков");
        }
    }

    private void checkItemLootCollection() {
        long elapsedTime = System.currentTimeMillis() - lootCollectionStartTime;

        boolean itemStillExists = targetItem != null && targetItem.isAlive();

        if (!itemStillExists) {
            sendActionBar("§aПредмет подобран!" + (returnToHub.getValue() ? " Возврат в хаб..." : ""));
            if (returnToHub.getValue()) {
                returnToHub();
            } else {
                state = LootState.SEARCHING_ITEM;
                targetItem = null;
            }
        } else if (elapsedTime > 5000) {
            sendActionBar("§cНе удалось подобрать предмет за 5 секунд" + (returnToHub.getValue() ? ", возврат в хаб..." : ""));
            if (returnToHub.getValue()) {
                returnToHub();
            } else {
                state = LootState.SEARCHING_ITEM;
                targetItem = null;
            }
        } else {
            int secondsLeft = 5 - (int) (elapsedTime / 1000);
            sendActionBar("§eПодбор предмета... " + secondsLeft + "с");
        }
    }

    // ========== ОБЩИЕ МЕТОДЫ ==========

    private void findLootPosition() {
        ItemEntity nearestItem = null;
        double nearestDistance = Double.MAX_VALUE;

        for (net.minecraft.entity.Entity entity : mc.world.getAllEntities()) {
            if (entity instanceof ItemEntity) {
                ItemEntity item = (ItemEntity) entity;
                if (isItemEntityValid(item)) {
                    double dx = item.getPosX() - deathPosition.x;
                    double dz = item.getPosZ() - deathPosition.z;
                    double distance = Math.sqrt(dx * dx + dz * dz);

                    if (distance <= lootRadius.getValue() && distance < nearestDistance) {
                        nearestDistance = distance;
                        nearestItem = item;
                    }
                }
            }
        }

        if (nearestItem != null) {
            lootPosition = new Vector3d(
                    deathPosition.x,
                    nearestItem.getPosY(),
                    deathPosition.z
            );
            sendActionBar("§aТелепортация к луту на высоте: §f" + String.format("%.1f", nearestItem.getPosY()));
        } else {
            lootPosition = deathPosition;
            sendActionBar("§eЛут не найден, телепортация к точке смерти");
        }
    }

    private void teleportToLootPosition() {
        if (lootPosition == null) return;

        int maxHeight = maxFreeHeight.getValue().intValue();

        if (hasTallObstacleAbove(lootPosition, maxHeight)) {
            sendActionBar("§cОбнаружено препятствие выше " + maxHeight + " блоков!");
            if (returnToHub.getValue()) {
                returnToHub();
            } else {
                state = mode.is("Игроки") ? LootState.SEARCHING_PLAYER : LootState.SEARCHING_ITEM;
            }
            return;
        }

        mc.player.setMotion(0, 0, 0);

        for (int i = 0; i < 2; i++) {
            mc.player.connection.sendPacket(new CPlayerPacket.PositionPacket(lootPosition.x,
                    mc.player.getPosY(), lootPosition.z, false));
        }
        mc.player.connection.sendPacket(new CEntityActionPacket(mc.player, CEntityActionPacket.Action.START_FALL_FLYING));
        mc.player.connection.sendPacket(new CPlayerPacket.PositionPacket(lootPosition.x,
                lootPosition.y, lootPosition.z, false));
        mc.player.connection.sendPacket(new CEntityActionPacket(mc.player, CEntityActionPacket.Action.START_FALL_FLYING));
        mc.player.setPosition(lootPosition.x, lootPosition.y, lootPosition.z);

        sendActionBar("§aТелепортирован к луту!");
        collectingLoot = true;
    }

    private boolean hasTallObstacleAbove(Vector3d targetPos, int maxFreeHeight) {
        if (mc.world == null || targetPos == null) return false;

        BlockPos basePos = new BlockPos(targetPos.x, targetPos.y, targetPos.z);
        int solidCount = 0;

        for (int i = 1; i <= 6; i++) {
            BlockPos checkPos = basePos.up(i);

            if (!mc.world.isAirBlock(checkPos)) {
                solidCount++;
                if (solidCount > maxFreeHeight) {
                    return true;
                }
            } else {
                if (solidCount > 0) {
                    break;
                }
            }
        }

        return false;
    }

    private void checkLootCollection() {
        if (!collectingLoot) return;

        long elapsedTime = System.currentTimeMillis() - lootCollectionStartTime;

        boolean lootStillExists = checkLootExists();

        if (!lootStillExists) {
            hasLooted = true;
            sendActionBar("§aВесь лут подобран!" + (returnToHub.getValue() ? " Возврат в хаб..." : ""));
            if (returnToHub.getValue()) {
                returnToHub();
            } else {
                state = LootState.SEARCHING_PLAYER;
            }
        } else if (elapsedTime > 10000) {
            sendActionBar("§cНе удалось подобрать весь лут за 10 секунд" + (returnToHub.getValue() ? ", возврат в хаб..." : ""));
            if (returnToHub.getValue()) {
                returnToHub();
            } else {
                state = LootState.SEARCHING_PLAYER;
            }
        } else {
            int secondsLeft = 10 - (int) (elapsedTime / 1000);
            sendActionBar("§eСбор лута... " + secondsLeft + "с");
        }
    }

    private boolean checkLootExists() {
        for (net.minecraft.entity.Entity entity : mc.world.getAllEntities()) {
            if (entity instanceof ItemEntity) {
                ItemEntity item = (ItemEntity) entity;
                if (isItemEntityValid(item)) {
                    double dx = item.getPosX() - deathPosition.x;
                    double dz = item.getPosZ() - deathPosition.z;
                    double distance = Math.sqrt(dx * dx + dz * dz);
                    if (distance <= lootRadius.getValue()) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private boolean isItemEntityValid(ItemEntity item) {
        return item != null &&
                item.isAlive() &&
                !item.getItem().isEmpty() &&
                item.world == mc.world;
    }

    private boolean isAboveTeleportPoint(Vector3d targetPos) {
        if (mc.player == null || targetPos == null) return false;

        double playerX = mc.player.getPosX();
        double playerZ = mc.player.getPosZ();
        double targetX = targetPos.x;
        double targetZ = targetPos.z;

        double deltaX = playerX - targetX;
        double deltaZ = playerZ - targetZ;
        double horizontalDistance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ);

        return horizontalDistance <= 4.0;
    }

    /**
     * Строгая проверка положения игрока - находится ли он ПРЯМО над точкой телепортации
     * (без диагонального смещения). Используется в безопасном режиме.
     */
    private boolean isStrictlyAboveTeleportPoint(Vector3d targetPos) {
        if (mc.player == null || targetPos == null) return false;

        double playerX = mc.player.getPosX();
        double playerZ = mc.player.getPosZ();
        double targetX = targetPos.x;
        double targetZ = targetPos.z;

        double deltaX = Math.abs(playerX - targetX);
        double deltaZ = Math.abs(playerZ - targetZ);

        // Допускаем минимальное отклонение (0.5 блока) по каждой оси
        return deltaX <= 0.5 && deltaZ <= 0.5;
    }

    private String getArenaNumberFromScoreboard() {
        if (mc.player == null || mc.world == null) return null;

        Scoreboard scoreboard = mc.world.getScoreboard();
        if (scoreboard == null) return null;

        ScoreObjective objective = scoreboard.getObjectiveInDisplaySlot(1);
        if (objective == null) return null;

        try {
            ITextComponent displayName = objective.getDisplayName();
            if (displayName != null) {
                String title = displayName.getString();
                String digitsFromTitle = extractDigits(title);
                if (digitsFromTitle != null) {
                    return digitsFromTitle;
                }
            }

            List<String> lines = scoreboard.getSortedScores(objective).stream()
                    .map(score -> score.getPlayerName())
                    .collect(Collectors.toList());

            for (String rawLine : lines) {
                String digits = extractDigits(rawLine);
                if (digits != null) {
                    return digits;
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        return null;
    }

    private String extractDigits(String text) {
        if (text == null) return null;

        String cleaned = text.replaceAll("§[0-9A-FK-ORa-fk-or]", "");

        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(cleaned);

        if (matcher.find()) {
            return matcher.group();
        }

        return null;
    }

    private void returnToHub() {
        // Проверяем, не отправляли ли уже /hub в этом цикле работы модуля
        if (hubCommandSent) {
            return;
        }

        sendActionBar("§aВозврат в хаб...");

        // Получаем номер арены из скорборда
        arenaNumber = getArenaNumberFromScoreboard();

        // Сразу помечаем, что команда /hub уже запрошена
        hubCommandSent = true;
        hubCommandTime = System.currentTimeMillis();

        new Thread(() -> {
            try {
                Thread.sleep(100);
                mc.execute(() -> {
                    if (mc.player != null) {
                        mc.player.sendChatMessage("/hub");

                        if (arenaNumber != null) {
                            sendActionBar("§eОпределен номер арены: " + arenaNumber);
                        } else {
                            sendActionBar("§cНе удалось определить номер арены");
                            if (autoDisable.getValue()) {
                                new Thread(() -> {
                                    try {
                                        Thread.sleep(1000);
                                        mc.execute(() -> {
                                            if (this.isEnabled()) {
                                                toggle();
                                            }
                                        });
                                    } catch (InterruptedException ex) {
                                        ex.printStackTrace();
                                    }
                                }).start();
                            }
                        }
                    }
                });
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }).start();
    }

    private int countInventoryItems() {
        int count = 0;
        for (int i = 0; i < mc.player.inventory.getSizeInventory(); i++) {
            if (!mc.player.inventory.getStackInSlot(i).isEmpty()) {
                count += mc.player.inventory.getStackInSlot(i).getCount();
            }
        }
        return count;
    }

    private void sendActionBar(String message) {
        if (!message.contains("Весь лут подобран") && !message.contains("Предмет подобран")) {
            return;
        }

        Notifications notifications = Notifications.getInstance();
        if (notifications != null && notifications.isEnabled()) {
            notifications.pushCustom("TPLoot", message, true, this.getCategory());
        }
    }

    private void resetState() {
        targetPlayer = null;
        deathPosition = null;
        lootPosition = null;
        targetDisappearedTime = 0;
        lootCollectionStartTime = 0;
        waitingForLoot = false;
        hasLooted = false;
        collectingLoot = false;
        initialInventorySize = 0;
        teleportedToDeathPoint = false;
        targetItem = null;
        hubCommandSent = false;
        anCommandSent = false;
        hubCommandTime = 0L;
        arenaNumber = null;
        state = LootState.IDLE;
    }
}
 
Последнее редактирование:
ss - нету т.к это дефолтный тп лут на сс. Сам выходит сам заходит на анку. Сразу говорю, это не моё говно мне это скинули
tploot:
Expand Collapse Copy
package dev.wh1tew1ndows.client.managers.module.impl.movement;

import dev.wh1tew1ndows.client.api.events.orbit.EventHandler;
import dev.wh1tew1ndows.client.managers.events.player.MotionEvent;
import dev.wh1tew1ndows.client.managers.events.player.UpdateEvent;
import dev.wh1tew1ndows.client.managers.module.Category;
import dev.wh1tew1ndows.client.managers.module.Module;
import dev.wh1tew1ndows.client.managers.module.ModuleInfo;
import dev.wh1tew1ndows.client.managers.module.impl.misc.Notifications;

import dev.wh1tew1ndows.client.managers.module.settings.impl.BooleanSetting;
import dev.wh1tew1ndows.client.managers.module.settings.impl.ModeSetting;
import dev.wh1tew1ndows.client.managers.module.settings.impl.SliderSetting;
import dev.wh1tew1ndows.client.utils.player.PlayerUtil;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Items;
import net.minecraft.network.play.client.CEntityActionPacket;
import net.minecraft.network.play.client.CPlayerPacket;
import net.minecraft.scoreboard.ScoreObjective;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.ArmorMaterial;
import net.minecraft.item.ItemStack;

import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Getter
@Accessors(fluent = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
@ModuleInfo(name = "TPLoot", category = Category.MOVEMENT, desc = "Автоматический сбор лута с убитых игроков")
public class TPLoot extends Module {

    public final ModeSetting mode = new ModeSetting(this, "Режим", "Игроки", "Предметы");
    public final SliderSetting followSpeed = new SliderSetting(this, "Скорость следования", 0.2F, 0.1F, 20.F, 1.00F);
    public final SliderSetting lootRadius = new SliderSetting(this, "Радиус лута", 10.0F, 3.0F, 15.0F, 0.5F);
    public final SliderSetting waitTime = new SliderSetting(this, "Время ожидания", 3.0F, 0.0F, 10.0F, 0.5F);
    public final SliderSetting itemRadius = new SliderSetting(this, "Радиус предметов", 20.0F, 5.0F, 50.0F, 1.0F);
    public final BooleanSetting safeMode = new BooleanSetting(this, "Безопасный режим", true);
    public final SliderSetting maxFreeHeight = new SliderSetting(this, "Макс. высота препятствия", 6.0F, 1.0F, 10.0F, 1.0F);
    public final BooleanSetting returnToHub = new BooleanSetting(this, "Возврат в хаб", true);
    public final BooleanSetting autoDisable = new BooleanSetting(this, "Авто выключение", true);
    public final BooleanSetting filterEnabled = new BooleanSetting(this, "Фильтр игроков", false);
    public final BooleanSetting filterTotemOffhand = new BooleanSetting(this, "Тотем в левой руке", true).setVisible(() -> filterEnabled.getValue());
    public final BooleanSetting filterHeadOffhand = new BooleanSetting(this, "Голова в левой руке", true).setVisible(() -> filterEnabled.getValue());
    public final BooleanSetting filterDiamondArmor = new BooleanSetting(this, "Алмазная броня", false).setVisible(() -> filterEnabled.getValue());
    public final BooleanSetting filterNetheriteArmor = new BooleanSetting(this, "Незеритовая броня", false).setVisible(() -> filterEnabled.getValue());

    double initialHeight;
    PlayerEntity targetPlayer;
    Vector3d deathPosition;

    Vector3d lootPosition;
    long targetDisappearedTime;
    long lootCollectionStartTime;
    boolean waitingForLoot;
    boolean hasLooted;
    boolean collectingLoot;
    int initialInventorySize;
    boolean teleportedToDeathPoint;
    ItemEntity targetItem;

    // Для работы с хабом и аренами
    boolean hubCommandSent = false;
    boolean anCommandSent = false;
    long hubCommandTime = 0;
    String arenaNumber = null;

    LootState state = LootState.IDLE;

    private enum LootState {
        IDLE,
        SEARCHING_PLAYER,
        FOLLOWING_PLAYER,
        WAITING_FOR_LOOT,
        LOOTING,
        SEARCHING_ITEM,
        LOOTING_ITEM
    }

    @Override
    public void onEnable() {
        super.onEnable();
        if (mc.player == null) return;

        // Устанавливаем дефолтное значение maxFreeHeight в зависимости от безопасного режима
        if (safeMode.getValue()) {
            maxFreeHeight.set(3.0F);
        }

        initialHeight = mc.player.getPosY();
        targetPlayer = null;
        deathPosition = null;
        lootPosition = null;
        targetDisappearedTime = 0;
        lootCollectionStartTime = 0;
        waitingForLoot = false;
        hasLooted = false;
        collectingLoot = false;
        initialInventorySize = 0;
        teleportedToDeathPoint = false;
        targetItem = null;
        hubCommandSent = false;
        anCommandSent = false;
        hubCommandTime = 0;
        arenaNumber = null;
        state = mode.is("Игроки") ? LootState.SEARCHING_PLAYER : LootState.SEARCHING_ITEM;
    }

    @Override
    public void onDisable() {
        super.onDisable();
        resetState();
        sendActionBar("§7TPLoot деактивирован");
    }

    @EventHandler
    public void onUpdate(UpdateEvent e) {
        if (mc.player == null || mc.world == null) return;

        // Обработка команд хаба и арены
        if (hubCommandSent && !anCommandSent) {
            long elapsed = System.currentTimeMillis() - hubCommandTime;
            if (elapsed > 1000) { // Ждем 1 секунду после /hub
                if (arenaNumber != null) {
                    mc.player.sendChatMessage("/an" + arenaNumber);
                    sendActionBar("§aВозврат на арену " + arenaNumber);
                    anCommandSent = true;

                    // Выключаем модуль после команды /an
                    if (autoDisable.getValue()) {
                        new Thread(() -> {
                            try {
                                Thread.sleep(500);
                                mc.execute(() -> {
                                    if (this.isEnabled()) {
                                        toggle();
                                    }
                                });
                            } catch (InterruptedException ex) {
                                ex.printStackTrace();
                            }
                        }).start();
                    }
                } else {
                    // Если номер арены не найден, просто выключаем модуль
                    if (autoDisable.getValue()) {
                        toggle();
                    }
                }
            }
            return;
        }

        switch (state) {
            case SEARCHING_PLAYER:
                findTargetPlayer();
                break;
            case FOLLOWING_PLAYER:
                followTargetPlayer();
                break;
            case WAITING_FOR_LOOT:
                checkForLoot();
                break;
            case LOOTING:
                checkLootCollection();
                break;
            case SEARCHING_ITEM:
                findTargetItem();
                break;
            case LOOTING_ITEM:
                checkItemLootCollection();
                break;
        }
    }

    @EventHandler
    public void onMotion(MotionEvent e) {
        if (state == LootState.FOLLOWING_PLAYER && targetPlayer != null) {
            moveTowardsTarget();
        }
    }

    // ========== РЕЖИМ "ИГРОКИ" ==========

    private void findTargetPlayer() {
        List<PlayerEntity> validPlayers = mc.world.getPlayers().stream()
                .filter(player -> player != mc.player)
                .filter(player -> !player.isSpectator())
                .filter(player -> player.isAlive())
                .filter(player -> player.getPosY() < 109)
                .filter(player -> PlayerUtil.isNameValid(player.getName().getString()))
                .filter(player -> mc.player.getDistance(player) < 50)
                .filter(this::isPlayerMatchesFilter)
                .sorted(Comparator.comparingDouble(p -> p.getHealth()))
                .collect(Collectors.toList());

        if (!validPlayers.isEmpty()) {
            PlayerEntity newTarget = validPlayers.get(0);
            if (newTarget != targetPlayer) {
                targetPlayer = newTarget;
                deathPosition = targetPlayer.getPositionVec();
            } else {
                targetPlayer = newTarget;
            }
            deathPosition = targetPlayer.getPositionVec();
            state = LootState.FOLLOWING_PLAYER;
            sendActionBar("§aЦель найдена: §f" + targetPlayer.getName().getString());
        }
    }

    private void followTargetPlayer() {
        if (targetPlayer == null) {
            state = LootState.SEARCHING_PLAYER;
            return;
        }

        if (!targetPlayer.isAlive() || targetPlayer.getHealth() <= 0 || !mc.world.getPlayers().contains(targetPlayer)) {
            deathPosition = targetPlayer.getPositionVec();
            targetDisappearedTime = System.currentTimeMillis();
            waitingForLoot = true;
            if (mc.player != null && deathPosition != null) {
                mc.player.setMotion(0.0, mc.player.getMotion().y, 0.0);
            }
            state = LootState.WAITING_FOR_LOOT;
            sendActionBar("§eЦель умерла, ожидание лута...");
            return;
        }

        deathPosition = targetPlayer.getPositionVec();

        if (targetPlayer.getPosY() >= 109 || !PlayerUtil.isNameValid(targetPlayer.getName().getString())) {
            targetPlayer = null;
            state = LootState.SEARCHING_PLAYER;
            sendActionBar("§cЦель потеряна, поиск новой...");
        }
    }

    private boolean isPlayerMatchesFilter(PlayerEntity player) {
        if (!filterEnabled.getValue()) {
            return true;
        }

        boolean matched = false;

        ItemStack offhand = player.getHeldItemOffhand();

        if (filterTotemOffhand.getValue()) {
            if (!offhand.isEmpty() && offhand.getItem() == Items.TOTEM_OF_UNDYING && offhand.isEnchanted()) {
                matched = true;
            }
        }

        if (filterHeadOffhand.getValue()) {
            if (!offhand.isEmpty() && offhand.getItem() == Items.PLAYER_HEAD) {
                matched = true;
            }
        }

        if (filterDiamondArmor.getValue() || filterNetheriteArmor.getValue()) {
            if (hasRequiredArmor(player)) {
                matched = true;
            }
        }

        return matched;
    }

    private boolean hasRequiredArmor(PlayerEntity player) {
        boolean hasDiamond = false;
        boolean hasNetherite = false;

        for (ItemStack armorStack : player.getArmorInventoryList()) {
            if (armorStack.isEmpty() || !(armorStack.getItem() instanceof ArmorItem)) {
                continue;
            }

            ArmorItem armorItem = (ArmorItem) armorStack.getItem();
            ArmorMaterial material = (ArmorMaterial) armorItem.getArmorMaterial();

            if (material == ArmorMaterial.DIAMOND) {
                hasDiamond = true;
            } else if (material == ArmorMaterial.NETHERITE) {
                hasNetherite = true;
            }
        }

        if (filterDiamondArmor.getValue() && hasDiamond) {
            return true;
        }

        if (filterNetheriteArmor.getValue() && hasNetherite) {
            return true;
        }

        return false;
    }

    private void moveTowardsTarget() {
        if (targetPlayer == null || deathPosition == null) return;

        double targetX = deathPosition.x;
        double targetZ = deathPosition.z;

        double deltaX = targetX - mc.player.getPosX();
        double deltaZ = targetZ - mc.player.getPosZ();
        double distance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ);

        if (distance > 1.0) {
            double moveX = (deltaX / distance) * followSpeed.getValue();
            double moveZ = (deltaZ / distance) * followSpeed.getValue();

            mc.player.setMotion(moveX, mc.player.getMotion().y, moveZ);

            if (Math.abs(mc.player.getPosY() - initialHeight) > 0.5) {
                double yDiff = initialHeight - mc.player.getPosY();
                mc.player.setMotion(mc.player.getMotion().x, yDiff * 0.1, mc.player.getMotion().z);
            }
        } else {
            mc.player.setMotion(0, mc.player.getMotion().y, 0);
        }
    }

    private void checkForLoot() {
        if (!waitingForLoot || deathPosition == null) return;

        long elapsedTime = System.currentTimeMillis() - targetDisappearedTime;
        int waitSeconds = (int) waitTime.getValue().intValue();

        if (elapsedTime < waitSeconds * 1000) {
            int secondsLeft = waitSeconds - (int) (elapsedTime / 1000);
            sendActionBar("§eОжидание лута... " + secondsLeft + "с");
            return;
        }

        if (!teleportedToDeathPoint) {
            findLootPosition();
            if (lootPosition != null) {
                // Проверка безопасного режима
                if (safeMode.getValue() && !isStrictlyAboveTeleportPoint(lootPosition)) {
                    sendActionBar("§c[Безопасный режим] Не находитесь прямо над точкой лута!");
                    if (returnToHub.getValue()) {
                        returnToHub();
                    } else {
                        state = LootState.SEARCHING_PLAYER;
                    }
                    return;
                }

                if (isAboveTeleportPoint(lootPosition)) {
                    teleportToLootPosition();
                    teleportedToDeathPoint = true;
                    lootCollectionStartTime = System.currentTimeMillis();
                    initialInventorySize = countInventoryItems();
                    sendActionBar("§aТелепортация к луту...");
                    state = LootState.LOOTING;
                } else {
                    sendActionBar("§cНе над точкой лута! Подойдите ближе по X/Z");
                }
            } else {
                sendActionBar("§cЛут не найден" + (returnToHub.getValue() ? ", возврат в хаб..." : ""));
                if (returnToHub.getValue()) {
                    returnToHub();
                } else {
                    state = LootState.SEARCHING_PLAYER;
                }
            }
        }
    }

    // ========== РЕЖИМ "ПРЕДМЕТЫ" ==========

    private void findTargetItem() {
        ItemEntity bestItem = null;
        double bestDistance = Double.MAX_VALUE;

        for (net.minecraft.entity.Entity entity : mc.world.getAllEntities()) {
            if (entity instanceof ItemEntity) {
                ItemEntity item = (ItemEntity) entity;
                if (item.getPosY() < 109 && isItemEntityValid(item)) {
                    double distance = mc.player.getDistance(item);

                    if (distance <= itemRadius.getValue() && distance < bestDistance) {
                        bestDistance = distance;
                        bestItem = item;
                    }
                }
            }
        }

        if (bestItem != null) {
            targetItem = bestItem;
            lootPosition = new Vector3d(
                    bestItem.getPosX(),
                    bestItem.getPosY(),
                    bestItem.getPosZ()
            );

            // Проверка безопасного режима
            if (safeMode.getValue() && !isStrictlyAboveTeleportPoint(lootPosition)) {
                sendActionBar("§c[Безопасный режим] Не находитесь прямо над предметом!");
                targetItem = null;
                lootPosition = null;
                return;
            }

            if (isAboveTeleportPoint(lootPosition)) {
                sendActionBar("§aНайден предмет, телепортация...");
                teleportToLootPosition();
                lootCollectionStartTime = System.currentTimeMillis();
                initialInventorySize = countInventoryItems();
                state = LootState.LOOTING_ITEM;
            } else {
                sendActionBar("§cНе над точкой предмета! Подойдите ближе по X/Z");
                targetItem = null;
                lootPosition = null;
            }
        } else {
            sendActionBar("§cПредметы не найдены в радиусе " + itemRadius.getValue() + " блоков");
        }
    }

    private void checkItemLootCollection() {
        long elapsedTime = System.currentTimeMillis() - lootCollectionStartTime;

        boolean itemStillExists = targetItem != null && targetItem.isAlive();

        if (!itemStillExists) {
            sendActionBar("§aПредмет подобран!" + (returnToHub.getValue() ? " Возврат в хаб..." : ""));
            if (returnToHub.getValue()) {
                returnToHub();
            } else {
                state = LootState.SEARCHING_ITEM;
                targetItem = null;
            }
        } else if (elapsedTime > 5000) {
            sendActionBar("§cНе удалось подобрать предмет за 5 секунд" + (returnToHub.getValue() ? ", возврат в хаб..." : ""));
            if (returnToHub.getValue()) {
                returnToHub();
            } else {
                state = LootState.SEARCHING_ITEM;
                targetItem = null;
            }
        } else {
            int secondsLeft = 5 - (int) (elapsedTime / 1000);
            sendActionBar("§eПодбор предмета... " + secondsLeft + "с");
        }
    }

    // ========== ОБЩИЕ МЕТОДЫ ==========

    private void findLootPosition() {
        ItemEntity nearestItem = null;
        double nearestDistance = Double.MAX_VALUE;

        for (net.minecraft.entity.Entity entity : mc.world.getAllEntities()) {
            if (entity instanceof ItemEntity) {
                ItemEntity item = (ItemEntity) entity;
                if (isItemEntityValid(item)) {
                    double dx = item.getPosX() - deathPosition.x;
                    double dz = item.getPosZ() - deathPosition.z;
                    double distance = Math.sqrt(dx * dx + dz * dz);

                    if (distance <= lootRadius.getValue() && distance < nearestDistance) {
                        nearestDistance = distance;
                        nearestItem = item;
                    }
                }
            }
        }

        if (nearestItem != null) {
            lootPosition = new Vector3d(
                    deathPosition.x,
                    nearestItem.getPosY(),
                    deathPosition.z
            );
            sendActionBar("§aТелепортация к луту на высоте: §f" + String.format("%.1f", nearestItem.getPosY()));
        } else {
            lootPosition = deathPosition;
            sendActionBar("§eЛут не найден, телепортация к точке смерти");
        }
    }

    private void teleportToLootPosition() {
        if (lootPosition == null) return;

        int maxHeight = maxFreeHeight.getValue().intValue();

        if (hasTallObstacleAbove(lootPosition, maxHeight)) {
            sendActionBar("§cОбнаружено препятствие выше " + maxHeight + " блоков!");
            if (returnToHub.getValue()) {
                returnToHub();
            } else {
                state = mode.is("Игроки") ? LootState.SEARCHING_PLAYER : LootState.SEARCHING_ITEM;
            }
            return;
        }

        mc.player.setMotion(0, 0, 0);

        for (int i = 0; i < 2; i++) {
            mc.player.connection.sendPacket(new CPlayerPacket.PositionPacket(lootPosition.x,
                    mc.player.getPosY(), lootPosition.z, false));
        }
        mc.player.connection.sendPacket(new CEntityActionPacket(mc.player, CEntityActionPacket.Action.START_FALL_FLYING));
        mc.player.connection.sendPacket(new CPlayerPacket.PositionPacket(lootPosition.x,
                lootPosition.y, lootPosition.z, false));
        mc.player.connection.sendPacket(new CEntityActionPacket(mc.player, CEntityActionPacket.Action.START_FALL_FLYING));
        mc.player.setPosition(lootPosition.x, lootPosition.y, lootPosition.z);

        sendActionBar("§aТелепортирован к луту!");
        collectingLoot = true;
    }

    private boolean hasTallObstacleAbove(Vector3d targetPos, int maxFreeHeight) {
        if (mc.world == null || targetPos == null) return false;

        BlockPos basePos = new BlockPos(targetPos.x, targetPos.y, targetPos.z);
        int solidCount = 0;

        for (int i = 1; i <= 6; i++) {
            BlockPos checkPos = basePos.up(i);

            if (!mc.world.isAirBlock(checkPos)) {
                solidCount++;
                if (solidCount > maxFreeHeight) {
                    return true;
                }
            } else {
                if (solidCount > 0) {
                    break;
                }
            }
        }

        return false;
    }

    private void checkLootCollection() {
        if (!collectingLoot) return;

        long elapsedTime = System.currentTimeMillis() - lootCollectionStartTime;

        boolean lootStillExists = checkLootExists();

        if (!lootStillExists) {
            hasLooted = true;
            sendActionBar("§aВесь лут подобран!" + (returnToHub.getValue() ? " Возврат в хаб..." : ""));
            if (returnToHub.getValue()) {
                returnToHub();
            } else {
                state = LootState.SEARCHING_PLAYER;
            }
        } else if (elapsedTime > 10000) {
            sendActionBar("§cНе удалось подобрать весь лут за 10 секунд" + (returnToHub.getValue() ? ", возврат в хаб..." : ""));
            if (returnToHub.getValue()) {
                returnToHub();
            } else {
                state = LootState.SEARCHING_PLAYER;
            }
        } else {
            int secondsLeft = 10 - (int) (elapsedTime / 1000);
            sendActionBar("§eСбор лута... " + secondsLeft + "с");
        }
    }

    private boolean checkLootExists() {
        for (net.minecraft.entity.Entity entity : mc.world.getAllEntities()) {
            if (entity instanceof ItemEntity) {
                ItemEntity item = (ItemEntity) entity;
                if (isItemEntityValid(item)) {
                    double dx = item.getPosX() - deathPosition.x;
                    double dz = item.getPosZ() - deathPosition.z;
                    double distance = Math.sqrt(dx * dx + dz * dz);
                    if (distance <= lootRadius.getValue()) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private boolean isItemEntityValid(ItemEntity item) {
        return item != null &&
                item.isAlive() &&
                !item.getItem().isEmpty() &&
                item.world == mc.world;
    }

    private boolean isAboveTeleportPoint(Vector3d targetPos) {
        if (mc.player == null || targetPos == null) return false;

        double playerX = mc.player.getPosX();
        double playerZ = mc.player.getPosZ();
        double targetX = targetPos.x;
        double targetZ = targetPos.z;

        double deltaX = playerX - targetX;
        double deltaZ = playerZ - targetZ;
        double horizontalDistance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ);

        return horizontalDistance <= 4.0;
    }

    /**
     * Строгая проверка положения игрока - находится ли он ПРЯМО над точкой телепортации
     * (без диагонального смещения). Используется в безопасном режиме.
     */
    private boolean isStrictlyAboveTeleportPoint(Vector3d targetPos) {
        if (mc.player == null || targetPos == null) return false;

        double playerX = mc.player.getPosX();
        double playerZ = mc.player.getPosZ();
        double targetX = targetPos.x;
        double targetZ = targetPos.z;

        double deltaX = Math.abs(playerX - targetX);
        double deltaZ = Math.abs(playerZ - targetZ);

        // Допускаем минимальное отклонение (0.5 блока) по каждой оси
        return deltaX <= 0.5 && deltaZ <= 0.5;
    }

    private String getArenaNumberFromScoreboard() {
        if (mc.player == null || mc.world == null) return null;

        Scoreboard scoreboard = mc.world.getScoreboard();
        if (scoreboard == null) return null;

        ScoreObjective objective = scoreboard.getObjectiveInDisplaySlot(1);
        if (objective == null) return null;

        try {
            ITextComponent displayName = objective.getDisplayName();
            if (displayName != null) {
                String title = displayName.getString();
                String digitsFromTitle = extractDigits(title);
                if (digitsFromTitle != null) {
                    return digitsFromTitle;
                }
            }

            List<String> lines = scoreboard.getSortedScores(objective).stream()
                    .map(score -> score.getPlayerName())
                    .collect(Collectors.toList());

            for (String rawLine : lines) {
                String digits = extractDigits(rawLine);
                if (digits != null) {
                    return digits;
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        return null;
    }

    private String extractDigits(String text) {
        if (text == null) return null;

        String cleaned = text.replaceAll("§[0-9A-FK-ORa-fk-or]", "");

        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(cleaned);

        if (matcher.find()) {
            return matcher.group();
        }

        return null;
    }

    private void returnToHub() {
        // Проверяем, не отправляли ли уже /hub в этом цикле работы модуля
        if (hubCommandSent) {
            return;
        }

        sendActionBar("§aВозврат в хаб...");

        // Получаем номер арены из скорборда
        arenaNumber = getArenaNumberFromScoreboard();

        // Сразу помечаем, что команда /hub уже запрошена
        hubCommandSent = true;
        hubCommandTime = System.currentTimeMillis();

        new Thread(() -> {
            try {
                Thread.sleep(100);
                mc.execute(() -> {
                    if (mc.player != null) {
                        mc.player.sendChatMessage("/hub");

                        if (arenaNumber != null) {
                            sendActionBar("§eОпределен номер арены: " + arenaNumber);
                        } else {
                            sendActionBar("§cНе удалось определить номер арены");
                            if (autoDisable.getValue()) {
                                new Thread(() -> {
                                    try {
                                        Thread.sleep(1000);
                                        mc.execute(() -> {
                                            if (this.isEnabled()) {
                                                toggle();
                                            }
                                        });
                                    } catch (InterruptedException ex) {
                                        ex.printStackTrace();
                                    }
                                }).start();
                            }
                        }
                    }
                });
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }).start();
    }

    private int countInventoryItems() {
        int count = 0;
        for (int i = 0; i < mc.player.inventory.getSizeInventory(); i++) {
            if (!mc.player.inventory.getStackInSlot(i).isEmpty()) {
                count += mc.player.inventory.getStackInSlot(i).getCount();
            }
        }
        return count;
    }

    private void sendActionBar(String message) {
        if (!message.contains("Весь лут подобран") && !message.contains("Предмет подобран")) {
            return;
        }

        Notifications notifications = Notifications.getInstance();
        if (notifications != null && notifications.isEnabled()) {
            notifications.pushCustom("TPLoot", message, true, this.getCategory());
        }
    }

    private void resetState() {
        targetPlayer = null;
        deathPosition = null;
        lootPosition = null;
        targetDisappearedTime = 0;
        lootCollectionStartTime = 0;
        waitingForLoot = false;
        hasLooted = false;
        collectingLoot = false;
        initialInventorySize = 0;
        teleportedToDeathPoint = false;
        targetItem = null;
        hubCommandSent = false;
        anCommandSent = false;
        hubCommandTime = 0L;
        arenaNumber = null;
        state = LootState.IDLE;
    }
}
/del
 

Похожие темы

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