Fix BadPacket

This commit is contained in:
BruceChen 2022-10-16 18:42:11 +08:00 committed by GitHub
parent 12e2c6b4bb
commit 10f21dc01c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -73,6 +73,7 @@ namespace MinecraftClient.Protocol.Handlers
private int currentDimension; private int currentDimension;
private bool isOnlineMode = false; private bool isOnlineMode = false;
private readonly BlockingCollection<Tuple<int, Queue<byte>>> packetQueue = new(); private readonly BlockingCollection<Tuple<int, Queue<byte>>> packetQueue = new();
private float LastYaw, LastPitch;
private int pendingAcknowledgments = 0; private int pendingAcknowledgments = 0;
private readonly LastSeenMessagesCollector lastSeenMessagesCollector = new(5); private readonly LastSeenMessagesCollector lastSeenMessagesCollector = new(5);
@ -688,37 +689,52 @@ namespace MinecraftClient.Protocol.Handlers
handler.OnRespawn(); handler.OnRespawn();
break; break;
case PacketTypesIn.PlayerPositionAndLook: case PacketTypesIn.PlayerPositionAndLook:
// These always need to be read, since we need the field after them for teleport confirm
double x = dataTypes.ReadNextDouble(packetData);
double y = dataTypes.ReadNextDouble(packetData);
double z = dataTypes.ReadNextDouble(packetData);
float yaw = dataTypes.ReadNextFloat(packetData);
float pitch = dataTypes.ReadNextFloat(packetData);
byte locMask = dataTypes.ReadNextByte(packetData);
// entity handling require player pos for distance calculating
if (handler.GetTerrainEnabled() || handler.GetEntityHandlingEnabled())
{ {
if (protocolVersion >= MC_1_8_Version) // These always need to be read, since we need the field after them for teleport confirm
double x = dataTypes.ReadNextDouble(packetData);
double y = dataTypes.ReadNextDouble(packetData);
double z = dataTypes.ReadNextDouble(packetData);
Location location = new(x, y, z);
float yaw = dataTypes.ReadNextFloat(packetData);
float pitch = dataTypes.ReadNextFloat(packetData);
byte locMask = dataTypes.ReadNextByte(packetData);
// entity handling require player pos for distance calculating
if (handler.GetTerrainEnabled() || handler.GetEntityHandlingEnabled())
{ {
Location location = handler.GetCurrentLocation(); if (protocolVersion >= MC_1_8_Version)
location.X = (locMask & 1 << 0) != 0 ? location.X + x : x; {
location.Y = (locMask & 1 << 1) != 0 ? location.Y + y : y; Location current = handler.GetCurrentLocation();
location.Z = (locMask & 1 << 2) != 0 ? location.Z + z : z; location.X = (locMask & 1 << 0) != 0 ? current.X + x : x;
handler.UpdateLocation(location, yaw, pitch); location.Y = (locMask & 1 << 1) != 0 ? current.Y + y : y;
location.Z = (locMask & 1 << 2) != 0 ? current.Z + z : z;
}
} }
else handler.UpdateLocation(new Location(x, y, z), yaw, pitch);
}
if (protocolVersion >= MC_1_9_Version) if (protocolVersion >= MC_1_9_Version)
{ {
int teleportID = dataTypes.ReadNextVarInt(packetData); int teleportID = dataTypes.ReadNextVarInt(packetData);
// Teleport confirm packet
SendPacket(PacketTypesOut.TeleportConfirm, dataTypes.GetVarInt(teleportID));
}
if (protocolVersion >= MC_1_17_Version) if (teleportID < 0) { yaw = LastYaw; pitch = LastPitch; }
dataTypes.ReadNextBool(packetData); // Dismount Vehicle - 1.17 and above else { LastYaw = yaw; LastPitch = pitch; }
handler.UpdateLocation(location, yaw, pitch);
// Teleport confirm packet
SendPacket(PacketTypesOut.TeleportConfirm, dataTypes.GetVarInt(teleportID));
SendLocationUpdate(location, true, yaw, pitch, true);
if (teleportID == 1)
SendLocationUpdate(location, true, yaw, pitch, true);
}
else
{
handler.UpdateLocation(location, yaw, pitch);
LastYaw = yaw; LastPitch = pitch;
}
if (protocolVersion >= MC_1_17_Version)
dataTypes.ReadNextBool(packetData); // Dismount Vehicle - 1.17 and above
}
break; break;
case PacketTypesIn.ChunkData: case PacketTypesIn.ChunkData:
if (handler.GetTerrainEnabled()) if (handler.GetTerrainEnabled())
@ -2495,6 +2511,7 @@ namespace MinecraftClient.Protocol.Handlers
return false; return false;
} }
/// <summary> /// <summary>
/// Send a location update to the server /// Send a location update to the server
/// </summary> /// </summary>
@ -2503,17 +2520,24 @@ namespace MinecraftClient.Protocol.Handlers
/// <param name="yaw">Optional new yaw for updating player look</param> /// <param name="yaw">Optional new yaw for updating player look</param>
/// <param name="pitch">Optional new pitch for updating player look</param> /// <param name="pitch">Optional new pitch for updating player look</param>
/// <returns>True if the location update was successfully sent</returns> /// <returns>True if the location update was successfully sent</returns>
public bool SendLocationUpdate(Location location, bool onGround, float? yaw = null, float? pitch = null) public bool SendLocationUpdate(Location location, bool onGround, float? yaw, float? pitch)
{
return SendLocationUpdate(location, onGround, yaw, pitch, false);
}
public bool SendLocationUpdate(Location location, bool onGround, float? yaw = null, float? pitch = null, bool forceUpdate = false)
{ {
if (handler.GetTerrainEnabled()) if (handler.GetTerrainEnabled())
{ {
byte[] yawpitch = Array.Empty<byte>(); byte[] yawpitch = Array.Empty<byte>();
PacketTypesOut packetType = PacketTypesOut.PlayerPosition; PacketTypesOut packetType = PacketTypesOut.PlayerPosition;
if (yaw.HasValue && pitch.HasValue) if (yaw.HasValue && pitch.HasValue && (forceUpdate || yaw.Value != LastYaw || pitch.Value != LastPitch))
{ {
yawpitch = dataTypes.ConcatBytes(dataTypes.GetFloat(yaw.Value), dataTypes.GetFloat(pitch.Value)); yawpitch = dataTypes.ConcatBytes(dataTypes.GetFloat(yaw.Value), dataTypes.GetFloat(pitch.Value));
packetType = PacketTypesOut.PlayerPositionAndRotation; packetType = PacketTypesOut.PlayerPositionAndRotation;
LastYaw = yaw.Value; LastPitch = pitch.Value;
} }
try try