Skip to content
This repository has been archived by the owner on Nov 10, 2017. It is now read-only.

Разбор командной строки на примере запуска Minecraft 1.8

dedepete edited this page Dec 24, 2014 · 5 revisions

Данная статья является расширенным дополнением другой статьи.

Введение

Запуск Minecraft на "джебовском" лаунчере довольно сильно отличается от запуска на "нотчевстком".

Запуск Minecraft на "нотчевском" лаунчере:

javaw -Xmx1G -cp "%APPDATA%/.minecraft/bin/minecraft.jar;%APPDATA%/.minecraft/bin/jinput.jar;%APPDATA%/.minecraft/bin/lwjgl.jar;%APPDATA%/.minecraft/bin/lwjgl_util.jar" -Djava.library.path="%APPDATA%/.minecraft/bin/natives/" net.minecraft.client.Minecraft USERNAME SESSION

План построения командной строки

  1. Проверка наличия библиотек, которые требуются для запускаемой версии.
  2. Проверка наличия 1.8.jar файла версии.
  3. Если вы хотите играть на лицензии, то получение uuid, accessToken и userProperties(Для работы Twitch'a). Если вы хотите играть на пиратке, то генерация случайных uuid, accessToken и userProperties. Для userProperties обязателен формат {"key": ["value"]}).
  4. Распаковка natives в какую-нибудь директорию.
  5. Построение процесса и запуск.

Пример командной строки

Minecraft можно запустить без особых навыков программирования. Это значит, что лаунчер можно создать на любом языке программирования. Однако, для этого необходимо построить очень длинную команду.

C:\Program Files\Java\jre7\bin\java.exe 
-Xmx1G 
-Djava.library.path=C:\Users\Popov\AppData\Roaming\.minecraft\natives 
-cp C:\Users\Popov\AppData\Roaming\.minecraft\libraries\java3d\vecmath\1.5.2\vecmath-1.5.2.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\net\sf\trove4j\trove4j\3.0.3\trove4j-3.0.3.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.6\jopt-simple-4.6.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\io\netty\netty-all\4.0.15.Final\netty-all-4.0.15.Final.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\com\google\guava\guava\17.0\guava-17.0.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\org\apache\commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\commons-codec\commons-codec\1.9\commons-codec-1.9.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\com\mojang\authlib\1.5.17\authlib-1.5.17.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\com\mojang\realms\1.5.4\realms-1.5.4.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\org\apache\commons\commons-compress\1.8.1\commons-compress-1.8.1.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\org\apache\httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\org\apache\httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.1\lwjgl-2.9.1.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.1\lwjgl_util-2.9.1.jar;C:\Users\Popov\AppData\Roaming\.minecraft\libraries\tv\twitch\twitch\6.5\twitch-6.5.jar;C:\Users\Popov\AppData\Roaming\.minecraft\versions\1.8\1.8.jar 
net.minecraft.client.main.Main 
--username Nickname  
--version 1.8 
--gameDir C:\Users\Popov\AppData\Roaming\.minecraft 
--assetsDir C:\Users\Popov\AppData\Roaming\.minecraft\assets\ 
--assetIndex 1.8 
--uuid 1a2b3c4d5e6f7g8h9i0g 
--accessToken 1a2b3c4d5e6f7g8h9i0g 
--userProperties {"twitch_access_token":["1a2b3c4d5e6f7g8h9i0g"]} 
--userType mojang 
--server play.minez.net 
--port 25565
--height 480
--width 854

Разбор командной строки

${propertyName} обозначены параметры, которые являются непостоянными и могут изменяться

${javaExecutable} 
${javaParameters}
-Djava.library.path=${nativesPath} 
-cp ${library};${library};${library}...
${mainClass} 
--username ${username}  
--version ${version} 
--gameDir ${gameDir} 
--assetsDir ${assetsDir} 
--assetIndex ${assetIndex} 
--uuid ${uuid} 
--accessToken ${accessToken} 
--userProperties ${userProperties} 
--userType ${userType} 
[--server ${serverIp}] 
[--port ${serverPort}]
[--height ${windowHeight}]
[--width ${windowWidth}]

[ ] взяты необязательные аргументы

Параметр Аргумент Обозначение Принимаемые значения Пример параметра
${javaExecutable} НЕТ Полный путь до исполняемого файла Java Строка C:\Program Files\Java\jre7\bin\java.exe
${javaParameters} НЕТ Параметры Java То, что принимает Java -Xmx1G
${nativesPath} -Djava.library.path= Полный путь до директории с распакованными natives Строка C:\Users\Popov\AppData\Roaming\.minecraft\natives
${library} Формат -cp ${library};${library};${library}... Полный путь до библиотеки .jar. Сюда же относится 1.8.jar Строки ...C:\Users\Popov\AppData\Roaming\.minecraft\libraries\tv\twitch\twitch\6.5\twitch-6.5.jar;C:\Users\Popov\AppData\Roaming\.minecraft\versions\1.8\1.8.jar
${mainClass} НЕТ Класс в 1.8.jar, который содержит главный метод Строка net.minecraft.client.main.Main
${username} --username Имя игрока Строка DedePete
${version} --version Версия, которая запускается(возможно, данный параметр не играет важной роли) Строка 1.8
${gameDir} --gameDir Рабочая папка игры. Отсюда загружаются моды, ресурс паки и т.п. Строка C:\Users\Popov\AppData\Roaming\.minecraft\
${assetsDir} --assetsDir Папка с ресурсами для игры Строка C:\Users\Popov\AppData\Roaming\.minecraft\assets\
${assetsIndex} --assetsIndex Файл с картой хэшей для ресурсов Строка 1.8
${uuid} --uuid UUID игрока Строка 1a2b3c4d5e6f7g8h9i0g
${accessToken} --accessToken Сессия Строка 1a2b3c4d5e6f7g8h9i0g
${userProperties} --userProperties Пользовательские настройки. Получаются через Yggdrasil Объект JSON {"twitch_access_token":["1a2b3c4d5e6f7g8h9i0g"]}
${userType} --userType Тип аккаунта mojang/legacy mojang
${serverIp} --serverIp IP сервера, к которому будет осуществлено подключение после запуска игры(Необязательно) IP адрес 127.0.0.1
${serverPort} --serverPort Порт сервера, к которому будет осуществлено подключение после запуска игры(При введённом IP) Число 25565
${windowHeight} --height Ширина окна Minecraft Число 480
${windowWidth} --width Длина окна Minecraft Число 854

Запуск игры

Запустить игру можно через Process.Start(${javaExecutable}, ${"все остальные параметры"});

Рассмотрим способ запуска, который используется в Luncher'e

  1. Из /versions/1.8/1.8.json считывается значение minecraftArguments [В нашем случае, это "--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}"]
  2. Параметры вносятся в словарь в формате (${auth_player_name} = value)(Вносится только выделенное), где auth_player_name - это параметр, а value - то, что этот параметр должен принимать.
  3. При помощи Regex \$\{(\w+)\} заменяем по словарю параметры на значения. Если значение содержит пробелы, то оно берётся в кавычки
  4. В исполняемый файл указывается ${javaExecutable}, аргументы указываем по формату ${javaParameters} -Djava.library.path="${nativesPath}" -cp "${library};${library};${library}...${library}" ${mainClass} ${"обработанная строка"}
  5. Готово, вы прекрасны.
var proc = new ProcessStartInfo
{
    FileName = JavaExec, // Исполняемый файл
    WorkingDirectory = GameDir // Рабочая папка игры
};
var nativespath = "-Djava.library.path=\"" + Program.Minecraft + "\\natives\""; //Путь до natives
var re = new Regex(@"\$\{(\w+)\}", RegexOptions.IgnoreCase);
var values = new Dictionary<string, string>
{
    {"auth_player_name", Variables.UserName}, //Имя игрока
    {"version_name", PName},                  //Версия, которая запускается(В Luncher'e используется название профиля)
    {"game_directory", GameDir},              //Рабочая директория
    {"assets_root", Assetspath},              //Путь до папки с ресурсами
    {"game_assets", Assetspath},              //Путь до папки с ресурсами
    {"assets_index_name", Assets},            //Файл с картой хэшей для ресурсов
    {"auth_session", Variables.AccessToken},  //Сессия
    {"auth_access_token", Variables.AccessToken},  //Сессия
    {"auth_uuid", Variables.ClientToken},     //UUID пользователя
    {"user_properties", userProperties.ToString(Formatting.None)},  //Пользовательские параметры
    {"user_type", "mojang"}                   //Тип аккаунта
};
Arg = re.Replace(Arg,
    match =>
        !values[match.Groups[1].Value].Contains(' ')
            ? values[match.Groups[1].Value]
            : string.Format("\"{0}\"", values[match.Groups[1].Value])); // Обработка строки с параметрами
proc.Arguments = string.Format("{0}{1} -cp {2} {3} {4}", JavaArgs, nativespath, Libs, MainClass, Arg); // Подстановка