Вопрос Краш MediaPlayer

  • Автор темы Автор темы mewiz
  • Дата начала Дата начала
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
29 Июл 2025
Сообщения
154
Реакции
2

Перед прочтением основного контента ниже, пожалуйста, обратите внимание на обновление внутри секции Майна на нашем форуме. У нас появились:

  • бесплатные читы для Майнкрафт — любое использование на свой страх и риск;
  • маркетплейс Майнкрафт — абсолютно любая коммерция, связанная с игрой, за исключением продажи читов (аккаунты, предоставления услуг, поиск кодеров читов и так далее);
  • приватные читы для Minecraft — в этом разделе только платные хаки для игры, покупайте группу "Продавец" и выставляйте на продажу свой софт;
  • обсуждения и гайды — всё тот же раздел с вопросами, но теперь модернизированный: поиск нужных хаков, пати с игроками-читерами и другая полезная информация.

Спасибо!

после закрытия стриминговой платформы (будь то спотифай или что-то другое) происходит краш (как только getMediaSessions() возвращает null) в нативном коде и после чего жвм падает, перепробывал всё что можно и нельзя, хэшировал текстуру, делал проверки и защиту на нулл, один хер он крашит, в итоге психанул и переписал MediaPlayer с более улучшенной логикой работы onTick, но проблема осталась прежней, надеюсь на помощь знатоков с форума :pepe14:
123:
Expand Collapse Copy
package ru.mytheria.api.util.media;


import com.google.common.io.BaseEncoding;
import dev.redstones.mediaplayerinfo.IMediaSession;
import dev.redstones.mediaplayerinfo.MediaInfo;
import dev.redstones.mediaplayerinfo.MediaPlayerInfo;
import net.minecraft.client.texture.AbstractTexture;
import ru.mytheria.api.util.render.RenderEngine;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static ru.mytheria.api.clientannotation.QuickImport.mc;

public class MediaPlayer {

    private BufferedImage image;
    private AbstractTexture texture;
    private String title = "", artist = "", owner = "", lastTitle = "";
    private long duration = 0, position = 0;
    private boolean changeTrack;
    private IMediaSession session;
    private final ExecutorService executor = Executors.newSingleThreadExecutor();


    private BufferedImage previousArtwork = null;
    private final Object lock = new Object();
    private String previousHash = "";


    public void onTick() {
        executor.submit(() -> {
            try {
                List<IMediaSession> currentSessions = MediaPlayerInfo.Instance.getMediaSessions();
                IMediaSession currentSession = currentSessions.stream()
                        .filter(s -> {
                            MediaInfo media = s.getMedia();
                            return media != null && (!media.getArtist().isEmpty() || !media.getTitle().isEmpty());
                        })
                        .findFirst()
                        .orElse(null);

                synchronized (lock) {
                    if (currentSession == null) {
                        clearState();
                        return;
                    }

                    MediaInfo info = currentSession.getMedia();
                    String newTitle = safe(info.getTitle());
                    String newArtist = safe(info.getArtist());
                    BufferedImage newArtwork = info.getArtwork();
                    long newDuration = info.getDuration();
                    long newPosition = info.getPosition();

                    boolean trackChanged = !Objects.equals(newTitle, lastTitle) || !Objects.equals(newArtist, artist);
                    boolean artworkChanged = !areImagesEqual(newArtwork, previousArtwork);

                    title = newTitle;
                    artist = newArtist;
                    duration = newDuration;
                    position = newPosition;
                    session = currentSession;
                    owner = currentSession.getOwner();

                    if (trackChanged) {
                        lastTitle = newTitle;
                        changeTrack = true;
                    }

                    if (changeTrack || artworkChanged) {
                        String newHash = (newArtwork != null) ? hashImage(newArtwork) : "";
                        if (!newHash.equals(previousHash)) {
                            AbstractTexture old = texture;
                            if (newArtwork != null) {
                                AbstractTexture newTexture = RenderEngine.convert(newArtwork);
                                texture = newTexture;
                                previousArtwork = newArtwork;
                                previousHash = newHash;
                            } else {
                                texture = null;
                                previousArtwork = null;
                                previousHash = "";
                            }


                            if (old != null) {
                                mc.getInstance().execute(old::close);
                            }
                        }

                        changeTrack = false;
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
                synchronized (lock) {
                    clearState();
                }
            }
        });
    }

    private void clearState() {
        title = "";
        artist = "";
        owner = "";
        lastTitle = "";
        duration = 0;
        position = 0;
        session = null;
        image = null;
        previousArtwork = null;
        previousHash = "";
        AbstractTexture old = texture;
        texture = null;
        if (old != null) {
            mc.getInstance().execute(old::close);
        }
    }

    private String safe(String s) {
        return s != null ? s : "";
    }


    private String hashImage(BufferedImage img) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(img, "png", baos);
            byte[] bytes = baos.toByteArray();
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(bytes);
            return BaseEncoding.base16().lowerCase().encode(digest);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    private boolean areImagesEqual(BufferedImage img1, BufferedImage img2) {
        if (img1 == img2) return true;
        if (img1 == null || img2 == null) return false;
        if (img1.getWidth() != img2.getWidth() || img1.getHeight() != img2.getHeight()) return false;

        for (int x = 0; x < img1.getWidth(); x += 10) {
            for (int y = 0; y < img1.getHeight(); y += 10) {
                if (img1.getRGB(x, y) != img2.getRGB(x, y)) return false;
            }
        }
        return true;
    }


    public String getLastTitle() {
        return lastTitle;
    }

    public AbstractTexture getTexture() {
        return texture;
    }

    public String getArtist() {
        return artist;
    }


    public boolean fullNullCheck() {
        synchronized (lock) {
            return session == null || texture == null || lastTitle.isEmpty();
        }
    }
}
 
Скинь часть ошибки jvm краша где стактрейс описан

Пример:
1754588844918.png
 
Скинь часть ошибки jvm краша где стактрейс описан

Пример:
Посмотреть вложение 312700
ошибки то по сути и нету, с такой вот хуйней все падает:

Код:
Expand Collapse Copy
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_UNCAUGHT_CXX_EXCEPTION (0xe06d7363) at pc=0x00007fff6aa99f0a, pid=16772, tid=6024
#
# JRE version: OpenJDK Runtime Environment Corretto-21.0.6.7.1 (21.0.6+7) (build 21.0.6+7-LTS)
# Java VM: OpenJDK 64-Bit Server VM Corretto-21.0.6.7.1 (21.0.6+7-LTS, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)
# Problematic frame:
# C  [KERNELBASE.dll+0xc9f0a]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# H:\untitled\run\hs_err_pid16772.log
[44.721s][warning][os] Loading hsdis library failed
#
# If you would like to submit a bug report, please visit:
#   https://github.com/corretto/corretto-21/issues/
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

> Task :runClient FAILED

[Incubating] Problems report is available at: file:///H:/untitled/build/reports/problems/problems-report.html

Execution failed for task ':runClient'.
> Process 'command 'C:\Users\shadow\.jdks\corretto-21.0.6\bin\java.exe'' finished with non-zero exit value -1073740791

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
For more on this, please refer to https://docs.gradle.org/8.14.1/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
BUILD FAILED in 1m 1s
7 actionable tasks: 2 executed, 5 up-to-date
 
ошибки то по сути и нету, с такой вот хуйней все падает:
В консоль оно обычно кидает обрезанный вариант, а вот в файле уже стактрейс есть практически всегда
Код:
Expand Collapse Copy
# An error report file with more information is saved as:
# H:\untitled\run\hs_err_pid16772.log
Открой этот файл и глянь
 
В консоль оно обычно кидает обрезанный вариант, а вот в файле уже стактрейс есть практически всегда
Код:
Expand Collapse Copy
# An error report file with more information is saved as:
# H:\untitled\run\hs_err_pid16772.log
Открой этот файл и глянь
Код:
Expand Collapse Copy
Current thread (0x000001d5ad56fe40):  JavaThread "pool-8-thread-1"        [_thread_in_native, id=6024, stack(0x0000000ca7b00000,0x0000000ca7c00000) (1024K)]

Stack: [0x0000000ca7b00000,0x0000000ca7c00000],  sp=0x0000000ca7bfe920,  free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [KERNELBASE.dll+0xc9f0a]
C  [VCRUNTIME140.dll+0x6480]
C  [MediaPlayerInfo.dll+0x3c0e]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J 30236  dev.redstones.mediaplayerinfo.impl.win.WindowsMediaPlayerInfo.getMediaSessions()Ljava/util/List; (0 bytes) @ 0x000001d54e841893 [0x000001d54e841840+0x0000000000000053]
J 32720 c1 ru.mytheria.api.util.media.MediaPlayer.lambda$onTick$1()V (384 bytes) @ 0x000001d54925cea4 [0x000001d54925cd40+0x0000000000000164]
J 32719 c1 ru.mytheria.api.util.media.MediaPlayer$$Lambda+0x000001d56083e3b8.run()V (8 bytes) @ 0x000001d54925c654 [0x000001d54925c5c0+0x0000000000000094]
J 32679 c2 java.util.concurrent.FutureTask.run$$$capture()V java.base@21.0.6 (123 bytes) @ 0x000001d54fb66378 [0x000001d54fb66280+0x00000000000000f8]
J 26456 c1 java.util.concurrent.FutureTask.run()V java.base@21.0.6 (18 bytes) @ 0x000001d548eb3e94 [0x000001d548eb3de0+0x00000000000000b4]
j  java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V+92 java.base@21.0.6
j  java.util.concurrent.ThreadPoolExecutor$Worker.run()V+5 java.base@21.0.6
j  java.lang.Thread.runWith(Ljava/lang/Object;Ljava/lang/Runnable;)V+5 java.base@21.0.6
j  java.lang.Thread.run()V+19 java.base@21.0.6
v  ~StubRoutines::call_stub 0x000001d54e0c100d

siginfo: EXCEPTION_UNCAUGHT_CXX_EXCEPTION (0xe06d7363), ExceptionInformation=0x0000000019930520 0x0000000ca7bfeab0 0x00007fff4b289b40 0x00007fff4b280000
 
Код:
Expand Collapse Copy
Current thread (0x000001d5ad56fe40):  JavaThread "pool-8-thread-1"        [_thread_in_native, id=6024, stack(0x0000000ca7b00000,0x0000000ca7c00000) (1024K)]

Stack: [0x0000000ca7b00000,0x0000000ca7c00000],  sp=0x0000000ca7bfe920,  free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [KERNELBASE.dll+0xc9f0a]
C  [VCRUNTIME140.dll+0x6480]
C  [MediaPlayerInfo.dll+0x3c0e]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J 30236  dev.redstones.mediaplayerinfo.impl.win.WindowsMediaPlayerInfo.getMediaSessions()Ljava/util/List; (0 bytes) @ 0x000001d54e841893 [0x000001d54e841840+0x0000000000000053]
J 32720 c1 ru.mytheria.api.util.media.MediaPlayer.lambda$onTick$1()V (384 bytes) @ 0x000001d54925cea4 [0x000001d54925cd40+0x0000000000000164]
J 32719 c1 ru.mytheria.api.util.media.MediaPlayer$$Lambda+0x000001d56083e3b8.run()V (8 bytes) @ 0x000001d54925c654 [0x000001d54925c5c0+0x0000000000000094]
J 32679 c2 java.util.concurrent.FutureTask.run$$$capture()V java.base@21.0.6 (123 bytes) @ 0x000001d54fb66378 [0x000001d54fb66280+0x00000000000000f8]
J 26456 c1 java.util.concurrent.FutureTask.run()V java.base@21.0.6 (18 bytes) @ 0x000001d548eb3e94 [0x000001d548eb3de0+0x00000000000000b4]
j  java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V+92 java.base@21.0.6
j  java.util.concurrent.ThreadPoolExecutor$Worker.run()V+5 java.base@21.0.6
j  java.lang.Thread.runWith(Ljava/lang/Object;Ljava/lang/Runnable;)V+5 java.base@21.0.6
j  java.lang.Thread.run()V+19 java.base@21.0.6
v  ~StubRoutines::call_stub 0x000001d54e0c100d

siginfo: EXCEPTION_UNCAUGHT_CXX_EXCEPTION (0xe06d7363), ExceptionInformation=0x0000000019930520 0x0000000ca7bfeab0 0x00007fff4b289b40 0x00007fff4b280000
Печально что оно умирает именно в библиотеке, ну щас повтыкаю подумаю мб чет получится сказать

Хотя что-то интересное я уже нашел, getMediaSessions не должен возвращать пустой лист:

C++:
Expand Collapse Copy
jobject Java_dev_redstones_mediaplayerinfo_impl_win_WindowsMediaPlayerInfo_getMediaSessions(JNIEnv* env, jobject obj) {
    // достаёт инфу об классах
    jclass listClass = env->FindClass("Ljava/util/LinkedList;");
    jmethodID listConstructor = env->GetMethodID(listClass, "<init>", "()V");
    jmethodID listAdd = env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");
    jclass mediaSessionClass = env->FindClass("Ldev/redstones/mediaplayerinfo/impl/win/WindowsMediaSession;");
    jmethodID mediaSessionConstructor = env->GetMethodID(mediaSessionClass, "<init>", "(Ldev/redstones/mediaplayerinfo/MediaInfo;Ljava/lang/String;I)V");
    jclass mediaInfoClass = env->FindClass("Ldev/redstones/mediaplayerinfo/MediaInfo;");
    jmethodID mediaInfoConstructor = env->GetMethodID(mediaInfoClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;[BJJZ)V");

    // создаёт линкедлист
    jobject list = env->NewObject(listClass, listConstructor);
   
    // получает менеджер сессии SMTC в async'е
    auto smtc = GlobalSystemMediaTransportControlsSessionManager::RequestAsync().get();
   
    // получает сессии (и вот тут интересно, может ли smtc быть null из-за async реквеста? хотя по идее там есть же get()...)
    auto sessions = smtc.GetSessions();
    for (int i = 0; i < sessions.Size(); ++i) {
        // объекты сессии создаются тут
    }
   
    return list;
}

UPD:
Не могу ниче придумать кроме того что оно фейлится на получении SMTC из-за того что get() выкидывает эксепшн который ваще никак не обрабатывается (IAsyncOperation может его дропать при get() если операция отменена либо поломалось чёта), сессии нема, ошибка, метод даёт по ёбу и JNI возвращает null

Как варик - добавить проверку кривого завершения получения SMTC и возвращать в таком случае null уже без краша всей жвм, пересобрать библиотеку, profit
Если в падлу заниматься этим, могу попробовать форкануть и пересобрать, но я тут ниче не гарантирую, плюсам я не друг
 
Последнее редактирование:
Печально что оно умирает именно в библиотеке, ну щас повтыкаю подумаю мб чет получится сказать

Хотя что-то интересное я уже нашел, getMediaSessions не должен возвращать пустой лист:

C++:
Expand Collapse Copy
jobject Java_dev_redstones_mediaplayerinfo_impl_win_WindowsMediaPlayerInfo_getMediaSessions(JNIEnv* env, jobject obj) {
    // достаёт инфу об классах
    jclass listClass = env->FindClass("Ljava/util/LinkedList;");
    jmethodID listConstructor = env->GetMethodID(listClass, "<init>", "()V");
    jmethodID listAdd = env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");
    jclass mediaSessionClass = env->FindClass("Ldev/redstones/mediaplayerinfo/impl/win/WindowsMediaSession;");
    jmethodID mediaSessionConstructor = env->GetMethodID(mediaSessionClass, "<init>", "(Ldev/redstones/mediaplayerinfo/MediaInfo;Ljava/lang/String;I)V");
    jclass mediaInfoClass = env->FindClass("Ldev/redstones/mediaplayerinfo/MediaInfo;");
    jmethodID mediaInfoConstructor = env->GetMethodID(mediaInfoClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;[BJJZ)V");

    // создаёт линкедлист
    jobject list = env->NewObject(listClass, listConstructor);
   
    // получает менеджер сессии SMTC в async'е
    auto smtc = GlobalSystemMediaTransportControlsSessionManager::RequestAsync().get();
   
    // получает сессии (и вот тут интересно, может ли smtc быть null из-за async реквеста? хотя по идее там есть же get()...)
    auto sessions = smtc.GetSessions();
    for (int i = 0; i < sessions.Size(); ++i) {
        // объекты сессии создаются тут
    }
   
    return list;
}
пойду подумою
и главное что с индентичном кодом, с теми же утилками проблем нет, версии те же, не понимаю почему такое случается :(
 
и главное что с индентичном кодом, с теми же утилками проблем нет, версии те же, не понимаю почему такое случается :(
Я обновил сообщение, но тип просто это супер странно что такое может случаться
Что-бы понять на 100% че не так, над дебаггер цеплять, а это, ну... типа...
1754591839396.png

В общем в душе не знаю как это сделать (я не про джаваагенты и дебаггеры джава кода)
 
Я обновил сообщение, но тип просто это супер странно что такое может случаться
Что-бы понять на 100% че не так, над дебаггер цеплять, а это, ну... типа...
Посмотреть вложение 312706
В общем в душе не знаю как это сделать (я не про джаваагенты и дебаггеры джава кода)
ну я не знаю, видимо прокляли, ну я в своем старом клиенте с таким же медиаплеером прочекал, почти ничем не отличается от реализации в моем нынешним, скорее всего обойдусь без медиа, пока не найду решение проблемы
 
за 500 рублей скину либку с фиксом
 
Код:
Expand Collapse Copy
Current thread (0x000001d5ad56fe40):  JavaThread "pool-8-thread-1"        [_thread_in_native, id=6024, stack(0x0000000ca7b00000,0x0000000ca7c00000) (1024K)]

Stack: [0x0000000ca7b00000,0x0000000ca7c00000],  sp=0x0000000ca7bfe920,  free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [KERNELBASE.dll+0xc9f0a]
C  [VCRUNTIME140.dll+0x6480]
C  [MediaPlayerInfo.dll+0x3c0e]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J 30236  dev.redstones.mediaplayerinfo.impl.win.WindowsMediaPlayerInfo.getMediaSessions()Ljava/util/List; (0 bytes) @ 0x000001d54e841893 [0x000001d54e841840+0x0000000000000053]
J 32720 c1 ru.mytheria.api.util.media.MediaPlayer.lambda$onTick$1()V (384 bytes) @ 0x000001d54925cea4 [0x000001d54925cd40+0x0000000000000164]
J 32719 c1 ru.mytheria.api.util.media.MediaPlayer$$Lambda+0x000001d56083e3b8.run()V (8 bytes) @ 0x000001d54925c654 [0x000001d54925c5c0+0x0000000000000094]
J 32679 c2 java.util.concurrent.FutureTask.run$$$capture()V java.base@21.0.6 (123 bytes) @ 0x000001d54fb66378 [0x000001d54fb66280+0x00000000000000f8]
J 26456 c1 java.util.concurrent.FutureTask.run()V java.base@21.0.6 (18 bytes) @ 0x000001d548eb3e94 [0x000001d548eb3de0+0x00000000000000b4]
j  java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V+92 java.base@21.0.6
j  java.util.concurrent.ThreadPoolExecutor$Worker.run()V+5 java.base@21.0.6
j  java.lang.Thread.runWith(Ljava/lang/Object;Ljava/lang/Runnable;)V+5 java.base@21.0.6
j  java.lang.Thread.run()V+19 java.base@21.0.6
v  ~StubRoutines::call_stub 0x000001d54e0c100d

siginfo: EXCEPTION_UNCAUGHT_CXX_EXCEPTION (0xe06d7363), ExceptionInformation=0x0000000019930520 0x0000000ca7bfeab0 0x00007fff4b289b40 0x00007fff4b280000
сам код или либка хуйня значит
 
сам код или либка хуйня значит
F374o2qXAAA7iOc.png


Библиотека +- нормальная, местами есть вопросы, но это в целом норм (если не считать что он на сайт мелкомягких либо не заходил, либо смотрел через очки с дырочками)
 
Гпт попроси если музыка завершается ставить трек на не играет или что то такое
 
Библиотека +- нормальная, местами есть вопросы, но это в целом норм (если не считать что он на сайт мелкомягких либо не заходил, либо смотрел через очки с дырочками)
нативка говна у нее, мемори ликает, фикс за 500р продам :pepemoney: вы тут хоть всем скопом пытайтесь, но не зафиксите
, в итоге психанул и переписал MediaPlayer с более улучшенной логикой работы onTick, но
логично, что ты тупой джпт пастер не додумался о том, что проблема на нативной стороне, если уж пиздел, что умный, то оправдай свои знания пастер) хех
ну я не знаю, видимо прокляли, ну я в своем старом клиенте с таким же медиаплеером прочекал, почти ничем не отличается от реализации в моем нынешним, скорее всего обойдусь без медиа, пока не найду решение проблемы
не прокляли тебя не переживай, просто ты ничего неумеющий слабак, который лишь способен попукивать, что то в сторону, но сам являешься обычным пустословом, знания которого ограничены запросом гпт) сиди дальше мозги еби бомж)
 
после закрытия стриминговой платформы (будь то спотифай или что-то другое) происходит краш (как только getMediaSessions() возвращает null) в нативном коде и после чего жвм падает, перепробывал всё что можно и нельзя, хэшировал текстуру, делал проверки и защиту на нулл, один хер он крашит, в итоге психанул и переписал MediaPlayer с более улучшенной логикой работы onTick, но проблема осталась прежней, надеюсь на помощь знатоков с форума :pepe14:
123:
Expand Collapse Copy
package ru.mytheria.api.util.media;


import com.google.common.io.BaseEncoding;
import dev.redstones.mediaplayerinfo.IMediaSession;
import dev.redstones.mediaplayerinfo.MediaInfo;
import dev.redstones.mediaplayerinfo.MediaPlayerInfo;
import net.minecraft.client.texture.AbstractTexture;
import ru.mytheria.api.util.render.RenderEngine;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static ru.mytheria.api.clientannotation.QuickImport.mc;

public class MediaPlayer {

    private BufferedImage image;
    private AbstractTexture texture;
    private String title = "", artist = "", owner = "", lastTitle = "";
    private long duration = 0, position = 0;
    private boolean changeTrack;
    private IMediaSession session;
    private final ExecutorService executor = Executors.newSingleThreadExecutor();


    private BufferedImage previousArtwork = null;
    private final Object lock = new Object();
    private String previousHash = "";


    public void onTick() {
        executor.submit(() -> {
            try {
                List<IMediaSession> currentSessions = MediaPlayerInfo.Instance.getMediaSessions();
                IMediaSession currentSession = currentSessions.stream()
                        .filter(s -> {
                            MediaInfo media = s.getMedia();
                            return media != null && (!media.getArtist().isEmpty() || !media.getTitle().isEmpty());
                        })
                        .findFirst()
                        .orElse(null);

                synchronized (lock) {
                    if (currentSession == null) {
                        clearState();
                        return;
                    }

                    MediaInfo info = currentSession.getMedia();
                    String newTitle = safe(info.getTitle());
                    String newArtist = safe(info.getArtist());
                    BufferedImage newArtwork = info.getArtwork();
                    long newDuration = info.getDuration();
                    long newPosition = info.getPosition();

                    boolean trackChanged = !Objects.equals(newTitle, lastTitle) || !Objects.equals(newArtist, artist);
                    boolean artworkChanged = !areImagesEqual(newArtwork, previousArtwork);

                    title = newTitle;
                    artist = newArtist;
                    duration = newDuration;
                    position = newPosition;
                    session = currentSession;
                    owner = currentSession.getOwner();

                    if (trackChanged) {
                        lastTitle = newTitle;
                        changeTrack = true;
                    }

                    if (changeTrack || artworkChanged) {
                        String newHash = (newArtwork != null) ? hashImage(newArtwork) : "";
                        if (!newHash.equals(previousHash)) {
                            AbstractTexture old = texture;
                            if (newArtwork != null) {
                                AbstractTexture newTexture = RenderEngine.convert(newArtwork);
                                texture = newTexture;
                                previousArtwork = newArtwork;
                                previousHash = newHash;
                            } else {
                                texture = null;
                                previousArtwork = null;
                                previousHash = "";
                            }


                            if (old != null) {
                                mc.getInstance().execute(old::close);
                            }
                        }

                        changeTrack = false;
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
                synchronized (lock) {
                    clearState();
                }
            }
        });
    }

    private void clearState() {
        title = "";
        artist = "";
        owner = "";
        lastTitle = "";
        duration = 0;
        position = 0;
        session = null;
        image = null;
        previousArtwork = null;
        previousHash = "";
        AbstractTexture old = texture;
        texture = null;
        if (old != null) {
            mc.getInstance().execute(old::close);
        }
    }

    private String safe(String s) {
        return s != null ? s : "";
    }


    private String hashImage(BufferedImage img) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(img, "png", baos);
            byte[] bytes = baos.toByteArray();
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(bytes);
            return BaseEncoding.base16().lowerCase().encode(digest);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    private boolean areImagesEqual(BufferedImage img1, BufferedImage img2) {
        if (img1 == img2) return true;
        if (img1 == null || img2 == null) return false;
        if (img1.getWidth() != img2.getWidth() || img1.getHeight() != img2.getHeight()) return false;

        for (int x = 0; x < img1.getWidth(); x += 10) {
            for (int y = 0; y < img1.getHeight(); y += 10) {
                if (img1.getRGB(x, y) != img2.getRGB(x, y)) return false;
            }
        }
        return true;
    }


    public String getLastTitle() {
        return lastTitle;
    }

    public AbstractTexture getTexture() {
        return texture;
    }

    public String getArtist() {
        return artist;
    }


    public boolean fullNullCheck() {
        synchronized (lock) {
            return session == null || texture == null || lastTitle.isEmpty();
        }
    }
}
у тебя nativeimage падает NULL
;
 
нативка говна у нее, мемори ликает
Спс, не зря профайлером посмотрел

вы тут хоть всем скопом пытайтесь, но не зафиксите
Вообще-т починил:goplol:

ты тупой джпт пастер... ...если уж пиздел, что умный, то оправдай свои знания пастер) хех
...не прокляли тебя не переживай, просто ты ничего неумеющий слабак, который лишь способен попукивать
1754669805916.png
 
Назад
Сверху Снизу