Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Часть функционала GPSLony | Javeline / Mendix (Update)

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
1 Ноя 2025
Сообщения
15
Реакции
0
Выберите загрузчик игры
  1. Forge
  2. NeoForge
  3. ForgeOptiFine
Короче два режима: LonyGrief и SlimeWorldG3 (3 Гриф)
Пожалуйста, авторизуйтесь для просмотра ссылки.

GPSLony:
Expand Collapse Copy
package fun.mendix.client.modules.impl.misc;

import com.nrz.eventapi.EventTarget;
import fun.mendix.Mendix;
import fun.mendix.client.modules.api.Module;
import fun.mendix.client.modules.api.ModuleAnnotation;
import fun.mendix.client.modules.api.Category;
import fun.mendix.client.modules.api.setting.impl.ModeSetting;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;

import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@ModuleAnnotation(
        name = "GPSLony",
        category = Category.MISC,
        description = "Автоматически добавляет GPS точки при RTP телепортации"
)
public class GPSLony extends Module {

    public static final GPSLony INSTANCE = new GPSLony();

    // ========== РЕЖИМЫ ==========
    private final ModeSetting mode = new ModeSetting("Mode", new String[]{""});
    private final ModeSetting.Value lonyGriefMode;
    private final ModeSetting.Value swGrief3Mode;

    private Thread monitorThread;
    private final AtomicBoolean running = new AtomicBoolean(true);
    private String lastProcessedMessage = "";

    private GPSLony() {
        // Создаём значения режимов
        this.lonyGriefMode = new ModeSetting.Value(mode, "LonyGrief", "Формат LonyGrief: ʟᴏɴʏɢʀɪᴇꜰ » ... координаты: X. Y. Z.");
        this.swGrief3Mode  = new ModeSetting.Value(mode, "SWGrief3",  "Формат SWGrief3: ▶ ... координаты X, Y, Z");
        mode.setValue(lonyGriefMode); // по умолчанию старый формат

        startMonitorThread();
    }

    @Override
    public void onEnable() {
        super.onEnable();
        running.set(true);
    }

    @Override
    public void onDisable() {
        super.onDisable();
        running.set(false);
        if (monitorThread != null) monitorThread.interrupt();
    }

    private void startMonitorThread() {
        monitorThread = new Thread(() -> {
            while (running.get() && !Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(100);
                    if (isEnabled()) checkChatHistory();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception ignored) {}
            }
        }, "GPSLony-Monitor");
        monitorThread.setDaemon(true);
        monitorThread.start();
    }

    private void checkChatHistory() {
        try {
            MinecraftClient mc = MinecraftClient.getInstance();
            if (mc.inGameHud == null || mc.inGameHud.getChatHud() == null) return;

            Field messagesField = mc.inGameHud.getChatHud().getClass().getDeclaredField("messages");
            messagesField.setAccessible(true);
            List<?> messages = (List<?>) messagesField.get(mc.inGameHud.getChatHud());
            if (messages == null || messages.isEmpty()) return;

            Object lastMessage = messages.get(0);
            Field contentField = lastMessage.getClass().getDeclaredField("content");
            contentField.setAccessible(true);
            Object content = contentField.get(lastMessage);

            if (content instanceof Text) {
                String message = ((Text) content).getString();
                if (!message.isEmpty() && !message.equals(lastProcessedMessage)) {
                    lastProcessedMessage = message;
                    processIfRTPMessage(message);
                }
            }
        } catch (Exception ignored) {}
    }

    private void processIfRTPMessage(String message) {
        String clean = message.replaceAll("§[0-9a-fk-or]", "");
        if (mode.getValue() == lonyGriefMode) {
            // Старый формат: содержит "телепортировались" и "координаты:"
            if (clean.contains("телепортировались") &&
                    clean.contains("игроком") &&
                    clean.contains("координаты:")) {
                processLonyGrief(clean);
            }
        } else if (mode.getValue() == swGrief3Mode) {
            // Новый формат: начинается с "▶", содержит "телепортировались", "координаты"
            if (clean.contains("▶") &&
                    clean.contains("телепортировались") &&
                    clean.contains("игроком") &&
                    clean.contains("координаты")) {
                processSwGrief3(clean);
            }
        }
    }

    // ========== ПАРСИНГ СТАРОГО ФОРМАТА (LonyGrief) ==========
    private void processLonyGrief(String message) {
        try {
            message = message.replace("ʟᴏɴʏɢʀɪᴇꜰ » ", "").trim();

            // Имя игрока
            String playerName = null;
            int playerStart = message.indexOf("игроком ");
            if (playerStart != -1) {
                playerStart += 8;
                int playerEnd = message.indexOf("!", playerStart);
                if (playerEnd != -1) {
                    playerName = message.substring(playerStart, playerEnd).trim();
                }
            }
            if (playerName == null || playerName.isEmpty()) return;

            // Координаты (формат X. Y. Z.)
            int coordsStart = message.indexOf("координаты:");
            if (coordsStart == -1) return;
            coordsStart += 11;
            String coordsText = message.substring(coordsStart).trim();
            if (coordsText.endsWith("."))
                coordsText = coordsText.substring(0, coordsText.length() - 1);

            String[] parts = coordsText.split("\\s*\\.\\s*");
            if (parts.length < 3) return;

            int x = Integer.parseInt(parts[0].trim());
            int z = Integer.parseInt(parts[2].trim()); // Y не нужен

            // Выполняем команду GPS
            String command = "gps " + x + " " + z;
            Mendix.getInstance().getCommandManager().getDispatcher().execute(
                    command,
                    Mendix.getInstance().getCommandManager().getSource()
            );

        } catch (Exception ignored) {}
    }

    // ========== ПАРСИНГ НОВОГО ФОРМАТА (SWGrief3) ==========
    private void processSwGrief3(String message) {
        try {
            // Убираем лишнее, оставляем после "▶ "
            if (message.startsWith("▶ ")) {
                message = message.substring(2).trim();
            }

            // Имя игрока
            String playerName = null;
            int playerStart = message.indexOf("игроком ");
            if (playerStart != -1) {
                playerStart += 8;
                int playerEnd = message.indexOf(",", playerStart);
                if (playerEnd == -1) playerEnd = message.indexOf(" ", playerStart);
                if (playerEnd != -1) {
                    playerName = message.substring(playerStart, playerEnd).trim();
                }
            }
            if (playerName == null || playerName.isEmpty()) return;

            // Координаты (формат: X, Y, Z или X, Y, Z.)
            int coordsStart = message.indexOf("координаты");
            if (coordsStart == -1) return;
            coordsStart += 10; // длина "координаты"
            // пропускаем пробелы и запятые
            while (coordsStart < message.length() && (message.charAt(coordsStart) == ' ' || message.charAt(coordsStart) == ',' || message.charAt(coordsStart) == ':')) {
                coordsStart++;
            }
            if (coordsStart >= message.length()) return;

            String coordsText = message.substring(coordsStart).trim();
            // Убираем точку в конце, если есть
            if (coordsText.endsWith("."))
                coordsText = coordsText.substring(0, coordsText.length() - 1);
            if (coordsText.endsWith(","))
                coordsText = coordsText.substring(0, coordsText.length() - 1);

            // Разделитель - запятая или пробел
            String[] parts;
            if (coordsText.contains(",")) {
                parts = coordsText.split("\\s*,\\s*");
            } else {
                parts = coordsText.split("\\s+");
            }
            if (parts.length < 3) return;

            int x = Integer.parseInt(parts[0].trim());
            int z = Integer.parseInt(parts[2].trim()); // Y игнорируем

            // Выполняем команду GPS
            String command = "gps " + x + " " + z;
            Mendix.getInstance().getCommandManager().getDispatcher().execute(
                    command,
                    Mendix.getInstance().getCommandManager().getSource()
            );

        } catch (Exception ignored) {}
    }

    // ========== ГЕТТЕРЫ ==========
    public ModeSetting getMode() { return mode; }
    public ModeSetting.Value getLonyGriefMode() { return lonyGriefMode; }
    public ModeSetting.Value getSwGrief3Mode() { return swGrief3Mode; }
}
 
Короче два режима: LonyGrief и SlimeWorldG3 (3 Гриф)
Пожалуйста, авторизуйтесь для просмотра ссылки.

GPSLony:
Expand Collapse Copy
package fun.mendix.client.modules.impl.misc;

import com.nrz.eventapi.EventTarget;
import fun.mendix.Mendix;
import fun.mendix.client.modules.api.Module;
import fun.mendix.client.modules.api.ModuleAnnotation;
import fun.mendix.client.modules.api.Category;
import fun.mendix.client.modules.api.setting.impl.ModeSetting;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;

import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@ModuleAnnotation(
        name = "GPSLony",
        category = Category.MISC,
        description = "Автоматически добавляет GPS точки при RTP телепортации"
)
public class GPSLony extends Module {

    public static final GPSLony INSTANCE = new GPSLony();

    // ========== РЕЖИМЫ ==========
    private final ModeSetting mode = new ModeSetting("Mode", new String[]{""});
    private final ModeSetting.Value lonyGriefMode;
    private final ModeSetting.Value swGrief3Mode;

    private Thread monitorThread;
    private final AtomicBoolean running = new AtomicBoolean(true);
    private String lastProcessedMessage = "";

    private GPSLony() {
        // Создаём значения режимов
        this.lonyGriefMode = new ModeSetting.Value(mode, "LonyGrief", "Формат LonyGrief: ʟᴏɴʏɢʀɪᴇꜰ » ... координаты: X. Y. Z.");
        this.swGrief3Mode  = new ModeSetting.Value(mode, "SWGrief3",  "Формат SWGrief3: ▶ ... координаты X, Y, Z");
        mode.setValue(lonyGriefMode); // по умолчанию старый формат

        startMonitorThread();
    }

    @Override
    public void onEnable() {
        super.onEnable();
        running.set(true);
    }

    @Override
    public void onDisable() {
        super.onDisable();
        running.set(false);
        if (monitorThread != null) monitorThread.interrupt();
    }

    private void startMonitorThread() {
        monitorThread = new Thread(() -> {
            while (running.get() && !Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(100);
                    if (isEnabled()) checkChatHistory();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception ignored) {}
            }
        }, "GPSLony-Monitor");
        monitorThread.setDaemon(true);
        monitorThread.start();
    }

    private void checkChatHistory() {
        try {
            MinecraftClient mc = MinecraftClient.getInstance();
            if (mc.inGameHud == null || mc.inGameHud.getChatHud() == null) return;

            Field messagesField = mc.inGameHud.getChatHud().getClass().getDeclaredField("messages");
            messagesField.setAccessible(true);
            List<?> messages = (List<?>) messagesField.get(mc.inGameHud.getChatHud());
            if (messages == null || messages.isEmpty()) return;

            Object lastMessage = messages.get(0);
            Field contentField = lastMessage.getClass().getDeclaredField("content");
            contentField.setAccessible(true);
            Object content = contentField.get(lastMessage);

            if (content instanceof Text) {
                String message = ((Text) content).getString();
                if (!message.isEmpty() && !message.equals(lastProcessedMessage)) {
                    lastProcessedMessage = message;
                    processIfRTPMessage(message);
                }
            }
        } catch (Exception ignored) {}
    }

    private void processIfRTPMessage(String message) {
        String clean = message.replaceAll("§[0-9a-fk-or]", "");
        if (mode.getValue() == lonyGriefMode) {
            // Старый формат: содержит "телепортировались" и "координаты:"
            if (clean.contains("телепортировались") &&
                    clean.contains("игроком") &&
                    clean.contains("координаты:")) {
                processLonyGrief(clean);
            }
        } else if (mode.getValue() == swGrief3Mode) {
            // Новый формат: начинается с "▶", содержит "телепортировались", "координаты"
            if (clean.contains("▶") &&
                    clean.contains("телепортировались") &&
                    clean.contains("игроком") &&
                    clean.contains("координаты")) {
                processSwGrief3(clean);
            }
        }
    }

    // ========== ПАРСИНГ СТАРОГО ФОРМАТА (LonyGrief) ==========
    private void processLonyGrief(String message) {
        try {
            message = message.replace("ʟᴏɴʏɢʀɪᴇꜰ » ", "").trim();

            // Имя игрока
            String playerName = null;
            int playerStart = message.indexOf("игроком ");
            if (playerStart != -1) {
                playerStart += 8;
                int playerEnd = message.indexOf("!", playerStart);
                if (playerEnd != -1) {
                    playerName = message.substring(playerStart, playerEnd).trim();
                }
            }
            if (playerName == null || playerName.isEmpty()) return;

            // Координаты (формат X. Y. Z.)
            int coordsStart = message.indexOf("координаты:");
            if (coordsStart == -1) return;
            coordsStart += 11;
            String coordsText = message.substring(coordsStart).trim();
            if (coordsText.endsWith("."))
                coordsText = coordsText.substring(0, coordsText.length() - 1);

            String[] parts = coordsText.split("\\s*\\.\\s*");
            if (parts.length < 3) return;

            int x = Integer.parseInt(parts[0].trim());
            int z = Integer.parseInt(parts[2].trim()); // Y не нужен

            // Выполняем команду GPS
            String command = "gps " + x + " " + z;
            Mendix.getInstance().getCommandManager().getDispatcher().execute(
                    command,
                    Mendix.getInstance().getCommandManager().getSource()
            );

        } catch (Exception ignored) {}
    }

    // ========== ПАРСИНГ НОВОГО ФОРМАТА (SWGrief3) ==========
    private void processSwGrief3(String message) {
        try {
            // Убираем лишнее, оставляем после "▶ "
            if (message.startsWith("▶ ")) {
                message = message.substring(2).trim();
            }

            // Имя игрока
            String playerName = null;
            int playerStart = message.indexOf("игроком ");
            if (playerStart != -1) {
                playerStart += 8;
                int playerEnd = message.indexOf(",", playerStart);
                if (playerEnd == -1) playerEnd = message.indexOf(" ", playerStart);
                if (playerEnd != -1) {
                    playerName = message.substring(playerStart, playerEnd).trim();
                }
            }
            if (playerName == null || playerName.isEmpty()) return;

            // Координаты (формат: X, Y, Z или X, Y, Z.)
            int coordsStart = message.indexOf("координаты");
            if (coordsStart == -1) return;
            coordsStart += 10; // длина "координаты"
            // пропускаем пробелы и запятые
            while (coordsStart < message.length() && (message.charAt(coordsStart) == ' ' || message.charAt(coordsStart) == ',' || message.charAt(coordsStart) == ':')) {
                coordsStart++;
            }
            if (coordsStart >= message.length()) return;

            String coordsText = message.substring(coordsStart).trim();
            // Убираем точку в конце, если есть
            if (coordsText.endsWith("."))
                coordsText = coordsText.substring(0, coordsText.length() - 1);
            if (coordsText.endsWith(","))
                coordsText = coordsText.substring(0, coordsText.length() - 1);

            // Разделитель - запятая или пробел
            String[] parts;
            if (coordsText.contains(",")) {
                parts = coordsText.split("\\s*,\\s*");
            } else {
                parts = coordsText.split("\\s+");
            }
            if (parts.length < 3) return;

            int x = Integer.parseInt(parts[0].trim());
            int z = Integer.parseInt(parts[2].trim()); // Y игнорируем

            // Выполняем команду GPS
            String command = "gps " + x + " " + z;
            Mendix.getInstance().getCommandManager().getDispatcher().execute(
                    command,
                    Mendix.getInstance().getCommandManager().getSource()
            );

        } catch (Exception ignored) {}
    }

    // ========== ГЕТТЕРЫ ==========
    public ModeSetting getMode() { return mode; }
    public ModeSetting.Value getLonyGriefMode() { return lonyGriefMode; }
    public ModeSetting.Value getSwGrief3Mode() { return swGrief3Mode; }
}
а зачем оно нужно что оно делает
 
Короче два режима: LonyGrief и SlimeWorldG3 (3 Гриф)
Пожалуйста, авторизуйтесь для просмотра ссылки.

GPSLony:
Expand Collapse Copy
package fun.mendix.client.modules.impl.misc;

import com.nrz.eventapi.EventTarget;
import fun.mendix.Mendix;
import fun.mendix.client.modules.api.Module;
import fun.mendix.client.modules.api.ModuleAnnotation;
import fun.mendix.client.modules.api.Category;
import fun.mendix.client.modules.api.setting.impl.ModeSetting;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;

import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@ModuleAnnotation(
        name = "GPSLony",
        category = Category.MISC,
        description = "Автоматически добавляет GPS точки при RTP телепортации"
)
public class GPSLony extends Module {

    public static final GPSLony INSTANCE = new GPSLony();

    // ========== РЕЖИМЫ ==========
    private final ModeSetting mode = new ModeSetting("Mode", new String[]{""});
    private final ModeSetting.Value lonyGriefMode;
    private final ModeSetting.Value swGrief3Mode;

    private Thread monitorThread;
    private final AtomicBoolean running = new AtomicBoolean(true);
    private String lastProcessedMessage = "";

    private GPSLony() {
        // Создаём значения режимов
        this.lonyGriefMode = new ModeSetting.Value(mode, "LonyGrief", "Формат LonyGrief: ʟᴏɴʏɢʀɪᴇꜰ » ... координаты: X. Y. Z.");
        this.swGrief3Mode  = new ModeSetting.Value(mode, "SWGrief3",  "Формат SWGrief3: ▶ ... координаты X, Y, Z");
        mode.setValue(lonyGriefMode); // по умолчанию старый формат

        startMonitorThread();
    }

    @Override
    public void onEnable() {
        super.onEnable();
        running.set(true);
    }

    @Override
    public void onDisable() {
        super.onDisable();
        running.set(false);
        if (monitorThread != null) monitorThread.interrupt();
    }

    private void startMonitorThread() {
        monitorThread = new Thread(() -> {
            while (running.get() && !Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(100);
                    if (isEnabled()) checkChatHistory();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception ignored) {}
            }
        }, "GPSLony-Monitor");
        monitorThread.setDaemon(true);
        monitorThread.start();
    }

    private void checkChatHistory() {
        try {
            MinecraftClient mc = MinecraftClient.getInstance();
            if (mc.inGameHud == null || mc.inGameHud.getChatHud() == null) return;

            Field messagesField = mc.inGameHud.getChatHud().getClass().getDeclaredField("messages");
            messagesField.setAccessible(true);
            List<?> messages = (List<?>) messagesField.get(mc.inGameHud.getChatHud());
            if (messages == null || messages.isEmpty()) return;

            Object lastMessage = messages.get(0);
            Field contentField = lastMessage.getClass().getDeclaredField("content");
            contentField.setAccessible(true);
            Object content = contentField.get(lastMessage);

            if (content instanceof Text) {
                String message = ((Text) content).getString();
                if (!message.isEmpty() && !message.equals(lastProcessedMessage)) {
                    lastProcessedMessage = message;
                    processIfRTPMessage(message);
                }
            }
        } catch (Exception ignored) {}
    }

    private void processIfRTPMessage(String message) {
        String clean = message.replaceAll("§[0-9a-fk-or]", "");
        if (mode.getValue() == lonyGriefMode) {
            // Старый формат: содержит "телепортировались" и "координаты:"
            if (clean.contains("телепортировались") &&
                    clean.contains("игроком") &&
                    clean.contains("координаты:")) {
                processLonyGrief(clean);
            }
        } else if (mode.getValue() == swGrief3Mode) {
            // Новый формат: начинается с "▶", содержит "телепортировались", "координаты"
            if (clean.contains("▶") &&
                    clean.contains("телепортировались") &&
                    clean.contains("игроком") &&
                    clean.contains("координаты")) {
                processSwGrief3(clean);
            }
        }
    }

    // ========== ПАРСИНГ СТАРОГО ФОРМАТА (LonyGrief) ==========
    private void processLonyGrief(String message) {
        try {
            message = message.replace("ʟᴏɴʏɢʀɪᴇꜰ » ", "").trim();

            // Имя игрока
            String playerName = null;
            int playerStart = message.indexOf("игроком ");
            if (playerStart != -1) {
                playerStart += 8;
                int playerEnd = message.indexOf("!", playerStart);
                if (playerEnd != -1) {
                    playerName = message.substring(playerStart, playerEnd).trim();
                }
            }
            if (playerName == null || playerName.isEmpty()) return;

            // Координаты (формат X. Y. Z.)
            int coordsStart = message.indexOf("координаты:");
            if (coordsStart == -1) return;
            coordsStart += 11;
            String coordsText = message.substring(coordsStart).trim();
            if (coordsText.endsWith("."))
                coordsText = coordsText.substring(0, coordsText.length() - 1);

            String[] parts = coordsText.split("\\s*\\.\\s*");
            if (parts.length < 3) return;

            int x = Integer.parseInt(parts[0].trim());
            int z = Integer.parseInt(parts[2].trim()); // Y не нужен

            // Выполняем команду GPS
            String command = "gps " + x + " " + z;
            Mendix.getInstance().getCommandManager().getDispatcher().execute(
                    command,
                    Mendix.getInstance().getCommandManager().getSource()
            );

        } catch (Exception ignored) {}
    }

    // ========== ПАРСИНГ НОВОГО ФОРМАТА (SWGrief3) ==========
    private void processSwGrief3(String message) {
        try {
            // Убираем лишнее, оставляем после "▶ "
            if (message.startsWith("▶ ")) {
                message = message.substring(2).trim();
            }

            // Имя игрока
            String playerName = null;
            int playerStart = message.indexOf("игроком ");
            if (playerStart != -1) {
                playerStart += 8;
                int playerEnd = message.indexOf(",", playerStart);
                if (playerEnd == -1) playerEnd = message.indexOf(" ", playerStart);
                if (playerEnd != -1) {
                    playerName = message.substring(playerStart, playerEnd).trim();
                }
            }
            if (playerName == null || playerName.isEmpty()) return;

            // Координаты (формат: X, Y, Z или X, Y, Z.)
            int coordsStart = message.indexOf("координаты");
            if (coordsStart == -1) return;
            coordsStart += 10; // длина "координаты"
            // пропускаем пробелы и запятые
            while (coordsStart < message.length() && (message.charAt(coordsStart) == ' ' || message.charAt(coordsStart) == ',' || message.charAt(coordsStart) == ':')) {
                coordsStart++;
            }
            if (coordsStart >= message.length()) return;

            String coordsText = message.substring(coordsStart).trim();
            // Убираем точку в конце, если есть
            if (coordsText.endsWith("."))
                coordsText = coordsText.substring(0, coordsText.length() - 1);
            if (coordsText.endsWith(","))
                coordsText = coordsText.substring(0, coordsText.length() - 1);

            // Разделитель - запятая или пробел
            String[] parts;
            if (coordsText.contains(",")) {
                parts = coordsText.split("\\s*,\\s*");
            } else {
                parts = coordsText.split("\\s+");
            }
            if (parts.length < 3) return;

            int x = Integer.parseInt(parts[0].trim());
            int z = Integer.parseInt(parts[2].trim()); // Y игнорируем

            // Выполняем команду GPS
            String command = "gps " + x + " " + z;
            Mendix.getInstance().getCommandManager().getDispatcher().execute(
                    command,
                    Mendix.getInstance().getCommandManager().getSource()
            );

        } catch (Exception ignored) {}
    }

    // ========== ГЕТТЕРЫ ==========
    public ModeSetting getMode() { return mode; }
    public ModeSetting.Value getLonyGriefMode() { return lonyGriefMode; }
    public ModeSetting.Value getSwGrief3Mode() { return swGrief3Mode; }
}
легенда
 
Короче два режима: LonyGrief и SlimeWorldG3 (3 Гриф)
Пожалуйста, авторизуйтесь для просмотра ссылки.

GPSLony:
Expand Collapse Copy
package fun.mendix.client.modules.impl.misc;

import com.nrz.eventapi.EventTarget;
import fun.mendix.Mendix;
import fun.mendix.client.modules.api.Module;
import fun.mendix.client.modules.api.ModuleAnnotation;
import fun.mendix.client.modules.api.Category;
import fun.mendix.client.modules.api.setting.impl.ModeSetting;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;

import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

@ModuleAnnotation(
        name = "GPSLony",
        category = Category.MISC,
        description = "Автоматически добавляет GPS точки при RTP телепортации"
)
public class GPSLony extends Module {

    public static final GPSLony INSTANCE = new GPSLony();

    // ========== РЕЖИМЫ ==========
    private final ModeSetting mode = new ModeSetting("Mode", new String[]{""});
    private final ModeSetting.Value lonyGriefMode;
    private final ModeSetting.Value swGrief3Mode;

    private Thread monitorThread;
    private final AtomicBoolean running = new AtomicBoolean(true);
    private String lastProcessedMessage = "";

    private GPSLony() {
        // Создаём значения режимов
        this.lonyGriefMode = new ModeSetting.Value(mode, "LonyGrief", "Формат LonyGrief: ʟᴏɴʏɢʀɪᴇꜰ » ... координаты: X. Y. Z.");
        this.swGrief3Mode  = new ModeSetting.Value(mode, "SWGrief3",  "Формат SWGrief3: ▶ ... координаты X, Y, Z");
        mode.setValue(lonyGriefMode); // по умолчанию старый формат

        startMonitorThread();
    }

    @Override
    public void onEnable() {
        super.onEnable();
        running.set(true);
    }

    @Override
    public void onDisable() {
        super.onDisable();
        running.set(false);
        if (monitorThread != null) monitorThread.interrupt();
    }

    private void startMonitorThread() {
        monitorThread = new Thread(() -> {
            while (running.get() && !Thread.currentThread().isInterrupted()) {
                try {
                    Thread.sleep(100);
                    if (isEnabled()) checkChatHistory();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception ignored) {}
            }
        }, "GPSLony-Monitor");
        monitorThread.setDaemon(true);
        monitorThread.start();
    }

    private void checkChatHistory() {
        try {
            MinecraftClient mc = MinecraftClient.getInstance();
            if (mc.inGameHud == null || mc.inGameHud.getChatHud() == null) return;

            Field messagesField = mc.inGameHud.getChatHud().getClass().getDeclaredField("messages");
            messagesField.setAccessible(true);
            List<?> messages = (List<?>) messagesField.get(mc.inGameHud.getChatHud());
            if (messages == null || messages.isEmpty()) return;

            Object lastMessage = messages.get(0);
            Field contentField = lastMessage.getClass().getDeclaredField("content");
            contentField.setAccessible(true);
            Object content = contentField.get(lastMessage);

            if (content instanceof Text) {
                String message = ((Text) content).getString();
                if (!message.isEmpty() && !message.equals(lastProcessedMessage)) {
                    lastProcessedMessage = message;
                    processIfRTPMessage(message);
                }
            }
        } catch (Exception ignored) {}
    }

    private void processIfRTPMessage(String message) {
        String clean = message.replaceAll("§[0-9a-fk-or]", "");
        if (mode.getValue() == lonyGriefMode) {
            // Старый формат: содержит "телепортировались" и "координаты:"
            if (clean.contains("телепортировались") &&
                    clean.contains("игроком") &&
                    clean.contains("координаты:")) {
                processLonyGrief(clean);
            }
        } else if (mode.getValue() == swGrief3Mode) {
            // Новый формат: начинается с "▶", содержит "телепортировались", "координаты"
            if (clean.contains("▶") &&
                    clean.contains("телепортировались") &&
                    clean.contains("игроком") &&
                    clean.contains("координаты")) {
                processSwGrief3(clean);
            }
        }
    }

    // ========== ПАРСИНГ СТАРОГО ФОРМАТА (LonyGrief) ==========
    private void processLonyGrief(String message) {
        try {
            message = message.replace("ʟᴏɴʏɢʀɪᴇꜰ » ", "").trim();

            // Имя игрока
            String playerName = null;
            int playerStart = message.indexOf("игроком ");
            if (playerStart != -1) {
                playerStart += 8;
                int playerEnd = message.indexOf("!", playerStart);
                if (playerEnd != -1) {
                    playerName = message.substring(playerStart, playerEnd).trim();
                }
            }
            if (playerName == null || playerName.isEmpty()) return;

            // Координаты (формат X. Y. Z.)
            int coordsStart = message.indexOf("координаты:");
            if (coordsStart == -1) return;
            coordsStart += 11;
            String coordsText = message.substring(coordsStart).trim();
            if (coordsText.endsWith("."))
                coordsText = coordsText.substring(0, coordsText.length() - 1);

            String[] parts = coordsText.split("\\s*\\.\\s*");
            if (parts.length < 3) return;

            int x = Integer.parseInt(parts[0].trim());
            int z = Integer.parseInt(parts[2].trim()); // Y не нужен

            // Выполняем команду GPS
            String command = "gps " + x + " " + z;
            Mendix.getInstance().getCommandManager().getDispatcher().execute(
                    command,
                    Mendix.getInstance().getCommandManager().getSource()
            );

        } catch (Exception ignored) {}
    }

    // ========== ПАРСИНГ НОВОГО ФОРМАТА (SWGrief3) ==========
    private void processSwGrief3(String message) {
        try {
            // Убираем лишнее, оставляем после "▶ "
            if (message.startsWith("▶ ")) {
                message = message.substring(2).trim();
            }

            // Имя игрока
            String playerName = null;
            int playerStart = message.indexOf("игроком ");
            if (playerStart != -1) {
                playerStart += 8;
                int playerEnd = message.indexOf(",", playerStart);
                if (playerEnd == -1) playerEnd = message.indexOf(" ", playerStart);
                if (playerEnd != -1) {
                    playerName = message.substring(playerStart, playerEnd).trim();
                }
            }
            if (playerName == null || playerName.isEmpty()) return;

            // Координаты (формат: X, Y, Z или X, Y, Z.)
            int coordsStart = message.indexOf("координаты");
            if (coordsStart == -1) return;
            coordsStart += 10; // длина "координаты"
            // пропускаем пробелы и запятые
            while (coordsStart < message.length() && (message.charAt(coordsStart) == ' ' || message.charAt(coordsStart) == ',' || message.charAt(coordsStart) == ':')) {
                coordsStart++;
            }
            if (coordsStart >= message.length()) return;

            String coordsText = message.substring(coordsStart).trim();
            // Убираем точку в конце, если есть
            if (coordsText.endsWith("."))
                coordsText = coordsText.substring(0, coordsText.length() - 1);
            if (coordsText.endsWith(","))
                coordsText = coordsText.substring(0, coordsText.length() - 1);

            // Разделитель - запятая или пробел
            String[] parts;
            if (coordsText.contains(",")) {
                parts = coordsText.split("\\s*,\\s*");
            } else {
                parts = coordsText.split("\\s+");
            }
            if (parts.length < 3) return;

            int x = Integer.parseInt(parts[0].trim());
            int z = Integer.parseInt(parts[2].trim()); // Y игнорируем

            // Выполняем команду GPS
            String command = "gps " + x + " " + z;
            Mendix.getInstance().getCommandManager().getDispatcher().execute(
                    command,
                    Mendix.getInstance().getCommandManager().getSource()
            );

        } catch (Exception ignored) {}
    }

    // ========== ГЕТТЕРЫ ==========
    public ModeSetting getMode() { return mode; }
    public ModeSetting.Value getLonyGriefMode() { return lonyGriefMode; }
    public ModeSetting.Value getSwGrief3Mode() { return swGrief3Mode; }
}
Ахуеть, как же сложно такое сделать, хоть бы коменты убрал от аи
 
Назад
Сверху Снизу