Начинающий
- Статус
- Оффлайн
- Регистрация
- 5 Май 2025
- Сообщения
- 76
- Реакции
- 0
Чуть доделать и хорошо будетЗдарова югейи, на гпт фастиком написал, может кому то надо, моя 1 работа, HUD скинул для того что бы работали режимы ватермарки и для того что бы можно было включать/выключать элементы ватермарки.
HUD:package client.main.module.impl.visuals; import client.autobuy.ClientBlur; import client.display.hud.impl.*; import client.events.RenderItemEvent; import client.events.RenderScoreBoardEvent; import client.main.Client; import client.main.module.settings.impl.SliderSetting; import client.util.display.render.*; import com.google.common.eventbus.Subscribe; import com.mojang.blaze3d.matrix.MatrixStack; import lombok.AccessLevel; import lombok.Synchronized; import lombok.experimental.FieldDefaults; import client.events.EventRenderer2D; import client.events.EventUpdate; import client.main.module.api.Category; import client.main.module.api.Module; import client.main.module.api.ModuleRegister; import client.main.module.settings.impl.BooleanSetting; import client.main.module.settings.impl.ModeListSetting; import client.main.module.settings.impl.StringSetting; import client.util.drag.DragManager; import client.util.drag.Dragging; @FieldDefaults(level = AccessLevel.PRIVATE) @ModuleRegister(name = "Interface", type = Category.Visual, desc = "Настроить элементы Interface, чтобы всегда быть в курсе важной информации") public class HUD extends Module { public final ModeListSetting elements = new ModeListSetting("Элементы Interface", new BooleanSetting("Ватермарка", true), new BooleanSetting("Эффекты", true), new BooleanSetting("Список модерации", true), new BooleanSetting("Активные бинды", true), new BooleanSetting("Броня", true), new BooleanSetting("Уведомления", true), new BooleanSetting("Активный таргет", true), new BooleanSetting("Табло", true), new BooleanSetting("Предмет Хелпер", true) ); // Элементы watermark как отдельные BooleanSetting private final BooleanSetting watermarkName = new BooleanSetting("Нейм", true); private final BooleanSetting watermarkUsername = new BooleanSetting("Ник", true); private final BooleanSetting watermarkFPS = new BooleanSetting("FPS", true); private final BooleanSetting watermarkPing = new BooleanSetting("Пинг", true); // ModeListSetting для элементов watermark public final ModeListSetting watermarkElements = new ModeListSetting("Элементы Watermark", watermarkName, watermarkUsername, watermarkFPS, watermarkPing ); // Режимы водяного знака как отдельные BooleanSetting private final BooleanSetting staticModeSetting = new BooleanSetting("Статичный", true); private final BooleanSetting animatedModeSetting = new BooleanSetting("Анимированный", false); // ModeListSetting для режима watermark public final ModeListSetting watermarkMode = new ModeListSetting("Режим", staticModeSetting, animatedModeSetting ); final WatermarkRenderer watermarkRenderer; final CoordsRenderer coordsRenderer; final PotionRenderer potionRenderer; final KeyBindRenderer keyBindRenderer; final TargetInfoRenderer targetInfoRenderer; final ArmorRenderer armorRenderer; final StaffListRenderer staffListRenderer; final ScoreBoardRenderer scoreBoardRenderer; final FunRender funRender; final EventsRenderer eventsRenderer; final NearbyMinesRenderer nearbyMinesRenderer; // Для отслеживания предыдущих состояний private boolean lastStaticState = true; private boolean lastAnimatedState = false; @Subscribe private void onUpdate(EventUpdate e) { if (mc.gameSettings.showDebugInfo) { return; } if (elements.getValueByName("Список модерации").get()) staffListRenderer.update(e); updateWatermarkMode(); // Передаем настройки элементов в watermarkRenderer if (watermarkRenderer != null) { watermarkRenderer.setShowName(watermarkName.get()); watermarkRenderer.setShowUsername(watermarkUsername.get()); watermarkRenderer.setShowFPS(watermarkFPS.get()); watermarkRenderer.setShowPing(watermarkPing.get()); } } @Subscribe public void onEvent(RenderScoreBoardEvent event) { if (elements.getValueByName("Табло").get()) scoreBoardRenderer.renderScoreBoard(event); } @Subscribe private void onDisplay(EventRenderer2D e) { if (mc.gameSettings.showDebugInfo || e.getType() != EventRenderer2D.Type.POST) { return; } // Применяем режим к водяному знаку watermarkRenderer.setAnimatedMode(animatedModeSetting.get()); if (elements.getValueByName("Эффекты").get()) potionRenderer.render(e); if (elements.getValueByName("Ватермарка").get()) watermarkRenderer.render(e); if (elements.getValueByName("Активные бинды").get()) keyBindRenderer.render(e); if (elements.getValueByName("Список модерации").get()) staffListRenderer.render(e); if (elements.getValueByName("Активный таргет").get()) targetInfoRenderer.render(e); if (elements.getValueByName("Броня").get()) armorRenderer.render(e); if (elements.getValueByName("Предмет Хелпер").get()) funRender.render(e); } private void updateWatermarkMode() { boolean currentStatic = staticModeSetting.get(); boolean currentAnimated = animatedModeSetting.get(); // Если состояния изменились if (currentStatic != lastStaticState || currentAnimated != lastAnimatedState) { // Если включили анимированный режим if (currentAnimated && !lastAnimatedState) { // Отключаем статичный режим staticModeSetting.set(false); watermarkRenderer.setAnimatedMode(true); lastStaticState = false; lastAnimatedState = true; } // Если включили статичный режим else if (currentStatic && !lastStaticState) { // Отключаем анимированный режим animatedModeSetting.set(false); watermarkRenderer.setAnimatedMode(false); lastStaticState = true; lastAnimatedState = false; } // Если оба режима выключены (может произойти при клике на активный режим) else if (!currentStatic && !currentAnimated) { // Включаем статичный режим по умолчанию staticModeSetting.set(true); watermarkRenderer.setAnimatedMode(false); lastStaticState = true; lastAnimatedState = false; } // Обновляем состояния else { lastStaticState = currentStatic; lastAnimatedState = currentAnimated; } } } public HUD() { Dragging watermark = Client.getInstance().createDrag(this, "WaterMark", 8, 8); Dragging potions = Client.getInstance().createDrag(this, "Potions", 278, 5); Dragging keyBinds = Client.getInstance().createDrag(this, "KeyBinds", 185, 5); Dragging dragging = Client.getInstance().createDrag(this, "TargetHUD", 74, 128); Dragging dragging45 = Client.getInstance().createDrag(this, "TargetHUD42", 144, 128); Dragging staffList = Client.getInstance().createDrag(this, "StaffList", 96, 5); Dragging dragging425 = Client.getInstance().createDrag(this, "TargetHUD422", 144, 128); Dragging scoreBoardDrag = Client.getInstance().createDrag(this, "TargetHUD4222", 444, 128); Dragging funDrag = Client.getInstance().createDrag(this, "FunDrag", 244, 428); Dragging nearbyMinesRenderer1 = Client.getInstance().createDrag(this, "AAALITKA", 226, 45); Dragging nearbyMinesRenderer12 = Client.getInstance().createDrag(this, "AAALITKA2", 226, 45); funRender = new FunRender(funDrag); armorRenderer = new ArmorRenderer(); watermarkRenderer = new WatermarkRenderer(watermark); potionRenderer = new PotionRenderer(potions); keyBindRenderer = new KeyBindRenderer(keyBinds); scoreBoardRenderer = new ScoreBoardRenderer(scoreBoardDrag); eventsRenderer = new EventsRenderer(dragging45); staffListRenderer = new StaffListRenderer(staffList); targetInfoRenderer = new TargetInfoRenderer(dragging); coordsRenderer = new CoordsRenderer(dragging425); nearbyMinesRenderer = new NearbyMinesRenderer(nearbyMinesRenderer1); // Инициализируем последние состояния lastStaticState = staticModeSetting.get(); lastAnimatedState = animatedModeSetting.get(); // Передаем начальные настройки в watermarkRenderer watermarkRenderer.setShowName(watermarkName.get()); watermarkRenderer.setShowUsername(watermarkUsername.get()); watermarkRenderer.setShowFPS(watermarkFPS.get()); watermarkRenderer.setShowPing(watermarkPing.get()); // Добавляем настройки addSettings(elements, watermarkElements, watermarkMode); DragManager.load(); } public static void drawClientRect(float x, float y, float width, float height, float anim,float bluranim, MatrixStack ms) { RenderUtil.Rounded.smooth(ms, x, y, width, height, ColorUtil.rgba(30,30,30, (int) (255 * anim)), ColorUtil.rgba(15,15,15, (int) (255 * anim)), ColorUtil.rgba(15,15,15, (int) (255 * anim)), ColorUtil.rgba(30, 30, 30, (int) (255 * anim)),5); RenderUtil.Rounded.roundedOutline(ms, x, y, width, height,1, ColorUtil.rgba(70,70,70, (int) (255 * anim)), ColorUtil.rgba(30, 30, 30, (int) (255 * anim )), ColorUtil.rgba(30,30,30, (int) (255 * anim)), ColorUtil.rgba(90,90,90, (int) (255 * anim )), Round.of(5)); } public static void drawClientGuiRect(float x, float y, float width, float height, MatrixStack ms,float radius) { RenderUtil.Rounded.smooth(ms, x, y, width, height, ColorUtil.rgba(30,30,30, (int) (255)), ColorUtil.rgba(15,15,15, (int) (255 )), ColorUtil.rgba(15,15,15, (int) (255 )), ColorUtil.rgba(30, 30, 30, (int) (255 )),5); RenderUtil.Rounded.roundedOutline(ms, x, y, width, height,1, ColorUtil.rgba(70,70,70, (int) (255 )), ColorUtil.rgba(30, 30, 30, (int) (255 )), ColorUtil.rgba(30,30,30, (int) (255 )), ColorUtil.rgba(70,70,70, (int) (255 )), Round.of(5)); } public static void drawCustomRect(float x, float y, float width, float height, MatrixStack ms,float radius,int coloroutile,int colormainrect,int colordb) { RenderUtil.Rounded.smooth(ms, x, y, width, height, ColorUtil.rgba(30,30,30, (int) (255)), ColorUtil.rgba(15,15,15, (int) (255 )), ColorUtil.rgba(15,15,15, (int) (255 )), ColorUtil.rgba(30, 30, 30, (int) (255 )),radius ); RenderUtil.Rounded.roundedOutline(ms, x, y, width, height,1, ColorUtil.rgba(70,70,70, (int) (255 )), ColorUtil.rgba(30, 30, 30, (int) (255 )), ColorUtil.rgba(15,15,15, (int) (255 )), ColorUtil.rgba(70,70,70, (int) (255 )), Round.of(radius)); } public static void drawClientRect(float x, float y, float width, float height, MatrixStack ms,float radius,int alpha) { RenderUtil.Rounded.smooth(ms, x, y, width, height, ColorUtil.rgba(30,30,30, (int) (alpha)), ColorUtil.rgba(15,15,15, (int) (alpha)), ColorUtil.rgba(15,15,15, (int) (alpha )), ColorUtil.rgba(30, 30, 30, (int) (alpha )),radius ); RenderUtil.Rounded.roundedOutline(ms, x, y, width, height,1, ColorUtil.rgba(70,70,70, (int) (alpha )), ColorUtil.rgba(30, 30, 30, (int) (alpha )), ColorUtil.rgba(15,15,15, (int) (alpha )), ColorUtil.rgba(70,70,70, (int) (alpha )), Round.of(radius)); } public static void drawClientRect(float x, float y, float width, float height, MatrixStack ms,float radius) { RenderUtil.Rounded.smooth(ms, x, y, width, height, ColorUtil.rgba(30,30,30, (int) (255)), ColorUtil.rgba(15,15,15, (int) (255 )), ColorUtil.rgba(15,15,15, (int) (255 )), ColorUtil.rgba(30, 30, 30, (int) (255 )),radius ); RenderUtil.Rounded.roundedOutline(ms, x, y, width, height,1, ColorUtil.rgba(70,70,70, (int) (255 )), ColorUtil.rgba(30, 30, 30, (int) (255 )), ColorUtil.rgba(30,30,30, (int) (255 )), ColorUtil.rgba(70,70,70, (int) (255 )), Round.of(radius)); } public static void drawRectWithOutline(float x, float y, float width, float height, MatrixStack ms,float radius,float alpha) { RenderUtil.Rounded.smooth(ms, x, y, width, height, ColorUtil.rgba(30,30,30, (int) (alpha)), ColorUtil.rgba(15,15,15, (int) (alpha )), ColorUtil.rgba(15,15,15, (int) (alpha )), ColorUtil.rgba(30, 30, 30, (int) (alpha )),radius ); RenderUtil.Rounded.roundedOutline(ms, x, y, width, height,1, ColorUtil.rgba(70,70,70, (int) (alpha )), ColorUtil.rgba(30, 30, 30, (int) (alpha )), ColorUtil.rgba(30,30,30, (int) (alpha )), ColorUtil.rgba(70,70,70, (int) (alpha )), Round.of(radius)); } public static void drawRectWith(float x, float y, float width, float height, MatrixStack ms,float radius) { RenderUtil.Rounded.smooth(ms, x, y, width, height, ColorUtil.rgba(30,30,30, (int) (255)), ColorUtil.rgba(15,15,15, (int) (255 )), ColorUtil.rgba(15,15,15, (int) (255 )), ColorUtil.rgba(30, 30, 30, (int) (255 )),radius ); RenderUtil.Rounded.roundedOutline(ms, x, y, width, height,1, ColorUtil.rgba(70,70,70, (int) (255 )), ColorUtil.rgba(30, 30, 30, (int) (255 )), ColorUtil.rgba(30,30,30, (int) (255 )), ColorUtil.rgba(70,70,70, (int) (255 )), Round.of(radius)); } public static void drawClientRect(float x, float y, float width, float height, MatrixStack ms) { RenderUtil.Rounded.smooth(ms, x, y, width, height, ColorUtil.rgba(30,30,30, (int) (255)), ColorUtil.rgba(15,15,15, (int) (255 )), ColorUtil.rgba(15,15,15,(int) (255 )), ColorUtil.rgba(30, 30, 30, (int) (255 )),5 ); RenderUtil.Rounded.roundedOutline(ms, x, y, width, height,1, ColorUtil.rgba(70, 70, 70, (int) (255 )), ColorUtil.rgba(30, 30, 30, (int) (255 )), ColorUtil.rgba(30,30,30, (int) (255 )), ColorUtil.rgba(70, 70, 70, (int) (255 )), Round.of(5)); } }Watermark:package client.display.hud.impl; import client.display.hud.ElementRenderer; import client.events.EventRenderer2D; import client.util.display.render.ColorUtil; import client.util.display.render.RenderUtil; import client.util.display.render.font.Fonts; import client.util.display.text.GradientUtil; import client.util.drag.Dragging; import com.google.common.eventbus.Subscribe; import com.mojang.blaze3d.matrix.MatrixStack; import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.experimental.FieldDefaults; import net.minecraft.client.Minecraft; import net.minecraft.client.network.play.ClientPlayNetHandler; import net.minecraft.client.network.play.NetworkPlayerInfo; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; @FieldDefaults(level = AccessLevel.PRIVATE) @RequiredArgsConstructor public class WatermarkRenderer implements ElementRenderer { @Getter final Dragging dragging; private int frameCount = 0; private long lastTime = 0; private int fps = 0; // Переменные для анимации private String currentAnimationText = "Neverlast.fun"; private long lastAnimationTime = 0; private int animationPhase = 0; private int animationIndex = 0; private final long animationDelay = 150; private String displayedText = "Neverlast.fun"; // Режим анимации private boolean animatedMode = false; // Настройки отображения элементов @Setter private boolean showName = true; @Setter private boolean showUsername = true; @Setter private boolean showFPS = true; @Setter private boolean showPing = true; // Иконки из шрифта nur private String nameIcon = "U"; private String nickIcon = "W"; private String fpsIcon = "X"; private String pingIcon = "Q"; // Шрифты private final float textSize = 7f; private final float iconSize = 7f; @Subscribe public void render(EventRenderer2D EventRenderer2D) { MatrixStack ms = EventRenderer2D.getMatrixStack(); float posX = dragging.getX(); float posY = dragging.getY(); // Подсчет FPS frameCount++; long currentTime = System.currentTimeMillis(); if (currentTime - lastTime >= 1000) { fps = frameCount; frameCount = 0; lastTime = currentTime; } // Обновление анимации if (animatedMode) { updateAnimation(); } else { displayedText = "Neverlast.fun"; animationPhase = 0; animationIndex = 0; } // Получаем данные int ping = getPlayerPing(); String pingValue = ping + "ms"; String fpsValue = String.valueOf(fps); String username = Minecraft.getInstance().getSession().getUsername(); String formattedUsername = formatUsername(username); // Рассчитываем общую ширину float height = 14; float currentX = posX + 4f; float separatorWidth = Fonts.regular_semibold.getWidth(" ", textSize); float spaceWidth = Fonts.regular_semibold.getWidth(" ", textSize); // Рассчитываем общую ширину float totalWidth = 4f; // Начальный отступ boolean hasPreviousElement = false; // Иконка перед Neverlast.fun if (showName) { totalWidth += Fonts.nur.getWidth(nameIcon, iconSize) + spaceWidth; totalWidth += Fonts.regular_semibold.getWidth(displayedText, textSize); hasPreviousElement = true; } // Иконка ника и ник (исправлено: иконка показывается независимо от пинга) if (showUsername) { if (hasPreviousElement) totalWidth += separatorWidth; // Добавляем ширину иконки ника если showUsername включен totalWidth += Fonts.nur.getWidth(nickIcon, iconSize) + spaceWidth; totalWidth += Fonts.regular_semibold.getWidth(formattedUsername, textSize); hasPreviousElement = true; } // FPS (с иконкой) if (showFPS) { if (hasPreviousElement) totalWidth += separatorWidth; totalWidth += Fonts.nur.getWidth(fpsIcon, iconSize) + spaceWidth; totalWidth += Fonts.regular_semibold.getWidth(fpsValue + "fps", textSize); } // Пинг (с иконкой) if (showPing) { if (hasPreviousElement) totalWidth += separatorWidth; totalWidth += Fonts.nur.getWidth(pingIcon, iconSize) + spaceWidth; totalWidth += Fonts.regular_semibold.getWidth(pingValue, textSize); } totalWidth += 4f; // Конечный отступ if (totalWidth <= 8f) { dragging.setWidth(0); dragging.setHeight(0); return; } // Рисуем фон drawWatermarkBackground(ms, posX, posY, totalWidth, height); // Отрисовываем элементы float textY = posY + (height - Fonts.regular_semibold.getHeight(textSize)) / 2 - 0.3f; float iconY = posY + (height - Fonts.nur.getHeight(iconSize)) / 2 + 0.7f; // Специальные позиции для иконок FPS и пинга (пониже) float fpsPingIconY = iconY + 0.5f; // На 0.5 пикселя ниже основной позиции иконок int color1 = ColorUtil.getColor(0); int color2 = ColorUtil.multDark(color1, 0.5F); // Цвета для иконок - такие же как у Neverlast.fun int iconColor1 = ColorUtil.getColor(0); int iconColor2 = ColorUtil.multDark(iconColor1, 0.5F); hasPreviousElement = false; // Иконка перед Neverlast.fun - цвет как у Neverlast.fun if (showName) { // Иконка перед названием - градиент как у текста Neverlast.fun ITextComponent nameIconGradient = GradientUtil.gradient(nameIcon, iconColor1, iconColor2); Fonts.nur.drawText(ms, nameIconGradient, currentX, iconY, iconSize, 255); currentX += Fonts.nur.getWidth(nameIcon, iconSize) + spaceWidth; // Название "Neverlast.fun" - цветное (градиент) ITextComponent gradientText = GradientUtil.gradient(displayedText, color1, color2); Fonts.regular_semibold.drawText(ms, gradientText, currentX, textY, textSize, 255); currentX += Fonts.regular_semibold.getWidth(displayedText, textSize); hasPreviousElement = true; } // Иконка ника и никнейм (исправлено: иконка показывается всегда когда включен showUsername) if (showUsername) { if (hasPreviousElement) { // Просто добавляем пробел вместо большой точки currentX += separatorWidth; } // Иконка ника - градиент как у Neverlast.fun ITextComponent nickIconGradient = GradientUtil.gradient(nickIcon, iconColor1, iconColor2); Fonts.nur.drawText(ms, nickIconGradient, currentX, iconY, iconSize, 255); currentX += Fonts.nur.getWidth(nickIcon, iconSize) + spaceWidth; // Никнейм - БЕЛЫЙ ITextComponent whiteUsernameText = new StringTextComponent(formattedUsername).mergeStyle(TextFormatting.WHITE); Fonts.regular_semibold.drawText(ms, whiteUsernameText, currentX, textY, textSize, 255); currentX += Fonts.regular_semibold.getWidth(formattedUsername, textSize); hasPreviousElement = true; } // FPS (с иконкой графика) - иконка пониже if (showFPS) { if (hasPreviousElement) { // Просто добавляем пробел вместо большой точки currentX += separatorWidth; } // Иконка графика перед FPS - градиент как у Neverlast.fun ITextComponent fpsIconGradient = GradientUtil.gradient(fpsIcon, iconColor1, iconColor2); Fonts.nur.drawText(ms, fpsIconGradient, currentX, fpsPingIconY, iconSize, 255); currentX += Fonts.nur.getWidth(fpsIcon, iconSize) + spaceWidth; // Значение FPS + надпись "fps" (слитно) - БЕЛОЕ String fpsText = fpsValue + "fps"; ITextComponent whiteFpsText = new StringTextComponent(fpsText).mergeStyle(TextFormatting.WHITE); Fonts.regular_semibold.drawText(ms, whiteFpsText, currentX, textY, textSize, 255); currentX += Fonts.regular_semibold.getWidth(fpsText, textSize); hasPreviousElement = true; } // Пинг (с иконкой) - иконка пониже if (showPing) { if (hasPreviousElement) { // Просто добавляем пробел вместо большой точки currentX += separatorWidth; } // Иконка пинга перед значением - градиент как у Neverlast.fun ITextComponent pingIconGradient = GradientUtil.gradient(pingIcon, iconColor1, iconColor2); Fonts.nur.drawText(ms, pingIconGradient, currentX, fpsPingIconY, iconSize, 255); currentX += Fonts.nur.getWidth(pingIcon, iconSize) + spaceWidth; // Значение пинга - БЕЛОЕ ITextComponent whitePingText = new StringTextComponent(pingValue).mergeStyle(TextFormatting.WHITE); Fonts.regular_semibold.drawText(ms, whitePingText, currentX, textY, textSize, 255); currentX += Fonts.regular_semibold.getWidth(pingValue, textSize); } dragging.setWidth(totalWidth); dragging.setHeight(height); } // Метод для нормализации имени пользователя private String formatUsername(String username) { if (username == null || username.isEmpty()) { return ""; } String lowerCaseName = username.toLowerCase(); if (lowerCaseName.length() == 1) { return lowerCaseName.toUpperCase(); } else { return Character.toUpperCase(lowerCaseName.charAt(0)) + lowerCaseName.substring(1); } } private void drawWatermarkBackground(MatrixStack ms, float x, float y, float width, float height) { int darkPanelColor = ColorUtil.getColor(0, 0, 0, 204); RenderUtil.Rounded.smooth(ms, x + 1, y + 1, width - 2, height - 2, darkPanelColor, 2); } private void updateAnimation() { long currentTime = System.currentTimeMillis(); if (currentTime - lastAnimationTime >= animationDelay) { lastAnimationTime = currentTime; if (animationPhase == 0) { if (animationIndex < currentAnimationText.length()) { int endIndex = currentAnimationText.length() - animationIndex; displayedText = currentAnimationText.substring(0, Math.max(0, endIndex - 1)); animationIndex++; } else { animationPhase = 1; animationIndex = 0; displayedText = ""; } } else { if (animationIndex < currentAnimationText.length()) { displayedText = currentAnimationText.substring(0, animationIndex + 1); animationIndex++; } else { animationPhase = 0; animationIndex = 0; displayedText = currentAnimationText; } } } } public void setAnimatedMode(boolean animated) { this.animatedMode = animated; if (!animated) { displayedText = "Neverlast.fun"; animationPhase = 0; animationIndex = 0; } } public boolean isAnimatedMode() { return animatedMode; } private int getPlayerPing() { try { Minecraft mc = Minecraft.getInstance(); if (mc.player == null || mc.getConnection() == null) { return 0; } ClientPlayNetHandler connection = mc.getConnection(); NetworkPlayerInfo playerInfo = connection.getPlayerInfo(mc.player.getUniqueID()); if (playerInfo != null) { return playerInfo.getResponseTime(); } } catch (Exception e) { // Игнорируем ошибку } return 0; } }