0x00 MineCraft協(xié)議概括

此文章為代理發(fā)布

0x00?這篇文章是給誰看的
這篇文章適合:
給同樣對(duì)MC協(xié)議有興趣且有一定編程能力的人
想要?jiǎng)?chuàng)建與 Minecraft 互操作的全新程序(例如機(jī)器人或服務(wù)器)的人
想要修改 Minecraft 客戶端或服務(wù)器的人
這篇文章不適合:
只是想玩MC的玩家
普通模組的開發(fā)者
對(duì)二進(jìn)制不熟悉的人
鑒于個(gè)人能力原因,可能有地方寫的不夠清楚,還請指出。
0x01 什么是MC協(xié)議
MC Protocol (JAVA) 是基于TCP流的一個(gè)協(xié)議,在服務(wù)器與客戶端的交互中使用。下面沒有特別申明的話,都指的是 Minecraft JAVA Edition 的協(xié)議。在這一系列文章里,Mocha將會(huì)以模擬1.16.5版本的原版MC客戶端進(jìn)行講解。
0x02 與服務(wù)器的會(huì)話狀態(tài)(State)
與正版服務(wù)器一共有四種常規(guī)狀態(tài):
HandShake 握手狀態(tài)(與TCP的握手無關(guān))
Status 查詢服務(wù)器狀態(tài)
Login 登陸服務(wù)器
Play 游戲狀態(tài)(正在進(jìn)行游戲)
其中,每次會(huì)話都從握手開始。
0x03 客戶端的正常工作流程
正常的 Ping 和 Status 查詢
C > S 表示客戶端向服務(wù)器發(fā)送數(shù)據(jù)
S > C 表示服務(wù)器向客戶端發(fā)送數(shù)據(jù)
下同客戶端服務(wù)器建立TCP連接
C > S HandShake包,同時(shí)設(shè)置下一個(gè)狀態(tài)為State為0x01(Status狀態(tài))
此時(shí)服務(wù)器和客戶端的狀態(tài)都變成StatusC > S 請求Status包
S > C 響應(yīng)的服務(wù)器Status包
C > S Ping包
S > C Pong包
服務(wù)器斷開與客戶端的連接正常的登陸周期
客戶端服務(wù)器建立TCP連接
C > S HandShake包,同時(shí)設(shè)置下一個(gè)狀態(tài)為State為0x02(Login狀態(tài))
此時(shí)服務(wù)器和客戶端狀態(tài)都變成LoginC > S 發(fā)送登陸包
S > C 發(fā)送加密請求包(只有正版服務(wù)器才有) 此時(shí)客戶端應(yīng)該去認(rèn)證
C > S 發(fā)送加密認(rèn)證的包(只有正版服務(wù)器才有) 此時(shí)服務(wù)器去正版服務(wù)器驗(yàn)證一下認(rèn)證,同時(shí)兩邊都打開加密
S > C 設(shè)置壓縮大小(可能有)
S > C 登陸成功 此時(shí)服務(wù)器和客戶端狀態(tài)都變成Play
看不懂? 沒關(guān)系,接下來我們會(huì)詳細(xì)講解
0x04 常用數(shù)據(jù)類型(部分)
主要來說,數(shù)據(jù)基本上也就那幾十種(劃掉) 一般來說常見的三種是
1. 定長整數(shù)
定長整數(shù)有 byte, short, int, long, unsigned byte, unsigned short, unsigned int, unsigned long。
大小如下:?

這些數(shù)據(jù)全部是大端(也叫網(wǎng)絡(luò)傳輸字節(jié)序)排列。
(就是表示高有效位的字節(jié)排在前面,第一位是符號(hào)位,負(fù)數(shù)用補(bǔ)碼的一種方式排列啦)
unsigned指的是無符號(hào)整數(shù),是沒有符號(hào)位的
PS: 這里可以上網(wǎng)查一下,網(wǎng)上的解釋比較全面
2. 變長整數(shù)
變長整數(shù)主要是Varint 和 Varlong, 下一篇文章會(huì)仔細(xì)講。
(也就是這里光明正大的咕咕咕了)
3. 字符串
MC的字符串是由兩部分組成的:
Varint + string
前面的Varint是后面字符串的長度
0x05 MC包的格式
MC協(xié)議里有兩種包,一種是壓縮過的包,一種是是普通包。其中壓縮過的包只有在Login狀態(tài)里接收到了設(shè)置壓縮大小包以后才會(huì)啟用
普通包
普通包由三個(gè)部分組成

壓縮包
首先申明,在接收到設(shè)置壓縮大小過后收到的包都是壓縮包(設(shè)置壓縮大小包傳回的數(shù)據(jù)是一個(gè)負(fù)數(shù)的話就還是普通包),并不是壓縮了才叫壓縮包
在收到設(shè)置壓縮大小的包以后 所有的包格式就變成了這樣:

特別聲明: 當(dāng)設(shè)置壓縮大小的值為0時(shí)所有數(shù)據(jù)壓縮,值為負(fù)數(shù)時(shí)仍然使用普通包。
結(jié)語
了解了這些基礎(chǔ)知識(shí),我們就可以馬上開始入門這個(gè)協(xié)議了,這個(gè)文檔可能會(huì)在以后被你經(jīng)常翻閱。
有不懂的問題可以在評(píng)論區(qū)提問,Mocha會(huì)盡量全部回答。
下一篇文章我們會(huì)講講Varint算法。