如何发包获取Minecraft(我的世界)PC服务器端MOTD信息?

前言:之前因为个人原因研究了一下PE服务器的MOTD获取方法
但是由于技术实在太LJ了,在Github上找到了一款PHP的MCPE-MOTD获取程序


就没有再研究
但是在研究的过程当中发现了PC服务器的MOTD获取方法
你说这气人不气人。。??
为了避免大家走弯路,将获取方法记录成帖子发布出来!
由于方法过于简单,一些大佬可能早就会了,但是不喜勿喷谢谢我的世界论坛
帖内部分专业术语可能描述不准确,欢迎指出错误!


首先我们通过一个Minecraft非官方Wiki查看Minecraft服务器的包协议
http://wiki.vg
这个Wiki是个非官方的Wiki网站,所以内容可能有些不完善。

Minecraft Modern (officially Minecraft: Java Edition) is one of the two updated versions of Minecraft which require a paid account to download, update and play. Most of the new development projects focus on either creating entirely new programs from scratch that interoperate with Minecraft (such as a bot or server) or modding projects that wrap the client or server and provide bug fixes, new features and enhancements to existing features.

↑这是wiki官网顶部的一句话。


我们从这个包协议列表页面中可以简单的了解到Minecraft发包是需要握手,服务端自己定义的一套握手。

https://wiki.vg/Protocol

wiki是英文的,写的非常多,由于我在英文和技术上都是渣渣,所以就智能通过各种百度试图查找中文文档

果然不出我所料,中文文档一个都没有【可能有但是我实在找不到】

没有办法,众所周知Baidu搜不到有用的外文内容,所以我选择了Bing国际版

通过搜索“minecraft server handshake”关键词,我找到了这样一篇帖子:

https://stackoverflow.com/questions/30768091/java-sending-handshake-packets-to-minecraft-server

undefined


插一句题外话,在我寻找到下面这个工具之前,我还在GITHUB上找到了一款用于MOTD压测服务器的开源工具
我也是研究了一下它是如何进行操作的,但是代码写的有些散乱,所以没有读懂多少,后来发现了上面这篇帖子,
发现了GITHUB上的那款开源MOTD压测【具体链接我就不贴出来了】就是直接CV的上面这个帖子的代码,
并且做了一些修改,部分内容连注释和类名都是一摸一样的。真的是可还行咯。


通过他的一番描述以及贴出来了代码,我了解到了MC是如何接受和发送数据包

所以在Github上找到了一个有关于Java获取MC服务器MOTD一款工具

https://github.com/jamietech/MinecraftServerPing

通过代码的阅读和WIKI的学习,至此搞了一个下午终于搞懂搞懂了MCPC服务器的发包方式


undefined


首先建立Socket链接,打开Imputstream和Outputstream
然后通过特定的方式向内写入数据,这里都封装好了,具体原理由于我太菜了,Wiki上有说明,但是没看懂,涉及到数据字节的操作。


PACKET_HANDSHAKEID发送包的顺序:
传入PACKET_HANDSHAKEID 包ID(数值为0x00,上图用的是封装好的类)
传入协议版本(直接传入数字 4 好像就可以了具体没测试,wiki上没看懂解释)
传入服务器地址的长度
传入服务器地址
传入服务器端口


STATUS_HANDSHAKEID发送包的顺序:
传入PACKET_HANDSHAKEID 包ID(数值为 1 ,上图用的是封装好的类)
传入handshake包的长度
传入handshake的包toByteArray()


Status request状态请求
传入Status request包的长度(直接写0x01就好了)
再写入一个0x00的空字节即可


Status response状态返回
首先通过封装好的readVarInt获取状态包的大小(就在第一个字节里)
在通过封装好的readVarInt获取获取状态包的状态值
(如果是-1 则代表服务器数据流过早结束,传输异常)
(只有传回来的包状态值等于0x00采薇传输正常)
接着在读取包的长度(在包的第二个字节里,直接使用封装好的readVarInt即可)
(长度如果是-1代表传输异常,如果是0代表服务器出意外了,返回了一个意外值)
最后通过一个字节数组接受,长度九尾接受的length
通过readFully方法读入inputstream流
在通过String方法的构造器转换成字符串,返回的就是Json值了!
Json中包含有MOTD信息,即可通过JSON解析获取MOTD了!


最终成果如下图示例:

undefined


↓↓↓这里有针对于Server_List_Ping的例子,GITHUB里还有Demo↓↓↓

https://wiki.vg/Server_List_Ping

Github 的 e.g. : 【需要科学上网】

C#:https://gist.github.com/csh/2480d14fbbb33b4bbae3
Java:https://gist.github.com/zh32/7190955
Python:https://gist.github.com/1209061
Python3:https://gist.github.com/ewized/97814f57ac85af7128bf
Php:https://github.com/winny-/mcstat

↑↑↑这里有针对于Server_List_Ping的例子,GITHUB里还有Demo↑↑↑


溜了溜了

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

Captcha Code