1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
  3. Данный раздел создан исключительно для релизов! Вопросы по лаунчеру или обвязке задавайте ТОЛЬКО в соответсвующей теме автора. Любые другие темы будут удалены, а авторы понесут наказание.

Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

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

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

  1. Автор темы
    Racvol

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

    Баллы:
    123
    Эта статья является продолжением статьи http://rubukkit.org/threads/Способы-запуска-клиента-игры-из-Лаунчера-Часть-1.26937/
    III в) Запуск клиента игры с собственной реализацией Java.exe без промежуточного кода на высокоуровневом языке C++ .

    В предыдущем разделе был описан пример где вызывалась java.exe однако этот бинарник является неуправляемым, а следовательно и мы можем реализовать свой собственный бинарник без вызова java.exe, в седлающей реализации мне удалось снять основное ограничения которое описаны в предыдущем разделе, мне удалось создать java классы в коде С++ и вызывать Java методы и классы из C++, перспектив у данного метода очень много, однако я не видел ни одного лаунчера его реализующего.

    Основные 3 этапы запуска игры
    • Создание виртуальной машины Java в собственном коде
    • Модификация net.minecraft.client.MinecraftApplet из minecraft.jar
    • Создание фрейма и запуск Applet
    Памятка:
    Таблица 1 Возможные параметры MinecraftApplet 1.4.6 от 20.12.12​
    PHP:
    "username"        "UserName"
    "stand-alone"    "true"
    или"false"
    "demo"            "true"
    или"false"
    "fullscreen"    "true"
    или"false"
    "sessionid"        "sessionid"
    "server"        "Ip_сервера"
    "port"            "port_сервера"
    Таблица 2 Строка запуска клиента из консоли​
    Код:
    java -Djava.class.path=%APPDATA%\.minecraft\bin\lwjgl.jar;%APPDATA%\.minecraft\bin\jinput.jar;%APPDATA%\.minecraft\bin\lwjgl_util.jar;%APPDATA%\.minecraft\bin\minecraft.jar; -Djava.library.path=%APPDATA%\.minecraft\bin\natives net.minecraft.client.Minecraft UserName SessionId [-demo || --applet || --password]
    Таблица 3 Код main функции net.minecraft.client.Minecraft
    Код:
     public static void main(String[] paramArrayOfString) {
        HashMap localHashMap = new HashMap();
    
        boolean bool1 = false;
        boolean bool2 = true;
        boolean bool3 = false;
    
        String str1 = "Player" + F() % 1000L;
        if (paramArrayOfString.length > 0) str1 = paramArrayOfString[0];
    
        String str2 = "-";
        if (paramArrayOfString.length > 1) str2 = paramArrayOfString[1];
    
        for (int i1 = 2; i1 < paramArrayOfString.length; i1++) {
          localObject1 = paramArrayOfString[i1];
          localObject2 = i1 == paramArrayOfString.length - 1 ? null : paramArrayOfString[(i1 + 1)];
          int i2 = 0;
    
          if ((((String)localObject1).equals("-demo")) || (((String)localObject1).equals("--demo"))) {
            bool1 = true;
          } else if (((String)localObject1).equals("--applet")) {
            bool2 = false;
          } else if ((((String)localObject1).equals("--password")) && (localObject2 != null)) {
            String[] arrayOfString = jv.a(str1, (String)localObject2);
            if (arrayOfString != null) {
              str1 = arrayOfString[0];
              str2 = arrayOfString[1];
              System.out.println("Logged in insecurely as " + str1 + " - sessionId is " + str2);
            } else {
              System.out.println("Could not log in as " + str1 + " with given password");
            }
            i2 = 1;
          }
    
          if (i2 != 0) {
            i1++;
          }
    
        }
    
        localHashMap.put("demo", "" + bool1);
        localHashMap.put("stand-alone", "" + bool2);
        localHashMap.put("username", str1);
        localHashMap.put("fullscreen", "" + bool3);
        localHashMap.put("sessionid", str2);
    
        Frame localFrame = new Frame();
        localFrame.setTitle("Minecraft");
        localFrame.setBackground(Color.BLACK);
    
        Object localObject1 = new JPanel();
        localFrame.setLayout(new BorderLayout());
        ((JPanel)localObject1).setPreferredSize(new Dimension(854, 480));
        localFrame.add((Component)localObject1, "Center");
        localFrame.pack();
    
        localFrame.setLocationRelativeTo(null);
        localFrame.setVisible(true);
    
        localFrame.addWindowListener(new ask());
    
        Object localObject2 = new asf(localHashMap);
        MinecraftApplet localMinecraftApplet = new MinecraftApplet();
        localMinecraftApplet.setStub((AppletStub)localObject2);
    
        ((asf)localObject2).setLayout(new BorderLayout());
        ((asf)localObject2).add(localMinecraftApplet, "Center");
        ((asf)localObject2).validate();
    
        localFrame.removeAll();
        localFrame.setLayout(new BorderLayout());
        localFrame.add((Component)localObject2, "Center");
        localFrame.validate();
    
        localMinecraftApplet.init();
        localMinecraftApplet.start();
    
        Runtime.getRuntime().addShutdownHook(new asl());
      }
    ЭТАП 1 Создание виртуальной машины Java в собственном коде


    Самое первое что необходимо сделать это указать расположение заговочных файлов jni.h и jni_md.h в этих заговочных файлах указаны прототипы функций и классы.

    Наш код Лаунчер должен загрузить jvm.dll, эта библиотека осужесвляет взаимодействие нашего кода с виртуальной машиной Java. Чтобы создать виртуальную машину мы должны вызвать функцию "JNI_CreateJavaVM" из этой jvm.dll, мы должны указать виртуальной машине где находятся нативные библиотеки игры и классы(Таблица 2)
    Код:
    #pragma region ЭТАП I: начальная инициализация
        HMODULE hJvm = ::LoadLibrary(_T(JAVA_HOME) _T("\\bin\\server\\jvm.dll"));
    
        jni_JNI_CreateJavaVM = (JNI_CREATEJAVAVM)GetProcAddress(hJvm, "JNI_CreateJavaVM"); //Получаем адреес функции в dll
    
    
        /*
            Для запуска клиента игры необходимо указать виртуальной машине java
            где находятся классы клиента и нативные библиотеки
        */
        JavaVMOption options[2];
        options[0].optionString = "-Djava.class.path=" GAME_PATH "\\bin\\lwjgl_util.jar;"
                                                      GAME_PATH "\\bin\\lwjgl.jar;"
                                                      GAME_PATH "\\bin\\jinput.jar;"
                                                      GAME_PATH "\\bin\\minecraft.jar;";
    
        options[1].optionString = "-Djava.library.path=" GAME_PATH "\\bin\\natives";
    
    
        //Формируем опции запуска виртуальной машины
        JavaVMInitArgs args;
        args.options = options;
        args.nOptions = 2; // Количество опций
        args.ignoreUnrecognized = FALSE;
        args.version = JNI_VERSION_1_6;
    
        //Вспомогательные классы, олицетворяющие виртуальную машину Java и среду выпонения
        JavaVM* jvm = NULL;
        JNIEnv* env = NULL;
    
        //Вызываем функцию JNI_CreateJavaVM из dll адрес которой получили ранее
        jni_JNI_CreateJavaVM(&jvm, &env, &args);
    На данный момент наш лаунчер уже создал виртуальную машину Java и подключил указанные библиотеки классов игры, и другие стандартные библиотеки классов

    [​IMG]

    ЭТАП 2 Модификация net.minecraft.client.MinecraftApplet

    При анализе Minecraft 1.4.6 я увидел что Нотч хранит параметры MinecraftApplet в специальном классе (Таблица 3 стр 62 и стр 64) этот класс реализует интерфейс AppletStub также он определяет алгоритм изъятия параметров из хранилища.
    Устанавливается данный класс в MinecraftApplet с помощью вызова метода setStub
    Код:
    Object localObject2 = new asf(localHashMap);
    localMinecraftApplet.setStub((AppletStub)localObject2);
    Все что нам нужно сделать это:
    1. Создать класс HashMap (хранилище параметров MinecraftApplet)
    2. Положить в него параметры с помощью метода put
    3. Создать класс asf на основе созданного HashMap с установленными параметрами
    4. Создать стандартный класс MinecraftApplet и передать ему с помощью метода setStub созданный ранее класс asf
    Код:
    #pragma region ЭТАП II: Модифицируем стандартный MinecraftApplete
    
            /* Создание класса MinecraftApplete */
            jclass class_appletStub = env->FindClass("asf"); // Получение класса реализующего интерфей AppletStub (Minecraft 1.4.6)
            jmethodID mtid_appletStub = env->GetMethodID(class_appletStub, "<init>" , "(Ljava/util/Map;)V"); // Получаем метод конструктора
    
            jobject obj_hashMap = env->NewObject(env->FindClass("java/util/HashMap"), env->GetMethodID(env->FindClass("java/util/HashMap"), "<init>", "()V"));
            jmethodID mtid_put =  env->GetMethodID(env->FindClass("java/util/HashMap"), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
    
            //Ради чего весь геморой, это установить данные параметры
            env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("username"),        env->NewStringUTF("Racvol"));
            env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("stand-alone"),    env->NewStringUTF("true"));
            env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("demo"),            env->NewStringUTF("false"));
            env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("fullscreen"),    env->NewStringUTF("false"));
            env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("sessionid"),    env->NewStringUTF("-"));
            //env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("server"),        env->NewStringUTF("127.0.0.1"));
            //env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("port"),        env->NewStringUTF("25555"));
    
            jobject obj_appletStub = env->NewObject(class_appletStub, mtid_appletStub, obj_hashMap); // Создаем обьект полученного типа реализующего AppletStub
    
            jobject obj_minecraftApplet = env->NewObject(env->FindClass("net/minecraft/client/MinecraftApplet"), env->GetMethodID(env->FindClass("net/minecraft/client/MinecraftApplet"), "<init>", "()V"));// Создаем стандартный MinecraftApplet
    
            // Вызываем функцию setStub и передаем в качестве аргумента модифицированный appletStub
            env->CallVoidMethod(obj_minecraftApplet, env->GetMethodID(env->GetObjectClass(obj_minecraftApplet), "setStub", "(Ljava/applet/AppletStub;)V"), obj_appletStub);
    #pragma endregion
    
    1. Создать класс HashMap
    Код:
     jobject obj_hashMap = env->NewObject(env->FindClass("java/util/HashMap"), env->GetMethodID(env->FindClass("java/util/HashMap"), "<init>", "()V"));
    Создание объекта java осуществляется за счет вызова функции NewObject он принимает тип создаваемого класса (находится за счет вызова функции FindClass("java/util/HashMap") которое возвращает тип найденного класса), метод которое мы хотим вызвать (получает за счет вызова GetMethodID(env->FindClass("java/util/HashMap"), "<init>", "()V") обратите внимание на второй параметр он говорит о том что мы хотим вызвать конструктор и третий параметр это сигнатура данной функции говорящая что конструктор не принимает никаких параметров и не возвращает их)

    Сигнатуру методов можно посмотреть с помощью утилиты javap например сигнатура конструкторадля класса asf из minecraft.jar

    Код:
    C:\Users\Алексей>javap -p -classpath C:\Users\Алексей\AppData\Roaming\.minecraft\bin\minecraft.jar -s asf
    Compiled from "SourceFile"
    public class asf extends java.applet.Applet implements java.applet.AppletStub {
      final java.util.Map a;
        Signature: Ljava/util/Map;
      public asf(java.util.Map);
        Signature: (Ljava/util/Map;)V
    он принимает объект которое наследует от класса java.util.Map и имеет вид (Ljava/util/Map;)V
    2. Положить в объект HashMap параметры с помощью метода put
    Код:
    env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("username"),        env->NewStringUTF("Racvol"));
    Данная функция принимает:
    1. Объект java, у которого хотим вызвать метод
    2. Сам метод, найденный ранее
    3. Параметры этого метода согласно сигнатуре метода
     
    Последнее редактирование: 12 янв 2014
    Sm1leTwo, maksimkurb, Skyline и 15 другим нравится это.
  2. Автор темы
    Racvol

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

    Баллы:
    123
    ЭТАП 3 Создание фрейма и запуск Applet

    Создание фрейма будет осуществляться по следующему алгоритму:​
    Код:
                JFrame frame = new JFrame();
                frame.setTitle("My Minecraft Title");
                frame.setSize(854, 480);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
     
                BorderLayout borderLayout = new BorderLayout();
                appletStub.setLayout(borderLayout);
                appletStub.add(minecraftApplet, BorderLayout.CENTER);
                appletStub.validate();
             
                frame.add(appletStub, BorderLayout.CENTER);         
                frame.validate();
     
                minecraftApplet.init();
                minecraftApplet.start();    
    Код реализующий это на С++
    Код:
            jobject obj_frame = env->NewObject(env->FindClass("javax/swing/JFrame"), env->GetMethodID(env->FindClass("javax/swing/JFrame"), "<init>", "()V"));     
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setTitle", "(Ljava/lang/String;)V"), env->NewStringUTF("My Minecraft Title"));
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setSize", "(II)V"), 854, 480);
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setDefaultCloseOperation", "(I)V"), 3);
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setVisible", "(Z)V"), (jboolean)true);
     
            jobject obj_borderLayout = env->NewObject(env->FindClass("java/awt/BorderLayout"), env->GetMethodID(env->FindClass("java/awt/BorderLayout"), "<init>", "()V"));
            env->CallVoidMethod(obj_appletStub, env->GetMethodID(env->GetObjectClass(obj_appletStub), "setLayout", "(Ljava/awt/LayoutManager;)V"), obj_borderLayout);
            env->CallVoidMethod(obj_appletStub, env->GetMethodID(env->GetObjectClass(obj_appletStub), "add", "(Ljava/awt/Component;Ljava/lang/Object;)V"), obj_minecraftApplet, env->NewStringUTF("Center"));
            env->CallVoidMethod(obj_appletStub, env->GetMethodID(env->GetObjectClass(obj_appletStub), "validate", "()V"));
     
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "add", "(Ljava/awt/Component;Ljava/lang/Object;)V"), obj_appletStub, env->NewStringUTF("Center"));     
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "validate", "()V")); 
     
            env->CallVoidMethod(obj_minecraftApplet, env->GetMethodID(env->GetObjectClass(obj_minecraftApplet), "init", "()V"));
            env->CallVoidMethod(obj_minecraftApplet, env->GetMethodID(env->GetObjectClass(obj_minecraftApplet), "start", "()V"));
    
    Единственное отличие от предыдущего этапа это использование CallVoidMethodвместо CallObjectMethod тк данные методы не возвращают объектов.

    На этом все как видно на рисунке ниже запуск клиента прошел успешно
    [​IMG]

    Преимущество данного подхода в том что он не создает отдельный процесс а запускает игру как поток внутри текущего процесса лаунчера, а следовательно можно мониторить клиент на предмет читов или изменения клиента игры на протяжении всей игры, а не тока при запуске, по сути дела Лаунчер сам является клиентом игры, также у вас есть полный контроль над адресным пространством игры, можно из лаунчера вызывать различные события в клиенте игры.

    Весь код реализующий данный метод
    Код:
    #include <jni.h>
    #include <windows.h>
    #include <tchar.h>
     
    #define JAVA_HOME "C:\\Program Files\\Java\\jre8"
    #define GAME_PATH "C:\\Users\\Алексей\\AppData\\Roaming\\.minecraft"
     
    typedef jint (JNICALL *JNI_CREATEJAVAVM)(JavaVM **, JNIEnv **, void *);
    JNI_CREATEJAVAVM jni_JNI_CreateJavaVM = NULL;
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    #pragma region ЭТАП I: начальная инициализация
        HMODULE hJvm = ::LoadLibrary(_T(JAVA_HOME) _T("\\bin\\server\\jvm.dll"));
     
        jni_JNI_CreateJavaVM = (JNI_CREATEJAVAVM)GetProcAddress(hJvm, "JNI_CreateJavaVM"); //Получаем адреес функции в dll
       
     
        /*
            Для запуска клиента игры необходимо указать виртуальной машине java
            где находятся классы клиента и нативные библиотеки
        */
        JavaVMOption options[2];
        options[0].optionString = "-Djava.class.path=" GAME_PATH "\\bin\\lwjgl_util.jar;"
                                                      GAME_PATH "\\bin\\lwjgl.jar;"
                                                      GAME_PATH "\\bin\\jinput.jar;"
                                                      GAME_PATH "\\bin\\minecraft.jar;";
     
        options[1].optionString = "-Djava.library.path=" GAME_PATH "\\bin\\natives";
       
     
        //Формируем опции запуска виртуальной машины
        JavaVMInitArgs args;
        args.options = options;
        args.nOptions = 2; // Количество опций
        args.ignoreUnrecognized = FALSE;
        args.version = JNI_VERSION_1_6;
     
        //Вспомогательные классы, олицитворяющие виртуальную машину Java и среду выпонения
        JavaVM* jvm = NULL;
        JNIEnv* env = NULL;
     
        //Вызываем функцию JNI_CreateJavaVM из dll адресс которой получили ранее
        jni_JNI_CreateJavaVM(&jvm, &env, &args);
    #pragma endregion
        /* На данный момен у нас создана виртуальная машина, теперь нам нужно запустить сам клиент */
    #pragma region ЭТАП II: Модифицируем стандартный MinecraftApplete
     
            /* Создание класса MinecraftApplete */
            jclass class_appletStub = env->FindClass("asf"); // Получение класса реализующего интерфей AppletStub (Minecraft 1.4.6)
            jmethodID mtid_appletStub = env->GetMethodID(class_appletStub, "<init>" , "(Ljava/util/Map;)V"); // Получаем метод конструктора
           
            jobject obj_hashMap = env->NewObject(env->FindClass("java/util/HashMap"), env->GetMethodID(env->FindClass("java/util/HashMap"), "<init>", "()V"));
            jmethodID mtid_put =  env->GetMethodID(env->FindClass("java/util/HashMap"), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
           
            //Ради чего весь геморой, это установить данные параметры
            env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("username"),        env->NewStringUTF("Racvol"));
            env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("stand-alone"),    env->NewStringUTF("true"));
            env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("demo"),            env->NewStringUTF("false"));
            env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("fullscreen"),    env->NewStringUTF("false"));
            env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("sessionid"),    env->NewStringUTF("-"));
            //env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("server"),        env->NewStringUTF("127.0.0.1"));
            //env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("port"),        env->NewStringUTF("25555"));
           
            jobject obj_appletStub = env->NewObject(class_appletStub, mtid_appletStub, obj_hashMap); // Создаем обьект полученного типа реализующего AppletStub
     
            jobject obj_minecraftApplet = env->NewObject(env->FindClass("net/minecraft/client/MinecraftApplet"), env->GetMethodID(env->FindClass("net/minecraft/client/MinecraftApplet"), "<init>", "()V"));// Создаем стандартный MinecraftApplet
           
            // Вызываем функцию setStub и передаем в качестве аргумента модифицированный appletStub
            env->CallVoidMethod(obj_minecraftApplet, env->GetMethodID(env->GetObjectClass(obj_minecraftApplet), "setStub", "(Ljava/applet/AppletStub;)V"), obj_appletStub);
    #pragma endregion
    #pragma region ЭТАП III: Запуск клиента игры
            /* Запуск клиента будет осущесвляться по нижеследающему Java алгоритму*/
            /*
                JFrame frame = new JFrame();
                frame.setTitle("My Minecraft Title");
                frame.setSize(854, 480);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
     
                BorderLayout borderLayout = new BorderLayout();
                appletStub.setLayout(borderLayout);
                appletStub.add(minecraftApplet, BorderLayout.CENTER);
                appletStub.validate();
               
                frame.add(appletStub, BorderLayout.CENTER);           
                frame.validate();
     
                minecraftApplet.init();
                minecraftApplet.start();   
            */
     
            jobject obj_frame = env->NewObject(env->FindClass("javax/swing/JFrame"), env->GetMethodID(env->FindClass("javax/swing/JFrame"), "<init>", "()V"));       
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setTitle", "(Ljava/lang/String;)V"), env->NewStringUTF("My Minecraft Title"));
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setSize", "(II)V"), 854, 480);
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setDefaultCloseOperation", "(I)V"), 3);
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setVisible", "(Z)V"), (jboolean)true);
     
            jobject obj_borderLayout = env->NewObject(env->FindClass("java/awt/BorderLayout"), env->GetMethodID(env->FindClass("java/awt/BorderLayout"), "<init>", "()V"));
            env->CallVoidMethod(obj_appletStub, env->GetMethodID(env->GetObjectClass(obj_appletStub), "setLayout", "(Ljava/awt/LayoutManager;)V"), obj_borderLayout);
            env->CallVoidMethod(obj_appletStub, env->GetMethodID(env->GetObjectClass(obj_appletStub), "add", "(Ljava/awt/Component;Ljava/lang/Object;)V"), obj_minecraftApplet, env->NewStringUTF("Center"));
            env->CallVoidMethod(obj_appletStub, env->GetMethodID(env->GetObjectClass(obj_appletStub), "validate", "()V"));
     
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "add", "(Ljava/awt/Component;Ljava/lang/Object;)V"), obj_appletStub, env->NewStringUTF("Center"));       
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "validate", "()V"));   
     
            env->CallVoidMethod(obj_minecraftApplet, env->GetMethodID(env->GetObjectClass(obj_minecraftApplet), "init", "()V"));
            env->CallVoidMethod(obj_minecraftApplet, env->GetMethodID(env->GetObjectClass(obj_minecraftApplet), "start", "()V"));
     
    #pragma endregion
            // Ставим паузу на основной поток, при завершении основного потока, завершают свою работы все дочерние потоки
            Sleep(100000000);
        return 0;
     
    }
    
     
    Inspector, Hephest, Сало и 18 другим нравится это.
  3. hummer

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

    Баллы:
    123
    Skype:
    bond_russia
    Неплохо поработал)
     
    LeftMyHouse нравится это.
  4. hummer

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

    Баллы:
    123
    Skype:
    bond_russia
    Я вот читая эту часть подумал, а как насчет кроссПлатформости?
    Есть идеи? ведь .dll не лучший вариант, поэтому найти бы исходники данного dll
     
  5. NaparNIK

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

    Баллы:
    78
    @Racvol, а как развернуть окно на весь экран? setExtendedState(MAXIMIZED_BOTH) почему-то не работает (у меня не получилось). И еще, как реализовать настоящий полноэкранный режим (как по нажатию F11)?
     
  6. Автор темы
    Racvol

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

    Баллы:
    123
    Исходники есть в сорцах, в инете также есть примеры сборки данной dll в библиотеку под Unix.

    Я этим еше не занимался, но в планах написать модуль для Linux под свой сервер
     
    ВремяПриключений нравится это.
  7. Автор темы
    Racvol

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

    Баллы:
    123

    Вообще надо проконсультироваться у Java программистов но судя по всему надо вызвать два метода

    setUndecorated(true); Убираем рамку
    setExtendedState(Frame.MAXIMIZED_BOTH); Разворачиваем на полный экран

    http://docs.oracle.com/javase/1.4.2/docs/api/constant-values.html#java.awt.Frame.MAXIMIZED_BOTH
    тут указанно что MAXIMIZED_BOTH имеет значение 6

    Последний кусок кода будет выглядеть так:
    Код:
     jobject obj_frame = env->NewObject(env->FindClass("javax/swing/JFrame"), env->GetMethodID(env->FindClass("javax/swing/JFrame"), "<init>", "()V"));
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setTitle", "(Ljava/lang/String;)V"), env->NewStringUTF("My Minecraft Title"));
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setSize", "(II)V"), 854, 480);
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setUndecorated","(Z)V"), (jboolean)true);
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setExtendedState", "(I)V"), 6);
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setDefaultCloseOperation", "(I)V"), 3);
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "setVisible", "(Z)V"), (jboolean)true);
     
            jobject obj_borderLayout = env->NewObject(env->FindClass("java/awt/BorderLayout"), env->GetMethodID(env->FindClass("java/awt/BorderLayout"), "<init>", "()V"));
            env->CallVoidMethod(obj_appletStub, env->GetMethodID(env->GetObjectClass(obj_appletStub), "setLayout", "(Ljava/awt/LayoutManager;)V"), obj_borderLayout);
            env->CallVoidMethod(obj_appletStub, env->GetMethodID(env->GetObjectClass(obj_appletStub), "add", "(Ljava/awt/Component;Ljava/lang/Object;)V"), obj_minecraftApplet, env->NewStringUTF("Center"));
            env->CallVoidMethod(obj_appletStub, env->GetMethodID(env->GetObjectClass(obj_appletStub), "validate", "()V"));
     
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "add", "(Ljava/awt/Component;Ljava/lang/Object;)V"), obj_appletStub, env->NewStringUTF("Center"));
            env->CallVoidMethod(obj_frame, env->GetMethodID(env->GetObjectClass(obj_frame), "validate", "()V"));
     
            env->CallVoidMethod(obj_minecraftApplet, env->GetMethodID(env->GetObjectClass(obj_minecraftApplet), "init", "()V"));
            env->CallVoidMethod(obj_minecraftApplet, env->GetMethodID(env->GetObjectClass(obj_minecraftApplet), "start", "()V"));
     
  8. Автор темы
    Racvol

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

    Баллы:
    123
    Кстате более правильным будет установить свойство fullscreen в true (cм II этап)
     
  9. NaparNIK

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

    Баллы:
    78
    Я пробовал, но ничего не вышло. Кстати я переписал код на Delphi, если надо - выложу.
     
  10. Russiablackbird

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

    Баллы:
    103
    Skype:
    russiablackbird
    Так а толку от win платформы одной.Перепиши под freepascal тогда куда лучше
     
  11. Автор темы
    Racvol

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

    Баллы:
    123
    Выкладывай, хочу знать как там сишные заголовочные файлы используются
     
  12. mr.cashzoomhello

    mr.cashzoomhello Активный участник

    Баллы:
    63
    Имя в Minecraft:
    Mr_CashZoomHello
    Ух ты да вы профессионалы, мож ктоньть научит програмированию?
     
  13. Автор темы
    Racvol

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

    Баллы:
    123
  14. mr.cashzoomhello

    mr.cashzoomhello Активный участник

    Баллы:
    63
    Имя в Minecraft:
    Mr_CashZoomHello
    ок спс)
     
    zuma2 нравится это.
  15. pizzlywizzly

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

    Баллы:
    123
    Читая это, понимаю, что надо приниматься за C++. Но пока даже джавой не владею, стыд и позор.
     
    Bafolol нравится это.
  16. Russiablackbird

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

    Баллы:
    103
    Skype:
    russiablackbird
    Это даже хорошо что не владеешь ей
     
    zuma2, REZAYS, HoShiMin и ещё 1-му нравится это.
  17. Автор темы
    Racvol

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

    Баллы:
    123
    Мне на работе помогло частичное знание Java, когда javaRKVM отказался запускаться на 64 битной Linux
     
  18. pizzlywizzly

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

    Баллы:
    123
    Смотрю на Ваши работы и удивляюсь, как красиво все оформлено и сколько труда вложено. Познания действительно обширные, выходящие за рамки обычного серверодержателя. Кем работаете, если не секрет?
     
    ПриветОтМиднайта нравится это.
  19. Автор темы
    Racvol

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

    Баллы:
    123
    Инженер у интернет провайдера
     
  20. pizzlywizzly

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

    Баллы:
    123
    Как студент-экономист завидую, что работа позволяет хорошо делать то, что нравится. Хотя возможно мои приоритеты изменятся, но все равно чертовски завидую. Сам не могу пару строчек в джаву встроить толком, хех.
     

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