我知道你非常心急,但是相信我——一步一步来才有可能写出自己满意的程序。不妨先了解一下启动器是如何启动Minecraft的吧。
由于我的设备是Windows 10,所以教程中很多地方都采用Windows系统中的相关说法。如果您的系统与此不同,烦请自行替换(

启动思路


启动器,点击一下启动按钮,两秒之后就能弹出一个Java窗口,变成一个Minecraft。
往往来说,您的启动器是生成了一个启动脚本,然后将脚本敲给您系统内的java.exe或javaw.exe。这便是主流的启动MC的思路了。(我本人不确定是否还有其他的启动思路,FCL是根据此思路写的启动引擎)
那么,就让我们首先了解:这个启动脚本到底长什么样吧。

启动脚本


HMCL启动器中有一个为指定版本生成启动脚本的功能,并且生成的脚本中不会引用HMCL自身,直接将必要的内容送入cmd,然后就能启动该指定的Minecraft版本。
我们可以借此,先获取一个完整的启动脚本来研究研究。
这不,生成好了。

  1. @echo off
  2. set APPDATA=D:\FCL
  3. set INST_JAVA=C:\Program Files\Java\jdk-15.0.2\bin\java.exe
  4. set INST_MC_DIR=D:\FCL\.minecraft
  5. set INST_NAME=1.8.9
  6. set INST_ID=1.8.9
  7. set INST_DIR=D:\FCL\.minecraft\versions\1.8.9
  8. cd /D D:\FCL\.minecraft
  9. "C:\\Program Files\\Java\\jdk-15.0.2\\bin\\java.exe" -Dfile.encoding=GB18030 -Dminecraft.client.jar=D:\FCL\.minecraft\versions\1.8.9\1.8.9.jar -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50 -XX:G1HeapRegionSize=16m -XX:-UseAdaptiveSizePolicy -XX:-OmitStackTraceInFastThrow -XX:-DontCompileHugeMethods -Xmn128m -Xmx5858m -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true -Djava.rmi.server.useCodebaseOnly=true -Dcom.sun.jndi.rmi.object.trustURLCodebase=false -Dcom.sun.jndi.cosnaming.object.trustURLCodebase=false -Dlog4j2.formatMsgNoLookups=true -Dlog4j.configurationFile=D:\FCL\.minecraft\versions\1.8.9\log4j2.xml -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Djava.library.path=D:\FCL\.minecraft\versions\1.8.9\natives-windows-x86_64 -Dminecraft.launcher.brand=HMCL -Dminecraft.launcher.version=3.5.2.216 -cp D:\FCL\.minecraft\libraries\com\mojang\netty\1.8.8\netty-1.8.8.jar;D:\FCL\.minecraft\libraries\oshi-project\oshi-core\1.1\oshi-core-1.1.jar;D:\FCL\.minecraft\libraries\net\java\dev\jna\jna\3.4.0\jna-3.4.0.jar;D:\FCL\.minecraft\libraries\net\java\dev\jna\platform\3.4.0\platform-3.4.0.jar;D:\FCL\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;D:\FCL\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.6\jopt-simple-4.6.jar;D:\FCL\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;D:\FCL\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;D:\FCL\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;D:\FCL\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;D:\FCL\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;D:\FCL\.minecraft\libraries\io\netty\netty-all\4.0.23.Final\netty-all-4.0.23.Final.jar;D:\FCL\.minecraft\libraries\com\google\guava\guava\17.0\guava-17.0.jar;D:\FCL\.minecraft\libraries\org\apache\commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar;D:\FCL\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;D:\FCL\.minecraft\libraries\commons-codec\commons-codec\1.9\commons-codec-1.9.jar;D:\FCL\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;D:\FCL\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;D:\FCL\.minecraft\libraries\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;D:\FCL\.minecraft\libraries\com\mojang\authlib\1.5.21\authlib-1.5.21.jar;D:\FCL\.minecraft\libraries\com\mojang\realms\1.7.59\realms-1.7.59.jar;D:\FCL\.minecraft\libraries\org\apache\commons\commons-compress\1.8.1\commons-compress-1.8.1.jar;D:\FCL\.minecraft\libraries\org\apache\httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar;D:\FCL\.minecraft\libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;D:\FCL\.minecraft\libraries\org\apache\httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar;D:\FCL\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar;D:\FCL\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar;D:\FCL\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.4-nightly-20150209\lwjgl-2.9.4-nightly-20150209.jar;D:\FCL\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.4-nightly-20150209\lwjgl_util-2.9.4-nightly-20150209.jar;D:\FCL\.minecraft\libraries\tv\twitch\twitch\6.5\twitch-6.5.jar;D:\FCL\.minecraft\versions\1.8.9\1.8.9.jar -javaagent:C:\Users\芒\AppData\Roaming\.hmcl\log4j-patch-agent-1.0.jar=true net.minecraft.client.main.Main --username mangofanfan --version 1.8.9 --gameDir D:\FCL\.minecraft --assetsDir D:\FCL\.minecraft\assets --assetIndex 1.8 --uuid 6023fc0b49864b3c9479ea37f07720ff --accessToken eyJhbGciOiJIUzI1NiJ9.eyJ4dWlkIjoiMjUzNTQwOTk4NTA5ODg1MyIsImFnZyI6IkFkdWx0Iiwic3ViIjoiMmZjN2RlYzQtOTNmYi00ZjkwLTk3N2ItYmRhMTFkNWI2MjI4IiwibmJmIjoxNjM3OTc5MDU2LCJhdXRoIjoiWEJPWCIsInJvbGVzIjpbXSwiaXNzIjoiYXV0aGVudGljYXRpb24iLCJleHAiOjE2MzgwNjU0NTYsImlhdCI6MTYzNzk3OTA1NiwicGxhdGZvcm0iOiJVTktOT1dOIiwieXVpZCI6IjViNTQ4ODZmNzEyMjZmMjc0MjJmNjc3ZTc3ZjcxYmI0In0.NboSLV4UM9LoaPr19_dFPRbET-LraDEpoEoJZ0RHtlo --userProperties {} --userType mojang --width 854 --height 480
  10. pause

看起来很吓人,很恐怖对不对~
尤其是那个啥第10行,什么鬼东西啊这么多玩意儿!

那我们就先拿第10行来开刀叭!🍳✨

脚本解读


在1.6版本以后,由于Mojang大改了MC的启动方式,启动脚本变成了今天的这个样子。上面HMCL生成的脚本中,最关键的部分位于第10行,也就是最长的这一行——没有1-9行,或没有11行,脚本输入到cmd里面都是可以跑动的而且没有任何问题。

请不要把上面这个脚本复制到你的cmd里面跑,肯定跑不动,毕竟这上面的游戏目录是我的电脑上的!

在这第10行中,也不是每一个字符都很必要,我们对这上面的内容进行极致删减之后,得到的精简版是下面这样的:

  1. "C:\\Program Files\\Java\\jdk-15.0.2\\bin\\java.exe" -Dminecraft.client.jar=D:\FCL\.minecraft\versions\1.8.9\1.8.9.jar -Xmn128m -Xmx5858m -Djava.library.path=D:\FCL\.minecraft\versions\1.8.9\natives-windows-x86_64 -cp D:\FCL\.minecraft\libraries\com\mojang\netty\1.8.8\netty-1.8.8.jar;D:\FCL\.minecraft\libraries\oshi-project\oshi-core\1.1\oshi-core-1.1.jar;D:\FCL\.minecraft\libraries\net\java\dev\jna\jna\3.4.0\jna-3.4.0.jar;D:\FCL\.minecraft\libraries\net\java\dev\jna\platform\3.4.0\platform-3.4.0.jar;D:\FCL\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;D:\FCL\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.6\jopt-simple-4.6.jar;D:\FCL\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;D:\FCL\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;D:\FCL\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;D:\FCL\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;D:\FCL\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;D:\FCL\.minecraft\libraries\io\netty\netty-all\4.0.23.Final\netty-all-4.0.23.Final.jar;D:\FCL\.minecraft\libraries\com\google\guava\guava\17.0\guava-17.0.jar;D:\FCL\.minecraft\libraries\org\apache\commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar;D:\FCL\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;D:\FCL\.minecraft\libraries\commons-codec\commons-codec\1.9\commons-codec-1.9.jar;D:\FCL\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;D:\FCL\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;D:\FCL\.minecraft\libraries\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;D:\FCL\.minecraft\libraries\com\mojang\authlib\1.5.21\authlib-1.5.21.jar;D:\FCL\.minecraft\libraries\com\mojang\realms\1.7.59\realms-1.7.59.jar;D:\FCL\.minecraft\libraries\org\apache\commons\commons-compress\1.8.1\commons-compress-1.8.1.jar;D:\FCL\.minecraft\libraries\org\apache\httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar;D:\FCL\.minecraft\libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;D:\FCL\.minecraft\libraries\org\apache\httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar;D:\FCL\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar;D:\FCL\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar;D:\FCL\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.4-nightly-20150209\lwjgl-2.9.4-nightly-20150209.jar;D:\FCL\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.4-nightly-20150209\lwjgl_util-2.9.4-nightly-20150209.jar;D:\FCL\.minecraft\libraries\tv\twitch\twitch\6.5\twitch-6.5.jar;D:\FCL\.minecraft\versions\1.8.9\1.8.9.jar net.minecraft.client.main.Main --username mangofanfan --version 1.8.9 --gameDir D:\FCL\.minecraft --assetsDir D:\FCL\.minecraft\assets --assetIndex 1.8 --uuid 6023fc0b49864b3c9479ea37f07720ff --accessToken eyJhbGdiOiJIUzI1NiJ9.eyJ4dWlkIjoiMjUzNTQwOTk4NTA5ODg1MyIsImFnZyI6IkFkdWx0Iiwic3ViIjoiMmZjN2RlYzQtOTNmYi00ZjkwLTk3N2ItYmRhMTFkNWI2MjF3IiwibmJmIjoxNjM3OTc5MDU2LCJhdXRoIjoiWEJPWCIsInJvbGVzIjpbXSwiaXNzIjtiYXV0aGVudGljYXRpb24iLCJleHAiOjE2MzgwNjU0NTYsImlhdCI6MTYzNzk3OTA1NiwicGxhdGZvcm0iOiJVTktOT1dOIiwieXVpZCI6IjViNTQ4ODZmNzEyOKSNMjc0MjJmNjc3ZTc3ZjcxYmI0In0.NboSLV4UM9LoaPr19_dFPRbET-LraDEpoEoJZ0RHtlo --userProperties {} --userType mojang

别上下对比了,我说精简过就是精简过!(?
剩下的部分属于是最基本的部分,仅使用这些内容您也可以启动该版本的Minecraft。然后我们来顺次分析以下,很容易就可以得到(?:

Java路径 “C:\\Program Files\\Java\\jdk-15.0.2\\bin\\java.exe”
JVM参数 -Dminecraft.client.jar=D:\FCL\.minecraft\versions\1.8.9\1.8.9.jar -Xmn128m -Xmx5858m -Djava.library.path=D:\FCL\.minecraft\versions\1.8.9\natives-windows-x86_64
-cp 普通库文件
可以看出,这一串的最末尾加上了该版本 client.jar 的路径,不要忘记。
-cp D:\FCL\.minecraft\libraries\com\mojang\netty\1.8.8\netty-1.8.8.jar;D:\FCL\.minecraft\libraries\oshi-project\oshi-core\1.1\oshi-core-1.1.jar;D:\FCL\.minecraft\libraries\net\java\dev\jna\jna\3.4.0\jna-3.4.0.jar;D:\FCL\.minecraft\libraries\net\java\dev\jna\platform\3.4.0\platform-3.4.0.jar;D:\FCL\.minecraft\libraries\com\ibm\icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar;D:\FCL\.minecraft\libraries\net\sf\jopt-simple\jopt-simple\4.6\jopt-simple-4.6.jar;D:\FCL\.minecraft\libraries\com\paulscode\codecjorbis\20101023\codecjorbis-20101023.jar;D:\FCL\.minecraft\libraries\com\paulscode\codecwav\20101023\codecwav-20101023.jar;D:\FCL\.minecraft\libraries\com\paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar;D:\FCL\.minecraft\libraries\com\paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar;D:\FCL\.minecraft\libraries\com\paulscode\soundsystem\20120107\soundsystem-20120107.jar;D:\FCL\.minecraft\libraries\io\netty\netty-all\4.0.23.Final\netty-all-4.0.23.Final.jar;D:\FCL\.minecraft\libraries\com\google\guava\guava\17.0\guava-17.0.jar;D:\FCL\.minecraft\libraries\org\apache\commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar;D:\FCL\.minecraft\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar;D:\FCL\.minecraft\libraries\commons-codec\commons-codec\1.9\commons-codec-1.9.jar;D:\FCL\.minecraft\libraries\net\java\jinput\jinput\2.0.5\jinput-2.0.5.jar;D:\FCL\.minecraft\libraries\net\java\jutils\jutils\1.0.0\jutils-1.0.0.jar;D:\FCL\.minecraft\libraries\com\google\code\gson\gson\2.2.4\gson-2.2.4.jar;D:\FCL\.minecraft\libraries\com\mojang\authlib\1.5.21\authlib-1.5.21.jar;D:\FCL\.minecraft\libraries\com\mojang\realms\1.7.59\realms-1.7.59.jar;D:\FCL\.minecraft\libraries\org\apache\commons\commons-compress\1.8.1\commons-compress-1.8.1.jar;D:\FCL\.minecraft\libraries\org\apache\httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar;D:\FCL\.minecraft\libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;D:\FCL\.minecraft\libraries\org\apache\httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar;D:\FCL\.minecraft\libraries\org\apache\logging\log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar;D:\FCL\.minecraft\libraries\org\apache\logging\log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar;D:\FCL\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl\2.9.4-nightly-20150209\lwjgl-2.9.4-nightly-20150209.jar;D:\FCL\.minecraft\libraries\org\lwjgl\lwjgl\lwjgl_util\2.9.4-nightly-20150209\lwjgl_util-2.9.4-nightly-20150209.jar;D:\FCL\.minecraft\libraries\tv\twitch\twitch\6.5\twitch-6.5.jar;D:\FCL\.minecraft\versions\1.8.9\1.8.9.jar
类名 net.minecraft.client.main.Main
Minecraft参数 —username mangofanfan —version 1.8.9 —gameDir D:\FCL\.minecraft —assetsDir D:\FCL\.minecraft\assets —assetIndex 1.8 —uuid 6023fc0b49864b3c9479ea37f07720ff —accessToken eyJhbGdiOiJIUzI1NiJ9.eyJ4dWlkIjoiMjUzNTQwOTk4NTA5ODg1MyIsImFnZyI6IkFkdWx0Iiwic3ViIjoiMmZjN2RlYzQtOTNmYi00ZjkwLTk3N2ItYmRhMTFkNWI2MjF3IiwibmJmIjoxNjM3OTc5MDU2LCJhdXRoIjoiWEJPWCIsInJvbGVzIjpbXSwiaXNzIjtiYXV0aGVudGljYXRpb24iLCJleHAiOjE2MzgwNjU0NTYsImlhdCI6MTYzNzk3OTA1NiwicGxhdGZvcm0iOiJVTktOT1dOIiwieXVpZCI6IjViNTQ4ODZmNzEyOKSNMjc0MjJmNjc3ZTc3ZjcxYmI0In0.NboSLV4UM9LoaPr19_dFPRbET-LraDEpoEoJZ0RHtlo —userProperties {} —userType mojang

类似地,只要能生成这样的一个脚本,就能启动Minecraft了!
现在您已经学会启动脚本的基本构造了,尝试在你的电脑上,根据您的Minecraft相关信息,手敲一串这样的脚本然后复制到cmd里面看看吧!
什么?你不会?你懒??

所以这就是Minecraft启动器存在的意义了。
下面,我们将介绍,这样的一串脚本是如何生成的,并将使用Python代码作为示例。