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

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

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:
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​
Java:
 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)
Java:
#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 и подключил указанные библиотеки классов игры, и другие стандартные библиотеки классов



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

При анализе Minecraft 1.4.6 я увидел что Нотч хранит параметры MinecraftApplet в специальном классе (Таблица 3 стр 62 и стр 64) этот класс реализует интерфейс AppletStub также он определяет алгоритм изъятия параметров из хранилища.
Устанавливается данный класс в MinecraftApplet с помощью вызова метода setStub
Java:
Object localObject2 = new asf(localHashMap);
localMinecraftApplet.setStub((AppletStub)localObject2);

Все что нам нужно сделать это:
  1. Создать класс HashMap (хранилище параметров MinecraftApplet)
  2. Положить в него параметры с помощью метода put
  3. Создать класс asf на основе созданного HashMap с установленными параметрами
  4. Создать стандартный класс MinecraftApplet и передать ему с помощью метода setStub созданный ранее класс asf
Java:
#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
Java:
 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

Java:
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
Java:
env->CallObjectMethod(obj_hashMap, mtid_put, env->NewStringUTF("username"),        env->NewStringUTF("Racvol"));

Данная функция принимает:
  1. Объект java, у которого хотим вызвать метод
  2. Сам метод, найденный ранее
  3. Параметры этого метода согласно сигнатуре метода
 
Последнее редактирование:
ЭТАП 3 Создание фрейма и запуск Applet
​
Создание фрейма будет осуществляться по следующему алгоритму:​
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();

Код реализующий это на С++
Java:
        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 тк данные методы не возвращают объектов.

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


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

Весь код реализующий данный метод
Java:
#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;
 
}
 
Я вот читая эту часть подумал, а как насчет кроссПлатформости?
Есть идеи? ведь .dll не лучший вариант, поэтому найти бы исходники данного dll
 
@Racvol, а как развернуть окно на весь экран? setExtendedState(MAXIMIZED_BOTH) почему-то не работает (у меня не получилось). И еще, как реализовать настоящий полноэкранный режим (как по нажатию F11)?
 
Я вот читая эту часть подумал, а как насчет кроссПлатформости?
Есть идеи? ведь .dll не лучший вариант, поэтому найти бы исходники данного dll
Исходники есть в сорцах, в инете также есть примеры сборки данной dll в библиотеку под Unix.

Я этим еше не занимался, но в планах написать модуль для Linux под свой сервер
 
Racvol, а как развернуть окно на весь экран? setExtendedState(MAXIMIZED_BOTH) почему-то не работает (у меня не получилось). И еще, как реализовать настоящий полноэкранный режим (как по нажатию F11)?
Вообще надо проконсультироваться у 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

Последний кусок кода будет выглядеть так:
Java:
 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"));
 
Кстате более правильным будет установить свойство fullscreen в true (cм II этап)
 
Читая это, понимаю, что надо приниматься за C++. Но пока даже джавой не владею, стыд и позор.
 
Мне на работе помогло частичное знание Java, когда javaRKVM отказался запускаться на 64 битной Linux
 
Мне на работе помогло частичное знание Java, когда javaRKVM отказался запускаться на 64 битной Linux
Смотрю на Ваши работы и удивляюсь, как красиво все оформлено и сколько труда вложено. Познания действительно обширные, выходящие за рамки обычного серверодержателя. Кем работаете, если не секрет?
 
Как студент-экономист завидую, что работа позволяет хорошо делать то, что нравится. Хотя возможно мои приоритеты изменятся, но все равно чертовски завидую. Сам не могу пару строчек в джаву встроить толком, хех.
 

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

Назад
Верх