[英]C# Getting a packet from a Minecraft server using tcp/ip
My main goal is to connect a C# client to a Minecraft server but i have some trouble to get content of the packet sended by the server.我的主要目标是将 C# 客户端连接到 Minecraft 服务器,但我在获取服务器发送的数据包内容时遇到了一些麻烦。 According to this page , a packet in Minecraft should match a specific format.
根据这个页面,Minecraft 中的数据包应该匹配特定的格式。 ( Format of a packet )
(数据包格式)
Also, according to this , a string is prefixed by is length.此外,根据this ,字符串以 is length 为前缀。
Here's the packet i'my trying to get.这是我想要得到的数据包。
Knowing these informations, here's my code:知道这些信息,这是我的代码:
//S->C : Login Success
int packet_Length = ReadVarInt(stream);
int packet_Id = ReadVarInt(stream);
int uuid_length = ReadVarInt(stream);
string uuid = ReadString(stream, 16);
int name_length = ReadVarInt(stream);
string name = ReadString(stream, 16);
public static int ReadVarInt(Stream stream)
{
int value = 0;
int length = 0;
int currentByte;
while (true)
{
currentByte = stream.ReadByte();
value |= (currentByte & 0x7F) << (length++ * 7);
if (length > 5) throw new IOException("VarInt too big");
if ((currentByte & 0x80) != 0x80) break;
}
return value;
}
public static string ReadString(Stream stream, int length)
{
byte[] data = new byte[length];
stream.Read(data);
return Encoding.UTF8.GetString(data);
}
And the result:结果:
packet_Length : 3
packet_Id : 3
uuid : ↓☻►v9Q?►1??w??
name : 9♠mc_bot
The problem is that the packet ID should be 1, the uuid a regular string and the name only have " mc_bot " as value.问题是数据包ID应该是 1, uuid是一个常规字符串,并且名称只有“ mc_bot ”作为值。 I precise that the part who have to be done before work perfectly ( i think ) because the client join the server after getting the Login Success packet but i just can't get any data correctly.
我确切地说,必须在完美工作之前完成的部分(我认为)因为客户端在获取登录成功数据包后加入服务器,但我无法正确获取任何数据。
Thanks !谢谢 !
So, with some help i finally found what was wrong with my process.所以,在一些帮助下,我终于发现了我的过程出了什么问题。 I would like to point out that honestly, this type of error can be easily avoided by reading the documentation correctly, Which I didn't do...
老实说,我想指出,通过正确阅读文档可以轻松避免此类错误,但我没有这样做...
Here's my final code这是我的最终代码
int packet_Length = ReadVarInt(stream);
int packet_Id = ReadVarInt(stream);
Console.WriteLine($"packet_Length : {packet_Length}");
Console.WriteLine($"packet_Id : {packet_Id}");
//Enables compression. If compression is enabled,
//all following packets are encoded in the compressed packet format.
//Negative or zero values will disable compression,
//meaning the packet format should remain in the uncompressed packet format.
//However, this packet is entirely optional, and if not sent,
//compression will also not be enabled (the notchian server does not send the packet when compression is disabled).
if (packet_Id == 0x03)
{
//S->C : Set Compression (Optional)
int compression_threshold = ReadVarInt(stream);
Console.WriteLine($"packet_Id : {packet_Id}");
}
//S->C : Login Success
string uuid = ReadUUID(stream, 16);
int name_length = ReadVarInt(stream);
string name = ReadString(stream, name_length);
Console.WriteLine($"uuid : {uuid}");
Console.WriteLine($"name_length : {name_length}");
Console.WriteLine($"name : {name}");
public static string ReadUUID(Stream stream, int length)
{
byte[] data = new byte[length];
stream.Read(data);
ulong b1 = BitConverter.ToUInt64(data,0);
ulong b2 = BitConverter.ToUInt64(data,8);
byte[] bytes = new byte[0];
bytes = bytes.Concat(BitConverter.GetBytes(b1)).Concat(BitConverter.GetBytes(b2)).ToArray();
string uuid = "";
foreach (byte b in bytes)
uuid += b.ToString("x2");
return uuid.Substring(0, 8) + "-" + uuid.Substring(8, 4) + "-" + uuid.Substring(12, 4) + "-" + uuid.Substring(16, 4) + "-" + uuid.Substring(20, 12);
}
public static int ReadVarInt(Stream stream)
{
int value = 0;
int length = 0;
int currentByte;
while (true)
{
currentByte = stream.ReadByte();
value |= (currentByte & 0x7F) << (length++ * 7);
if (length > 5) throw new IOException("VarInt too big");
if ((currentByte & 0x80) != 0x80) break;
}
return value;
}
public static string ReadString(Stream stream, int length)
{
byte[] data = new byte[length];
stream.Read(data);
return Encoding.UTF8.GetString(data);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.