- Выберите загрузчик игры
- Fabric
Я хз вроде Рокстар едишион (ХЗ) xD.
гпт
SS:
CODE:
Решил чуть чуть обновить мьюзик бар от снегопада. Если вам не нравится можете настроить под себя | поставил коментарии для вашего решения.
Что я обновил?
1. Добавил прикольный скроллинг если название песни более 25 символов.
2. Пофиксил шрифты (от снегопада почти 0 визуала). | Пофикшены вылеты и все дела.
3. А еще добнул для цвета соответствующие темам выбранные в клиенте.
Как добнуть библиотеку? 1 - Заходите в гитхаб и скачиваете mediatransport4j-1.0.3 и все и дальше регаете его в build.gradle (ну или же по другому)
и обязательные аддоны
гпт
SS:
CODE:
MediaUtils:
package sweetie.evaware.api.utils.media;
import by.bonenaut7.mediatransport4j.api.MediaSession;
import by.bonenaut7.mediatransport4j.api.MediaTransport;
import net.minecraft.client.texture.AbstractTexture;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class MediaUtils {
private static boolean initialized = false;
private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private static volatile MediaInfo mediaInfo = null;
private static final Map<String, AbstractTexture> textureCache = new ConcurrentHashMap<>();
private static String lastMetadataKey = "";
private static String currentTextureHash = "";
private static final float[] waveHeights = new float[4];
private static final float[] waveTargets = new float[4];
private static long lastWaveUpdate = 0L;
public enum Status {
PLAYING, PAUSED
}
public static class MediaInfo {
public final String title;
public final String artist;
public final String textureHash;
public final Status status;
public final float[] heights;
public MediaInfo(String title, String artist, String textureHash, Status status, float[] heights) {
this.title = title;
this.artist = artist;
this.textureHash = textureHash;
this.status = status;
this.heights = heights.clone();
}
public AbstractTexture getTexture() {
return textureCache.get(textureHash);
}
}
public static MediaInfo getCurrentMedia() {
if (!initialized) {
MediaTransport.init();
initialized = true;
scheduler.scheduleAtFixedRate(() -> {
try {
List<MediaSession> sessions = MediaTransport.getMediaSessions();
if (sessions != null && !sessions.isEmpty()) {
MediaSession session = sessions.get(0);
String title = session.getTitle() != null ? session.getTitle() : "Unknown";
String artist = session.getArtist() != null ? session.getArtist() : "Artist";
String metadataKey = title + artist;
if (!metadataKey.equals(lastMetadataKey)) {
clearCache();
if (session.hasThumbnail()) {
ByteBuffer buffer = session.getThumbnail();
AbstractTexture texture = convertTexture(buffer);
if (texture != null) {
currentTextureHash = String.valueOf(metadataKey.hashCode());
textureCache.put(currentTextureHash, texture);
}
} else {
currentTextureHash = "";
}
lastMetadataKey = metadataKey;
}
boolean playing = session.isPlaying();
updateWaveLogic(playing);
mediaInfo = new MediaInfo(
title,
artist,
currentTextureHash,
playing ? Status.PLAYING : Status.PAUSED,
waveHeights
);
} else {
if (mediaInfo != null) {
clearCache();
mediaInfo = null;
lastMetadataKey = "";
}
}
} catch (Exception e) {
e.printStackTrace();
}
}, 0, 50, TimeUnit.MILLISECONDS);
}
return mediaInfo;
}
private static void updateWaveLogic(boolean playing) {
if (playing) {
if (System.currentTimeMillis() - lastWaveUpdate > 90) {
lastWaveUpdate = System.currentTimeMillis();
waveTargets[0] = 4.0f + (float) (Math.random() * 6.0f);
waveTargets[1] = 2.0f + (float) (Math.random() * 10.0f);
waveTargets[2] = 5.0f + (float) (Math.random() * 4.0f);
waveTargets[3] = 3.0f + (float) (Math.random() * 5.0f);
}
} else {
for (int i = 0; i < 4; i++) waveTargets[i] = 0f;
}
for (int i = 0; i < 4; i++) {
float smoothness = (i == 1) ? 0.1f : 0.25f;
waveHeights[i] += (waveTargets[i] - waveHeights[i]) * smoothness;
}
}
private static AbstractTexture convertTexture(ByteBuffer buffer) {
try {
ByteBuffer duplicate = buffer.asReadOnlyBuffer();
duplicate.clear();
byte[] bytes = new byte[duplicate.remaining()];
duplicate.get(bytes);
BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
if (img == null) return null;
NativeImage ni = new NativeImage(img.getWidth(), img.getHeight(), false);
for (int y = 0; y < img.getHeight(); y++) {
for (int x = 0; x < img.getWidth(); x++) {
ni.setColorArgb(x, y, img.getRGB(x, y));
}
}
return new NativeImageBackedTexture(ni);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static void clearCache() {
textureCache.values().forEach(AbstractTexture::close);
textureCache.clear();
currentTextureHash = "";
}
}
MusicBarWidget:
package sweetie.evaware.client.ui.widget.overlay;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.texture.AbstractTexture;
import net.minecraft.client.util.math.MatrixStack;
import sweetie.evaware.api.utils.media.MediaUtils;
import sweetie.evaware.api.utils.render.RenderUtil;
import sweetie.evaware.api.utils.render.fonts.Font;
import sweetie.evaware.api.utils.render.fonts.Fonts;
import sweetie.evaware.api.utils.color.UIColors;
import sweetie.evaware.client.ui.widget.Widget;
import java.awt.*;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class MusicBarWidget extends Widget {
private static final char WIFI_GLYPH = 'N';
private Font iconFont;
private float scrollOffset = 0f;
private long lastUpdate = System.currentTimeMillis();
public MusicBarWidget() {
super(0f, 5f);
}
@Override
public String getName() {
return "MusicBar";
}
@Override
public void render(MatrixStack matrixStack) {
if (!isEnabled()) return;
MediaUtils.MediaInfo mediaInfo = MediaUtils.getCurrentMedia();
if (mediaInfo == null) return;
String title = (mediaInfo.title == null || mediaInfo.title.isEmpty()) ? "Unknown" : mediaInfo.title;
String artist = (mediaInfo.artist == null || mediaInfo.artist.isEmpty()) ? "Artist" : mediaInfo.artist;
String label = title + " - " + artist;
Font font = Fonts.SF_REGULAR;
Font boldFont = Fonts.SF_BOLD != null ? Fonts.SF_BOLD : font;
Color textColor = UIColors.textColor(255);
Color accentColor = UIColors.primary(255);
//fonts
float fontSize = scaled(8.0f);
float timeFontSize = scaled(9.0f);
float artSize = scaled(14.0f);
float panelHeight = scaled(18.0f);
float maxTextWidth = scaled(100.0f);
String timeStr = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm"));
float timeWidth = boldFont.getWidth(timeStr, timeFontSize);
float timeGap = scaled(6.0f);
float waveBlockWidth = scaled(12.5f);
boolean hasArt = mediaInfo.getTexture() != null;
float leftOffset = scaled(4.0f);
float gapAfterArt = hasArt ? scaled(6.0f) : 0f;
float rightOffset = scaled(6.0f);
float gapAfterText = scaled(8.0f);
float textWidth = font.getWidth(label, fontSize);
float displayTabWidth = Math.min(textWidth, maxTextWidth);
float panelWidth = leftOffset + (hasArt ? artSize + gapAfterArt : 0) + displayTabWidth + gapAfterText + waveBlockWidth + rightOffset;
//wifi
Font wifiFont = getIconFont();
float wifiSize = scaled(10.0f);
float wifiWidth = (wifiFont != null) ? wifiFont.getWidth(String.valueOf(WIFI_GLYPH), wifiSize) : 0.0f;
float wifiGap = scaled(8.0f);
//position
float totalWidth = timeWidth + timeGap + panelWidth + (wifiWidth > 0 ? wifiGap + wifiWidth : 0);
float groupX = (mc.getWindow().getScaledWidth() - totalWidth) / 2.0f;
float y = getDraggable().getY();
float centerY = y + (panelHeight / 2.0f);
float barX = groupX + timeWidth + timeGap;
// time
boldFont.drawText(matrixStack, timeStr, groupX, centerY - (timeFontSize / 2.0f), timeFontSize, textColor);
drawBackground(matrixStack, barX, y, panelWidth, panelHeight, scaled(9.0f));
// content
float currentX = barX + leftOffset;
if (hasArt) {
drawTexture(matrixStack, mediaInfo.getTexture(), currentX, centerY - (artSize / 2.0f), artSize, artSize, scaled(5.0f));
currentX += artSize + gapAfterArt;
}
renderMarqueeText(matrixStack, font, label, currentX, centerY - (fontSize / 2.0f) + scaled(0.5f), displayTabWidth, fontSize, textColor);
currentX += displayTabWidth + gapAfterText;
// pause
renderVisualizer(matrixStack, mediaInfo, currentX, centerY, waveBlockWidth, accentColor, textColor);
// ic (wifiI)
if (wifiFont != null) {
float wifiX = barX + panelWidth + wifiGap;
wifiFont.drawText(matrixStack, String.valueOf(WIFI_GLYPH), wifiX, centerY - (wifiSize / 2.0f), wifiSize, textColor);
}
// Обновляем данные драггабла
getDraggable().setWidth(totalWidth);
getDraggable().setHeight(panelHeight);
getDraggable().setX(groupX);
}
private void renderMarqueeText(MatrixStack ms, Font font, String text, float x, float y, float maxWidth, float size, Color color) {
float textWidth = font.getWidth(text, size);
if (textWidth <= maxWidth) {
font.drawText(ms, text, x, y, size, color);
return;
}
long now = System.currentTimeMillis();
float delta = (now - lastUpdate) / 1000f;
lastUpdate = now;
float speed = 20f;
float gap = 30f;
scrollOffset += delta * speed;
if (scrollOffset > textWidth + gap) scrollOffset = 0;
double scale = mc.getWindow().getScaleFactor();
int scissorX = (int) (x * scale);
int scissorY = (int) (mc.getWindow().getHeight() - (y + size + scaled(2)) * scale);
int scissorW = (int) (maxWidth * scale);
int scissorH = (int) ((size + scaled(5)) * scale);
RenderSystem.enableScissor(scissorX, scissorY, scissorW, scissorH);
font.drawText(ms, text, x - scrollOffset, y, size, color);
font.drawText(ms, text, x - scrollOffset + textWidth + gap, y, size, color);
RenderSystem.disableScissor();
}
private void renderVisualizer(MatrixStack ms, MediaUtils.MediaInfo info, float x, float centerY, float width, Color accent, Color text) {
if (info.status == MediaUtils.Status.PLAYING) {
float barW = scaled(2.5f), barG = scaled(1.5f);
float barBaseY = centerY + scaled(4.0f);
for (int i = 0; i < 4; i++) {
float h = Math.min(scaled(info.heights[i]), scaled(10.0f));
RenderUtil.RECT.draw(ms, x + i * (barW + barG), barBaseY - h, barW, h, scaled(1.0f), accent);
}
} else {
float pW = scaled(2.0f), pH = scaled(7.0f), pG = scaled(2.0f);
float pX = x + (width - (pW * 2 + pG)) / 2.0f;
RenderUtil.RECT.draw(ms, pX, centerY - (pH / 2.0f), pW, pH, scaled(0.5f), text);
RenderUtil.RECT.draw(ms, pX + pW + pG, centerY - (pH / 2.0f), pW, pH, scaled(0.5f), text);
}
}
private void drawBackground(MatrixStack ms, float x, float y, float w, float h, float r) {
RenderUtil.BLUR_RECT.draw(ms, x, y, w, h, r, UIColors.widgetBlur(255));
RenderUtil.RECT.draw(ms, x, y, w, h, r, UIColors.backgroundBlur(255));
}
private void drawTexture(MatrixStack ms, AbstractTexture texture, float x, float y, float w, float h, float radius) {
if (texture != null) {
RenderUtil.TEXTURE_RECT.draw(ms, x, y, w, h, radius, Color.WHITE, 0f, 0f, 1f, 1f, texture.getGlId());
}
}
private Font getIconFont() {
if (iconFont != null) return iconFont;
try {
iconFont = Font.builder().find("other/icons").load();
} catch (Exception ignored) {}
return iconFont;
}
}
Решил чуть чуть обновить мьюзик бар от снегопада. Если вам не нравится можете настроить под себя | поставил коментарии для вашего решения.
Что я обновил?
1. Добавил прикольный скроллинг если название песни более 25 символов.
2. Пофиксил шрифты (от снегопада почти 0 визуала). | Пофикшены вылеты и все дела.
3. А еще добнул для цвета соответствующие темам выбранные в клиенте.
Как добнуть библиотеку? 1 - Заходите в гитхаб и скачиваете mediatransport4j-1.0.3 и все и дальше регаете его в build.gradle (ну или же по другому)
и обязательные аддоны
Код:
implementation 'net.java.dev.jna:jna:5.13.0'
implementation 'net.java.dev.jna:jna-platform:5.13.0'