mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 17:43:52 +00:00
net: ack SMSG_MOVE_SET/UNSET_CAN_TRANSITION_SWIM_FLY and SMSG_MOVE_SET_COLLISION_HGT
These three server-push opcodes were silently consumed without sending the required client acks, causing the server to stall waiting for confirmation before granting the capability. - SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY → CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK (via handleForceMoveFlagChange) - SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY → same ack opcode (no separate unset ack exists in WotLK 3.3.5a) - SMSG_MOVE_SET_COLLISION_HGT → CMSG_MOVE_SET_COLLISION_HGT_ACK via new handleMoveSetCollisionHeight() which appends the float height after the standard movement block (required by server-side ack validation)
This commit is contained in:
parent
c72186fd11
commit
84558fda69
2 changed files with 49 additions and 1 deletions
|
|
@ -1535,6 +1535,7 @@ private:
|
||||||
void handleForceSpeedChange(network::Packet& packet, const char* name, Opcode ackOpcode, float* speedStorage);
|
void handleForceSpeedChange(network::Packet& packet, const char* name, Opcode ackOpcode, float* speedStorage);
|
||||||
void handleForceMoveRootState(network::Packet& packet, bool rooted);
|
void handleForceMoveRootState(network::Packet& packet, bool rooted);
|
||||||
void handleForceMoveFlagChange(network::Packet& packet, const char* name, Opcode ackOpcode, uint32_t flag, bool set);
|
void handleForceMoveFlagChange(network::Packet& packet, const char* name, Opcode ackOpcode, uint32_t flag, bool set);
|
||||||
|
void handleMoveSetCollisionHeight(network::Packet& packet);
|
||||||
void handleMoveKnockBack(network::Packet& packet);
|
void handleMoveKnockBack(network::Packet& packet);
|
||||||
|
|
||||||
// ---- Area trigger detection ----
|
// ---- Area trigger detection ----
|
||||||
|
|
|
||||||
|
|
@ -5546,9 +5546,15 @@ void GameHandler::handlePacket(network::Packet& packet) {
|
||||||
handleForceMoveFlagChange(packet, "NORMAL_FALL", Opcode::CMSG_MOVE_FEATHER_FALL_ACK, 0, false);
|
handleForceMoveFlagChange(packet, "NORMAL_FALL", Opcode::CMSG_MOVE_FEATHER_FALL_ACK, 0, false);
|
||||||
break;
|
break;
|
||||||
case Opcode::SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY:
|
case Opcode::SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY:
|
||||||
|
handleForceMoveFlagChange(packet, "SET_CAN_TRANSITION_SWIM_FLY",
|
||||||
|
Opcode::CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK, 0, true);
|
||||||
|
break;
|
||||||
case Opcode::SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY:
|
case Opcode::SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY:
|
||||||
|
handleForceMoveFlagChange(packet, "UNSET_CAN_TRANSITION_SWIM_FLY",
|
||||||
|
Opcode::CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK, 0, false);
|
||||||
|
break;
|
||||||
case Opcode::SMSG_MOVE_SET_COLLISION_HGT:
|
case Opcode::SMSG_MOVE_SET_COLLISION_HGT:
|
||||||
packet.setReadPos(packet.getSize());
|
handleMoveSetCollisionHeight(packet);
|
||||||
break;
|
break;
|
||||||
case Opcode::SMSG_MOVE_SET_FLIGHT:
|
case Opcode::SMSG_MOVE_SET_FLIGHT:
|
||||||
handleForceMoveFlagChange(packet, "SET_FLIGHT", Opcode::CMSG_MOVE_FLIGHT_ACK,
|
handleForceMoveFlagChange(packet, "SET_FLIGHT", Opcode::CMSG_MOVE_FLIGHT_ACK,
|
||||||
|
|
@ -11413,6 +11419,47 @@ void GameHandler::handleForceMoveFlagChange(network::Packet& packet, const char*
|
||||||
socket->send(ack);
|
socket->send(ack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameHandler::handleMoveSetCollisionHeight(network::Packet& packet) {
|
||||||
|
// SMSG_MOVE_SET_COLLISION_HGT: packed guid + counter + float (height)
|
||||||
|
// ACK: CMSG_MOVE_SET_COLLISION_HGT_ACK = packed guid + counter + movement block + float (height)
|
||||||
|
const bool legacyGuid = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||||
|
if (packet.getSize() - packet.getReadPos() < (legacyGuid ? 8u : 2u)) return;
|
||||||
|
uint64_t guid = legacyGuid ? packet.readUInt64() : UpdateObjectParser::readPackedGuid(packet);
|
||||||
|
if (packet.getSize() - packet.getReadPos() < 8) return; // counter(4) + height(4)
|
||||||
|
uint32_t counter = packet.readUInt32();
|
||||||
|
float height = packet.readFloat();
|
||||||
|
|
||||||
|
LOG_INFO("SMSG_MOVE_SET_COLLISION_HGT: guid=0x", std::hex, guid, std::dec,
|
||||||
|
" counter=", counter, " height=", height);
|
||||||
|
|
||||||
|
if (guid != playerGuid) return;
|
||||||
|
if (!socket) return;
|
||||||
|
|
||||||
|
uint16_t ackWire = wireOpcode(Opcode::CMSG_MOVE_SET_COLLISION_HGT_ACK);
|
||||||
|
if (ackWire == 0xFFFF) return;
|
||||||
|
|
||||||
|
network::Packet ack(ackWire);
|
||||||
|
const bool legacyGuidAck = isActiveExpansion("classic") || isActiveExpansion("tbc") || isActiveExpansion("turtle");
|
||||||
|
if (legacyGuidAck) {
|
||||||
|
ack.writeUInt64(playerGuid);
|
||||||
|
} else {
|
||||||
|
MovementPacket::writePackedGuid(ack, playerGuid);
|
||||||
|
}
|
||||||
|
ack.writeUInt32(counter);
|
||||||
|
|
||||||
|
MovementInfo wire = movementInfo;
|
||||||
|
wire.time = nextMovementTimestampMs();
|
||||||
|
glm::vec3 serverPos = core::coords::canonicalToServer(glm::vec3(wire.x, wire.y, wire.z));
|
||||||
|
wire.x = serverPos.x;
|
||||||
|
wire.y = serverPos.y;
|
||||||
|
wire.z = serverPos.z;
|
||||||
|
if (packetParsers_) packetParsers_->writeMovementPayload(ack, wire);
|
||||||
|
else MovementPacket::writeMovementPayload(ack, wire);
|
||||||
|
ack.writeFloat(height);
|
||||||
|
|
||||||
|
socket->send(ack);
|
||||||
|
}
|
||||||
|
|
||||||
void GameHandler::handleMoveKnockBack(network::Packet& packet) {
|
void GameHandler::handleMoveKnockBack(network::Packet& packet) {
|
||||||
// WotLK: packed GUID; TBC/Classic: full uint64
|
// WotLK: packed GUID; TBC/Classic: full uint64
|
||||||
const bool mkbTbc = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
const bool mkbTbc = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue