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

Визуальная часть Stafflist Hud sk3d wild 1.21.4

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
7 Мар 2025
Сообщения
97
Реакции
2
Выберите загрузчик игры
  1. Vanilla
хз делал с нуля за 2 часа мне не понравился ну думаю какимто пастером будет вкусно например какомуто ламчику)))) гпт насрал

SS -
1773416961329.png



Code -
сарделька:
Expand Collapse Copy
package dev.sk3d.display.hud;

import dev.sk3d.common.animation.implement.Decelerate;
import dev.sk3d.common.animation.implement.Decelerate;
import dev.sk3d.common.animation.implement.EaseOut;
import dev.sk3d.utils.display.render.post.KawaseBlur;
import com.mojang.authlib.GameProfile;
import dev.sk3d.utils.interactions.interact.PlayerInteractionHelper;
import dev.sk3d.utils.theme.ThemeManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.scoreboard.Team;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import dev.sk3d.utils.client.managers.api.draggable.AbstractDraggable;
import dev.sk3d.common.animation.Animation;
import dev.sk3d.common.repository.staff.StaffRepository;
import dev.sk3d.common.animation.Direction;
import dev.sk3d.utils.display.render.font.FontRenderer;
import dev.sk3d.utils.display.render.font.Fonts;
import dev.sk3d.utils.display.render.shape.ShapeProperties;
import dev.sk3d.utils.display.color.ColorAssist;
import dev.sk3d.utils.math.calc.Calculate;
import dev.sk3d.utils.client.Instance;
import dev.sk3d.utils.display.render.geometry.Render2D;
import dev.sk3d.features.impl.render.Hud;
import dev.sk3d.utils.client.packet.network.Network;
import dev.sk3d.features.impl.combat.AntiBot;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.entity.state.LivingEntityRenderState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import java.util.*;
import java.awt.*;
import java.util.List;
import java.util.regex.Pattern;

public class StaffList extends AbstractDraggable {
    public static StaffList getInstance() {
        return Instance.getDraggable(StaffList.class);
    }

    public final Map<PlayerListEntry, Animation> list = new HashMap<>();
    private final Set<String> notifiedPlayers = new HashSet<>();
    private final Set<String> addedViaPrefix = new HashSet<>();
    private final Pattern namePattern = Pattern.compile("^\\w{3,16}$");
    private long lastColorChange = 0;
    private int currentColorIndex = 0;
    private static final Map<String, String> CHAR_TO_NAME = new HashMap<>();
    private static final Map<String, Integer> PREFIX_COLORS = new HashMap<>();

    static {
        CHAR_TO_NAME.put("ꔀ", "player");
        CHAR_TO_NAME.put("ꔄ", "hero");
        CHAR_TO_NAME.put("ꔈ", "titan");
        CHAR_TO_NAME.put("ꔒ", "avenger");
        CHAR_TO_NAME.put("ꔖ", "overlord");
        CHAR_TO_NAME.put("ꔠ", "magister");
        CHAR_TO_NAME.put("ꔤ", "imperator");
        CHAR_TO_NAME.put("ꔨ", "dragon");
        CHAR_TO_NAME.put("ꔲ", "bull");
        CHAR_TO_NAME.put("ꕒ", "rabbit");
        CHAR_TO_NAME.put("ꔶ", "tiger");
        CHAR_TO_NAME.put("ꕄ", "dracula");
        CHAR_TO_NAME.put("ꕖ", "bunny");
        CHAR_TO_NAME.put("ꕀ", "hydra");
        CHAR_TO_NAME.put("ꕈ", "cobra");
        CHAR_TO_NAME.put("ꔁ", "media");
        CHAR_TO_NAME.put("ꔅ", "yt");
        CHAR_TO_NAME.put("ꕠ", "d.helper");
        CHAR_TO_NAME.put("ꔉ", "helper");
        CHAR_TO_NAME.put("ꔓ", "ml.moder");
        CHAR_TO_NAME.put("ꔗ", "moder");
        CHAR_TO_NAME.put("ꔡ", "moder+");
        CHAR_TO_NAME.put("ꔥ", "st.moder");
        CHAR_TO_NAME.put("ꔩ", "gl.moder");
        CHAR_TO_NAME.put("ꔳ", "ml.admin");
        CHAR_TO_NAME.put("ꔷ", "admin");

        PREFIX_COLORS.put("media", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("yt", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("d.helper", new Color(255, 255, 0, 255).getRGB());
        PREFIX_COLORS.put("helper", new Color(255, 255, 0, 255).getRGB());
        PREFIX_COLORS.put("ml.moder", new Color(0, 255, 255, 255).getRGB());
        PREFIX_COLORS.put("moder", new Color(0, 0, 255, 255).getRGB());
        PREFIX_COLORS.put("moder+", new Color(0, 0, 255, 255).getRGB());
        PREFIX_COLORS.put("st.moder", new Color(128, 0, 128, 255).getRGB());
        PREFIX_COLORS.put("gl.moder", new Color(128, 0, 128, 255).getRGB());
        PREFIX_COLORS.put("ml.admin", new Color(0, 255, 255, 255).getRGB());
        PREFIX_COLORS.put("admin", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("Vanish", new Color(255, 0, 0, 255).getRGB());
    }

    public StaffList() {
        super("Staff list", 115, 40, 70, 20, true);
        this.scaleAnimation = new EaseOut().setValue(1).setMs(100);
    }

    private static final List<String> STAFF_KEYWORDS = Arrays.asList("админ", "модер", "moder", "admin", "helper", "хелпер", "стажер", "мл.сотрудник", "ст.сотрудник", "сотрудник");

    private void logDebug(String message) {
        System.out.println("[StaffList] " + message);
    }

    private boolean isNPC(String name) {
        if (name == null) return false;
        String lowerName = name.toLowerCase();
        if (lowerName.equals("anarchy") || lowerName.equals("tokens")) {
            return true;
        }
        return lowerName.contains("npc")
            || lowerName.contains("[znpc]")
            || lowerName.startsWith("cit-")
            || lowerName.startsWith("§")
            || name.contains("NPC")
            || name.contains("[ZNPC]");
    }

    private boolean containsStaffKeyword(String text) {
        if (text == null || text.isEmpty()) {
            return false;
        }
        String lower = text.toLowerCase(Locale.ROOT);
        for (String keyword : STAFF_KEYWORDS) {
            if (lower.contains(keyword)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean visible() {
        return !list.isEmpty() || PlayerInteractionHelper.isChat(mc.currentScreen);
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        if (button == 0) {
            FontRenderer HAWENFont = Fonts.getSize(15, Fonts.Type.HAWEN);
            float pX = getX() + getWidth() - HAWENFont.getStringWidth("p") - 8;
            float pY = getY() + 9.5f;
            float pWidth = HAWENFont.getStringWidth("p");
            float pHeight = HAWENFont.getStringHeight("p");
            
            if (mouseX >= pX && mouseX <= pX + pWidth && mouseY >= pY && mouseY <= pY + pHeight) {
                java.util.List<String> selected = new java.util.ArrayList<>(Hud.getInstance().interfaceSettings.getSelected());
                selected.remove("Staff list");
                Hud.getInstance().interfaceSettings.setSelected(selected);
                return true;
            }
        }
        return super.mouseClicked(mouseX, mouseY, button);
    }

    @Override
    public void tick() {
        if (mc.world == null || mc.player == null || mc.getNetworkHandler() == null) {
            list.clear();
            return;
        }

        Collection<PlayerListEntry> playerList = mc.getNetworkHandler().getPlayerList();
        Scoreboard scoreboard = mc.world.getScoreboard();
        Set<String> addedNames = new HashSet<>();
        Set<String> addedNamesLower = new HashSet<>();

        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - lastColorChange >= 1000) {
                currentColorIndex = (currentColorIndex + 1) % PREFIX_COLORS.size();
                lastColorChange = System.currentTimeMillis();
            }
            return;
        }

        for (PlayerListEntry entry : playerList) {
            String name = entry.getProfile().getName();
            String nameLower = name.toLowerCase();
            
            if (addedNames.contains(name) || addedNamesLower.contains(nameLower) || list.containsKey(entry) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            boolean isNPCName = isNPC(name);
            if (isNPCName) {
                continue;
            }
            String display = entry.getDisplayName() != null ? entry.getDisplayName().getString() : name;
            boolean isNPCDisplay = isNPC(display);
            if (isNPCDisplay) {
                continue;
            }
            if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(entry.getProfile().getId())) {
                continue;
            }
            PlayerEntity playerEntity = mc.world.getPlayerByUuid(entry.getProfile().getId());
            if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                continue;
            }
            Team playerTeam = entry.getScoreboardTeam();
            String teamPrefix = playerTeam != null ? playerTeam.getPrefix().getString() : "";
            boolean hasStaffPrefix = containsStaffKeyword(teamPrefix);
            if (hasStaffPrefix) {
                list.put(entry, new Decelerate().setMs(150).setValue(1));
                addedNames.add(name);
                addedNamesLower.add(nameLower);
                addedViaPrefix.add(name);

                if (Hud.getInstance().notificationSettings.isSelected("Входе админа") && !notifiedPlayers.contains(name)) {
                    Notifications.getInstance().addList(Text.literal(name + " - Зашел на сервер!"), 5000);
                    notifiedPlayers.add(name);
                }
            }
        }

        for (StaffRepository.Staff staff : StaffRepository.getStaff()) {
            String staffName = staff.getName();
            String staffNameLower = staffName.toLowerCase();
            
            if (addedNames.contains(staffName) || addedNamesLower.contains(staffNameLower) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(staffName))) {
                continue;
            }
            playerList.stream()
                    .filter(p -> p.getProfile().getName().equalsIgnoreCase(staffName))
                    .filter(p -> {
                        String name = p.getProfile().getName();
                        if (isNPC(name)) {
                            return false;
                        }
                        if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(p.getProfile().getId())) {
                            return false;
                        }
                        PlayerEntity playerEntity = mc.world.getPlayerByUuid(p.getProfile().getId());
                        boolean isBot = playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity);
                        return playerEntity == null || AntiBot.getInstance() == null || !isBot;
                    })
                    .findFirst()
                    .ifPresent(entry -> {
                        list.put(entry, new Decelerate().setMs(150).setValue(1));
                        addedNames.add(staffName);
                        addedNamesLower.add(staffNameLower);
                    });
        }

        List<Team> teams = new ArrayList<>(scoreboard.getTeams());
        teams.sort(Comparator.comparing(Team::getName));
        Collection<PlayerListEntry> online = mc.getNetworkHandler().getPlayerList();

        for (Team team : teams) {
            Collection<String> members = team.getPlayerList();
            if (members.size() != 1) {
                continue;
            }
            String name = members.iterator().next();
            String nameLower = name.toLowerCase();
            
            if (!namePattern.matcher(name).matches() || addedNames.contains(name) || addedNamesLower.contains(nameLower) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            boolean isNPCName = isNPC(name);
            if (isNPCName) {
                continue;
            }
            PlayerListEntry entry = online.stream()
                    .filter(e -> e.getProfile() != null && name.equals(e.getProfile().getName()))
                    .findFirst()
                    .orElse(null);
            if (entry != null) {
                if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(entry.getProfile().getId())) {
                    continue;
                }
                String display = entry.getDisplayName() != null ? entry.getDisplayName().getString() : name;
                if (isNPC(display)) {
                    continue;
                }
                PlayerEntity playerEntity = mc.world.getPlayerByUuid(entry.getProfile().getId());
                if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                    continue;
                }
                continue;
            }
            UUID generatedUUID = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes());
            if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(generatedUUID)) {
                continue;
            }
            PlayerEntity playerEntity = mc.world.getPlayerByUuid(generatedUUID);
            if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                continue;
            }
            
            if (list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            String teamPrefix = team.getPrefix().getString();
            String prefix = CHAR_TO_NAME.entrySet().stream()
                    .filter(e -> teamPrefix.contains(e.getKey()))
                    .map(Map.Entry::getValue)
                    .findFirst()
                    .orElse("");
            MutableText displayName = Text.empty();
            if (Network.isReallyWorld()) {
                displayName.append(Text.literal(name).formatted(Formatting.GRAY))
                        .append(Text.literal(" [").formatted(Formatting.GRAY))
                        .append(Text.literal(prefix.isEmpty() ? "V" : prefix).formatted(Formatting.RESET))
                        .append(Text.literal("]").formatted(Formatting.GRAY));
            } else {
                displayName.append(Text.literal("[").formatted(Formatting.GRAY))
                        .append(Text.literal(prefix.isEmpty() ? "V" : prefix).formatted(Formatting.RESET))
                        .append(Text.literal("] ").formatted(Formatting.GRAY))
                        .append(Text.literal(name).formatted(Formatting.GRAY));
            }
            GameProfile fakeProfile = new GameProfile(UUID.randomUUID(), name);
            PlayerListEntry fake = new PlayerListEntry(fakeProfile, mc.isInSingleplayer());
            fake.setDisplayName(displayName);
            fake.setListOrder(Integer.MIN_VALUE);
            list.put(fake, new Decelerate().setMs(150).setValue(1));
            addedNames.add(name);
            addedNamesLower.add(nameLower);

            if (Hud.getInstance().notificationSettings.isSelected("Входе админа") && !notifiedPlayers.contains(name)) {
                Notifications.getInstance().addList(Text.literal(name + " - Зашел на сервер!"), 5000);
                notifiedPlayers.add(name);
            }
        }

        list.entrySet().removeIf(entry -> {
            String name = entry.getKey().getProfile().getName();
            boolean isFromRepo = StaffRepository.isStaff(name);
            boolean isFromPrefix = addedViaPrefix.contains(name);
            boolean inPlayerList = playerList.stream().anyMatch(p -> p.getProfile().getName().equals(name));
            boolean inTeam = scoreboard.getTeams().stream().flatMap(t -> t.getPlayerList().stream()).anyMatch(name::equals);

            boolean stillHasStaffPrefix = false;
            if (isFromPrefix && inPlayerList) {
                PlayerListEntry currentEntry = playerList.stream()
                        .filter(p -> p.getProfile().getName().equals(name))
                        .findFirst().orElse(null);
                if (currentEntry != null) {
                    String display = currentEntry.getDisplayName() != null ? currentEntry.getDisplayName().getString() : name;
                    Team playerTeam = currentEntry.getScoreboardTeam();
                    stillHasStaffPrefix = containsStaffKeyword(display) || (playerTeam != null && containsStaffKeyword(playerTeam.getPrefix().getString()));
                }
            }
            
            boolean shouldRemove = false;
            if (isFromRepo) {
                if (!inPlayerList) {
                    shouldRemove = true;
                }
            } else if (isFromPrefix) {
                if (!inPlayerList || !stillHasStaffPrefix) {
                    shouldRemove = true;
                }
            } else {
                if (inPlayerList || !inTeam) {
                    shouldRemove = true;
                }
            }
            
            if (shouldRemove) {
          
                entry.getValue().setDirection(Direction.BACKWARDS);
            }
            if (entry.getValue().isFinished(Direction.BACKWARDS)) {
            
                notifiedPlayers.remove(name);
                addedViaPrefix.remove(name);
                if (!inPlayerList && Hud.getInstance().notificationSettings.isSelected("Выходе админа")) {
                    Notifications.getInstance().addList(Text.literal(name + " - Вышел с сервера!"), 5000);
                }
                return true;
            }
            return false;
        });
    }

    @Override
    public void drawDraggable(DrawContext context) {
        MatrixStack matrix = context.getMatrices();
        FontRenderer fontTitle = Fonts.getSize(16, Fonts.Type.BOLD);
        FontRenderer fontPrefix = Fonts.getSize(14, Fonts.Type.BOLD);
        FontRenderer fontName = Fonts.getSize(13, Fonts.Type.SEMI);

        long activeStaff = list.entrySet().stream().filter(e -> !e.getValue().isFinished(Direction.BACKWARDS)).count();

        float panelWidth = 140f;
        float titleHeight = 24f;
        float playerHeight = 18f;
        float spacing = -4f;
        float titleSpacing = -2f;
        float statusPanelWidth = 18f;
        float mainPanelWidth = panelWidth - statusPanelWidth - 13f;
        float totalHeight = titleHeight + titleSpacing + 8f;

        if (!list.isEmpty() || PlayerInteractionHelper.isChat(mc.currentScreen)) {
            int visibleCount = list.isEmpty() ? 3 : (int) activeStaff;
            totalHeight += visibleCount * (playerHeight + spacing);
        }


        if (Hud.blur.isValue()) {
            Render2D.rectangleWithMask(matrix.peek().getPositionMatrix(), getX(), getY(), panelWidth, totalHeight, 8f, 0,
                    KawaseBlur.INSTANCE.fbos.getFirst().getColorAttachment());
        }

        rectangle.render(ShapeProperties.create(matrix, getX(), getY(), panelWidth, totalHeight)
                .round(8f)
                .color(ThemeManager.BackgroundGui.getColor())
                .build());


        rectangle.render(ShapeProperties.create(matrix, getX() + 5, getY() + 5, panelWidth - 10, titleHeight - 10)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());


        fontTitle.drawString(matrix, "Staff", getX() + 12f, getY() + 10f, ThemeManager.textColor.getColor());


        Fonts.getSize(20, Fonts.Type.KEFIREBAL).drawString(matrix, "F", getX() + panelWidth - 19f, getY() + 9f, ThemeManager.textColor.getColor());

        float currentY = getY() + titleHeight + titleSpacing;
        Collection<PlayerListEntry> playerList = mc.player != null && mc.player.networkHandler != null ?
                mc.player.networkHandler.getPlayerList() : new ArrayList<>();


        float contentHeight = 0;
        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            contentHeight = 3 * (playerHeight + spacing) - spacing;
        } else {
            for (Map.Entry<PlayerListEntry, Animation> staff : list.entrySet()) {
                float animation = staff.getValue().getOutput().floatValue();
                if (animation > 0.01f) {
                    contentHeight += (playerHeight + spacing) * animation;
                }
            }
            contentHeight -= spacing;
        }


        rectangle.render(ShapeProperties.create(matrix, getX() + 5, currentY, mainPanelWidth, contentHeight)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());


        float statusPanelX = getX() + 5 + mainPanelWidth + 3f;
        rectangle.render(ShapeProperties.create(matrix, statusPanelX, currentY, statusPanelWidth, contentHeight)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());

        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            String[] exampleNames = {"kefir", "winda", "greufs"};
            String[] examplePrefixes = {"CODER", "CODER", "DEV"};
            int[] exampleColors = {
                new Color(255, 3, 3, 255).getRGB(),
                new Color(85, 255, 85, 255).getRGB(),
                new Color(255, 170, 85, 255).getRGB()
            };

            for (int i = 0; i < 3; i++) {
                drawPlayerContent(matrix, context, getX() + 5, statusPanelX, currentY, mainPanelWidth, statusPanelWidth, playerHeight,
                        exampleNames[i], examplePrefixes[i], exampleColors[i], 1.0f, fontPrefix, fontName);
                currentY += playerHeight + spacing;
            }
        } else {
            for (Map.Entry<PlayerListEntry, Animation> staff : list.entrySet()) {
                PlayerListEntry player = staff.getKey();
                if (player == null) continue;

                String name = player.getProfile().getName();
                float animation = staff.getValue().getOutput().floatValue();

                if (animation > 0.01f) {
                    boolean isVisible = playerList.stream().anyMatch(p -> p.getProfile().getName().equals(name));
                    PlayerListEntry renderEntry = isVisible ?
                            playerList.stream().filter(p -> p.getProfile().getName().equals(name)).findFirst().orElse(player) :
                            player;

                    String displayName = renderEntry.getDisplayName() != null ? renderEntry.getDisplayName().getString() : name;
                    String prefix = CHAR_TO_NAME.entrySet().stream()
                            .filter(e -> displayName.contains(e.getKey()))
                            .map(Map.Entry::getValue)
                            .findFirst()
                            .orElse("Vanish");

                    int statusColor = PREFIX_COLORS.getOrDefault(prefix, new Color(255, 0, 0, 255).getRGB());

                    drawPlayerContent(matrix, context, getX() + 5, statusPanelX, currentY, mainPanelWidth, statusPanelWidth, playerHeight,
                            name, prefix.toUpperCase(), statusColor, animation, fontPrefix, fontName);

                    currentY += (playerHeight + spacing) * animation;
                }
            }
        }

        setWidth((int) panelWidth);
        setHeight((int) totalHeight);
    }
    
    private void drawPlayerContent(MatrixStack matrix, DrawContext context, float mainPanelX, float statusPanelX, float y,
                                  float mainPanelWidth, float statusPanelWidth, float height,
                                  String name, String prefixText, int statusColor, float animation,
                                  FontRenderer fontPrefix, FontRenderer fontName) {
        float centerX = mainPanelX + mainPanelWidth / 2f;
        float centerY = y + height / 2f;

        Calculate.scale(matrix, centerX, centerY, animation, animation, () -> {
            float headPanelWidth = 18f;


            float headSize = 10f;
            float headX = mainPanelX + 3f;
            float headY = y + (height - headSize) / 2f;
            
            if (mc.player != null) {
                Identifier skinTexture = mc.player.getSkinTextures().texture();
                Render2D.drawTexture(context, skinTexture, headX, headY, headSize, 4f, 8, 8, 64, -1, -1);
            }
            

            FontRenderer arrowFont = Fonts.getSize(16, Fonts.Type.HAWEN);
            float arrowX = headX + headSize + 3f;
            float arrowY = y + height - 11f;
            arrowFont.drawString(matrix, "»", arrowX, arrowY, new Color(253, 248, 248, 255).getRGB());


            float textStartX = arrowX + arrowFont.getStringWidth("»") + 3f;
            float prefixY = y + height - 11f;
            fontPrefix.drawString(matrix, prefixText, textStartX, prefixY, statusColor);


            float nameX = textStartX + fontPrefix.getStringWidth(prefixText) + 3f;
            float nameY = y + height - 11f;
            fontName.drawString(matrix, name, nameX, nameY, ThemeManager.textColor.getColor());


            float statusWidth = 8f;
            float statusHeight = 3f;
            float statusX = statusPanelX + (statusPanelWidth - statusWidth) / 2f;
            float statusY = y + (height - statusHeight) / 2f;

            rectangle.render(ShapeProperties.create(matrix, statusX, statusY, statusWidth, statusHeight)
                    .round(1.5f)
                    .color(statusColor)
                    .build());
        });
    }
}
 
хз делал с нуля за 2 часа мне не понравился ну думаю какимто пастером будет вкусно например какомуто ламчику)))) гпт насрал

SS - Посмотреть вложение 330207


Code -
сарделька:
Expand Collapse Copy
package dev.sk3d.display.hud;

import dev.sk3d.common.animation.implement.Decelerate;
import dev.sk3d.common.animation.implement.Decelerate;
import dev.sk3d.common.animation.implement.EaseOut;
import dev.sk3d.utils.display.render.post.KawaseBlur;
import com.mojang.authlib.GameProfile;
import dev.sk3d.utils.interactions.interact.PlayerInteractionHelper;
import dev.sk3d.utils.theme.ThemeManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.scoreboard.Team;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import dev.sk3d.utils.client.managers.api.draggable.AbstractDraggable;
import dev.sk3d.common.animation.Animation;
import dev.sk3d.common.repository.staff.StaffRepository;
import dev.sk3d.common.animation.Direction;
import dev.sk3d.utils.display.render.font.FontRenderer;
import dev.sk3d.utils.display.render.font.Fonts;
import dev.sk3d.utils.display.render.shape.ShapeProperties;
import dev.sk3d.utils.display.color.ColorAssist;
import dev.sk3d.utils.math.calc.Calculate;
import dev.sk3d.utils.client.Instance;
import dev.sk3d.utils.display.render.geometry.Render2D;
import dev.sk3d.features.impl.render.Hud;
import dev.sk3d.utils.client.packet.network.Network;
import dev.sk3d.features.impl.combat.AntiBot;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.entity.state.LivingEntityRenderState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import java.util.*;
import java.awt.*;
import java.util.List;
import java.util.regex.Pattern;

public class StaffList extends AbstractDraggable {
    public static StaffList getInstance() {
        return Instance.getDraggable(StaffList.class);
    }

    public final Map<PlayerListEntry, Animation> list = new HashMap<>();
    private final Set<String> notifiedPlayers = new HashSet<>();
    private final Set<String> addedViaPrefix = new HashSet<>();
    private final Pattern namePattern = Pattern.compile("^\\w{3,16}$");
    private long lastColorChange = 0;
    private int currentColorIndex = 0;
    private static final Map<String, String> CHAR_TO_NAME = new HashMap<>();
    private static final Map<String, Integer> PREFIX_COLORS = new HashMap<>();

    static {
        CHAR_TO_NAME.put("ꔀ", "player");
        CHAR_TO_NAME.put("ꔄ", "hero");
        CHAR_TO_NAME.put("ꔈ", "titan");
        CHAR_TO_NAME.put("ꔒ", "avenger");
        CHAR_TO_NAME.put("ꔖ", "overlord");
        CHAR_TO_NAME.put("ꔠ", "magister");
        CHAR_TO_NAME.put("ꔤ", "imperator");
        CHAR_TO_NAME.put("ꔨ", "dragon");
        CHAR_TO_NAME.put("ꔲ", "bull");
        CHAR_TO_NAME.put("ꕒ", "rabbit");
        CHAR_TO_NAME.put("ꔶ", "tiger");
        CHAR_TO_NAME.put("ꕄ", "dracula");
        CHAR_TO_NAME.put("ꕖ", "bunny");
        CHAR_TO_NAME.put("ꕀ", "hydra");
        CHAR_TO_NAME.put("ꕈ", "cobra");
        CHAR_TO_NAME.put("ꔁ", "media");
        CHAR_TO_NAME.put("ꔅ", "yt");
        CHAR_TO_NAME.put("ꕠ", "d.helper");
        CHAR_TO_NAME.put("ꔉ", "helper");
        CHAR_TO_NAME.put("ꔓ", "ml.moder");
        CHAR_TO_NAME.put("ꔗ", "moder");
        CHAR_TO_NAME.put("ꔡ", "moder+");
        CHAR_TO_NAME.put("ꔥ", "st.moder");
        CHAR_TO_NAME.put("ꔩ", "gl.moder");
        CHAR_TO_NAME.put("ꔳ", "ml.admin");
        CHAR_TO_NAME.put("ꔷ", "admin");

        PREFIX_COLORS.put("media", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("yt", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("d.helper", new Color(255, 255, 0, 255).getRGB());
        PREFIX_COLORS.put("helper", new Color(255, 255, 0, 255).getRGB());
        PREFIX_COLORS.put("ml.moder", new Color(0, 255, 255, 255).getRGB());
        PREFIX_COLORS.put("moder", new Color(0, 0, 255, 255).getRGB());
        PREFIX_COLORS.put("moder+", new Color(0, 0, 255, 255).getRGB());
        PREFIX_COLORS.put("st.moder", new Color(128, 0, 128, 255).getRGB());
        PREFIX_COLORS.put("gl.moder", new Color(128, 0, 128, 255).getRGB());
        PREFIX_COLORS.put("ml.admin", new Color(0, 255, 255, 255).getRGB());
        PREFIX_COLORS.put("admin", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("Vanish", new Color(255, 0, 0, 255).getRGB());
    }

    public StaffList() {
        super("Staff list", 115, 40, 70, 20, true);
        this.scaleAnimation = new EaseOut().setValue(1).setMs(100);
    }

    private static final List<String> STAFF_KEYWORDS = Arrays.asList("админ", "модер", "moder", "admin", "helper", "хелпер", "стажер", "мл.сотрудник", "ст.сотрудник", "сотрудник");

    private void logDebug(String message) {
        System.out.println("[StaffList] " + message);
    }

    private boolean isNPC(String name) {
        if (name == null) return false;
        String lowerName = name.toLowerCase();
        if (lowerName.equals("anarchy") || lowerName.equals("tokens")) {
            return true;
        }
        return lowerName.contains("npc")
            || lowerName.contains("[znpc]")
            || lowerName.startsWith("cit-")
            || lowerName.startsWith("§")
            || name.contains("NPC")
            || name.contains("[ZNPC]");
    }

    private boolean containsStaffKeyword(String text) {
        if (text == null || text.isEmpty()) {
            return false;
        }
        String lower = text.toLowerCase(Locale.ROOT);
        for (String keyword : STAFF_KEYWORDS) {
            if (lower.contains(keyword)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean visible() {
        return !list.isEmpty() || PlayerInteractionHelper.isChat(mc.currentScreen);
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        if (button == 0) {
            FontRenderer HAWENFont = Fonts.getSize(15, Fonts.Type.HAWEN);
            float pX = getX() + getWidth() - HAWENFont.getStringWidth("p") - 8;
            float pY = getY() + 9.5f;
            float pWidth = HAWENFont.getStringWidth("p");
            float pHeight = HAWENFont.getStringHeight("p");
           
            if (mouseX >= pX && mouseX <= pX + pWidth && mouseY >= pY && mouseY <= pY + pHeight) {
                java.util.List<String> selected = new java.util.ArrayList<>(Hud.getInstance().interfaceSettings.getSelected());
                selected.remove("Staff list");
                Hud.getInstance().interfaceSettings.setSelected(selected);
                return true;
            }
        }
        return super.mouseClicked(mouseX, mouseY, button);
    }

    @Override
    public void tick() {
        if (mc.world == null || mc.player == null || mc.getNetworkHandler() == null) {
            list.clear();
            return;
        }

        Collection<PlayerListEntry> playerList = mc.getNetworkHandler().getPlayerList();
        Scoreboard scoreboard = mc.world.getScoreboard();
        Set<String> addedNames = new HashSet<>();
        Set<String> addedNamesLower = new HashSet<>();

        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - lastColorChange >= 1000) {
                currentColorIndex = (currentColorIndex + 1) % PREFIX_COLORS.size();
                lastColorChange = System.currentTimeMillis();
            }
            return;
        }

        for (PlayerListEntry entry : playerList) {
            String name = entry.getProfile().getName();
            String nameLower = name.toLowerCase();
           
            if (addedNames.contains(name) || addedNamesLower.contains(nameLower) || list.containsKey(entry) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            boolean isNPCName = isNPC(name);
            if (isNPCName) {
                continue;
            }
            String display = entry.getDisplayName() != null ? entry.getDisplayName().getString() : name;
            boolean isNPCDisplay = isNPC(display);
            if (isNPCDisplay) {
                continue;
            }
            if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(entry.getProfile().getId())) {
                continue;
            }
            PlayerEntity playerEntity = mc.world.getPlayerByUuid(entry.getProfile().getId());
            if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                continue;
            }
            Team playerTeam = entry.getScoreboardTeam();
            String teamPrefix = playerTeam != null ? playerTeam.getPrefix().getString() : "";
            boolean hasStaffPrefix = containsStaffKeyword(teamPrefix);
            if (hasStaffPrefix) {
                list.put(entry, new Decelerate().setMs(150).setValue(1));
                addedNames.add(name);
                addedNamesLower.add(nameLower);
                addedViaPrefix.add(name);

                if (Hud.getInstance().notificationSettings.isSelected("Входе админа") && !notifiedPlayers.contains(name)) {
                    Notifications.getInstance().addList(Text.literal(name + " - Зашел на сервер!"), 5000);
                    notifiedPlayers.add(name);
                }
            }
        }

        for (StaffRepository.Staff staff : StaffRepository.getStaff()) {
            String staffName = staff.getName();
            String staffNameLower = staffName.toLowerCase();
           
            if (addedNames.contains(staffName) || addedNamesLower.contains(staffNameLower) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(staffName))) {
                continue;
            }
            playerList.stream()
                    .filter(p -> p.getProfile().getName().equalsIgnoreCase(staffName))
                    .filter(p -> {
                        String name = p.getProfile().getName();
                        if (isNPC(name)) {
                            return false;
                        }
                        if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(p.getProfile().getId())) {
                            return false;
                        }
                        PlayerEntity playerEntity = mc.world.getPlayerByUuid(p.getProfile().getId());
                        boolean isBot = playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity);
                        return playerEntity == null || AntiBot.getInstance() == null || !isBot;
                    })
                    .findFirst()
                    .ifPresent(entry -> {
                        list.put(entry, new Decelerate().setMs(150).setValue(1));
                        addedNames.add(staffName);
                        addedNamesLower.add(staffNameLower);
                    });
        }

        List<Team> teams = new ArrayList<>(scoreboard.getTeams());
        teams.sort(Comparator.comparing(Team::getName));
        Collection<PlayerListEntry> online = mc.getNetworkHandler().getPlayerList();

        for (Team team : teams) {
            Collection<String> members = team.getPlayerList();
            if (members.size() != 1) {
                continue;
            }
            String name = members.iterator().next();
            String nameLower = name.toLowerCase();
           
            if (!namePattern.matcher(name).matches() || addedNames.contains(name) || addedNamesLower.contains(nameLower) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            boolean isNPCName = isNPC(name);
            if (isNPCName) {
                continue;
            }
            PlayerListEntry entry = online.stream()
                    .filter(e -> e.getProfile() != null && name.equals(e.getProfile().getName()))
                    .findFirst()
                    .orElse(null);
            if (entry != null) {
                if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(entry.getProfile().getId())) {
                    continue;
                }
                String display = entry.getDisplayName() != null ? entry.getDisplayName().getString() : name;
                if (isNPC(display)) {
                    continue;
                }
                PlayerEntity playerEntity = mc.world.getPlayerByUuid(entry.getProfile().getId());
                if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                    continue;
                }
                continue;
            }
            UUID generatedUUID = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes());
            if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(generatedUUID)) {
                continue;
            }
            PlayerEntity playerEntity = mc.world.getPlayerByUuid(generatedUUID);
            if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                continue;
            }
           
            if (list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            String teamPrefix = team.getPrefix().getString();
            String prefix = CHAR_TO_NAME.entrySet().stream()
                    .filter(e -> teamPrefix.contains(e.getKey()))
                    .map(Map.Entry::getValue)
                    .findFirst()
                    .orElse("");
            MutableText displayName = Text.empty();
            if (Network.isReallyWorld()) {
                displayName.append(Text.literal(name).formatted(Formatting.GRAY))
                        .append(Text.literal(" [").formatted(Formatting.GRAY))
                        .append(Text.literal(prefix.isEmpty() ? "V" : prefix).formatted(Formatting.RESET))
                        .append(Text.literal("]").formatted(Formatting.GRAY));
            } else {
                displayName.append(Text.literal("[").formatted(Formatting.GRAY))
                        .append(Text.literal(prefix.isEmpty() ? "V" : prefix).formatted(Formatting.RESET))
                        .append(Text.literal("] ").formatted(Formatting.GRAY))
                        .append(Text.literal(name).formatted(Formatting.GRAY));
            }
            GameProfile fakeProfile = new GameProfile(UUID.randomUUID(), name);
            PlayerListEntry fake = new PlayerListEntry(fakeProfile, mc.isInSingleplayer());
            fake.setDisplayName(displayName);
            fake.setListOrder(Integer.MIN_VALUE);
            list.put(fake, new Decelerate().setMs(150).setValue(1));
            addedNames.add(name);
            addedNamesLower.add(nameLower);

            if (Hud.getInstance().notificationSettings.isSelected("Входе админа") && !notifiedPlayers.contains(name)) {
                Notifications.getInstance().addList(Text.literal(name + " - Зашел на сервер!"), 5000);
                notifiedPlayers.add(name);
            }
        }

        list.entrySet().removeIf(entry -> {
            String name = entry.getKey().getProfile().getName();
            boolean isFromRepo = StaffRepository.isStaff(name);
            boolean isFromPrefix = addedViaPrefix.contains(name);
            boolean inPlayerList = playerList.stream().anyMatch(p -> p.getProfile().getName().equals(name));
            boolean inTeam = scoreboard.getTeams().stream().flatMap(t -> t.getPlayerList().stream()).anyMatch(name::equals);

            boolean stillHasStaffPrefix = false;
            if (isFromPrefix && inPlayerList) {
                PlayerListEntry currentEntry = playerList.stream()
                        .filter(p -> p.getProfile().getName().equals(name))
                        .findFirst().orElse(null);
                if (currentEntry != null) {
                    String display = currentEntry.getDisplayName() != null ? currentEntry.getDisplayName().getString() : name;
                    Team playerTeam = currentEntry.getScoreboardTeam();
                    stillHasStaffPrefix = containsStaffKeyword(display) || (playerTeam != null && containsStaffKeyword(playerTeam.getPrefix().getString()));
                }
            }
           
            boolean shouldRemove = false;
            if (isFromRepo) {
                if (!inPlayerList) {
                    shouldRemove = true;
                }
            } else if (isFromPrefix) {
                if (!inPlayerList || !stillHasStaffPrefix) {
                    shouldRemove = true;
                }
            } else {
                if (inPlayerList || !inTeam) {
                    shouldRemove = true;
                }
            }
           
            if (shouldRemove) {
         
                entry.getValue().setDirection(Direction.BACKWARDS);
            }
            if (entry.getValue().isFinished(Direction.BACKWARDS)) {
           
                notifiedPlayers.remove(name);
                addedViaPrefix.remove(name);
                if (!inPlayerList && Hud.getInstance().notificationSettings.isSelected("Выходе админа")) {
                    Notifications.getInstance().addList(Text.literal(name + " - Вышел с сервера!"), 5000);
                }
                return true;
            }
            return false;
        });
    }

    @Override
    public void drawDraggable(DrawContext context) {
        MatrixStack matrix = context.getMatrices();
        FontRenderer fontTitle = Fonts.getSize(16, Fonts.Type.BOLD);
        FontRenderer fontPrefix = Fonts.getSize(14, Fonts.Type.BOLD);
        FontRenderer fontName = Fonts.getSize(13, Fonts.Type.SEMI);

        long activeStaff = list.entrySet().stream().filter(e -> !e.getValue().isFinished(Direction.BACKWARDS)).count();

        float panelWidth = 140f;
        float titleHeight = 24f;
        float playerHeight = 18f;
        float spacing = -4f;
        float titleSpacing = -2f;
        float statusPanelWidth = 18f;
        float mainPanelWidth = panelWidth - statusPanelWidth - 13f;
        float totalHeight = titleHeight + titleSpacing + 8f;

        if (!list.isEmpty() || PlayerInteractionHelper.isChat(mc.currentScreen)) {
            int visibleCount = list.isEmpty() ? 3 : (int) activeStaff;
            totalHeight += visibleCount * (playerHeight + spacing);
        }


        if (Hud.blur.isValue()) {
            Render2D.rectangleWithMask(matrix.peek().getPositionMatrix(), getX(), getY(), panelWidth, totalHeight, 8f, 0,
                    KawaseBlur.INSTANCE.fbos.getFirst().getColorAttachment());
        }

        rectangle.render(ShapeProperties.create(matrix, getX(), getY(), panelWidth, totalHeight)
                .round(8f)
                .color(ThemeManager.BackgroundGui.getColor())
                .build());


        rectangle.render(ShapeProperties.create(matrix, getX() + 5, getY() + 5, panelWidth - 10, titleHeight - 10)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());


        fontTitle.drawString(matrix, "Staff", getX() + 12f, getY() + 10f, ThemeManager.textColor.getColor());


        Fonts.getSize(20, Fonts.Type.KEFIREBAL).drawString(matrix, "F", getX() + panelWidth - 19f, getY() + 9f, ThemeManager.textColor.getColor());

        float currentY = getY() + titleHeight + titleSpacing;
        Collection<PlayerListEntry> playerList = mc.player != null && mc.player.networkHandler != null ?
                mc.player.networkHandler.getPlayerList() : new ArrayList<>();


        float contentHeight = 0;
        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            contentHeight = 3 * (playerHeight + spacing) - spacing;
        } else {
            for (Map.Entry<PlayerListEntry, Animation> staff : list.entrySet()) {
                float animation = staff.getValue().getOutput().floatValue();
                if (animation > 0.01f) {
                    contentHeight += (playerHeight + spacing) * animation;
                }
            }
            contentHeight -= spacing;
        }


        rectangle.render(ShapeProperties.create(matrix, getX() + 5, currentY, mainPanelWidth, contentHeight)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());


        float statusPanelX = getX() + 5 + mainPanelWidth + 3f;
        rectangle.render(ShapeProperties.create(matrix, statusPanelX, currentY, statusPanelWidth, contentHeight)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());

        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            String[] exampleNames = {"kefir", "winda", "greufs"};
            String[] examplePrefixes = {"CODER", "CODER", "DEV"};
            int[] exampleColors = {
                new Color(255, 3, 3, 255).getRGB(),
                new Color(85, 255, 85, 255).getRGB(),
                new Color(255, 170, 85, 255).getRGB()
            };

            for (int i = 0; i < 3; i++) {
                drawPlayerContent(matrix, context, getX() + 5, statusPanelX, currentY, mainPanelWidth, statusPanelWidth, playerHeight,
                        exampleNames[i], examplePrefixes[i], exampleColors[i], 1.0f, fontPrefix, fontName);
                currentY += playerHeight + spacing;
            }
        } else {
            for (Map.Entry<PlayerListEntry, Animation> staff : list.entrySet()) {
                PlayerListEntry player = staff.getKey();
                if (player == null) continue;

                String name = player.getProfile().getName();
                float animation = staff.getValue().getOutput().floatValue();

                if (animation > 0.01f) {
                    boolean isVisible = playerList.stream().anyMatch(p -> p.getProfile().getName().equals(name));
                    PlayerListEntry renderEntry = isVisible ?
                            playerList.stream().filter(p -> p.getProfile().getName().equals(name)).findFirst().orElse(player) :
                            player;

                    String displayName = renderEntry.getDisplayName() != null ? renderEntry.getDisplayName().getString() : name;
                    String prefix = CHAR_TO_NAME.entrySet().stream()
                            .filter(e -> displayName.contains(e.getKey()))
                            .map(Map.Entry::getValue)
                            .findFirst()
                            .orElse("Vanish");

                    int statusColor = PREFIX_COLORS.getOrDefault(prefix, new Color(255, 0, 0, 255).getRGB());

                    drawPlayerContent(matrix, context, getX() + 5, statusPanelX, currentY, mainPanelWidth, statusPanelWidth, playerHeight,
                            name, prefix.toUpperCase(), statusColor, animation, fontPrefix, fontName);

                    currentY += (playerHeight + spacing) * animation;
                }
            }
        }

        setWidth((int) panelWidth);
        setHeight((int) totalHeight);
    }
   
    private void drawPlayerContent(MatrixStack matrix, DrawContext context, float mainPanelX, float statusPanelX, float y,
                                  float mainPanelWidth, float statusPanelWidth, float height,
                                  String name, String prefixText, int statusColor, float animation,
                                  FontRenderer fontPrefix, FontRenderer fontName) {
        float centerX = mainPanelX + mainPanelWidth / 2f;
        float centerY = y + height / 2f;

        Calculate.scale(matrix, centerX, centerY, animation, animation, () -> {
            float headPanelWidth = 18f;


            float headSize = 10f;
            float headX = mainPanelX + 3f;
            float headY = y + (height - headSize) / 2f;
           
            if (mc.player != null) {
                Identifier skinTexture = mc.player.getSkinTextures().texture();
                Render2D.drawTexture(context, skinTexture, headX, headY, headSize, 4f, 8, 8, 64, -1, -1);
            }
           

            FontRenderer arrowFont = Fonts.getSize(16, Fonts.Type.HAWEN);
            float arrowX = headX + headSize + 3f;
            float arrowY = y + height - 11f;
            arrowFont.drawString(matrix, "»", arrowX, arrowY, new Color(253, 248, 248, 255).getRGB());


            float textStartX = arrowX + arrowFont.getStringWidth("»") + 3f;
            float prefixY = y + height - 11f;
            fontPrefix.drawString(matrix, prefixText, textStartX, prefixY, statusColor);


            float nameX = textStartX + fontPrefix.getStringWidth(prefixText) + 3f;
            float nameY = y + height - 11f;
            fontName.drawString(matrix, name, nameX, nameY, ThemeManager.textColor.getColor());


            float statusWidth = 8f;
            float statusHeight = 3f;
            float statusX = statusPanelX + (statusPanelWidth - statusWidth) / 2f;
            float statusY = y + (height - statusHeight) / 2f;

            rectangle.render(ShapeProperties.create(matrix, statusX, statusY, statusWidth, statusHeight)
                    .round(1.5f)
                    .color(statusColor)
                    .build());
        });
    }
}
ну 50/50
 
хз делал с нуля за 2 часа мне не понравился ну думаю какимто пастером будет вкусно например какомуто ламчику)))) гпт насрал

SS - Посмотреть вложение 330207


Code -
сарделька:
Expand Collapse Copy
package dev.sk3d.display.hud;

import dev.sk3d.common.animation.implement.Decelerate;
import dev.sk3d.common.animation.implement.Decelerate;
import dev.sk3d.common.animation.implement.EaseOut;
import dev.sk3d.utils.display.render.post.KawaseBlur;
import com.mojang.authlib.GameProfile;
import dev.sk3d.utils.interactions.interact.PlayerInteractionHelper;
import dev.sk3d.utils.theme.ThemeManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.scoreboard.Team;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import dev.sk3d.utils.client.managers.api.draggable.AbstractDraggable;
import dev.sk3d.common.animation.Animation;
import dev.sk3d.common.repository.staff.StaffRepository;
import dev.sk3d.common.animation.Direction;
import dev.sk3d.utils.display.render.font.FontRenderer;
import dev.sk3d.utils.display.render.font.Fonts;
import dev.sk3d.utils.display.render.shape.ShapeProperties;
import dev.sk3d.utils.display.color.ColorAssist;
import dev.sk3d.utils.math.calc.Calculate;
import dev.sk3d.utils.client.Instance;
import dev.sk3d.utils.display.render.geometry.Render2D;
import dev.sk3d.features.impl.render.Hud;
import dev.sk3d.utils.client.packet.network.Network;
import dev.sk3d.features.impl.combat.AntiBot;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.entity.state.LivingEntityRenderState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import java.util.*;
import java.awt.*;
import java.util.List;
import java.util.regex.Pattern;

public class StaffList extends AbstractDraggable {
    public static StaffList getInstance() {
        return Instance.getDraggable(StaffList.class);
    }

    public final Map<PlayerListEntry, Animation> list = new HashMap<>();
    private final Set<String> notifiedPlayers = new HashSet<>();
    private final Set<String> addedViaPrefix = new HashSet<>();
    private final Pattern namePattern = Pattern.compile("^\\w{3,16}$");
    private long lastColorChange = 0;
    private int currentColorIndex = 0;
    private static final Map<String, String> CHAR_TO_NAME = new HashMap<>();
    private static final Map<String, Integer> PREFIX_COLORS = new HashMap<>();

    static {
        CHAR_TO_NAME.put("ꔀ", "player");
        CHAR_TO_NAME.put("ꔄ", "hero");
        CHAR_TO_NAME.put("ꔈ", "titan");
        CHAR_TO_NAME.put("ꔒ", "avenger");
        CHAR_TO_NAME.put("ꔖ", "overlord");
        CHAR_TO_NAME.put("ꔠ", "magister");
        CHAR_TO_NAME.put("ꔤ", "imperator");
        CHAR_TO_NAME.put("ꔨ", "dragon");
        CHAR_TO_NAME.put("ꔲ", "bull");
        CHAR_TO_NAME.put("ꕒ", "rabbit");
        CHAR_TO_NAME.put("ꔶ", "tiger");
        CHAR_TO_NAME.put("ꕄ", "dracula");
        CHAR_TO_NAME.put("ꕖ", "bunny");
        CHAR_TO_NAME.put("ꕀ", "hydra");
        CHAR_TO_NAME.put("ꕈ", "cobra");
        CHAR_TO_NAME.put("ꔁ", "media");
        CHAR_TO_NAME.put("ꔅ", "yt");
        CHAR_TO_NAME.put("ꕠ", "d.helper");
        CHAR_TO_NAME.put("ꔉ", "helper");
        CHAR_TO_NAME.put("ꔓ", "ml.moder");
        CHAR_TO_NAME.put("ꔗ", "moder");
        CHAR_TO_NAME.put("ꔡ", "moder+");
        CHAR_TO_NAME.put("ꔥ", "st.moder");
        CHAR_TO_NAME.put("ꔩ", "gl.moder");
        CHAR_TO_NAME.put("ꔳ", "ml.admin");
        CHAR_TO_NAME.put("ꔷ", "admin");

        PREFIX_COLORS.put("media", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("yt", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("d.helper", new Color(255, 255, 0, 255).getRGB());
        PREFIX_COLORS.put("helper", new Color(255, 255, 0, 255).getRGB());
        PREFIX_COLORS.put("ml.moder", new Color(0, 255, 255, 255).getRGB());
        PREFIX_COLORS.put("moder", new Color(0, 0, 255, 255).getRGB());
        PREFIX_COLORS.put("moder+", new Color(0, 0, 255, 255).getRGB());
        PREFIX_COLORS.put("st.moder", new Color(128, 0, 128, 255).getRGB());
        PREFIX_COLORS.put("gl.moder", new Color(128, 0, 128, 255).getRGB());
        PREFIX_COLORS.put("ml.admin", new Color(0, 255, 255, 255).getRGB());
        PREFIX_COLORS.put("admin", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("Vanish", new Color(255, 0, 0, 255).getRGB());
    }

    public StaffList() {
        super("Staff list", 115, 40, 70, 20, true);
        this.scaleAnimation = new EaseOut().setValue(1).setMs(100);
    }

    private static final List<String> STAFF_KEYWORDS = Arrays.asList("админ", "модер", "moder", "admin", "helper", "хелпер", "стажер", "мл.сотрудник", "ст.сотрудник", "сотрудник");

    private void logDebug(String message) {
        System.out.println("[StaffList] " + message);
    }

    private boolean isNPC(String name) {
        if (name == null) return false;
        String lowerName = name.toLowerCase();
        if (lowerName.equals("anarchy") || lowerName.equals("tokens")) {
            return true;
        }
        return lowerName.contains("npc")
            || lowerName.contains("[znpc]")
            || lowerName.startsWith("cit-")
            || lowerName.startsWith("§")
            || name.contains("NPC")
            || name.contains("[ZNPC]");
    }

    private boolean containsStaffKeyword(String text) {
        if (text == null || text.isEmpty()) {
            return false;
        }
        String lower = text.toLowerCase(Locale.ROOT);
        for (String keyword : STAFF_KEYWORDS) {
            if (lower.contains(keyword)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean visible() {
        return !list.isEmpty() || PlayerInteractionHelper.isChat(mc.currentScreen);
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        if (button == 0) {
            FontRenderer HAWENFont = Fonts.getSize(15, Fonts.Type.HAWEN);
            float pX = getX() + getWidth() - HAWENFont.getStringWidth("p") - 8;
            float pY = getY() + 9.5f;
            float pWidth = HAWENFont.getStringWidth("p");
            float pHeight = HAWENFont.getStringHeight("p");
           
            if (mouseX >= pX && mouseX <= pX + pWidth && mouseY >= pY && mouseY <= pY + pHeight) {
                java.util.List<String> selected = new java.util.ArrayList<>(Hud.getInstance().interfaceSettings.getSelected());
                selected.remove("Staff list");
                Hud.getInstance().interfaceSettings.setSelected(selected);
                return true;
            }
        }
        return super.mouseClicked(mouseX, mouseY, button);
    }

    @Override
    public void tick() {
        if (mc.world == null || mc.player == null || mc.getNetworkHandler() == null) {
            list.clear();
            return;
        }

        Collection<PlayerListEntry> playerList = mc.getNetworkHandler().getPlayerList();
        Scoreboard scoreboard = mc.world.getScoreboard();
        Set<String> addedNames = new HashSet<>();
        Set<String> addedNamesLower = new HashSet<>();

        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - lastColorChange >= 1000) {
                currentColorIndex = (currentColorIndex + 1) % PREFIX_COLORS.size();
                lastColorChange = System.currentTimeMillis();
            }
            return;
        }

        for (PlayerListEntry entry : playerList) {
            String name = entry.getProfile().getName();
            String nameLower = name.toLowerCase();
           
            if (addedNames.contains(name) || addedNamesLower.contains(nameLower) || list.containsKey(entry) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            boolean isNPCName = isNPC(name);
            if (isNPCName) {
                continue;
            }
            String display = entry.getDisplayName() != null ? entry.getDisplayName().getString() : name;
            boolean isNPCDisplay = isNPC(display);
            if (isNPCDisplay) {
                continue;
            }
            if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(entry.getProfile().getId())) {
                continue;
            }
            PlayerEntity playerEntity = mc.world.getPlayerByUuid(entry.getProfile().getId());
            if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                continue;
            }
            Team playerTeam = entry.getScoreboardTeam();
            String teamPrefix = playerTeam != null ? playerTeam.getPrefix().getString() : "";
            boolean hasStaffPrefix = containsStaffKeyword(teamPrefix);
            if (hasStaffPrefix) {
                list.put(entry, new Decelerate().setMs(150).setValue(1));
                addedNames.add(name);
                addedNamesLower.add(nameLower);
                addedViaPrefix.add(name);

                if (Hud.getInstance().notificationSettings.isSelected("Входе админа") && !notifiedPlayers.contains(name)) {
                    Notifications.getInstance().addList(Text.literal(name + " - Зашел на сервер!"), 5000);
                    notifiedPlayers.add(name);
                }
            }
        }

        for (StaffRepository.Staff staff : StaffRepository.getStaff()) {
            String staffName = staff.getName();
            String staffNameLower = staffName.toLowerCase();
           
            if (addedNames.contains(staffName) || addedNamesLower.contains(staffNameLower) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(staffName))) {
                continue;
            }
            playerList.stream()
                    .filter(p -> p.getProfile().getName().equalsIgnoreCase(staffName))
                    .filter(p -> {
                        String name = p.getProfile().getName();
                        if (isNPC(name)) {
                            return false;
                        }
                        if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(p.getProfile().getId())) {
                            return false;
                        }
                        PlayerEntity playerEntity = mc.world.getPlayerByUuid(p.getProfile().getId());
                        boolean isBot = playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity);
                        return playerEntity == null || AntiBot.getInstance() == null || !isBot;
                    })
                    .findFirst()
                    .ifPresent(entry -> {
                        list.put(entry, new Decelerate().setMs(150).setValue(1));
                        addedNames.add(staffName);
                        addedNamesLower.add(staffNameLower);
                    });
        }

        List<Team> teams = new ArrayList<>(scoreboard.getTeams());
        teams.sort(Comparator.comparing(Team::getName));
        Collection<PlayerListEntry> online = mc.getNetworkHandler().getPlayerList();

        for (Team team : teams) {
            Collection<String> members = team.getPlayerList();
            if (members.size() != 1) {
                continue;
            }
            String name = members.iterator().next();
            String nameLower = name.toLowerCase();
           
            if (!namePattern.matcher(name).matches() || addedNames.contains(name) || addedNamesLower.contains(nameLower) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            boolean isNPCName = isNPC(name);
            if (isNPCName) {
                continue;
            }
            PlayerListEntry entry = online.stream()
                    .filter(e -> e.getProfile() != null && name.equals(e.getProfile().getName()))
                    .findFirst()
                    .orElse(null);
            if (entry != null) {
                if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(entry.getProfile().getId())) {
                    continue;
                }
                String display = entry.getDisplayName() != null ? entry.getDisplayName().getString() : name;
                if (isNPC(display)) {
                    continue;
                }
                PlayerEntity playerEntity = mc.world.getPlayerByUuid(entry.getProfile().getId());
                if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                    continue;
                }
                continue;
            }
            UUID generatedUUID = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes());
            if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(generatedUUID)) {
                continue;
            }
            PlayerEntity playerEntity = mc.world.getPlayerByUuid(generatedUUID);
            if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                continue;
            }
           
            if (list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            String teamPrefix = team.getPrefix().getString();
            String prefix = CHAR_TO_NAME.entrySet().stream()
                    .filter(e -> teamPrefix.contains(e.getKey()))
                    .map(Map.Entry::getValue)
                    .findFirst()
                    .orElse("");
            MutableText displayName = Text.empty();
            if (Network.isReallyWorld()) {
                displayName.append(Text.literal(name).formatted(Formatting.GRAY))
                        .append(Text.literal(" [").formatted(Formatting.GRAY))
                        .append(Text.literal(prefix.isEmpty() ? "V" : prefix).formatted(Formatting.RESET))
                        .append(Text.literal("]").formatted(Formatting.GRAY));
            } else {
                displayName.append(Text.literal("[").formatted(Formatting.GRAY))
                        .append(Text.literal(prefix.isEmpty() ? "V" : prefix).formatted(Formatting.RESET))
                        .append(Text.literal("] ").formatted(Formatting.GRAY))
                        .append(Text.literal(name).formatted(Formatting.GRAY));
            }
            GameProfile fakeProfile = new GameProfile(UUID.randomUUID(), name);
            PlayerListEntry fake = new PlayerListEntry(fakeProfile, mc.isInSingleplayer());
            fake.setDisplayName(displayName);
            fake.setListOrder(Integer.MIN_VALUE);
            list.put(fake, new Decelerate().setMs(150).setValue(1));
            addedNames.add(name);
            addedNamesLower.add(nameLower);

            if (Hud.getInstance().notificationSettings.isSelected("Входе админа") && !notifiedPlayers.contains(name)) {
                Notifications.getInstance().addList(Text.literal(name + " - Зашел на сервер!"), 5000);
                notifiedPlayers.add(name);
            }
        }

        list.entrySet().removeIf(entry -> {
            String name = entry.getKey().getProfile().getName();
            boolean isFromRepo = StaffRepository.isStaff(name);
            boolean isFromPrefix = addedViaPrefix.contains(name);
            boolean inPlayerList = playerList.stream().anyMatch(p -> p.getProfile().getName().equals(name));
            boolean inTeam = scoreboard.getTeams().stream().flatMap(t -> t.getPlayerList().stream()).anyMatch(name::equals);

            boolean stillHasStaffPrefix = false;
            if (isFromPrefix && inPlayerList) {
                PlayerListEntry currentEntry = playerList.stream()
                        .filter(p -> p.getProfile().getName().equals(name))
                        .findFirst().orElse(null);
                if (currentEntry != null) {
                    String display = currentEntry.getDisplayName() != null ? currentEntry.getDisplayName().getString() : name;
                    Team playerTeam = currentEntry.getScoreboardTeam();
                    stillHasStaffPrefix = containsStaffKeyword(display) || (playerTeam != null && containsStaffKeyword(playerTeam.getPrefix().getString()));
                }
            }
           
            boolean shouldRemove = false;
            if (isFromRepo) {
                if (!inPlayerList) {
                    shouldRemove = true;
                }
            } else if (isFromPrefix) {
                if (!inPlayerList || !stillHasStaffPrefix) {
                    shouldRemove = true;
                }
            } else {
                if (inPlayerList || !inTeam) {
                    shouldRemove = true;
                }
            }
           
            if (shouldRemove) {
         
                entry.getValue().setDirection(Direction.BACKWARDS);
            }
            if (entry.getValue().isFinished(Direction.BACKWARDS)) {
           
                notifiedPlayers.remove(name);
                addedViaPrefix.remove(name);
                if (!inPlayerList && Hud.getInstance().notificationSettings.isSelected("Выходе админа")) {
                    Notifications.getInstance().addList(Text.literal(name + " - Вышел с сервера!"), 5000);
                }
                return true;
            }
            return false;
        });
    }

    @Override
    public void drawDraggable(DrawContext context) {
        MatrixStack matrix = context.getMatrices();
        FontRenderer fontTitle = Fonts.getSize(16, Fonts.Type.BOLD);
        FontRenderer fontPrefix = Fonts.getSize(14, Fonts.Type.BOLD);
        FontRenderer fontName = Fonts.getSize(13, Fonts.Type.SEMI);

        long activeStaff = list.entrySet().stream().filter(e -> !e.getValue().isFinished(Direction.BACKWARDS)).count();

        float panelWidth = 140f;
        float titleHeight = 24f;
        float playerHeight = 18f;
        float spacing = -4f;
        float titleSpacing = -2f;
        float statusPanelWidth = 18f;
        float mainPanelWidth = panelWidth - statusPanelWidth - 13f;
        float totalHeight = titleHeight + titleSpacing + 8f;

        if (!list.isEmpty() || PlayerInteractionHelper.isChat(mc.currentScreen)) {
            int visibleCount = list.isEmpty() ? 3 : (int) activeStaff;
            totalHeight += visibleCount * (playerHeight + spacing);
        }


        if (Hud.blur.isValue()) {
            Render2D.rectangleWithMask(matrix.peek().getPositionMatrix(), getX(), getY(), panelWidth, totalHeight, 8f, 0,
                    KawaseBlur.INSTANCE.fbos.getFirst().getColorAttachment());
        }

        rectangle.render(ShapeProperties.create(matrix, getX(), getY(), panelWidth, totalHeight)
                .round(8f)
                .color(ThemeManager.BackgroundGui.getColor())
                .build());


        rectangle.render(ShapeProperties.create(matrix, getX() + 5, getY() + 5, panelWidth - 10, titleHeight - 10)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());


        fontTitle.drawString(matrix, "Staff", getX() + 12f, getY() + 10f, ThemeManager.textColor.getColor());


        Fonts.getSize(20, Fonts.Type.KEFIREBAL).drawString(matrix, "F", getX() + panelWidth - 19f, getY() + 9f, ThemeManager.textColor.getColor());

        float currentY = getY() + titleHeight + titleSpacing;
        Collection<PlayerListEntry> playerList = mc.player != null && mc.player.networkHandler != null ?
                mc.player.networkHandler.getPlayerList() : new ArrayList<>();


        float contentHeight = 0;
        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            contentHeight = 3 * (playerHeight + spacing) - spacing;
        } else {
            for (Map.Entry<PlayerListEntry, Animation> staff : list.entrySet()) {
                float animation = staff.getValue().getOutput().floatValue();
                if (animation > 0.01f) {
                    contentHeight += (playerHeight + spacing) * animation;
                }
            }
            contentHeight -= spacing;
        }


        rectangle.render(ShapeProperties.create(matrix, getX() + 5, currentY, mainPanelWidth, contentHeight)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());


        float statusPanelX = getX() + 5 + mainPanelWidth + 3f;
        rectangle.render(ShapeProperties.create(matrix, statusPanelX, currentY, statusPanelWidth, contentHeight)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());

        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            String[] exampleNames = {"kefir", "winda", "greufs"};
            String[] examplePrefixes = {"CODER", "CODER", "DEV"};
            int[] exampleColors = {
                new Color(255, 3, 3, 255).getRGB(),
                new Color(85, 255, 85, 255).getRGB(),
                new Color(255, 170, 85, 255).getRGB()
            };

            for (int i = 0; i < 3; i++) {
                drawPlayerContent(matrix, context, getX() + 5, statusPanelX, currentY, mainPanelWidth, statusPanelWidth, playerHeight,
                        exampleNames[i], examplePrefixes[i], exampleColors[i], 1.0f, fontPrefix, fontName);
                currentY += playerHeight + spacing;
            }
        } else {
            for (Map.Entry<PlayerListEntry, Animation> staff : list.entrySet()) {
                PlayerListEntry player = staff.getKey();
                if (player == null) continue;

                String name = player.getProfile().getName();
                float animation = staff.getValue().getOutput().floatValue();

                if (animation > 0.01f) {
                    boolean isVisible = playerList.stream().anyMatch(p -> p.getProfile().getName().equals(name));
                    PlayerListEntry renderEntry = isVisible ?
                            playerList.stream().filter(p -> p.getProfile().getName().equals(name)).findFirst().orElse(player) :
                            player;

                    String displayName = renderEntry.getDisplayName() != null ? renderEntry.getDisplayName().getString() : name;
                    String prefix = CHAR_TO_NAME.entrySet().stream()
                            .filter(e -> displayName.contains(e.getKey()))
                            .map(Map.Entry::getValue)
                            .findFirst()
                            .orElse("Vanish");

                    int statusColor = PREFIX_COLORS.getOrDefault(prefix, new Color(255, 0, 0, 255).getRGB());

                    drawPlayerContent(matrix, context, getX() + 5, statusPanelX, currentY, mainPanelWidth, statusPanelWidth, playerHeight,
                            name, prefix.toUpperCase(), statusColor, animation, fontPrefix, fontName);

                    currentY += (playerHeight + spacing) * animation;
                }
            }
        }

        setWidth((int) panelWidth);
        setHeight((int) totalHeight);
    }
   
    private void drawPlayerContent(MatrixStack matrix, DrawContext context, float mainPanelX, float statusPanelX, float y,
                                  float mainPanelWidth, float statusPanelWidth, float height,
                                  String name, String prefixText, int statusColor, float animation,
                                  FontRenderer fontPrefix, FontRenderer fontName) {
        float centerX = mainPanelX + mainPanelWidth / 2f;
        float centerY = y + height / 2f;

        Calculate.scale(matrix, centerX, centerY, animation, animation, () -> {
            float headPanelWidth = 18f;


            float headSize = 10f;
            float headX = mainPanelX + 3f;
            float headY = y + (height - headSize) / 2f;
           
            if (mc.player != null) {
                Identifier skinTexture = mc.player.getSkinTextures().texture();
                Render2D.drawTexture(context, skinTexture, headX, headY, headSize, 4f, 8, 8, 64, -1, -1);
            }
           

            FontRenderer arrowFont = Fonts.getSize(16, Fonts.Type.HAWEN);
            float arrowX = headX + headSize + 3f;
            float arrowY = y + height - 11f;
            arrowFont.drawString(matrix, "»", arrowX, arrowY, new Color(253, 248, 248, 255).getRGB());


            float textStartX = arrowX + arrowFont.getStringWidth("»") + 3f;
            float prefixY = y + height - 11f;
            fontPrefix.drawString(matrix, prefixText, textStartX, prefixY, statusColor);


            float nameX = textStartX + fontPrefix.getStringWidth(prefixText) + 3f;
            float nameY = y + height - 11f;
            fontName.drawString(matrix, name, nameX, nameY, ThemeManager.textColor.getColor());


            float statusWidth = 8f;
            float statusHeight = 3f;
            float statusX = statusPanelX + (statusPanelWidth - statusWidth) / 2f;
            float statusY = y + (height - statusHeight) / 2f;

            rectangle.render(ShapeProperties.create(matrix, statusX, statusY, statusWidth, statusHeight)
                    .round(1.5f)
                    .color(statusColor)
                    .build());
        });
    }
}
база?
 
хз делал с нуля за 2 часа мне не понравился ну думаю какимто пастером будет вкусно например какомуто ламчику)))) гпт насрал

SS - Посмотреть вложение 330207


Code -
сарделька:
Expand Collapse Copy
package dev.sk3d.display.hud;

import dev.sk3d.common.animation.implement.Decelerate;
import dev.sk3d.common.animation.implement.Decelerate;
import dev.sk3d.common.animation.implement.EaseOut;
import dev.sk3d.utils.display.render.post.KawaseBlur;
import com.mojang.authlib.GameProfile;
import dev.sk3d.utils.interactions.interact.PlayerInteractionHelper;
import dev.sk3d.utils.theme.ThemeManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.scoreboard.Team;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import dev.sk3d.utils.client.managers.api.draggable.AbstractDraggable;
import dev.sk3d.common.animation.Animation;
import dev.sk3d.common.repository.staff.StaffRepository;
import dev.sk3d.common.animation.Direction;
import dev.sk3d.utils.display.render.font.FontRenderer;
import dev.sk3d.utils.display.render.font.Fonts;
import dev.sk3d.utils.display.render.shape.ShapeProperties;
import dev.sk3d.utils.display.color.ColorAssist;
import dev.sk3d.utils.math.calc.Calculate;
import dev.sk3d.utils.client.Instance;
import dev.sk3d.utils.display.render.geometry.Render2D;
import dev.sk3d.features.impl.render.Hud;
import dev.sk3d.utils.client.packet.network.Network;
import dev.sk3d.features.impl.combat.AntiBot;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.entity.state.LivingEntityRenderState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import java.util.*;
import java.awt.*;
import java.util.List;
import java.util.regex.Pattern;

public class StaffList extends AbstractDraggable {
    public static StaffList getInstance() {
        return Instance.getDraggable(StaffList.class);
    }

    public final Map<PlayerListEntry, Animation> list = new HashMap<>();
    private final Set<String> notifiedPlayers = new HashSet<>();
    private final Set<String> addedViaPrefix = new HashSet<>();
    private final Pattern namePattern = Pattern.compile("^\\w{3,16}$");
    private long lastColorChange = 0;
    private int currentColorIndex = 0;
    private static final Map<String, String> CHAR_TO_NAME = new HashMap<>();
    private static final Map<String, Integer> PREFIX_COLORS = new HashMap<>();

    static {
        CHAR_TO_NAME.put("ꔀ", "player");
        CHAR_TO_NAME.put("ꔄ", "hero");
        CHAR_TO_NAME.put("ꔈ", "titan");
        CHAR_TO_NAME.put("ꔒ", "avenger");
        CHAR_TO_NAME.put("ꔖ", "overlord");
        CHAR_TO_NAME.put("ꔠ", "magister");
        CHAR_TO_NAME.put("ꔤ", "imperator");
        CHAR_TO_NAME.put("ꔨ", "dragon");
        CHAR_TO_NAME.put("ꔲ", "bull");
        CHAR_TO_NAME.put("ꕒ", "rabbit");
        CHAR_TO_NAME.put("ꔶ", "tiger");
        CHAR_TO_NAME.put("ꕄ", "dracula");
        CHAR_TO_NAME.put("ꕖ", "bunny");
        CHAR_TO_NAME.put("ꕀ", "hydra");
        CHAR_TO_NAME.put("ꕈ", "cobra");
        CHAR_TO_NAME.put("ꔁ", "media");
        CHAR_TO_NAME.put("ꔅ", "yt");
        CHAR_TO_NAME.put("ꕠ", "d.helper");
        CHAR_TO_NAME.put("ꔉ", "helper");
        CHAR_TO_NAME.put("ꔓ", "ml.moder");
        CHAR_TO_NAME.put("ꔗ", "moder");
        CHAR_TO_NAME.put("ꔡ", "moder+");
        CHAR_TO_NAME.put("ꔥ", "st.moder");
        CHAR_TO_NAME.put("ꔩ", "gl.moder");
        CHAR_TO_NAME.put("ꔳ", "ml.admin");
        CHAR_TO_NAME.put("ꔷ", "admin");

        PREFIX_COLORS.put("media", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("yt", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("d.helper", new Color(255, 255, 0, 255).getRGB());
        PREFIX_COLORS.put("helper", new Color(255, 255, 0, 255).getRGB());
        PREFIX_COLORS.put("ml.moder", new Color(0, 255, 255, 255).getRGB());
        PREFIX_COLORS.put("moder", new Color(0, 0, 255, 255).getRGB());
        PREFIX_COLORS.put("moder+", new Color(0, 0, 255, 255).getRGB());
        PREFIX_COLORS.put("st.moder", new Color(128, 0, 128, 255).getRGB());
        PREFIX_COLORS.put("gl.moder", new Color(128, 0, 128, 255).getRGB());
        PREFIX_COLORS.put("ml.admin", new Color(0, 255, 255, 255).getRGB());
        PREFIX_COLORS.put("admin", new Color(255, 0, 0, 255).getRGB());
        PREFIX_COLORS.put("Vanish", new Color(255, 0, 0, 255).getRGB());
    }

    public StaffList() {
        super("Staff list", 115, 40, 70, 20, true);
        this.scaleAnimation = new EaseOut().setValue(1).setMs(100);
    }

    private static final List<String> STAFF_KEYWORDS = Arrays.asList("админ", "модер", "moder", "admin", "helper", "хелпер", "стажер", "мл.сотрудник", "ст.сотрудник", "сотрудник");

    private void logDebug(String message) {
        System.out.println("[StaffList] " + message);
    }

    private boolean isNPC(String name) {
        if (name == null) return false;
        String lowerName = name.toLowerCase();
        if (lowerName.equals("anarchy") || lowerName.equals("tokens")) {
            return true;
        }
        return lowerName.contains("npc")
            || lowerName.contains("[znpc]")
            || lowerName.startsWith("cit-")
            || lowerName.startsWith("§")
            || name.contains("NPC")
            || name.contains("[ZNPC]");
    }

    private boolean containsStaffKeyword(String text) {
        if (text == null || text.isEmpty()) {
            return false;
        }
        String lower = text.toLowerCase(Locale.ROOT);
        for (String keyword : STAFF_KEYWORDS) {
            if (lower.contains(keyword)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean visible() {
        return !list.isEmpty() || PlayerInteractionHelper.isChat(mc.currentScreen);
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        if (button == 0) {
            FontRenderer HAWENFont = Fonts.getSize(15, Fonts.Type.HAWEN);
            float pX = getX() + getWidth() - HAWENFont.getStringWidth("p") - 8;
            float pY = getY() + 9.5f;
            float pWidth = HAWENFont.getStringWidth("p");
            float pHeight = HAWENFont.getStringHeight("p");
           
            if (mouseX >= pX && mouseX <= pX + pWidth && mouseY >= pY && mouseY <= pY + pHeight) {
                java.util.List<String> selected = new java.util.ArrayList<>(Hud.getInstance().interfaceSettings.getSelected());
                selected.remove("Staff list");
                Hud.getInstance().interfaceSettings.setSelected(selected);
                return true;
            }
        }
        return super.mouseClicked(mouseX, mouseY, button);
    }

    @Override
    public void tick() {
        if (mc.world == null || mc.player == null || mc.getNetworkHandler() == null) {
            list.clear();
            return;
        }

        Collection<PlayerListEntry> playerList = mc.getNetworkHandler().getPlayerList();
        Scoreboard scoreboard = mc.world.getScoreboard();
        Set<String> addedNames = new HashSet<>();
        Set<String> addedNamesLower = new HashSet<>();

        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - lastColorChange >= 1000) {
                currentColorIndex = (currentColorIndex + 1) % PREFIX_COLORS.size();
                lastColorChange = System.currentTimeMillis();
            }
            return;
        }

        for (PlayerListEntry entry : playerList) {
            String name = entry.getProfile().getName();
            String nameLower = name.toLowerCase();
           
            if (addedNames.contains(name) || addedNamesLower.contains(nameLower) || list.containsKey(entry) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            boolean isNPCName = isNPC(name);
            if (isNPCName) {
                continue;
            }
            String display = entry.getDisplayName() != null ? entry.getDisplayName().getString() : name;
            boolean isNPCDisplay = isNPC(display);
            if (isNPCDisplay) {
                continue;
            }
            if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(entry.getProfile().getId())) {
                continue;
            }
            PlayerEntity playerEntity = mc.world.getPlayerByUuid(entry.getProfile().getId());
            if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                continue;
            }
            Team playerTeam = entry.getScoreboardTeam();
            String teamPrefix = playerTeam != null ? playerTeam.getPrefix().getString() : "";
            boolean hasStaffPrefix = containsStaffKeyword(teamPrefix);
            if (hasStaffPrefix) {
                list.put(entry, new Decelerate().setMs(150).setValue(1));
                addedNames.add(name);
                addedNamesLower.add(nameLower);
                addedViaPrefix.add(name);

                if (Hud.getInstance().notificationSettings.isSelected("Входе админа") && !notifiedPlayers.contains(name)) {
                    Notifications.getInstance().addList(Text.literal(name + " - Зашел на сервер!"), 5000);
                    notifiedPlayers.add(name);
                }
            }
        }

        for (StaffRepository.Staff staff : StaffRepository.getStaff()) {
            String staffName = staff.getName();
            String staffNameLower = staffName.toLowerCase();
           
            if (addedNames.contains(staffName) || addedNamesLower.contains(staffNameLower) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(staffName))) {
                continue;
            }
            playerList.stream()
                    .filter(p -> p.getProfile().getName().equalsIgnoreCase(staffName))
                    .filter(p -> {
                        String name = p.getProfile().getName();
                        if (isNPC(name)) {
                            return false;
                        }
                        if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(p.getProfile().getId())) {
                            return false;
                        }
                        PlayerEntity playerEntity = mc.world.getPlayerByUuid(p.getProfile().getId());
                        boolean isBot = playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity);
                        return playerEntity == null || AntiBot.getInstance() == null || !isBot;
                    })
                    .findFirst()
                    .ifPresent(entry -> {
                        list.put(entry, new Decelerate().setMs(150).setValue(1));
                        addedNames.add(staffName);
                        addedNamesLower.add(staffNameLower);
                    });
        }

        List<Team> teams = new ArrayList<>(scoreboard.getTeams());
        teams.sort(Comparator.comparing(Team::getName));
        Collection<PlayerListEntry> online = mc.getNetworkHandler().getPlayerList();

        for (Team team : teams) {
            Collection<String> members = team.getPlayerList();
            if (members.size() != 1) {
                continue;
            }
            String name = members.iterator().next();
            String nameLower = name.toLowerCase();
           
            if (!namePattern.matcher(name).matches() || addedNames.contains(name) || addedNamesLower.contains(nameLower) ||
                list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            boolean isNPCName = isNPC(name);
            if (isNPCName) {
                continue;
            }
            PlayerListEntry entry = online.stream()
                    .filter(e -> e.getProfile() != null && name.equals(e.getProfile().getName()))
                    .findFirst()
                    .orElse(null);
            if (entry != null) {
                if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(entry.getProfile().getId())) {
                    continue;
                }
                String display = entry.getDisplayName() != null ? entry.getDisplayName().getString() : name;
                if (isNPC(display)) {
                    continue;
                }
                PlayerEntity playerEntity = mc.world.getPlayerByUuid(entry.getProfile().getId());
                if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                    continue;
                }
                continue;
            }
            UUID generatedUUID = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes());
            if (AntiBot.getInstance() != null && AntiBot.getInstance().isBot(generatedUUID)) {
                continue;
            }
            PlayerEntity playerEntity = mc.world.getPlayerByUuid(generatedUUID);
            if (playerEntity != null && AntiBot.getInstance() != null && AntiBot.getInstance().isBot(playerEntity)) {
                continue;
            }
           
            if (list.keySet().stream().anyMatch(e -> e.getProfile().getName().equalsIgnoreCase(name))) {
                continue;
            }
            String teamPrefix = team.getPrefix().getString();
            String prefix = CHAR_TO_NAME.entrySet().stream()
                    .filter(e -> teamPrefix.contains(e.getKey()))
                    .map(Map.Entry::getValue)
                    .findFirst()
                    .orElse("");
            MutableText displayName = Text.empty();
            if (Network.isReallyWorld()) {
                displayName.append(Text.literal(name).formatted(Formatting.GRAY))
                        .append(Text.literal(" [").formatted(Formatting.GRAY))
                        .append(Text.literal(prefix.isEmpty() ? "V" : prefix).formatted(Formatting.RESET))
                        .append(Text.literal("]").formatted(Formatting.GRAY));
            } else {
                displayName.append(Text.literal("[").formatted(Formatting.GRAY))
                        .append(Text.literal(prefix.isEmpty() ? "V" : prefix).formatted(Formatting.RESET))
                        .append(Text.literal("] ").formatted(Formatting.GRAY))
                        .append(Text.literal(name).formatted(Formatting.GRAY));
            }
            GameProfile fakeProfile = new GameProfile(UUID.randomUUID(), name);
            PlayerListEntry fake = new PlayerListEntry(fakeProfile, mc.isInSingleplayer());
            fake.setDisplayName(displayName);
            fake.setListOrder(Integer.MIN_VALUE);
            list.put(fake, new Decelerate().setMs(150).setValue(1));
            addedNames.add(name);
            addedNamesLower.add(nameLower);

            if (Hud.getInstance().notificationSettings.isSelected("Входе админа") && !notifiedPlayers.contains(name)) {
                Notifications.getInstance().addList(Text.literal(name + " - Зашел на сервер!"), 5000);
                notifiedPlayers.add(name);
            }
        }

        list.entrySet().removeIf(entry -> {
            String name = entry.getKey().getProfile().getName();
            boolean isFromRepo = StaffRepository.isStaff(name);
            boolean isFromPrefix = addedViaPrefix.contains(name);
            boolean inPlayerList = playerList.stream().anyMatch(p -> p.getProfile().getName().equals(name));
            boolean inTeam = scoreboard.getTeams().stream().flatMap(t -> t.getPlayerList().stream()).anyMatch(name::equals);

            boolean stillHasStaffPrefix = false;
            if (isFromPrefix && inPlayerList) {
                PlayerListEntry currentEntry = playerList.stream()
                        .filter(p -> p.getProfile().getName().equals(name))
                        .findFirst().orElse(null);
                if (currentEntry != null) {
                    String display = currentEntry.getDisplayName() != null ? currentEntry.getDisplayName().getString() : name;
                    Team playerTeam = currentEntry.getScoreboardTeam();
                    stillHasStaffPrefix = containsStaffKeyword(display) || (playerTeam != null && containsStaffKeyword(playerTeam.getPrefix().getString()));
                }
            }
           
            boolean shouldRemove = false;
            if (isFromRepo) {
                if (!inPlayerList) {
                    shouldRemove = true;
                }
            } else if (isFromPrefix) {
                if (!inPlayerList || !stillHasStaffPrefix) {
                    shouldRemove = true;
                }
            } else {
                if (inPlayerList || !inTeam) {
                    shouldRemove = true;
                }
            }
           
            if (shouldRemove) {
         
                entry.getValue().setDirection(Direction.BACKWARDS);
            }
            if (entry.getValue().isFinished(Direction.BACKWARDS)) {
           
                notifiedPlayers.remove(name);
                addedViaPrefix.remove(name);
                if (!inPlayerList && Hud.getInstance().notificationSettings.isSelected("Выходе админа")) {
                    Notifications.getInstance().addList(Text.literal(name + " - Вышел с сервера!"), 5000);
                }
                return true;
            }
            return false;
        });
    }

    @Override
    public void drawDraggable(DrawContext context) {
        MatrixStack matrix = context.getMatrices();
        FontRenderer fontTitle = Fonts.getSize(16, Fonts.Type.BOLD);
        FontRenderer fontPrefix = Fonts.getSize(14, Fonts.Type.BOLD);
        FontRenderer fontName = Fonts.getSize(13, Fonts.Type.SEMI);

        long activeStaff = list.entrySet().stream().filter(e -> !e.getValue().isFinished(Direction.BACKWARDS)).count();

        float panelWidth = 140f;
        float titleHeight = 24f;
        float playerHeight = 18f;
        float spacing = -4f;
        float titleSpacing = -2f;
        float statusPanelWidth = 18f;
        float mainPanelWidth = panelWidth - statusPanelWidth - 13f;
        float totalHeight = titleHeight + titleSpacing + 8f;

        if (!list.isEmpty() || PlayerInteractionHelper.isChat(mc.currentScreen)) {
            int visibleCount = list.isEmpty() ? 3 : (int) activeStaff;
            totalHeight += visibleCount * (playerHeight + spacing);
        }


        if (Hud.blur.isValue()) {
            Render2D.rectangleWithMask(matrix.peek().getPositionMatrix(), getX(), getY(), panelWidth, totalHeight, 8f, 0,
                    KawaseBlur.INSTANCE.fbos.getFirst().getColorAttachment());
        }

        rectangle.render(ShapeProperties.create(matrix, getX(), getY(), panelWidth, totalHeight)
                .round(8f)
                .color(ThemeManager.BackgroundGui.getColor())
                .build());


        rectangle.render(ShapeProperties.create(matrix, getX() + 5, getY() + 5, panelWidth - 10, titleHeight - 10)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());


        fontTitle.drawString(matrix, "Staff", getX() + 12f, getY() + 10f, ThemeManager.textColor.getColor());


        Fonts.getSize(20, Fonts.Type.KEFIREBAL).drawString(matrix, "F", getX() + panelWidth - 19f, getY() + 9f, ThemeManager.textColor.getColor());

        float currentY = getY() + titleHeight + titleSpacing;
        Collection<PlayerListEntry> playerList = mc.player != null && mc.player.networkHandler != null ?
                mc.player.networkHandler.getPlayerList() : new ArrayList<>();


        float contentHeight = 0;
        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            contentHeight = 3 * (playerHeight + spacing) - spacing;
        } else {
            for (Map.Entry<PlayerListEntry, Animation> staff : list.entrySet()) {
                float animation = staff.getValue().getOutput().floatValue();
                if (animation > 0.01f) {
                    contentHeight += (playerHeight + spacing) * animation;
                }
            }
            contentHeight -= spacing;
        }


        rectangle.render(ShapeProperties.create(matrix, getX() + 5, currentY, mainPanelWidth, contentHeight)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());


        float statusPanelX = getX() + 5 + mainPanelWidth + 3f;
        rectangle.render(ShapeProperties.create(matrix, statusPanelX, currentY, statusPanelWidth, contentHeight)
                .round(4f)
                .color(ThemeManager.BackgroundSettings.getColor())
                .build());

        if (list.isEmpty() && PlayerInteractionHelper.isChat(mc.currentScreen)) {
            String[] exampleNames = {"kefir", "winda", "greufs"};
            String[] examplePrefixes = {"CODER", "CODER", "DEV"};
            int[] exampleColors = {
                new Color(255, 3, 3, 255).getRGB(),
                new Color(85, 255, 85, 255).getRGB(),
                new Color(255, 170, 85, 255).getRGB()
            };

            for (int i = 0; i < 3; i++) {
                drawPlayerContent(matrix, context, getX() + 5, statusPanelX, currentY, mainPanelWidth, statusPanelWidth, playerHeight,
                        exampleNames[i], examplePrefixes[i], exampleColors[i], 1.0f, fontPrefix, fontName);
                currentY += playerHeight + spacing;
            }
        } else {
            for (Map.Entry<PlayerListEntry, Animation> staff : list.entrySet()) {
                PlayerListEntry player = staff.getKey();
                if (player == null) continue;

                String name = player.getProfile().getName();
                float animation = staff.getValue().getOutput().floatValue();

                if (animation > 0.01f) {
                    boolean isVisible = playerList.stream().anyMatch(p -> p.getProfile().getName().equals(name));
                    PlayerListEntry renderEntry = isVisible ?
                            playerList.stream().filter(p -> p.getProfile().getName().equals(name)).findFirst().orElse(player) :
                            player;

                    String displayName = renderEntry.getDisplayName() != null ? renderEntry.getDisplayName().getString() : name;
                    String prefix = CHAR_TO_NAME.entrySet().stream()
                            .filter(e -> displayName.contains(e.getKey()))
                            .map(Map.Entry::getValue)
                            .findFirst()
                            .orElse("Vanish");

                    int statusColor = PREFIX_COLORS.getOrDefault(prefix, new Color(255, 0, 0, 255).getRGB());

                    drawPlayerContent(matrix, context, getX() + 5, statusPanelX, currentY, mainPanelWidth, statusPanelWidth, playerHeight,
                            name, prefix.toUpperCase(), statusColor, animation, fontPrefix, fontName);

                    currentY += (playerHeight + spacing) * animation;
                }
            }
        }

        setWidth((int) panelWidth);
        setHeight((int) totalHeight);
    }
   
    private void drawPlayerContent(MatrixStack matrix, DrawContext context, float mainPanelX, float statusPanelX, float y,
                                  float mainPanelWidth, float statusPanelWidth, float height,
                                  String name, String prefixText, int statusColor, float animation,
                                  FontRenderer fontPrefix, FontRenderer fontName) {
        float centerX = mainPanelX + mainPanelWidth / 2f;
        float centerY = y + height / 2f;

        Calculate.scale(matrix, centerX, centerY, animation, animation, () -> {
            float headPanelWidth = 18f;


            float headSize = 10f;
            float headX = mainPanelX + 3f;
            float headY = y + (height - headSize) / 2f;
           
            if (mc.player != null) {
                Identifier skinTexture = mc.player.getSkinTextures().texture();
                Render2D.drawTexture(context, skinTexture, headX, headY, headSize, 4f, 8, 8, 64, -1, -1);
            }
           

            FontRenderer arrowFont = Fonts.getSize(16, Fonts.Type.HAWEN);
            float arrowX = headX + headSize + 3f;
            float arrowY = y + height - 11f;
            arrowFont.drawString(matrix, "»", arrowX, arrowY, new Color(253, 248, 248, 255).getRGB());


            float textStartX = arrowX + arrowFont.getStringWidth("»") + 3f;
            float prefixY = y + height - 11f;
            fontPrefix.drawString(matrix, prefixText, textStartX, prefixY, statusColor);


            float nameX = textStartX + fontPrefix.getStringWidth(prefixText) + 3f;
            float nameY = y + height - 11f;
            fontName.drawString(matrix, name, nameX, nameY, ThemeManager.textColor.getColor());


            float statusWidth = 8f;
            float statusHeight = 3f;
            float statusX = statusPanelX + (statusPanelWidth - statusWidth) / 2f;
            float statusY = y + (height - statusHeight) / 2f;

            rectangle.render(ShapeProperties.create(matrix, statusX, statusY, statusWidth, statusHeight)
                    .round(1.5f)
                    .color(statusColor)
                    .build());
        });
    }
}
тож прикол но почему ты отдельно все выложил
 

Похожие темы

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