nageyqma·git
HTTPS https://git.nageyqma.icu/nageyqma/blade-addons-next.git SSH git@git.nageyqma.icu:nageyqma/blade-addons-next.git

HTTPS 链接可直接 git clone;推送代码请使用 SSH。

7.2 KB · 212 行raw
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
package blade.addon.features.other.pet;

import blade.addon.utils.Constants;
import blade.addon.utils.Misc;
import blade.addon.utils.config.values.ExtraOptions;
import blade.addon.utils.data.ItemUtil;
import blade.addon.utils.debug.Debug;
import blade.addon.utils.events.Events;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
import net.minecraft.resources.Identifier;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerInput;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SelectedPet {

    //https://hypixelskyblock.minecraft.wiki/w/Pets
    //https://cloudconvert.com/to-png

    private static final int COLOR_OFFSET = 2;

    private static final Pattern TAB_PET_PATTERN = Pattern.compile(" \\[Lvl \\d+] (?:\\[[^\\]]+\\] )?(.+)");
    private static final Pattern MANUAL_EQUIP_PET_PATTERN = Pattern.compile("^You (summoned|despawned) your (?:\\[Lvl \\d+] )?(?:\\[[^\\]]+\\] )?(.+)!$");
    private static final Pattern RULE_EQUIP_PET_PATTERN = Pattern.compile("^Autopet equipped your \\[Lvl \\d+] (?:\\[[^\\]]+\\] )?(.+)! VIEW RULE$");
    private static final Pattern LEVEL_REGEX = Pattern.compile("\\[Lvl (\\d+)]");

    private static final int TOTAL_TICKS = 20;

    static final MutableComponent NO_PET = Component.literal("§cNo pet");
    private static final String identifierPrefix = "pets/";

    static MutableComponent currentPetText = NO_PET;
    static int currentPetLevel = -1;
    static String currentPetString = "";
    static Identifier spriteId = null;
    private static int tick = 0;

    private static boolean inLoadout = false;

    public static void init() {
        Events.ON_GAME_MESSAGE.register(message -> {
            String string = message.getString();
            Matcher matcher = MANUAL_EQUIP_PET_PATTERN.matcher(string);
            if (matcher.find()) {

                if (matcher.group(1).equals("despawned")) {
                    despawnPet();
                    return false;
                }

                String name = matcher.group(2).replace(" ✦", "");
                Style style = getStyle(message, name);
                summonPet(name, Component.literal(name).setStyle(style), getLevel(string), false);
                return false;
            }

            String unformattedLine = string.replaceAll("§.", "");
            matcher = RULE_EQUIP_PET_PATTERN.matcher(unformattedLine);
            if (matcher.find()) {
                String name = matcher.group(1).replace(" ✦", "");

                String textName = name;
                int index = string.indexOf(name);
                if (index > COLOR_OFFSET) {
                    textName = string.substring(index - COLOR_OFFSET, index) + textName;
                }

                summonPet(name, Component.literal(textName), getLevel(unformattedLine), true);
            }

            return false;
        });

        Events.ON_PLAYER_ENTRY.register(receivedEntry -> {
            if (receivedEntry == null) return false;
            Component text = receivedEntry.displayName();
            if (text == null) return false;

            String string = text.getString();
            if (string.equals(" No pet selected")) {
                despawnPet();
                return false;
            }

            int correctionCheck = string.indexOf("[");
            if (correctionCheck != 1) return false;

            Matcher matcher = TAB_PET_PATTERN.matcher(string);
            if (matcher.find()) {
                String petName = matcher.group(1).replace(" ✦", "");
                Style style = getStyle(text, petName);
                summonPet(petName, Component.literal(petName).setStyle(style), getLevel(string), false);
            }

            return false;
        });

        Events.ON_SCREEN.register(screen -> {
            if (screen == null) {
                inLoadout = false;
                return false;
            }

            Component title = screen.getTitle();
            inLoadout = title.getString().contains(") Loadouts");

            return false;
        });

        ClientTickEvents.END_LEVEL_TICK.register((_ -> {
            tick = Math.max(tick - 1, 0);
        }));

    }

    public static void testLoadoutClick(int container, int slotId, int button, ContainerInput containerInput, Player player) {
        if (!inLoadout || button != 0 || player == null) return;

        AbstractContainerMenu containerMenu = player.containerMenu;
        if (containerMenu == null) {
            Misc.addChatMessage(Component.literal("container is null"));
            return;
        }

        Component component = ItemUtil.findLore(containerMenu.getSlot(slotId).getItem(), "Pet: ");
        if (component == null) return;


        String string = component.getString();
        Matcher matcher = TAB_PET_PATTERN.matcher(string);
        if (matcher.find()) {
            String petName = matcher.group(1).replace(" ✦", "");
            Style style = getStyle(component, petName);
            summonPet(petName, Component.literal(petName).setStyle(style), getLevel(string), false);
        }
    }

    private static void despawnPet() {
        Events.ON_PET.invoke(petEvent -> petEvent.onPet(""));
        currentPetText = NO_PET;
        currentPetLevel = -1;
        currentPetString = "";
        spriteId = null;

    }

    private static void summonPet(String stringName, MutableComponent textName, int level, boolean sendSound) {
        currentPetLevel = level;
        if (stringName.equals(currentPetString)) {
            return;
        }

        currentPetText = textName;
        currentPetString = stringName;

        Events.ON_PET.invoke(petEvent -> petEvent.onPet(currentPetString));
        updateSprite(stringName);

        if (sendSound && ExtraOptions.sendOnPetSound) {
            Misc.sendSound(ExtraOptions.petSound);
        }
        tick = TOTAL_TICKS;
    }

    private static Style getStyle(Component text, String name) {
        Style style = Style.EMPTY;
        List<Component> lines = text.getSiblings();

        for (Component line : lines) {
            if (line.getString().equals(name)) {
                style = line.getStyle();
            }
        }

        return style;
    }

    private static int getLevel(String line) {
        Matcher matcher = LEVEL_REGEX.matcher(line);
        if (matcher.find()) {
            return Integer.parseInt(matcher.group(1));
        }

        return -1;
    }

    private static void updateSprite(String petName) {
        if (petName == null) {
            spriteId = null;
            return;
        }
        String formattedName = petName.toLowerCase().replace(" ", "-");
        if (Identifier.isValidNamespace(formattedName)) {
            spriteId = Identifier.fromNamespaceAndPath(Constants.NAMESPACE, identifierPrefix + formattedName);
        } else {
            Debug.LOGGER.warn("{} includes invalid chars", formattedName);
        }
    }

    public static boolean displayNotification() {
        return ExtraOptions.sendPetSwapNotification && tick > 0;
    }

}