前言:之前因为个人原因研究了一下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
插一句题外话,在我寻找到下面这个工具之前,我还在GITHUB上找到了一款用于MOTD压测服务器的开源工具 我也是研究了一下它是如何进行操作的,但是代码写的有些散乱,所以没有读懂多少,后来发现了上面这篇帖子, 发现了GITHUB上的那款开源MOTD压测【具体链接我就不贴出来了】就是直接CV的上面这个帖子的代码, 并且做了一些修改,部分内容连注释和类名都是一摸一样的。真的是可还行咯。
通过他的一番描述以及贴出来了代码,我了解到了MC是如何接受和发送数据包 所以在Github上找到了一个有关于Java获取MC服务器MOTD一款工具 https://github.com/jamietech/MinecraftServerPing 通过代码的阅读和WIKI的学习,至此搞了一个下午终于搞懂搞懂了MCPC服务器的发包方式
首先建立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了!
最终成果如下图示例:
↓↓↓这里有针对于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↑↑↑
溜了溜了