Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
  • Данный раздел создан исключительно для релизов! Вопросы по лаунчеру или обвязке задавайте ТОЛЬКО в соответсвующей теме автора. Любые другие темы будут удалены, а авторы понесут наказание.

Способ запуска клиента игры из Лаунчера Часть 2

высокоуровневом языке C++ .
Запуск клиента игры с собственной реализацией Java.exe на низкоуровневом языке С/C++

Язяк то высокоуровневый ... ASM - Это низкий уровень. JVM Код - это тоже низкий

перспектив у данного метода очень много, однако я не видел ни одного лаунчера его реализующего.

MCLab - Первый который прийшел на голову. У них он уже давно. Гдето примерно 3 года как раз таки они уже используют JNI.

Хорошая тема , обесняет как для тупых. Это работает не только с С / С++ - Delphi, C#, и многие другие языки так же содержат JNI. Можно делать дофигища защит с помощу JNI, можно выполнять любой код Java только с лаунчера. Как по мне , имхо , это самый высокий уровень защиты какой только можно придумать. Ну только от печаль беда - и правда нету лаунчеров которые используют активно JNI как метод защити. Некоторые только немного , тот же MCLab, почти не юзает JNI.

Хорошая тема , спасибо афтору за то что и так знал , но он молодец , посторался.
 
Язяк то высокоуровневый ... ASM - Это низкий уровень. JVM Код - это тоже низкий



MCLab - Первый который прийшел на голову. У них он уже давно. Гдето примерно 3 года как раз таки они уже используют JNI.

Хорошая тема , обесняет как для тупых. Это работает не только с С / С++ - Delphi, C#, и многие другие языки так же содержат JNI. Можно делать дофигища защит с помощу JNI, можно выполнять любой код Java только с лаунчера. Как по мне , имхо , это самый высокий уровень защиты какой только можно придумать. Ну только от печаль беда - и правда нету лаунчеров которые используют активно JNI как метод защити. Некоторые только немного , тот же MCLab, почти не юзает JNI.

Хорошая тема , спасибо афтору за то что и так знал , но он молодец , посторался.
Шкальник
 
Всем доброй ночи. Решение с использованием jvm.dll очень интересное. Есть только небольшое "но"..
На своей машине попробовал набрать следующее:
cd %JAVA_HOME%
ответом стало:
c:\Program Files\Java\jdk1.7.0_51>
Ну с этим все понятно, когда-то для экспериментов с Maven и прочим я добавлял эту переменную руками.
Решил поставить на ноутбук "чистые" ОС и яву и проверить. Сначала поставил Windows 7x64 и jdk 1.7, затем попробовал Windows 8x64 и jre 1.8.
В обоих случаях ответом на команду cd %JAVA_HOME% стало "Не удается найти указанный путь".
Или я чего то не понимаю, или переменную JAVA_HOME можно добавить только вручную? Дистрибутивы jdk/jre сами её не добавляют?
Если это так, то конструкция LoadLibrary(_T(JAVA_HOME) _T("\\bin\\server\\jvm.dll")) соответственно не будет работать, пока игрок сам не добавит переменную окружения?
Как быть в этом случае? Заранее спасибо.
 
Всем доброй ночи. Решение с использованием jvm.dll очень интересное. Есть только небольшое "но"..
На своей машине попробовал набрать следующее:
cd %JAVA_HOME%
ответом стало:
c:\Program Files\Java\jdk1.7.0_51>
Ну с этим все понятно, когда-то для экспериментов с Maven и прочим я добавлял эту переменную руками.
Решил поставить на ноутбук "чистые" ОС и яву и проверить. Сначала поставил Windows 7x64 и jdk 1.7, затем попробовал Windows 8x64 и jre 1.8.
В обоих случаях ответом на команду cd %JAVA_HOME% стало "Не удается найти указанный путь".
Или я чего то не понимаю, или переменную JAVA_HOME можно добавить только вручную? Дистрибутивы jdk/jre сами её не добавляют?
Если это так, то конструкция LoadLibrary(_T(JAVA_HOME) _T("\\bin\\server\\jvm.dll")) соответственно не будет работать, пока игрок сам не добавит переменную окружения?
Как быть в этом случае? Заранее спасибо.
Это неимеет значение, если качать свою яву в заданную директорию. Ее качать и проверять все равно придется, от всяких УО через яву.
 
Всем доброй ночи. Решение с использованием jvm.dll очень интересное. Есть только небольшое "но"..
На своей машине попробовал набрать следующее:
cd %JAVA_HOME%
ответом стало:
c:\Program Files\Java\jdk1.7.0_51>
Ну с этим все понятно, когда-то для экспериментов с Maven и прочим я добавлял эту переменную руками.
Решил поставить на ноутбук "чистые" ОС и яву и проверить. Сначала поставил Windows 7x64 и jdk 1.7, затем попробовал Windows 8x64 и jre 1.8.
В обоих случаях ответом на команду cd %JAVA_HOME% стало "Не удается найти указанный путь".
Или я чего то не понимаю, или переменную JAVA_HOME можно добавить только вручную? Дистрибутивы jdk/jre сами её не добавляют?
Если это так, то конструкция LoadLibrary(_T(JAVA_HOME) _T("\\bin\\server\\jvm.dll")) соответственно не будет работать, пока игрок сам не добавит переменную окружения?
Как быть в этом случае? Заранее спасибо.
Читать из реестра напрямую. Если пользователь своими кривыми руками не лезет куда не надо, то в 100% случаев там будет путь непосредственно к jvm.dll для текущей версии джавы соответствующей разрядности. Если же пользователь аутист и руками испортил запись, то достаточно проверить существование этой библиотеки по найденному пути, если её нет - вывести предупреждение, что предустановленная джава не найдена, с предложением ввести путь вручную. Или, как вариант, грузить в лаунчере свою джаву.

И как совет - меньше пользуйся сторонними переменными окружения. С достаточной уверенностью можно доверять только системным переменным, а в идеале - брать системные пути через GetSpecialFolderPath.
 
Читать из реестра напрямую. Если пользователь своими кривыми руками не лезет куда не надо, то в 100% случаев там будет путь непосредственно к jvm.dll для текущей версии джавы соответствующей разрядности. Если же пользователь аутист и руками испортил запись, то достаточно проверить существование этой библиотеки по найденному пути, если её нет - вывести предупреждение, что предустановленная джава не найдена, с предложением ввести путь вручную. Или, как вариант, грузить в лаунчере свою джаву.

И как совет - меньше пользуйся сторонними переменными окружения. С достаточной уверенностью можно доверять только системным переменным, а в идеале - брать системные пути через GetSpecialFolderPath.
Да в любом случае без своей явы мало пользы от лаунчера не на яве. Ибо можно будет юзать всякие УО или даже вообще пересобрать под себя jvm.dll.
 
Здравствуйте, хоть и некропост немного ну да ладно. Поможет всем на 1.7.10

В 1.7.10 и лицензионном лаунчере появилась немного другое понятие запуска в отличие от поста
http://rubukkit.org/threads/sposob-zapuska-klienta-igry-iz-launchera-chast-2.26970/page-6 для 1.7.5

Зайдя в файл .minecraft\versions\1.7.10\1.7.10.json
Я заметил такую строчку
--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type}
${auth_player_name} - Никнейм пользователя (Понятно)
${version_name} - версия игры (Понятно)
${game_directory} - игровая директория. Возможно, по умолчанию стоит .minecraft
${assets_root} - Папка assets (?)
${assets_index_name} - возможно \assets\indexes
${auth_uuid} - uuid. (Понятно)
${auth_access_token} - (Не знаю как описать, но в примере она = 0)
${user_properties} - Настройки пользователя (?)
${user_type} - тип пользователя (?)

В итоге, что бы запустить ванильный minecraft надо передать около 20 строк.

Forge:
Вызывается Твикер в конце ванильной строки --tweakClass cpw.mods.fml.common.launcher.FMLTweaker
--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type} --tweakClass cpw.mods.fml.common.launcher.FMLTweaker

LiteLoader
Вызывается Твикер в конце ванильной строки --tweakClass com.mumfrey.liteloader.launch.LiteLoaderTweaker
--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type} --tweakClass com.mumfrey.liteloader.launch.LiteLoaderTweaker

Forge + LiteLoader
В начале Forge строки вызывается Твикер
--tweakClass com.mumfrey.liteloader.launch.LiteLoaderTweaker
--tweakClass com.mumfrey.liteloader.launch.LiteLoaderTweaker --username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type} --tweakClass cpw.mods.fml.common.launcher.FMLTweaker
 
Язяк то высокоуровневый ... ASM - Это низкий уровень. JVM Код - это тоже низкий



MCLab - Первый который прийшел на голову. У них он уже давно. Гдето примерно 3 года как раз таки они уже используют JNI.

Хорошая тема , обесняет как для тупых. Это работает не только с С / С++ - Delphi, C#, и многие другие языки так же содержат JNI. Можно делать дофигища защит с помощу JNI, можно выполнять любой код Java только с лаунчера. Как по мне , имхо , это самый высокий уровень защиты какой только можно придумать. Ну только от печаль беда - и правда нету лаунчеров которые используют активно JNI как метод защити. Некоторые только немного , тот же MCLab, почти не юзает JNI.

Хорошая тема , спасибо афтору за то что и так знал , но он молодец , посторался.
Простите? MClab и JNI? А стримкрафт мклаба? просто помойму TheKoljas слил лаунчер...
 
ТС, под QT есть очень дикая проблема. При вызове jni_JNI_CreateJavaVM(&jvm,&env,&args); происходит вылет с надписью Error - RtlWerpReportException failed with status code :-1073741823. Will try to launch the process directly.
Хотя, если учесть, что jni.h используется от java8_74, вполне возможно, что в нем проблема.
И зачем jmethodID mid ? Он ведь не используется
Вот новый код main функции.
package net.minecraft.client.main;

import com.google.common.collect.HashMultimap;import com.google.common.collect.Multimap;import com.google.gson.Gson;import java.io.File;import java.io.PrintStream;import java.lang.reflect.Type;import java.net.Authenticator;import java.net.InetSocketAddress;import java.net.Proxy;import java.net.SocketAddress;import java.util.List;import java.util.Map;import java.util.Set;import joptsimple.ArgumentAcceptingOptionSpec;import joptsimple.NonOptionArgumentSpec;import joptsimple.OptionParser;import joptsimple.OptionSet;import joptsimple.OptionSpec;import joptsimple.OptionSpecBuilder;

publicclassMain{privatestaticfinalType a =new bgt();

publicstaticvoid main(String[] arrstring){System.setProperty("java.net.preferIPv4Stack","true");OptionParser optionParser =newOptionParser();
optionParser.allowsUnrecognizedOptions();
optionParser.accepts("demo");
optionParser.accepts("fullscreen");ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec = optionParser.accepts("server").withRequiredArg();ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec2 = optionParser.accepts("port").withRequiredArg().ofType((Class)Integer.class).defaultsTo((Object)25565,(Object[])newInteger[0]);ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec3 = optionParser.accepts("gameDir").withRequiredArg().ofType((Class)File.class).defaultsTo((Object)newFile("."),(Object[])newFile[0]);ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec4 = optionParser.accepts("assetsDir").withRequiredArg().ofType((Class)File.class);ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec5 = optionParser.accepts("resourcePackDir").withRequiredArg().ofType((Class)File.class);ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec6 = optionParser.accepts("proxyHost").withRequiredArg();ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec7 = optionParser.accepts("proxyPort").withRequiredArg().defaultsTo((Object)"8080",(Object[])newString[0]).ofType((Class)Integer.class);ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec8 = optionParser.accepts("proxyUser").withRequiredArg();ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec9 = optionParser.accepts("proxyPass").withRequiredArg();ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec10 = optionParser.accepts("username").withRequiredArg().defaultsTo((Object)("Player"+ bao.K()%1000),(Object[])newString[0]);ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec11 = optionParser.accepts("uuid").withRequiredArg();ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec12 = optionParser.accepts("accessToken").withRequiredArg().required();ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec13 = optionParser.accepts("version").withRequiredArg().required();ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec14 = optionParser.accepts("width").withRequiredArg().ofType((Class)Integer.class).defaultsTo((Object)854,(Object[])newInteger[0]);ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec15 = optionParser.accepts("height").withRequiredArg().ofType((Class)Integer.class).defaultsTo((Object)480,(Object[])newInteger[0]);ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec16 = optionParser.accepts("userProperties").withRequiredArg().required();ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec17 = optionParser.accepts("assetIndex").withRequiredArg();ArgumentAcceptingOptionSpec argumentAcceptingOptionSpec18 = optionParser.accepts("userType").withRequiredArg().defaultsTo((Object)"legacy",(Object[])newString[0]);NonOptionArgumentSpec nonOptionArgumentSpec = optionParser.nonOptions();OptionSet optionSet = optionParser.parse(arrstring);List list = optionSet.valuesOf((OptionSpec)nonOptionArgumentSpec);Stringstring=(String)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec6);Proxy proxy =Proxy.NO_PROXY;if(string!=null){try{
proxy =newProxy(Proxy.Type.SOCKS,newInetSocketAddress(string,(int)((Integer)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec7))));}catch(Exception var25_25){// empty catch block}}String string2 =(String)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec8);String string3 =(String)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec9);if(!proxy.equals(Proxy.NO_PROXY)&&Main.a(string2)&&Main.a(string3)){Authenticator.setDefault((Authenticator)new bgv(string2, string3));}int n =(Integer)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec14);int n2 =(Integer)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec15);boolean bl = optionSet.has("fullscreen");boolean bl2 = optionSet.has("demo");String string4 =(String)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec13);HashMultimap hashMultimap =HashMultimap.create();for(Map.Entry object2 :((Map)newGson().fromJson((String)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec16), a)).entrySet()){
hashMultimap.putAll(object2.getKey(),(Iterable)object2.getValue());}File file =(File)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec3);File file2 = optionSet.has((OptionSpec)argumentAcceptingOptionSpec4)?(File)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec4):newFile(file,"assets/");File file3 = optionSet.has((OptionSpec)argumentAcceptingOptionSpec5)?(File)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec5):newFile(file,"resourcepacks/");String string5 = optionSet.has((OptionSpec)argumentAcceptingOptionSpec11)?(String)argumentAcceptingOptionSpec11.value(optionSet):(String)argumentAcceptingOptionSpec10.value(optionSet);String string6 = optionSet.has((OptionSpec)argumentAcceptingOptionSpec17)?(String)argumentAcceptingOptionSpec17.value(optionSet):null;
bbs bbs2 =new bbs((String)argumentAcceptingOptionSpec10.value(optionSet), string5,(String)argumentAcceptingOptionSpec12.value(optionSet),(String)argumentAcceptingOptionSpec18.value(optionSet));
bao bao2 =new bao(bbs2, n, n2, bl, bl2, file, file2, file3, proxy, string4,(Multimap)hashMultimap, string6);String string7 =(String)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec);if(string7 !=null){
bao2.a(string7,((Integer)optionSet.valueOf((OptionSpec)argumentAcceptingOptionSpec2)).intValue());}Runtime.getRuntime().addShutdownHook((Thread)new bgw("Client Shutdown Thread"));if(!list.isEmpty()){System.out.println("Completely ignored arguments: "+ list);}Thread.currentThread().setName("Client thread");
bao2.f();}

privatestaticboolean a(Stringstring){returnstring!=null&&!string.isEmpty();}}
 

Поделиться этой страницей

Назад
Верх