Найти тему
Недопрограммист

Создание лаунчера Майнкрафт для чайников 1 часть

Оглавление

Перейдем сразу к делу.

1.) Во первых нам нужно скачать JRE на вашу операционную систему. Переходим на официальный сайт Java https://www.java.com ищем продукт подходящую для вашей ОС.

2.) Теперь нам нужно скачать JDK. Переходим на сайт https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html, читаем инструкцию и устанавливаем.

3.) После того, как вы все сделали вышеперечисленное мы переходим к скачиванию самой рабочей среды. Переходим на сайт eclipse.org, нажимаем на кнопку Download x86_64(Если у вас не устанавливается, можете скачать более позднюю версию Eclipse)

Download x86_64
Download x86_64
Download
Download
Устанавливаем Eclipse Java
Устанавливаем Eclipse Java

Выбираете директорию и устанавливаете её.

По окончанию установки, заходите на рабочий стол и запускаете приложение.

Создание проекта

Создаем в Eclipse проект "Create a Java project" под названием Launcher.

-5

Не изменяя больше ничего нажимаем на кнопку "Finish".(Можно выбрать версию JavaSE поменьше, например 1.8, потом можно будет изменить)

-6

Готово

Установка плагина WindowBuilder для GUI программирования

1.) Для начала заходим в Eclipse.

Ищем кнопку Help в верхней панели и нажимаем на нее.

-7

В списке находим кнопку Install New Software...

-8

Нажимаем на нее и у нас появляется данное окошко:

-9

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

-10
-11

Мы находим плагин и нажимаем Install

Начнется скачивание, ждем пока установится. После скачивания появится данное окошко:

-12

Нажимаем Restart Now и готово.

Создание класса(Class)

В созданном проекте создаем пакет(Package) net.minecraft нажимая ЛКМ на папку src в проекте Launcher.

-13

а в пакете net.minecraft создаем класс(class) LauncherFrame нажимая ЛКМ на наш пакет.

-14

Выбираем Other...

Появится новое окошко:

-15

Выбираем то что нужно, для создания окна приложения, я использую JFrame.

Класс создался, выбираем Design внизу редактирования кода.

-16

Чтоб вернуться обратно к коду, нажимаем на Source.

Появится окошко редактирование и туда копируем:

//====Код============================
//Здесь мы пишем имя пакета(путь к классу)
package net.minecraft;
//Здесь мы импортируем из java библиотеки
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
//Здесь мы пишем публикуем наш класс LauncherFrame как окно(JFrame)
public class LauncherFrame extends JFrame {
//Здесь мы публикуем панельку
private JPanel contentPane;
//Делам запуск окна
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
//Создаем окно frame
LauncherFrame frame = new LauncherFrame();
//Делаем окно видимым
frame.setVisible(true);
//По центру
frame.setLocationRelativeTo(null);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
//Здесь будет контент frame
public LauncherFrame() {
//Пишем что изменение размера пользователем запрещено
setResizable(false);
//Здесь пишем название приложения
setTitle("Launcher beta v1.0");
//Пишем что при нажатии на крестик идет выход из приложении
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Размеры окна
setBounds(100, 100, 871, 520);
//Создаем панель где именно он будет хранить все компоненты
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
//Добавляем панель
setContentPane(contentPane);
contentPane.setLayout(null);
//==================Здесь будут компоненты=======================
//==================Конец добавления компонентов=======================
}
}
//====Конец кода=======================

Сохраняем(Ctrl - s) и запускаем при этом выбрав класс LauncherFrame.

-17

Появится вот такое пусто окно:

-18

Закрываем.

Давайте создадим JTextField для ведении игроком ника.

Пишем в классе LauncherFrame между комментарием 'Здесь будут компоненты' и 'Конец добавления компонентов' такой код...

//Здесь мы создаем JTextField с именем User
User = new JTextField();
//Здесь мы определяем цвет текста
User.setForeground(Color.BLACK);
//Пишем координаты User
User.setBounds(86, 446, 174, 30);
//Добавляем его в панельку
contentPane.add(User);
User.setColumns(10);

И добавим строчку после private JPanel contentPane;

public static JTextField User;

Сохраняем, запускаем и у нас появится окошко и поле ввода. Пока что оно ничего не делает.

Давайте как-то украсим наш лаунчер и добавим фото на фон с помощью JLabel. Давайте скачаем любую картинку, добавим в папку src еще одну папку с именем img

-19

И в папку img перенесем(мышкой) наше фото. Ну всё, теперь к коду. И после 'Конец добавления компонентов'(иначе фон будет закрывать другие элементы) пишем вот это:

//Создаем JLabel с именем img
JLabel img = new JLabel("");
//Добавляем иконку к JLabel(titleImg.jpg - название моей фотографии)
img.setIcon(new ImageIcon(new ImageIcon(LauncherFrame.class.getResource("/img/titleImg.jpg")).getImage().getScaledInstance(this.getWidth(), this.getHeight(), Image.SCALE_DEFAULT)));
//Расположение и размер
img.setBounds(0, 0, 865, 491);
//Добавляем в панельку
contentPane.add(img);

Не забывайте импортировать библиотеки. Чтоб их импортировать наведите курсор например на JLabel помеченным красной линией и нажмите на "Import 'JLabel' (javax.swing)"

И когда оно импортируется красная линия пропадёт. Если вы не можете так, то можно текстом в начале кода после объявления package(пакета, если есть):

import javax.swing.JLabel;

Теперь давайте добавим кнопку, которая будет собирать данные из нашего JTextField и запускать игру. Добавляем наш код после строки User.setColumns(10);

//Создаем кнопку Play не забывая импортировать
JButton Play = new JButton("Играть"); //// //
//Пишем стиль текста кнопки
Play.setFont(new Font("Tahoma", Font.PLAIN, 32));
//Цвет фона
Play.setBackground(Color.WHITE);
//Убираем фокус выделения
Play.setFocusPainted(false);
//Цвет текста
Play.setForeground(Color.BLACK);
//Координаты кнопки и размер
Play.setBounds(704, 414, 151, 59);
//Добавляем в панельку
contentPane.add(Play);
//Делаем при наведении курсор рукой
Play.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

Запускаем и смотрим.

Запуск майнкрафт

Добавим новый класс Settings в пакет net.minecraft

Пусто
Пусто

В класс Settings Добавим вот такие строки:

package net.minecraft;
import java.util.ArrayList;
import java.util.Arrays;
public class Settings{
public static String folderMinecraft = ".launcherTest"; //Папка для майнкрафт
public static boolean forge = false;
}

Создадим новый пакет net.minecraft.Utils и в нем же класс Utils

Редактируем Utils:

package net.minecraft.Utils;
import net.minecraft.Settings;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
public class Utils
{
public static int numberLog = 0;
//Будем вести лог(консоль)
public static void logMsg(String msg) {
//Префикс
String prefix = "[TestLauncher - " + numberLog + "]";
//Печатаем в консоль
System.out.println(prefix + msg);
//Добавляем каждый раз к переменной один
numberLog++;
}
//Узнаем ос
public static String getOS() {
String osName = System.getProperty("os.name").toLowerCase();
if(osName.contains("win")) return "Windows";
if(osName.contains("mac")) return "MacOS";
if(osName.contains("linux")) return "Linux";
//Если ничего не подходит
return null;
}
//Здесь мы находим папку майнкрафт у разных ОС
public static String getMinecraftFolder() {
String home = System.getProperty("user.home");
String appData = System.getenv("AppData");
String slash = File.separator;
if (getOS().equals("Windows")) return appData + slash + Settings.folderMinecraft;
if (getOS().equals("MacOS")) return home + slash + "Library/Application Support/" + Settings.folderMinecraft;
if (getOS().equals("Linux")) return home + slash + Settings.folderMinecraft; return null;
}
//Здесь наши библиотеки
//Объявляем новую переменную со значением ArrayList
public static ArrayList<String> clientLibs = new ArrayList<String>( Arrays.asList(
//Для запуска ванильного minecraft
"libraries/net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar",
"libraries/org/ow2/asm/asm-all/4.1/asm-all-4.1.jar",
"libraries/org/lwjgl/lwjgl/lwjgl/2.9.0/lwjgl-2.9.0.jar",
"libraries/org/lwjgl/lwjgl/lwjgl_util/2.9.0/lwjgl_util-2.9.0.jar",
"libraries/org/lwjgl/lwjgl/lwjgl/2.9.0/jinput-2.0.5.jar",
"libraries/net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar",
"libraries/com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar",
"libraries/com/paulscode/codecwav/20101023/codecwav-20101023.jar",
"libraries/com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar",
"libraries/com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar",
"libraries/com/paulscode/soundsystem/20120107/soundsystem-20120107.jar",
"libraries/argo/argo/2.25_fixed/argo-2.25_fixed.jar",
"libraries/org/bouncycastle/bcprov-jdk15on/1.47/bcprov-jdk15on-1.47.jar",
"libraries/com/google/guava/guava/14.0/guava-14.0.jar",
"libraries/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar",
"libraries/commons-io/commons-io/2.4/commons-io-2.4.jar",
"libraries/com/google/code/gson/gson/2.2.2/gson-2.2.2.jar",
//Для forge
"libraries/org/scala-lang/scala-library/2.10.2/scala-library-2.10.2.jar",
"libraries/org/scala-lang/scala-compiler/2.10.2/scala-compiler-2.10.2.jar",
"libraries/org/ow2/asm/asm-all/4.1/asm-all-4.1.jar",
"libraries/lzma/lzma/0.0.1/lzma-0.0.1.jar",
"forge/lwrap.jar",
"forge/mcforge.jar"
) );
//Если обратятся к getClientLibs то она вернет список getClientLibs.
public static ArrayList<String> getClientLibs()
{
return clientLibs;
}
}

Сохраняем и создаем новый класс MinecraftClient в этом же пакете.

В этом классе мы напишем запуск нашего Minecraft:

package net.minecraft.Utils;
import net.minecraft.Settings;
import net.minecraft.Utils.Utils;
import static net.minecraft.Utils.Utils.logMsg;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class MinecraftClient {
private String playerName;
private String session;
private boolean forge;
private String serverIP;
private String serverPort;
private String minecraftFolderPath;
private String memory;
private String minecraftJar;
private String separatorLib;
private String javaHome;
private String libs = "";
private ProcessBuilder processBuilder;
public MinecraftClient(String playerName, String session, boolean forge, String serverIP, String serverPort){
this.playerName = playerName;
this.session = session;
this.forge = forge;
this.serverIP = serverIP;
this.serverPort = serverPort;
}
public void start() {
try {
//папка майнкрафт
minecraftFolderPath = Utils.getMinecraftFolder();
//память на игру
memory = "512M";
logMsg("Папка майнкрафт: " + minecraftFolderPath + "");
logMsg("ОЗУ: " +memory+ "");
logMsg("сессия: " + session + "");
//jar игры
minecraftJar = Utils.getMinecraftFolder() + File.separator + "versions"+ File.separator +"1.6.2"+ File.separator + "1.6.2.jar";
javaHome = System.getProperty("java.home");
logMsg("Путь к 1.6.2.jar: " + Utils.getMinecraftFolder() + File.separator + "versions"+ File.separator +"1.6.2"+ File.separator +"1.6.2.jar");
if (Utils.getOS() == "Windows") {
separatorLib = ";";
javaHome+=File.separator + "bin" + File.separator + "javaw.exe";
logMsg("Путь к java:" + System.getProperty("java.home") + File.separator + "bin" + File.separator + "javaw.exe" + "");
logMsg("Подключение к javaw.exe...");
} else {
separatorLib = ":";
javaHome+=File.separator + "bin" + File.separator + "java.exe";
logMsg("Подключение к java.exe...");
}
for (String lib : Utils.getClientLibs()) {
libs += lib + separatorLib;
logMsg("Переменная lib: " + lib + separatorLib + "");
}
List<String> parameters = new ArrayList<String>();
parameters.add(javaHome);
parameters.add("-Xmx" + memory);
parameters.add("-Djava.library.path=versions/1.6.2/natives");
parameters.add("-Dfml.ignoreInvalidMinecraftCertificates=true");
parameters.add("-Dfml.ignorePatchDiscrepancies=true");
parameters.add("-cp");
parameters.add(libs + minecraftJar);
if (!forge) {
parameters.add("net.minecraft.client.main.Main");
logMsg("Запуск майнкрафт forge...");
} else if (forge) {
parameters.add("net.minecraft.client.main.Main");
parameters.add("--tweakClass");
parameters.add("cpw.mods.fml.common.launcher.FMLTweaker");
logMsg("Запуск ванильный майнкрафт...");
}
parameters.add("--username");
parameters.add(playerName);
parameters.add("--session");
parameters.add(session);
parameters.add("--version");
parameters.add("1.6.2");
parameters.add("--gameDir");
parameters.add(minecraftFolderPath);
parameters.add("--assetsDir");
parameters.add(minecraftFolderPath + File.separator + "assets");
parameters.add("--fullscreen");
parameters.add("true");
if(serverIP != null && serverPort != null) {
parameters.add("--server");
parameters.add(serverIP);
parameters.add("--port");
parameters.add(serverPort);
}
processBuilder = new ProcessBuilder();
processBuilder.directory(new File(minecraftFolderPath).getCanonicalFile());
processBuilder.command(parameters);
processBuilder.inheritIO();
processBuilder.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}

Мы просто переделали cmd запуск майнкрафа. Я работаю с версией 1.6.2, но если она вам не нравится, то вы можете ее изменить.

Нам осталось только запустить все это с помощью кнопки Играть в классе LauncherFrame.

Переходим в класс LauncherFrame и находим наше кнопку.

После строки

Play.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

Мы пишем:

Path papka_sistem = Paths.get("" + Utils.getMinecraftFolder() + "");
Play.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
//============Если мы не вели логин===============
if(User.getText().equals("")) {
logMsg("Не вели логин");
}else {
//===============Проверяем существует ли папка с майнкрафтом===================
if (Files.notExists(papka_sistem)) {
logMsg("Ошибка: не существует папки " + Utils.getMinecraftFolder() );
}
//==================В остальном=======================
else {
logMsg("" + Utils.getMinecraftFolder() + "");
logMsg("Запуск версии: 1.6.2");
logMsg("Ник:" + User.getText() + ".");
logMsg("Версия forge: "+ Settings.forge +".");
logMsg("Запуск: Minecraft client");
MinecraftClient client = new MinecraftClient(User.getText(), "12345", Settings.forge, null, null);//Последние два значения это- IP и PORT
client.start();
logMsg("Выход из лаунчера...");
//============Выход из лаунчера===============
System.exit(0);
}
}
}
});

Все импортируем и импортируем вручную logMsg после import net.minecraft.Utils.Utils;

import static net.minecraft.Utils.Utils.logMsg;

Запустив лаунчер, мы получим такой ответ в консоли:

-21

Чтоб исправить, нужно создать такую папку по такому адресу как написано в консоли.

После этого скачать rar файл или скачать другую версию майнкрафт с библиотеками и  загрузить все файлы в эту папку.

launcher.rar

Как на фото:

-22

Нажмем на нашу кнопку и у нас запустится Майнкрафт 1.6.2.

-23

Исходный код:

launcher_code.rar

Как изменить версию Minecraft с 1.6.2 на более новую?

Например: Как запустить Minecraft 1.12.2.

  1. Скачиваем лаунчер с поддержкой командой строки или логов. Например: TLauncher.
  2. Заходим и устанавливаем 1.12.2 (Вы можете скачать другое).
  3. Включим командую строку или логи в Лаунчере.(В TLauncher они находятся в настройках):
-24

4. Устанавливаем и запускаем майнкрафт. При запуске в логах или в
консоле должна появиться такой текст:

-25

Получаем всё, что идёт после Full command:

C:\Users\1\AppData\Roaming\.minecraft\runtime\jre-legacy\windows\jre-legacy\bin\javaw.exe -Dos.name=Windows 10 -Dos.version=10.0 -Djava.library.path=C:\Users\1\AppData\Roaming\.minecraft\versions\1.12.2\natives -cp C:\Users\1\AppData\Roaming\.minecraft\libraries\org\tlauncher\tl_skin_cape_1.12.2\1.14\tl_skin_cape_1.12.2-1.14.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\ow2\asm\asm-tree\6.2\asm-tree-6.2.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\ow2\asm\asm\6.2\asm-6.2.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\ow2\asm\asm-commons\6.2\asm-commons-6.2.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\net\minecraft\launchwrapper\1.12\launchwrapper-1.12.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\tlauncher\patchy\1.3.9\patchy-1.3.9.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\oshi-project\oshi-core\1.1\oshi-core-1.1.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\net\java\dev\jna\jna\4.4.0\jna-4.4.0.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\net\java\dev\jna\platform\3.4.0\platform-3.4.0.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\5.0.3\jopt-simple-5.0.3.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\io\netty\netty-all\4.1.9.Final\netty-all-4.1.9.Final.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\com\google\guava\guava\21.0\guava-21.0.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\apache\commons\commons-lang3\3.5\commons-lang3-3.5.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\commons-io\commons-io\2.5\commons-io-2.5.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\commons-codec\commons-codec\1.10\commons-codec-1.10.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\com\google\code\gson\gson\2.8.0\gson-2.8.0.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\tlauncher\authlib\1.6.251\authlib-1.6.251.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\com\mojang\realms\1.10.22\realms-1.10.22.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\apache\commons\commons-compress\1.8.1\commons-compress-1.8.1.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\apache\httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\apache\httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\it\unimi\dsi\fastutil\7.1.0\fastutil-7.1.0.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.8.1\log4j-api-2.8.1.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.8.1\log4j-core-2.8.1.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.4-nightly-20150209\lwjgl-2.9.4-nightly-20150209.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.4-nightly-20150209\lwjgl_util-2.9.4-nightly-20150209.jar;C:\Users\1\AppData\Roaming\.minecraft\libraries\com\mojang\text2speech\1.10.3\text2speech-1.10.3.jar;C:\Users\1\AppData\Roaming\.minecraft\versions\1.12.2\1.12.2.jar -Xmn128M -Xmx2955M -XX:+UseConcMarkSweepGC -Dminecraft.applet.TargetDirectory=C:\Users\1\AppData\Roaming\.minecraft -Dlog4j.configurationFile=C:\Users\1\AppData\Roaming\.minecraft\assets\log_configs\client-1.12.xml org.tlauncher.Launch1_12_2 --username Name --version 1.12.2 --gameDir C:\Users\1\AppData\Roaming\.minecraft --assetsDir C:\Users\1\AppData\Roaming\.minecraft\assets --assetIndex 1.12 --uuid fb2defbcdcdd4b82ac31b9b841b59e2e --accessToken null --userType mojang --versionType release --width 925 --height 530

По этим данным замените класс .MinecraftClient.java на:

package net.minecraft.Utils;

import net.minecraft.LauncherFrame;
import net.minecraft.Settings;
import net.minecraft.Utils.Utils;

import static net.minecraft.Utils.Utils.logMsg;

import java.io.File;
import java.util.ArrayList;
import java.util.List;


public class MinecraftClient {

private String playerName;
private String session;
private boolean forge;
private String serverIP;
private String serverPort;
private String minecraftFolderPath;
private String memory;
private String minecraftJar;
private String separatorLib;
private String javaHome;
private String libs = "";




private ProcessBuilder processBuilder;

public MinecraftClient(String playerName, String session, boolean forge, String serverIP, String serverPort){
this.playerName = playerName;
this.session = session;
this.forge = forge;
this.serverIP = serverIP;
this.serverPort = serverPort;

}

public void start() {
try {

//папка майнкрафт
minecraftFolderPath = Utils.getMinecraftFolder();
//память на игру
memory = "1024M";
logMsg("Папка майнкрафт: " + minecraftFolderPath + "");
logMsg("ОЗУ: " +memory+ "");
logMsg("сессия: " + session + "");
//jar игры
minecraftJar = Utils.getMinecraftFolder() + File.separator + "versions"+ File.separator +"1.6.2"+ File.separator + "1.6.2.jar";
javaHome = System.getProperty("java.home");
logMsg("Путь к 1.6.2.jar: " + Utils.getMinecraftFolder() + File.separator + "versions"+ File.separator +"1.6.2"+ File.separator +"1.6.2.jar");

if (Utils.getOS() == "Windows") {
separatorLib = ";";
javaHome+=File.separator + "bin" + File.separator + "javaw.exe";
logMsg("Путь к java:" + System.getProperty("java.home") + File.separator + "bin" + File.separator + "javaw.exe" + "");
logMsg("Подключение к javaw.exe...");
} else {
separatorLib = ":";
javaHome+=File.separator + "bin" + File.separator + "java.exe";
logMsg("Подключение к java.exe...");

}

for (String lib : Utils.getClientLibs()) {
libs += lib + separatorLib;
logMsg("Переменная lib: " + lib + separatorLib + "");
}
List<String> parameters = new ArrayList<String>();
parameters.add(javaHome);
parameters.add("-Djava.net.preferIPv4Stack=true");

parameters.add("-Xmn128M");
parameters.add("-Xmx" + memory);
parameters.add("-Djava.library.path=versions/1.12.2/natives");
parameters.add("-cp");
parameters.add(libs + minecraftJar);
parameters.add("-Dminecraft.applet.TargetDirectory="+minecraftFolderPath+"");
parameters.add("-Dfml.ignoreInvalidMinecraftCertificates=true");
parameters.add("-Dfml.ignorePatchDiscrepancies=true");



parameters.add("net.minecraft.client.main.Main");


parameters.add("--username");
parameters.add(playerName);
parameters.add("--version");
parameters.add("1.12.2");
parameters.add("--gameDir");
parameters.add(minecraftFolderPath);
parameters.add("--assetsDir");
parameters.add(minecraftFolderPath + File.separator + "assets");
parameters.add("--assetIndex");
parameters.add("1.12");
parameters.add("--uuid");
parameters.add("00000000-0000-0000-0000-000000000000");
parameters.add("--accessToken");
parameters.add("null");
parameters.add("--userType");
parameters.add("legacy");
parameters.add("--versionType");
parameters.add("release");
parameters.add("--width");

parameters.add("512");
parameters.add("--height");
parameters.add("512");
processBuilder = new ProcessBuilder();
processBuilder.directory(new File(minecraftFolderPath).getCanonicalFile());
processBuilder.command(parameters);
processBuilder.inheritIO();
processBuilder.start();

} catch (Exception e) {
e.printStackTrace();
}
}
}

Замените массив clientLibs в Utils.java :

public static ArrayList<String> clientLibs = new ArrayList<String>( Arrays.asList(
//Для запуска ванильного minecraft
"libraries/org/tlauncher/patchy/1.1/patchy-1.1.jar",
...
"versions/1.12.2/1.12.2.jar"
) );

На

public static ArrayList<String> clientLibs = new ArrayList<String>( Arrays.asList(
//Для запуска ванильного minecraft
"libraries/org/tlauncher/patchy/1.1/patchy-1.1.jar",
"libraries/oshi-project/oshi-core/1.1/oshi-core-1.1.jar",
"libraries/net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar",
"libraries/net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar",
"libraries/com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar",
"libraries/net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar",
"libraries/com/paulscode/codecjorbis/20101023/codecjorbis-20101023.jar",
"libraries/com/paulscode/codecwav/20101023/codecwav-20101023.jar",
"libraries/com/paulscode/libraryjavasound/20101123/libraryjavasound-20101123.jar",
"libraries/com/paulscode/librarylwjglopenal/20100824/librarylwjglopenal-20100824.jar",
"libraries/com/paulscode/soundsystem/20120107/soundsystem-20120107.jar",
"libraries/io/netty/netty-all/4.1.9.Final/netty-all-4.1.9.Final.jar",
"libraries/com/google/guava/guava/21.0/guava-21.0.jar",
"libraries/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar", //=
"libraries/commons-io/commons-io/2.5/commons-io-2.5.jar",
"libraries/commons-codec/commons-codec/1.10/commons-codec-1.10.jar",
"libraries/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar",
"libraries/net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar",
"libraries/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar",
"libraries/com/mojang/authlib/1.5.25/authlib-1.5.25.jar",//=
"libraries/com/mojang/realms/1.10.22/realms-1.10.22.jar",//=
"libraries/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar",//=
"libraries/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar",//=
"libraries/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar",//=
"libraries/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar",//=
"libraries/it/unimi/dsi/fastutil/7.1.0/fastutil-7.1.0.jar",//=
"libraries/org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar",//=
"libraries/org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar",//=
"libraries/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209/lwjgl-2.9.4-nightly-20150209.jar",//=
"libraries/org/lwjgl/lwjgl/lwjgl_util/2.9.4-nightly-20150209/lwjgl_util-2.9.4-nightly-20150209.jar",//=
"libraries/com/mojang/text2speech/1.10.3/text2speech-1.10.3.jar",//=
"versions/1.12.2/1.12.2.jar"
) );

Также не забудьте поменять файлы в папке лаунчера .launcherTest или же просто поменяйте название папки лаунчера, где уже скачена Minecraft 1.12.2, на .launcherTest (Напр: .minecraft на .launcherTest)

В итоге у вас запустится Майнкрафт 1.12.2.

Майнкрафт 1.12.2
Майнкрафт 1.12.2

Лог ошибок вы можете смотреть в консоли вашего IDE

Надеюсь у вас получилось!

Исходный код Ч.2 (Utils.java, MinecraftClient.java):

Utils_and_MinecraftClient_code_L1_P2.zip