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

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

Тема в разделе "Веб-обвязки и лаунчеры", создана пользователем Racvol, 22 дек 2012.

  1. Natsu

    Natsu Активный участник Пользователь

    Баллы:
    88
    Skype:
    korotickiyvit
    Имя в Minecraft:
    Natsu_Zirok
    Никогда не думал, что библиотеки такие вредные бывают =\ Спасибо:eek:
     
  2. Хостинг MineCraft
    <
  3. fhntv24

    fhntv24 Активный участник Пользователь

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

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

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

    Хорошая тема , спасибо афтору за то что и так знал , но он молодец , посторался.
     
  4. fhntv24

    fhntv24 Активный участник Пользователь

    Баллы:
    88
    что вам уже не так ?
     
  5. Crazy-hacker

    Crazy-hacker Активный участник Пользователь

    Баллы:
    66
    А можно код для версий 1.6.4+ ?
     
  6. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    Парси json и будет универсальный запуск, как в моем труе лаунчере. В QT json парсится намного легче даже, чем в либе gson жабы.
     
  7. master_c

    master_c Активный участник Пользователь

    Баллы:
    61
    Всем доброй ночи. Решение с использованием 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")) соответственно не будет работать, пока игрок сам не добавит переменную окружения?
    Как быть в этом случае? Заранее спасибо.
     
  8. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    Это неимеет значение, если качать свою яву в заданную директорию. Ее качать и проверять все равно придется, от всяких УО через яву.
     
  9. HoShiMin

    HoShiMin Старожил Пользователь

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

    И как совет - меньше пользуйся сторонними переменными окружения. С достаточной уверенностью можно доверять только системным переменным, а в идеале - брать системные пути через GetSpecialFolderPath.
     
  10. alexandrage

    alexandrage Администратор

    Баллы:
    173
    Skype:
    alexandr0116
    Да в любом случае без своей явы мало пользы от лаунчера не на яве. Ибо можно будет юзать всякие УО или даже вообще пересобрать под себя jvm.dll.
     
  11. Natsu

    Natsu Активный участник Пользователь

    Баллы:
    88
    Skype:
    korotickiyvit
    Имя в Minecraft:
    Natsu_Zirok
    Здравствуйте, хоть и некропост немного ну да ладно. Поможет всем на 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
     
  12. log_inil

    log_inil Активный участник Пользователь

    Баллы:
    88
    Простите? MClab и JNI? А стримкрафт мклаба? просто помойму TheKoljas слил лаунчер...
     
  13. Natsu

    Natsu Активный участник Пользователь

    Баллы:
    88
    Skype:
    korotickiyvit
    Имя в Minecraft:
    Natsu_Zirok
    ТС, под 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 ? Он ведь не используется[DOUBLEPOST=1456033566,1455992041][/DOUBLEPOST]Вот новый код 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();}}
     

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