【问题标题】:handshake with the minecraft bukkit server - failed sending server host field与 minecraft bukkit 服务器握手 - 发送服务器主机字段失败
【发布时间】:2013-03-05 02:31:06
【问题描述】:

我正在尝试为我的世界服务器制作客户端/机器人,以自动保护聊天并禁止垃圾邮件发送者。 (第一个成就)
我在这里找到了一些文档,我已经实现了数据类型from hereso they look like this - 我还没有完成)。现在,我正在尝试发送初始0x02 数据包,它应该如下所示:

我的数据包格式

size    value                comment

1       0x02                 Packet ID
2+?     string               Username (I send "jakub")
2+?     another string       Server host name - here, the program FAILS*
4       25565                Port number

*Fails 表示 bukkit 服务器在控制台输出以下内容,socket 关闭:

11:09:45 [INFO] /127.0.0.1:51256 失去连接

我现在可以看到,如何测试我的数据类型是否正确,但因为我似乎发送用户名没有问题,我认为我发送错误信息,虽然在 正确的格式

生成字符串

但无论如何,我很好奇我是否做对了一切。我有 mc_shortmc_string 的课程。这就是mc_short 自己创建 2 个字节的方式:

//mc_short::val is type of short 
void mc_short::asBytes(char* data) {  
    for (int i = 0; i < 2; i++)
       data[endianity?i:1-i] = (val >> (i * 8));  //Some magic with byteshifting.
       //endianity is set to false, because java uses BigEndian everywhere** (UNFRIENDLY PERSONS!!)
}

**参考http://wiki.vg/Data_Types:

Java(以及我的世界)中的所有类型都是大端的,也就是说,最重要的字节在前。

然后字符串本身使用mc_shortstd::string 来填充char* 中的字节。

void mc_string::asBytes(char* data) {
    mc_short size((short)val.length());  //val is std::string
    size.endianity = endianity;          //mc_string::endianity is boolean, and is ony used to determine endianity of the first 2 bytes
    size.asBytes(data);  //Filling 2 bytes in data - length info
    for(short i=0; i<size.value(); i++) {
        data[i+2] = val[i];  //Copying std::string to data
    }
}

问题总结

  1. 我应该发送什么作为“服务器主机名”,0x02 的第三个字段?
  2. 我发送的字符串是否正确?不需要任何其他转换吗?

我知道,我的问题是关于不太为人所知的主题,因此您可能不知道也不知道答案,也不知道主题本身。在这种情况下,请忽略这个问题。

【问题讨论】:

    标签: c++ minecraft packets


    【解决方案1】:

    字符串以大端 unicode(UTF-16,但大端)编码。如果您不使用 Java,则无法直接从内存中映射您的字符(好吧,如果您只是在每个字符之间写一个零并接受这是一种糟糕的做法,那么您可以作弊)。在 C# 中有一个编码 Minecraft 字符串 here 的示例。

    至于该字符串的内容,它应该是要连接的主机名。如果 Google 运行 Minecraft 服务器,则该字符串可能是 minecraft.google.com

    使用这个实际数据包的一个例子是here

    因此,您的问题已得到实际回答,请提供一些建议。 Minecraft 协议很糟糕,编写客户端需要大量工作。您需要能够支持协议中的所有数据包(是的,所有数据包),并且您需要实现基本的物理掉到地上,这样您就不会因飞行而被踢。有几个选项,按从最佳到最差的顺序排列:

    • 使用 Bukkit 并为此编写插件
    • 编写代理而不是客户端
    • 写一个客户端,就像你现在正在尝试的那样

    所以,如果你先做,你需要用 Java 写一个插件。我对此了解不多。

    我确实对后两个选项了解很多。我是Craft.Net 的维护者,它是一堆库,包括一个通用网络库和一个客户端库。您可以在几个小时内组装一个客户端或代理。一个示例客户端在同一个 repo 中,并且有一个代理 here。这些都使用 C#。

    如果你还想完全自己动手,祝你好运。

    【讨论】:

    • 您好,感谢您的回答! :) 我知道 Craft.Net,但由于两个原因,我还没有使用这里的任何东西。首先,我总是遇到包括和使用新库的问题,其次,除非我完全迷失了方向,否则我喜欢自己解决问题。我不会将我的 bot 实现为 Bukkit 插件,因为它还应该具有其他功能,而且我不喜欢 java。如果我迷路了,有什么方法可以联系你吗? (#mcdevs IRC 也许吧?我发誓我只会在别无选择的时候打扰你。
    • 除此之外,我已经让机器人使用0x07 力场并实现了简单的库存操作。到目前为止,我糟糕的字符串没有给我带来任何问题:P 我现在准备好编写地图解析器了。
    • 我在 Freenode IRC 的 #craft.net 上闲逛。随意打扰我,我不介意。我是 SirCmpwn。
    猜你喜欢
    • 2015-08-26
    • 2015-08-17
    • 1970-01-01
    • 2013-05-04
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    相关资源
    最近更新 更多