1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
| #include <jni.h>
#include <windows.h>
#include <tchar.h>
#define JAVA_HOME "C:\\Program Files\\Java\\jre7"
#define GAME_PATH "C:\\Users\\Admin\\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("Admin"));
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;
} |