我的主要目標是將 C# 客戶端連接到 Minecraft 服務器,但我在獲取服務器發送的資料包內容時遇到了一些麻煩。根據此頁面,Minecraft 中的資料包應匹配特定格式。(資料包的格式)
此外,根據this,字串以 is length 為前綴。
這是我想拿到的包裹。
知道這些資訊,這是我的代碼:
//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);
}
結果:
packet_Length : 3
packet_Id : 3
uuid : ↓??v9Q??1??w??
name : 9?mc_bot
問題是資料包ID應該是 1,uuid是一個常規字串,名稱只有“ mc_bot ”作為值。我確切地說必須在完美作業之前完成的部分(我認為)因為客戶端在獲取登錄成功資料包后加入服務器,但我無法正確獲取任何資料。
謝謝 !
uj5u.com熱心網友回復:
所以,在一些幫助下,我終于發現了我的程序出了什么問題。我想指出,老實說,通過正確閱讀檔案可以輕松避免這種型別的錯誤,而我沒有這樣做......
這是我的最終代碼
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);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/383610.html
下一篇:來自Peggy生成的決議器的回呼
