Начинающий
- Статус
- Оффлайн
- Регистрация
- 26 Апр 2025
- Сообщения
- 59
- Реакции
- 1
- Выберите загрузчик игры
- Fabric
Привет
давно не заливал на юг что либо, по этому ловите вам перенос music info на евавар в3 с этой темки - https://yougame.biz/threads/374128/
Все кнопочки работают, так же взаимодействует с настройками прозрачности и размера худа. так же добавил чисто от себя крестик который отключает music info в модулях (хз зачем)
Небесное чудо:
ss:
(должно показывать обложку но из за того что я сижу на линуксе, он просто на просто не дает показать обложку трека, либо я чота не так сделал. хз)

давно не заливал на юг что либо, по этому ловите вам перенос music info на евавар в3 с этой темки - https://yougame.biz/threads/374128/
Все кнопочки работают, так же взаимодействует с настройками прозрачности и размера худа. так же добавил чисто от себя крестик который отключает music info в модулях (хз зачем)
Небесное чудо:
MusicInfoWidget.java:
package code.dream.client.ui.widget.overlay;
import code.dream.api.event.Listener;
import code.dream.api.event.events.client.TickEvent;
import code.dream.api.utils.color.UIColors;
import code.dream.api.utils.math.MathUtil;
import code.dream.api.utils.render.RenderUtil;
import code.dream.api.utils.render.ScissorUtil;
import code.dream.api.utils.render.fonts.Font;
import code.dream.api.utils.render.fonts.Fonts;
import code.dream.api.utils.render.fonts.Icons;
import code.dream.client.features.modules.render.InterfaceModule;
import code.dream.client.ui.widget.Widget;
import dev.redstones.mediaplayerinfo.IMediaSession;
import dev.redstones.mediaplayerinfo.MediaInfo;
import dev.redstones.mediaplayerinfo.MediaPlayerInfo;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;
import java.awt.*;
import java.util.Comparator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MusicInfoWidget extends Widget {
private static final Color BG = new Color(15, 15, 20, 220);
private static final Color OUTLINE = new Color(70, 70, 85, 150);
private final ExecutorService mediaExecutor = Executors.newSingleThreadExecutor(r -> {
Thread t = new Thread(r, "dream-mediainfo");
t.setDaemon(true);
return t;
});
private volatile MediaInfo mediaInfo = new MediaInfo("", "", new byte[0], 0L, 0L, false);
private volatile IMediaSession session;
private final Identifier artworkId = Identifier.of("dream", "hud/music_artwork");
private volatile boolean artworkRegistered;
private long lastMediaEventMs;
private float visibility = 0f;
private float progressAnimated;
public MusicInfoWidget() {
super(10f, 180f);
TickEvent.getInstance().subscribe(new Listener<>(e -> onClientTick()));
}
@Override
public String getName() {
return "Music Info";
}
private void onClientTick() {
if (!isEnabled() || !InterfaceModule.getInstance().isEnabled()) return;
updateVisibilityTarget();
if (mc.player == null) return;
if (mc.player.age % 5 != 0) return;
mediaExecutor.execute(() -> {
try {
var sessions = MediaPlayerInfo.Instance.getMediaSessions();
if (sessions == null || sessions.isEmpty()) return;
IMediaSession current = sessions.stream()
.filter(s -> s != null && s.getMedia() != null)
.max(Comparator.comparing(s -> {
try {
return s.getMedia().getPlaying();
} catch (Exception e) {
return false;
}
}))
.orElse(null);
if (current == null) return;
MediaInfo info = current.getMedia();
if (info == null) return;
if (info.getTitle().isEmpty() && info.getArtist().isEmpty() && !info.getPlaying()) return;
byte[] png = info.getArtworkPng();
if (png != null && png.length > 0) {
mc.execute(() -> registerArtwork(png));
}
mediaInfo = info;
session = current;
lastMediaEventMs = System.currentTimeMillis();
} catch (Exception ignored) {
}
});
}
private void updateVisibilityTarget() {
boolean inChat = mc.currentScreen instanceof ChatScreen;
boolean recent = System.currentTimeMillis() - lastMediaEventMs < 5000L;
boolean playing = false;
try {
playing = mediaInfo != null && mediaInfo.getPlaying();
} catch (Exception ignored) {
}
float target = (inChat || recent || playing) ? 1f : 0f;
visibility = MathUtil.interpolate(visibility, target, 0.18f);
}
private void registerArtwork(byte[] png) {
try {
NativeImage image = NativeImage.read(new java.io.ByteArrayInputStream(png));
NativeImageBackedTexture texture = new NativeImageBackedTexture(image);
mc.getTextureManager().registerTexture(artworkId, texture);
artworkRegistered = true;
} catch (Exception e) {
artworkRegistered = false;
}
}
@Override
public void render(MatrixStack matrixStack) {
boolean inChat = mc.currentScreen instanceof ChatScreen;
boolean recent = System.currentTimeMillis() - lastMediaEventMs < 5000L;
boolean playing = mediaInfo != null && mediaInfo.getPlaying();
if (visibility < 0.02f && !inChat && !recent && !playing) return;
float vis = inChat ? 1f : visibility;
if (vis < 0.02f) return;
Layout L = computeLayout();
float cx = L.x + L.totalW * 0.5f;
float cy = L.y + L.totalH * 0.5f;
matrixStack.push();
matrixStack.translate(cx, cy, 0f);
matrixStack.scale(vis, vis, 1f);
matrixStack.translate(-cx, -cy, 0f);
float outlineW = 0.5f;
float outerR = L.borderR + outlineW;
RenderUtil.RECT.draw(matrixStack, L.x - outlineW, L.y - outlineW,
L.totalW + outlineW * 2, L.totalH + outlineW * 2, outerR, OUTLINE);
RenderUtil.BLUR_RECT.draw(matrixStack, L.x, L.y, L.totalW, L.totalH, L.borderR, BG);
if (artworkRegistered && mediaInfo.getArtworkPng() != null && mediaInfo.getArtworkPng().length > 0) {
var tex = mc.getTextureManager().getTexture(artworkId);
if (tex != null) {
float cr = scaled(4f);
RenderUtil.RECT.draw(matrixStack, L.coverX, L.coverY, L.coverSize, L.coverSize, cr, Color.WHITE);
ScissorUtil.start(matrixStack, L.coverX, L.coverY, L.coverSize, L.coverSize);
RenderUtil.TEXTURE_RECT.draw(matrixStack, L.coverX, L.coverY, L.coverSize, L.coverSize, cr, Color.WHITE,
0f, 0f, 1f, 1f, tex.getGlId());
ScissorUtil.stop(matrixStack);
}
} else {
RenderUtil.BLUR_RECT.draw(matrixStack, L.coverX, L.coverY, L.coverSize, L.coverSize, scaled(4f),
new Color(25, 25, 32, 200));
}
Font textFont = getSemiBoldFont();
float titleSize = scaled(7f);
float artistSize = scaled(6.5f);
String title = mediaInfo.getTitle().isEmpty() ? "—" : mediaInfo.getTitle();
String artist = mediaInfo.getArtist().isEmpty() ? "—" : mediaInfo.getArtist();
float textMax = L.totalW - L.pad * 2f;
float textY = L.coverY + L.coverSize + L.pad * 0.5f;
drawClippedText(matrixStack, textFont, title, L.x + L.pad, textY, textMax, titleSize, UIColors.textColor());
textY += titleSize + scaled(1f);
drawClippedText(matrixStack, textFont, artist, L.x + L.pad, textY, textMax, artistSize, UIColors.inactiveTextColor());
RenderUtil.BLUR_RECT.draw(matrixStack, L.panelX, L.panelY, L.panelW, L.panelH, scaled(3f),
new Color(22, 22, 28, 210));
Font iconFont = Fonts.ICONS;
float iconSize = scaled(8f);
drawIconButton(matrixStack, iconFont, Icons.STEP_B, L.prevX(), L.btnY, L.btnSize, iconSize);
Icons playIcon = mediaInfo.getPlaying() ? Icons.PAUSE : Icons.PLAY;
drawIconButton(matrixStack, iconFont, playIcon, L.playX(), L.btnY, L.btnSize, iconSize);
drawIconButton(matrixStack, iconFont, Icons.STEP_F, L.nextX(), L.btnY, L.btnSize, iconSize);
RenderUtil.BLUR_RECT.draw(matrixStack, L.progPanelX, L.progPanelY, L.progPanelW, L.progPanelH, scaled(3f),
new Color(22, 22, 28, 210));
long dur = mediaInfo.getDuration();
long pos = mediaInfo.getPosition();
float targetProg = dur > 0 ? Math.min(1f, (float) pos / (float) dur) : 0f;
progressAnimated = MathUtil.interpolate(progressAnimated, targetProg, 0.22f);
RenderUtil.RECT.draw(matrixStack, L.progX, L.progY, L.progBarW, L.progBarH, scaled(1.5f),
new Color(40, 40, 50, 255));
if (progressAnimated > 0.001f) {
RenderUtil.RECT.draw(matrixStack, L.progX, L.progY, L.progBarW * Math.min(1f, progressAnimated), L.progBarH,
scaled(1.5f), UIColors.primary());
}
float closeSize = scaled(7f);
float cxClose = L.x + L.totalW - L.pad - closeSize * 0.5f;
float cyClose = L.y + L.pad + closeSize * 0.5f;
iconFont.drawText(matrixStack, String.valueOf(Icons.CROSS.getLetter()),
cxClose - iconFont.getWidth(String.valueOf(Icons.CROSS.getLetter()), closeSize) * 0.5f,
cyClose - iconFont.getHeight(closeSize) * 0.5f, closeSize, UIColors.inactiveTextColor());
matrixStack.pop();
getDraggable().setWidth(L.totalW);
getDraggable().setHeight(L.totalH);
}
private void drawIconButton(MatrixStack ms, Font font, Icons icon, float bx, float by, float box, float size) {
String ch = String.valueOf(icon.getLetter());
float tw = font.getWidth(ch, size);
float th = font.getHeight(size);
font.drawText(ms, ch, bx + (box - tw) * 0.5f, by + (box - th) * 0.5f, size, UIColors.primary());
}
private void drawClippedText(MatrixStack ms, Font font, String text, float x, float y, float maxW, float size, Color color) {
float w = font.getWidth(text, size);
if (w <= maxW) {
font.drawText(ms, text, x, y, size, color);
return;
}
ScissorUtil.start(ms, x, y, maxW, size + scaled(2f));
font.drawText(ms, text, x, y, size, color);
ScissorUtil.stop(ms);
}
private Layout computeLayout() {
float x = getDraggable().getX();
float y = getDraggable().getY();
float pad = scaled(5f);
float totalW = scaled(90f);
float coverSize = totalW - pad * 2f;
float borderR = scaled(4f);
float titleBlock = scaled(7f) + scaled(1f) + scaled(6.5f) + scaled(2f);
float panelH = scaled(22f);
float progPanelH = scaled(10f);
float gap = scaled(4f);
float totalH = pad + coverSize + titleBlock + gap + panelH + pad + progPanelH + pad;
float coverX = x + pad;
float coverY = y + pad;
float panelY = coverY + coverSize + titleBlock + gap;
float panelW = totalW - pad * 2f;
float panelX = x + pad;
float btnSize = scaled(16f);
float btnGap = scaled(8f);
float rowW = btnSize * 3f + btnGap * 2f;
float buttonsStartX = x + (totalW - rowW) * 0.5f;
float btnY = panelY + (panelH - btnSize) * 0.5f;
float progPanelY = panelY + panelH + pad;
float progPanelW = panelW;
float progPanelX = panelX;
float progPad = scaled(6f);
float progBarH = scaled(3f);
float progY = progPanelY + (progPanelH - progBarH) * 0.5f;
float progBarW = progPanelW - progPad * 2f;
float progX = progPanelX + progPad;
return new Layout(x, y, totalW, totalH, pad, borderR, coverX, coverY, coverSize,
panelX, panelY, panelW, panelH, buttonsStartX, btnY, btnSize, btnGap,
progPanelX, progPanelY, progPanelW, progPanelH, progX, progY, progBarW, progBarH);
}
public boolean tryConsumeMouseClick(double mouseX, double mouseY, int button) {
if (button != 0) return false;
if (!isEnabled() || !InterfaceModule.getInstance().isEnabled()) return false;
boolean inChat = mc.currentScreen instanceof ChatScreen;
boolean recent = System.currentTimeMillis() - lastMediaEventMs < 5000L;
boolean playing = mediaInfo != null && mediaInfo.getPlaying();
float vis = inChat ? 1f : visibility;
if (vis < 0.02f && !inChat && !recent && !playing) return false;
Layout L = computeLayout();
float mx = (float) mouseX;
float my = (float) mouseY;
if (!inChat) {
float cx = L.x + L.totalW * 0.5f;
float cy = L.y + L.totalH * 0.5f;
mx = cx + (mx - cx) / Math.max(0.05f, vis);
my = cy + (my - cy) / Math.max(0.05f, vis);
}
float closeSize = scaled(7f);
float closeX = L.x + L.totalW - L.pad - closeSize;
float closeY = L.y + L.pad;
if (mx >= closeX - scaled(2f) && mx <= L.x + L.totalW - scaled(1f)
&& my >= closeY - scaled(1f) && my <= closeY + closeSize + scaled(2f)) {
InterfaceModule.getInstance().widgets.getValue().stream()
.filter(s -> s.getName().equals(getName()))
.findFirst()
.ifPresent(s -> s.value(false));
return true;
}
float prevX = L.buttonsStartX;
float playX = prevX + L.btnSize + L.btnGap;
float nextX = playX + L.btnSize + L.btnGap;
if (hit(mx, my, prevX, L.btnY, L.btnSize)) {
invokeSession(IMediaSession::previous);
return true;
}
if (hit(mx, my, playX, L.btnY, L.btnSize)) {
invokeSession(s -> {
if (mediaInfo.getPlaying()) s.pause();
else s.play();
});
return true;
}
if (hit(mx, my, nextX, L.btnY, L.btnSize)) {
invokeSession(IMediaSession::next);
return true;
}
return false;
}
private static boolean hit(float mx, float my, float bx, float by, float size) {
return mx >= bx && mx <= bx + size && my >= by && my <= by + size;
}
private void invokeSession(java.util.function.Consumer<IMediaSession> action) {
IMediaSession s = session;
if (s == null) return;
mediaExecutor.execute(() -> {
try {
action.accept(s);
} catch (Exception ignored) {
}
});
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
render(context.getMatrices());
}
@Override
public void mouseClicked(double mouseX, double mouseY, int button) {}
@Override
public void mouseReleased(double mouseX, double mouseY, int button) {}
@Override
public void keyPressed(int keyCode, int scanCode, int modifiers) {}
@Override
public void mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {}
private record Layout(float x, float y, float totalW, float totalH, float pad, float borderR,
float coverX, float coverY, float coverSize,
float panelX, float panelY, float panelW, float panelH,
float buttonsStartX, float btnY, float btnSize, float btnGap,
float progPanelX, float progPanelY, float progPanelW, float progPanelH,
float progX, float progY, float progBarW, float progBarH) {
float prevX() {
return buttonsStartX;
}
float playX() {
return buttonsStartX + btnSize + btnGap;
}
float nextX() {
return playX() + btnSize + btnGap;
}
}
}
ss:
(должно показывать обложку но из за того что я сижу на линуксе, он просто на просто не дает показать обложку трека, либо я чота не так сделал. хз)