教學(xué)/如何編寫(xiě)一個(gè)minecraft啟動(dòng)器
本文轉(zhuǎn)自minecraftwiki
僅java版專(zhuān)有,并且正版登錄只能使用mojang賬號(hào)登錄,如使用微軟帳號(hào)登錄請(qǐng)另找教程
本教程介紹如何制作Java版啟動(dòng)器,并假定你已掌握任何一門(mén)編程語(yǔ)言。
目錄
1 ? ? ? ?基本原理
2 ? ? ? ?準(zhǔn)備
3 ? ? ? ?啟動(dòng)參數(shù)
3.1 ? ? ? ?JVM參數(shù)
3.1.1 ? ? ? ?-X、-XX參數(shù)
3.1.2 ? ? ? ?-D參數(shù)
3.1.3 ? ? ? ?-cp參數(shù)
3.2 ? ? ? ?Minecraft參數(shù)
3.3 ? ? ? ?獲取參數(shù)
4 ? ? ? ?游戲文件
4.1 ? ? ? ?JSON文件
4.1.1 ? ? ? ?版本清單文件
4.1.2 ? ? ? ?版本json文件
4.1.3 ? ? ? ?資源索引文件
4.1.4 ? ? ? ?啟動(dòng)器配置文件
4.2 ? ? ? ?游戲主文件
4.3 ? ? ? ?依賴(lài)庫(kù)文件
4.3.1 ? ? ? ?普通庫(kù)文件
4.3.2 ? ? ? ?natives庫(kù)文件
4.4 ? ? ? ?資源文件
5 ? ? ? ?正版驗(yàn)證
5.1 ? ? ? ?驗(yàn)證賬號(hào)密碼
5.2 ? ? ? ?檢驗(yàn)令牌有效性
5.3 ? ? ? ?刷新令牌
6 ? ? ? ?啟動(dòng)游戲
7 ? ? ? ?支持forge等Mod加載器
7.1 ? ? ? ?額外的版本json文件
8 ? ? ? ?優(yōu)化下載
9 ? ? ? ?皮膚管理
9.1 ? ? ? ?獲取皮膚及披風(fēng)
9.2 ? ? ? ?更換皮膚
9.3 ? ? ? ?上傳皮膚
9.4 ? ? ? ?重置皮膚
基本原理
因?yàn)镸inecraft制作時(shí)采用了“啟動(dòng)器+游戲文件”的模式:
將游戲文件單獨(dú)存儲(chǔ),而通過(guò)啟動(dòng)器調(diào)用JVM(Java Virtual Machine,Java虛擬機(jī))執(zhí)行游戲主文件并傳入一些游戲參數(shù)來(lái)啟動(dòng)Minecraft。
游戲依賴(lài)庫(kù)文件以及游戲資源文件由啟動(dòng)器補(bǔ)全。
玩家登錄認(rèn)證由啟動(dòng)器完成。
這使得我們能通過(guò)編寫(xiě)第三方啟動(dòng)器來(lái)接管游戲文件管理和登錄認(rèn)證。
準(zhǔn)備
要編寫(xiě)一個(gè)啟動(dòng)器,你需要:
一門(mén)編程語(yǔ)言其開(kāi)發(fā)環(huán)境。
Java運(yùn)行時(shí)環(huán)境(Java Runtime Environment,JRE),可于Java官網(wǎng)下載。
并擁有支持下列功能的庫(kù):
解析JSON文檔(得到啟動(dòng)參數(shù)的關(guān)鍵)。
解壓文件(解壓natives文件,也可使用鏈接外部程序替代)。
網(wǎng)絡(luò)庫(kù)(正版驗(yàn)證、皮膚管理等)。
啟動(dòng)參數(shù)
啟動(dòng)參數(shù)將傳入java.exe或javaw.exe,使JVM通過(guò)傳入的主類(lèi)正確地啟動(dòng)游戲。
啟動(dòng)參數(shù)分為JVM參數(shù)和Minecraft參數(shù)兩部分。
這對(duì)debug很有幫助,另外參考官方啟動(dòng)器的方法能得到更優(yōu)良的參數(shù)。
JVM參數(shù)
-X、-XX參數(shù)
配置JVM,如GC等:
-Xmx1024m 最大堆大小為1024MB。
-Xmn128m 新生代堆大小為128MB。
-XX:+UseG1GC 開(kāi)啟G1。
-XX:-UseAdaptiveSizePolicy 自動(dòng)選擇年輕代區(qū)大小和相應(yīng)的Survivor區(qū)比例。
-XX:-OmitStackTraceInFastThrow 省略異常棧信息從而快速拋出。
-D參數(shù)
配置JVM系統(tǒng)屬性,格式為-D<name>=<value>。
Dos.name=Windows 10 -Dos.version=10.0 當(dāng)前系統(tǒng)名稱(chēng)及版本。
-Dminecraft.launcher.brand=minecraft-launcher -Dminecraft.launcher.version=2.1.3674 當(dāng)前啟動(dòng)器名稱(chēng)及版本。
-Dlog4j.configurationFile=<文件路徑>\client-1.12.xml 游戲日志配置文件。
-Djava.library.path=<natives文件夾路徑> 當(dāng)前系統(tǒng)下游戲運(yùn)行所需的動(dòng)態(tài)鏈接庫(kù)。
-cp參數(shù)
全稱(chēng)為-classpath,后為所有當(dāng)前版本Minecraft的普通庫(kù)文件路徑及游戲主文件,中間在Windows下用;隔開(kāi),其它系統(tǒng)下用:隔開(kāi)。
Minecraft參數(shù)
以主類(lèi)名開(kāi)頭,通常為net.minecraft.client.main.Main,若安裝Mod加載器則一般為net.minecraft.launchwrapper.Launch
參數(shù)通常有:
--username 后接用戶名。
--version 后接游戲版本。
--gameDir 后接游戲路徑。
--assetsDir 后接資源文件路徑。
--assetIndex 后接資源索引版本。
--uuid 后接用戶UUID。
--accessToken 后接登錄令牌。
--userType 后接用戶類(lèi)型。
--versionType 后接版本類(lèi)型,會(huì)顯示在游戲主界面右下角。
--width 后接窗口寬度。
--height 后接窗口高度。
等等,可能因版本而異,具體應(yīng)參考當(dāng)前版本json文件內(nèi)提供的信息。
獲取參數(shù)
運(yùn)行此命令可獲取當(dāng)前運(yùn)行的Minecraft進(jìn)程的參數(shù):
wmic process where caption="javaw.exe" get caption,commandline /value>args.txt
wmic process where caption="java.exe" get caption,commandline /value>args_java.txt
此時(shí)args.txt或args_java.txt中大致有這樣的文件內(nèi)容:
Caption=javaw.exe
CommandLine="<javaw或java路徑>" -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump "-Dos.name=Windows 10" -Dos.version=10.0 -Xss1M -Djava.library.path=<natives文件夾路徑> -Dminecraft.launcher.brand=minecraft-launcher -Dminecraft.launcher.version=2.1.3674 -cp <一大串用;分開(kāi)的文件路徑> -Xmx2G -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50 -XX:G1HeapRegionSize=32M -Dlog4j.configurationFile=<log4j配置文件路徑> net.minecraft.client.main.Main --username <用戶名> --version <游戲版本號(hào)> --gameDir <游戲路徑> --assetsDir <資源文件路徑> --assetIndex <資源索引版本> --uuid <用戶uuid> --accessToken <登錄令牌> --userType mojang --versionType release --width <窗口寬度> --height <窗口高度>
僅保留CommandLine后的內(nèi)容,然后將該文件后綴改為.bat,雙擊即可啟動(dòng)Minecraft。
運(yùn)行前注意文件編碼。并注意官方啟動(dòng)器的解壓出的natives庫(kù)文件存儲(chǔ)在臨時(shí)文件夾下,可能因刪除導(dǎo)致無(wú)法啟動(dòng)。
游戲文件
列表 []
.minecraft
assets
indexes
version.json
log_configs
client-version.xml
objects
skins
virtual
bin
jinput.jar
lwjgl.jar
lwjgl_util.jar
minecraft.jar(這是1.5.2之前的client.jar。目前不再使用,而是使用“versions”文件夾。)
natives
(.dll文件)
debug
debug-report-年-月-日_時(shí).分.秒.zip
profile-report-年-月-日_時(shí).分.秒.txt
libraries
[按Maven公約包裝的各種庫(kù)(沒(méi)有POM文件)]
logs
年-月-日-會(huì)話編號(hào).log.gz
latest.log
resourcepacks
saves
世界名稱(chēng)
advancements
uuid.json
data
idcounts.dat
map_id.dat
scoreboard.dat
raids.dat
datapacks
DIM1
data
raids_end.dat
poi
r.x.z.mca
region
r.x.z.mca
DIM-1
data
raids_nether.dat
poi
r.x.z.mca
region
r.x.z.mca
generated
(命名空間)
structures
name.nbt
playerdata
uuid.dat
poi
r.x.z.mca
region
r.x.z.mca
stats
uuid.json
icon.png
level.dat
level.dat_mcr
level.dat_old
resources.zip
session.lock
screenshots
年-月-日_時(shí).分.秒.png
stats
stats_player_unsent.dat
stats_player_unsent.old
texturepacks
texturepacks-mp-cache
versions
版本
version.jar
version.json
debug.stitched_items.png
debug.stitched_terrain.png
hotbar.nbt
lastlogin
launcher_log.txt
launcher profiles.json
launcher_skins.json
options.txt
output-client.log
output-server.log
realms_persistence.json
servers.dat
textures_0.png
textures_1.png
textures_2.png
textures_3.png
textures_4.png
usercache.json
JSON文件
Minecraft大多數(shù)信息使用JSON文檔存儲(chǔ)管理,使用這些JSON文件可以獲取下載、管理及啟動(dòng)所需的大部分信息。
版本清單文件
主條目:/version_manifest.json
該文件可以在mojang官方服務(wù)器下載:
https://launchermeta.mojang.com/mc/game/version_manifest.json
內(nèi)容通常如下:[]
其中,latest中為當(dāng)前最新版本,分為發(fā)布版和快照版。versions后為所有可下載的游戲版本,url后為該版本的json文件下載地址。
版本json文件
主條目:/version.json
該文件一般下載后存儲(chǔ)在.minecraft/versions文件夾下,有如下內(nèi)容:
內(nèi)容通常如下:[]
rules
用于可選條目,使用features判斷并應(yīng)用其action。
arguments
1.13后新增鍵,舊版本為gameArguments,且不提供JVM參數(shù)及rules規(guī)則。
${****}
字符串模板,替換相應(yīng)內(nèi)容來(lái)使用。
assetIndex
當(dāng)前版本的資源文件索引,包含其下載地址等信息。
downloads
游戲主文件,分為客戶端及服務(wù)端,包含其下載地址等信息。
libraries
游戲所有依賴(lài)庫(kù),包含其下載地址等信息。
downloads下均含有artifact鍵,有些含有classifiers鍵。
只含有artifact鍵的為-cp參數(shù)后所需拼接的路徑,注意path鍵中為不完整路徑,請(qǐng)補(bǔ)全為完整路徑。
含有classifiers鍵的為natives庫(kù),在游戲啟動(dòng)前將對(duì)應(yīng)平臺(tái)的含有jar文件解壓至natives文件夾。
logging
log4j配置文件,包含其下載地址等信息。
mainClass
主類(lèi)名。
資源索引文件
一般存儲(chǔ)于.minecraft/assets/indexes路徑下,用于指示objects文件的信息及其下載地址。
該文件的下載地址等信息存儲(chǔ)在版本json文件中,該文件可能需要不定期更新。
內(nèi)容如下:
{
? ? "objects": {
? ? ? ? "icons/icon_16x16.png": {
? ? ? ? ? ? "hash": "bdf48ef6b5d0d23bbb02e17d04865216179f510a",
? ? ? ? ? ? "size": 3665
? ? ? ? },
? ? ? ? ...
? ? }
}
objects文件的下載地址為:
http://resources.download.minecraft.net/<hash的前兩位字符>/<hash>
存儲(chǔ)路徑為:
.minecraft/assets/objects/<hash的前兩位字符>/<hash>
并在.minecraft/assets/virtual/legacy/留下一份拷貝。
啟動(dòng)器配置文件
主條目:launcher_profiles.json
該文件不是必須的,但它是官方啟動(dòng)器的配置文件。所以可用于與官方啟動(dòng)器數(shù)據(jù)互通,以及Forge安裝檢驗(yàn)。
最簡(jiǎn)單的配置文件為:
{
? ? "profiles": {
? ? ? ? "(Default)": {
? ? ? ? ? ? "gameDir": "<游戲目錄>",
? ? ? ? ? ? "lastVersionId": "1.14.1",
? ? ? ? ? ? "name": "(Default)"
? ? ? ? }
? ? },
? ? "selectedProfileName": "(Default)",
}
profiles為啟動(dòng)器中創(chuàng)建的所有配置文件。
游戲主文件
通常存儲(chǔ)于.minecraft/versions/<version>/<version>.jar,下載地址等信息存儲(chǔ)在版本json文件中,下載時(shí)注意將該文件重命名為對(duì)應(yīng)版本號(hào)。
依賴(lài)庫(kù)文件
通常存儲(chǔ)于.minecraft/libraries/路徑下,下載地址等信息存儲(chǔ)在版本json文件中。
普通庫(kù)文件
在啟動(dòng)前需拼接在啟動(dòng)參數(shù)的-cp參數(shù)后。
natives庫(kù)文件
在啟動(dòng)前需解壓至natives路徑下。
資源文件
通常存儲(chǔ)在.minecraft/assets/objects/,并在.minecraft/assets/virtual/legacy/有一份拷貝。
下載地址等信息存儲(chǔ)在資源索引文件中。
這些文件可能在發(fā)布后更新,留意更新資源索引文件來(lái)更新他們。
正版驗(yàn)證
Minecraft自1.6后使用了Yggdrasil驗(yàn)證方法,驗(yàn)證服務(wù)器為:
https://authserver.mojang.com
驗(yàn)證時(shí)需要:
為POST請(qǐng)求
Content-Type設(shè)置為application/json
負(fù)載以JSON編碼
若請(qǐng)求成功則返回狀態(tài)碼200及一個(gè)JSON文檔。
若失敗則返回錯(cuò)誤信息:
{
? ?"error": "錯(cuò)誤簡(jiǎn)要描述",
? ?"errorMessage": "向用戶顯示的長(zhǎng)描述",
? ?"cause": "錯(cuò)誤原因" // 可選的
}
具體錯(cuò)誤信息可參考https://wiki.vg/ZH:Authentication#錯(cuò)誤。
驗(yàn)證賬號(hào)密碼
后綴:
/authenticate
負(fù)載:
{
? ?"agent": {
? ? ? ?"name": "Minecraft", ? ? ? ? ? ? ? ?// 默認(rèn)為Minecraft,可選
? ? ? ?"version": 1 ? ? ? ? ? ? ? ? ? ? ? ?// 未來(lái)可能會(huì)改(不會(huì))
? ?},
? ?"username": "mojang用戶名", ? ? ? ? ? ? ?// 可以是郵箱地址或舊版mojang用戶名
? ?"password": "密碼",
? ?"clientToken": "客戶端標(biāo)識(shí)符" ? ? ? ? ? ?// 可選的,用于復(fù)用該值
}
響應(yīng):
{
? ?"accessToken": "隨機(jī)令牌",
? ?"clientToken": "客戶端標(biāo)識(shí)符",
? ?"availableProfiles": [
? ? ? ?{
? ? ? ? ? ?"id": "profile identifier",
? ? ? ? ? ?"name": "玩家名"
? ? ? ?}
? ?],
? ?"selectedProfile": {
? ? ? ?"id": "不含-的uuid",
? ? ? ?"name": "玩家名"
? ?}
}
(有刪節(jié),參考https://wiki.vg/ZH:Authentication#Authentication)
你可以存儲(chǔ)這個(gè)clientToken,用來(lái)標(biāo)識(shí)這個(gè)客戶端。
此處獲取的uuid和accessToken即為啟動(dòng)參數(shù)中所需的,傳入你剛剛獲得的值,啟動(dòng)游戲后便能發(fā)現(xiàn)已顯示正版皮膚,即完成了正版登錄。
檢驗(yàn)令牌有效性
accessToken具有有效期,可能因?yàn)橐恍┰蚴?。你可以發(fā)送請(qǐng)求,驗(yàn)證當(dāng)前accessToken是否還是有效的.
后綴:
/validate
負(fù)載:
{
? ?"accessToken": "valid accessToken",
? ?"clientToken": "associated clientToken" //可選的
}
響應(yīng):
如果狀態(tài)碼為204 No Content則有效,而403 Forbidden為已失效。
刷新令牌
刷新一個(gè)accessToken,用于保持用戶在游戲會(huì)話之間登錄。
后綴:
/refresh
負(fù)載:
{
? ?"accessToken": "valid accessToken",
? ?"clientToken": "associated clientToken" //可選的
}
響應(yīng):
{
? ?"accessToken": "隨機(jī)令牌",
? ?"clientToken": "客戶端標(biāo)識(shí)符",
? ?"availableProfiles": [
? ? ? ?{
? ? ? ? ? ?"id": "profile identifier",
? ? ? ? ? ?"name": "玩家名"
? ? ? ?}
? ?],
? ?"selectedProfile": {
? ? ? ?"id": "不含-的uuid",
? ? ? ?"name": "玩家名"
? ?}
}
(有刪節(jié),參考https://wiki.vg/ZH:Authentication#Refresh)
與“驗(yàn)證賬號(hào)密碼”中相同。
啟動(dòng)游戲
首先必須保證啟動(dòng)參數(shù)中出現(xiàn)的所有文件及提供的資源索引文件中的object文件都存在且未被損壞。
選定一個(gè)natives路徑,可以自由選定,也可像官方啟動(dòng)器一樣使用臨時(shí)路徑。將natives庫(kù)文件解壓至該路徑,并將該路徑使用-Djava.library.path=傳入游戲。
完成正版驗(yàn)證,得到UUID及accessToken。
拼接啟動(dòng)參數(shù),創(chuàng)建游戲進(jìn)程。
處理游戲輸出及游戲錯(cuò)誤。
支持forge等Mod加載器
運(yùn)行forge等Mod加載器的安裝包后,可以發(fā)現(xiàn):
啟動(dòng)器配置文件中添加了一條新安裝的配置。
.minecraft/libraries/文件夾中多了一些文件。
.minecraft/versions/文件夾中多了一個(gè)版本json文件(也可能會(huì)有jar文件)。
額外的版本json文件
該文件相比原版的版本json文件文件多了inheritsFrom和jar鍵,而且其他鍵內(nèi)容明顯是不完整的。
inheritsFrom
該參數(shù)指定了當(dāng)前版本所繼承的原版版本,意思為除此版本json文件外,同時(shí)使用inheritsFrom中指定的版本json文件內(nèi)容。即,-cp參數(shù)后同時(shí)包含兩個(gè)版本json文件指定的普通庫(kù)文件,且natives庫(kù)文件也同時(shí)包含兩個(gè)版本json文件指定的,且該版本json文件優(yōu)先于原版版本json文件。
jar
該參數(shù)指定了-cp參數(shù)后的游戲主文件。
除此之外,版本json文件中的libraries鍵的格式也有些不一樣了,如:
{
? "name": "org.ow2.asm:asm-all:5.0.3",
? "serverreq": true
},
{
? "name": "jline:jline:2.13",
? "url": "http://files.minecraftforge.net/maven/",
? "checksums": [
? ? "2d9530d0a25daffaffda7c35037b046b627bb171"
? ],
? "serverreq": true,
? "clientreq": false
}
不再有downloads鍵了,只剩下name和url,文件路徑及下載路徑需要根據(jù)一定規(guī)則拼接。
name鍵的格式為:
<package>:<name>:<version>
我們將它變形重組一下:
<package>/<name>/<version>/<name>-<version>.jar
前方接上.minecraft/libraries/即為文件路徑,而接上url的內(nèi)容即為下載地址。
serverreq和clientreq用于區(qū)分客戶端和服務(wù)端的需要。
優(yōu)化下載
有時(shí),在官方服務(wù)器下載文件會(huì)很緩慢,這時(shí)可以考慮使用第三方鏡像下載。
當(dāng)前常用的第三方鏡像有:
BMCLAPI
另外,Minecraft的依賴(lài)庫(kù)文件和資源索引文件很多為小文件,可以考慮使用多線程下載來(lái)優(yōu)化速度。
皮膚管理
皮膚管理需要使用Mojang API:
api.mojang.com
可通過(guò)發(fā)送GET請(qǐng)求獲得Mojang API的狀態(tài):
https://status.mojang.com/check
獲取皮膚及披風(fēng)
可通過(guò)發(fā)送GET請(qǐng)求獲得皮膚及披風(fēng)地址:
https://sessionserver.mojang.com/session/minecraft/profile/<uuid>
響應(yīng):
{
? ?"id": "<配置標(biāo)識(shí)符>",
? ?"name": "<玩家名>",
? ?"properties": [
? ? ? ?{
? ? ? ? ? ?"name": "textures",
? ? ? ? ? ?"value": "<base64字符串>"
? ? ? ?}
? ?]
}
解碼該base64字符串,可獲得另一JSON文檔:
{
? ?"timestamp": <java time in ms>,
? ?"profileId": "<配置uuid>",
? ?"profileName": "<玩家名>",
? ?"textures": {
? ? ? ?"SKIN": {
? ? ? ? ? ?"url": "<玩家皮膚URL>"
? ? ? ?},
? ? ? ?"CAPE": {
? ? ? ? ? ?"url": "<玩家披風(fēng)URL>"
? ? ? ?}
? ?}
}
更換皮膚
發(fā)送POST請(qǐng)求至:
https://api.mojang.com/user/profile/<uuid>/skin
頭:
Authorization: Bearer <access token>
負(fù)載:
model=<""/"slim">&url=<皮膚url>
空字符串為Steve模型,“slim”為Alex模型。
上傳皮膚
發(fā)送PUT請(qǐng)求至:
https://api.mojang.com/user/profile/<uuid>/skin
頭:
Authorization: Bearer <access token>
負(fù)載:
由兩部分組成:
model:人物模型,空字符串為Steve模型,“slim”為Alex模型。
file:原始圖像文件數(shù)據(jù)。
重置皮膚
發(fā)送DELETE請(qǐng)求至:
https://api.mojang.com/user/profile/<uuid>/skin
頭:
Authorization: Bearer <access token>