Привет! Понимаю твою боль — тема написания софта под Майнкрафт через JNI (тем более под старые версии) реально скудно задокументирована, и на форумах часто вместо помощи кидаются тапками.
Сразу оговорюсь:
я текстовая нейросеть, поэтому прикрепленное видео или исходники я не вижу. Но по твоему описанию симптомов вырисовывается классическая картина для новичков в JNI. Вылет при попытке получить энтити (игрока) — это почти всегда краш самой виртуальной машины Java (JVM) из-за неверной работы с памятью.
Вот главные причины, почему твой Майнкрафт "умирает" при инжекте, и как это исправить.
1. Несовместимость версий Java (Главный подозреваемый)
Ты написал, что используешь
JDK 21. Майнкрафт 1.8.9 исторически и технически написан под
Java 8.Если ты компилируешь свою C++ DLL, используя заголовочные файлы (jni.h, jni_md.h) от JDK 21, а игра крутится на Java 8 (которую TLauncher обычно подтягивает сам для старых версий), происходит жесткий конфликт структур в памяти.
- Что делать: Скачай JDK 8 (например, Adoptium / Eclipse Temurin 8). В настройках твоего C++ проекта (Visual Studio или что ты используешь) укажи пути к папкам include и include/win32 именно от восьмой джавы. Полностью пересобери проект.
2. Обфускация и нулевые указатели (NullPointerException в C++)
В гайде, скорее всего, используют чистые маппинги (MCP) или пишут под Forge-клиент, где классы имеют читаемые названия (например, net/minecraft/client/entity/EntityPlayerSP).Если ты запускаешь обычную ванильную 1.8.9 через TLauncher (или OptiFine без Forge), классы игры
обфусцированы (перемешаны в буквы типа ave для Minecraft, bew для игрока и т.д.).
Если твой код пытается найти класс по нормальному имени:
C++
jclass playerClass = env->FindClass(<span>"net/minecraft/client/entity/EntityPlayerSP"</span>);<br>
А в твоем клиенте он называется bew, функция FindClass не найдет его и вернет nullptr (пустоту). Когда ты на следующем шаге попытаешься получить здоровье или координаты из этого nullptr, C++ попытается прочитать несуществующую память, и игра
моментально закроется без ошибок.
- Что делать: Обязательно проверяй КАЖДОЕ действие на nullptr и выводи в консоль отладки сообщения. Вот так:
C++
jclass playerClass = env->FindClass(<span>"net/minecraft/client/entity/EntityPlayerSP"</span>);<br><span>if</span> (playerClass == <span>nullptr</span>) {<br> <span>printf</span>(<span>"[-] ОШИБКА: Класс игрока не найден!\n"</span>);<br> env->ExceptionClear(); <span>// Очищаем ошибку JNI, чтобы JVM не умерла</span><br> <span>return</span>; <span>// Прерываем функцию, чтобы не крашнуть игру</span><br>}<br><span>printf</span>(<span>"[+] Класс игрока успешно найден!\n"</span>);<br>
3. Проблема с потоками (AttachCurrentThread)
JNIEnv* (указатель на окружение Java) привязан к конкретному потоку. Если ты делаешь инжект DLL и запускаешь свою логику в отдельном потоке (через CreateThread), ты не можешь просто взять и использовать функции JNI.
- Что делать: Тебе нужно сначала "прикрепить" твой C++ поток к JVM. В начале твоего рабочего потока должна быть функция jvm->AttachCurrentThread((void)&env, nullptr);, а при выходе — jvm->DetachCurrentThread();.
Как нам двигаться дальше?Попробуй расставить такие проверки (if (что-то == nullptr) printf...) перед каждым получением класса (FindClass), метода (GetMethodID) и поля (GetFieldID).
Скажи, какие именно маппинги/названия классов ты используешь в коде (MCP названия или обфусцированные буквы), и на какой конкретно строчке кода происходит вылет, если судить по выводу твоей консоли отладки?