mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-03 20:03:50 +00:00
refactor: extract buildForceAck from 5 duplicated force-ACK blocks
All five force-ACK handlers (speed, root, flag, collision-height, knockback) repeated the same ~25-line GUID+counter+movementInfo+coord- conversion+send sequence. Extracted into buildForceAck() which returns a ready-to-send packet with the movement payload already written. This also fixes a transport coordinate conversion bug: the collision- height handler was the only one that omitted the ONTRANSPORT check, causing position desync when riding boats/zeppelins. buildForceAck handles transport coords uniformly for all callers. Net -80 lines.
This commit is contained in:
parent
5fcb30be1a
commit
7462fdd41f
2 changed files with 53 additions and 157 deletions
|
|
@ -179,6 +179,7 @@ private:
|
||||||
void handleOtherPlayerMovement(network::Packet& packet);
|
void handleOtherPlayerMovement(network::Packet& packet);
|
||||||
void handleMoveSetSpeed(network::Packet& packet);
|
void handleMoveSetSpeed(network::Packet& packet);
|
||||||
void handleForceRunSpeedChange(network::Packet& packet);
|
void handleForceRunSpeedChange(network::Packet& packet);
|
||||||
|
network::Packet buildForceAck(Opcode ackOpcode, uint32_t counter);
|
||||||
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 handleMoveKnockBack(network::Packet& packet);
|
void handleMoveKnockBack(network::Packet& packet);
|
||||||
|
|
|
||||||
|
|
@ -762,6 +762,46 @@ void MovementHandler::dismount() {
|
||||||
// Force Speed / Root / Flag Change Handlers
|
// Force Speed / Root / Flag Change Handlers
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
|
// Shared force-ACK packet builder. All server-forced movement changes (speed,
|
||||||
|
// root, flag, collision-height, knockback) require the same ACK structure:
|
||||||
|
// GUID + counter + movement payload with server-space coordinates. Centralised
|
||||||
|
// here so transport coordinate conversion can't diverge between handlers.
|
||||||
|
network::Packet MovementHandler::buildForceAck(Opcode ackOpcode, uint32_t counter) {
|
||||||
|
network::Packet ack(wireOpcode(ackOpcode));
|
||||||
|
const bool legacyGuid =
|
||||||
|
isActiveExpansion("classic") || isActiveExpansion("tbc") || isActiveExpansion("turtle");
|
||||||
|
if (legacyGuid) {
|
||||||
|
ack.writeUInt64(owner_.playerGuid);
|
||||||
|
} else {
|
||||||
|
ack.writePackedGuid(owner_.playerGuid);
|
||||||
|
}
|
||||||
|
ack.writeUInt32(counter);
|
||||||
|
|
||||||
|
MovementInfo wire = movementInfo;
|
||||||
|
wire.time = nextMovementTimestampMs();
|
||||||
|
if (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
||||||
|
wire.transportTime = wire.time;
|
||||||
|
wire.transportTime2 = wire.time;
|
||||||
|
}
|
||||||
|
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 (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
||||||
|
glm::vec3 serverTransport =
|
||||||
|
core::coords::canonicalToServer(glm::vec3(wire.transportX, wire.transportY, wire.transportZ));
|
||||||
|
wire.transportX = serverTransport.x;
|
||||||
|
wire.transportY = serverTransport.y;
|
||||||
|
wire.transportZ = serverTransport.z;
|
||||||
|
}
|
||||||
|
if (owner_.packetParsers_) {
|
||||||
|
owner_.packetParsers_->writeMovementPayload(ack, wire);
|
||||||
|
} else {
|
||||||
|
MovementPacket::writeMovementPayload(ack, wire);
|
||||||
|
}
|
||||||
|
return ack;
|
||||||
|
}
|
||||||
|
|
||||||
void MovementHandler::handleForceSpeedChange(network::Packet& packet, const char* name,
|
void MovementHandler::handleForceSpeedChange(network::Packet& packet, const char* name,
|
||||||
Opcode ackOpcode, float* speedStorage) {
|
Opcode ackOpcode, float* speedStorage) {
|
||||||
const bool fscTbcLike = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
const bool fscTbcLike = isClassicLikeExpansion() || isActiveExpansion("tbc");
|
||||||
|
|
@ -790,39 +830,7 @@ void MovementHandler::handleForceSpeedChange(network::Packet& packet, const char
|
||||||
}
|
}
|
||||||
|
|
||||||
if (owner_.socket) {
|
if (owner_.socket) {
|
||||||
network::Packet ack(wireOpcode(ackOpcode));
|
auto ack = buildForceAck(ackOpcode, counter);
|
||||||
const bool legacyGuidAck =
|
|
||||||
isActiveExpansion("classic") || isActiveExpansion("tbc") || isActiveExpansion("turtle");
|
|
||||||
if (legacyGuidAck) {
|
|
||||||
ack.writeUInt64(owner_.playerGuid);
|
|
||||||
} else {
|
|
||||||
ack.writePackedGuid(owner_.playerGuid);
|
|
||||||
}
|
|
||||||
ack.writeUInt32(counter);
|
|
||||||
|
|
||||||
MovementInfo wire = movementInfo;
|
|
||||||
wire.time = nextMovementTimestampMs();
|
|
||||||
if (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
|
||||||
wire.transportTime = wire.time;
|
|
||||||
wire.transportTime2 = wire.time;
|
|
||||||
}
|
|
||||||
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 (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
|
||||||
glm::vec3 serverTransport =
|
|
||||||
core::coords::canonicalToServer(glm::vec3(wire.transportX, wire.transportY, wire.transportZ));
|
|
||||||
wire.transportX = serverTransport.x;
|
|
||||||
wire.transportY = serverTransport.y;
|
|
||||||
wire.transportZ = serverTransport.z;
|
|
||||||
}
|
|
||||||
if (owner_.packetParsers_) {
|
|
||||||
owner_.packetParsers_->writeMovementPayload(ack, wire);
|
|
||||||
} else {
|
|
||||||
MovementPacket::writeMovementPayload(ack, wire);
|
|
||||||
}
|
|
||||||
|
|
||||||
ack.writeFloat(newSpeed);
|
ack.writeFloat(newSpeed);
|
||||||
owner_.socket->send(ack);
|
owner_.socket->send(ack);
|
||||||
}
|
}
|
||||||
|
|
@ -863,41 +871,9 @@ void MovementHandler::handleForceMoveRootState(network::Packet& packet, bool roo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!owner_.socket) return;
|
if (!owner_.socket) return;
|
||||||
uint16_t ackWire = wireOpcode(rooted ? Opcode::CMSG_FORCE_MOVE_ROOT_ACK
|
Opcode ackOp = rooted ? Opcode::CMSG_FORCE_MOVE_ROOT_ACK : Opcode::CMSG_FORCE_MOVE_UNROOT_ACK;
|
||||||
: Opcode::CMSG_FORCE_MOVE_UNROOT_ACK);
|
if (wireOpcode(ackOp) == 0xFFFF) return;
|
||||||
if (ackWire == 0xFFFF) return;
|
owner_.socket->send(buildForceAck(ackOp, counter));
|
||||||
|
|
||||||
network::Packet ack(ackWire);
|
|
||||||
const bool legacyGuidAck =
|
|
||||||
isActiveExpansion("classic") || isActiveExpansion("tbc") || isActiveExpansion("turtle");
|
|
||||||
if (legacyGuidAck) {
|
|
||||||
ack.writeUInt64(owner_.playerGuid);
|
|
||||||
} else {
|
|
||||||
ack.writePackedGuid(owner_.playerGuid);
|
|
||||||
}
|
|
||||||
ack.writeUInt32(counter);
|
|
||||||
|
|
||||||
MovementInfo wire = movementInfo;
|
|
||||||
wire.time = nextMovementTimestampMs();
|
|
||||||
if (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
|
||||||
wire.transportTime = wire.time;
|
|
||||||
wire.transportTime2 = wire.time;
|
|
||||||
}
|
|
||||||
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 (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
|
||||||
glm::vec3 serverTransport =
|
|
||||||
core::coords::canonicalToServer(glm::vec3(wire.transportX, wire.transportY, wire.transportZ));
|
|
||||||
wire.transportX = serverTransport.x;
|
|
||||||
wire.transportY = serverTransport.y;
|
|
||||||
wire.transportZ = serverTransport.z;
|
|
||||||
}
|
|
||||||
if (owner_.packetParsers_) owner_.packetParsers_->writeMovementPayload(ack, wire);
|
|
||||||
else MovementPacket::writeMovementPayload(ack, wire);
|
|
||||||
|
|
||||||
owner_.socket->send(ack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MovementHandler::handleForceMoveFlagChange(network::Packet& packet, const char* name,
|
void MovementHandler::handleForceMoveFlagChange(network::Packet& packet, const char* name,
|
||||||
|
|
@ -922,40 +898,8 @@ void MovementHandler::handleForceMoveFlagChange(network::Packet& packet, const c
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!owner_.socket) return;
|
if (!owner_.socket) return;
|
||||||
uint16_t ackWire = wireOpcode(ackOpcode);
|
if (wireOpcode(ackOpcode) == 0xFFFF) return;
|
||||||
if (ackWire == 0xFFFF) return;
|
owner_.socket->send(buildForceAck(ackOpcode, counter));
|
||||||
|
|
||||||
network::Packet ack(ackWire);
|
|
||||||
const bool legacyGuidAck =
|
|
||||||
isActiveExpansion("classic") || isActiveExpansion("tbc") || isActiveExpansion("turtle");
|
|
||||||
if (legacyGuidAck) {
|
|
||||||
ack.writeUInt64(owner_.playerGuid);
|
|
||||||
} else {
|
|
||||||
ack.writePackedGuid(owner_.playerGuid);
|
|
||||||
}
|
|
||||||
ack.writeUInt32(counter);
|
|
||||||
|
|
||||||
MovementInfo wire = movementInfo;
|
|
||||||
wire.time = nextMovementTimestampMs();
|
|
||||||
if (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
|
||||||
wire.transportTime = wire.time;
|
|
||||||
wire.transportTime2 = wire.time;
|
|
||||||
}
|
|
||||||
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 (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
|
||||||
glm::vec3 serverTransport =
|
|
||||||
core::coords::canonicalToServer(glm::vec3(wire.transportX, wire.transportY, wire.transportZ));
|
|
||||||
wire.transportX = serverTransport.x;
|
|
||||||
wire.transportY = serverTransport.y;
|
|
||||||
wire.transportZ = serverTransport.z;
|
|
||||||
}
|
|
||||||
if (owner_.packetParsers_) owner_.packetParsers_->writeMovementPayload(ack, wire);
|
|
||||||
else MovementPacket::writeMovementPayload(ack, wire);
|
|
||||||
|
|
||||||
owner_.socket->send(ack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MovementHandler::handleMoveSetCollisionHeight(network::Packet& packet) {
|
void MovementHandler::handleMoveSetCollisionHeight(network::Packet& packet) {
|
||||||
|
|
@ -972,28 +916,11 @@ void MovementHandler::handleMoveSetCollisionHeight(network::Packet& packet) {
|
||||||
if (guid != owner_.playerGuid) return;
|
if (guid != owner_.playerGuid) return;
|
||||||
if (!owner_.socket) return;
|
if (!owner_.socket) return;
|
||||||
|
|
||||||
uint16_t ackWire = wireOpcode(Opcode::CMSG_MOVE_SET_COLLISION_HGT_ACK);
|
if (wireOpcode(Opcode::CMSG_MOVE_SET_COLLISION_HGT_ACK) == 0xFFFF) return;
|
||||||
if (ackWire == 0xFFFF) return;
|
// buildForceAck now handles transport coordinate conversion, fixing the
|
||||||
|
// previous omission that caused desync when riding boats/zeppelins.
|
||||||
network::Packet ack(ackWire);
|
auto ack = buildForceAck(Opcode::CMSG_MOVE_SET_COLLISION_HGT_ACK, counter);
|
||||||
const bool legacyGuidAck = isActiveExpansion("classic") || isActiveExpansion("tbc") || isActiveExpansion("turtle");
|
|
||||||
if (legacyGuidAck) {
|
|
||||||
ack.writeUInt64(owner_.playerGuid);
|
|
||||||
} else {
|
|
||||||
ack.writePackedGuid(owner_.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 (owner_.packetParsers_) owner_.packetParsers_->writeMovementPayload(ack, wire);
|
|
||||||
else MovementPacket::writeMovementPayload(ack, wire);
|
|
||||||
ack.writeFloat(height);
|
ack.writeFloat(height);
|
||||||
|
|
||||||
owner_.socket->send(ack);
|
owner_.socket->send(ack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1020,40 +947,8 @@ void MovementHandler::handleMoveKnockBack(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!owner_.socket) return;
|
if (!owner_.socket) return;
|
||||||
uint16_t ackWire = wireOpcode(Opcode::CMSG_MOVE_KNOCK_BACK_ACK);
|
if (wireOpcode(Opcode::CMSG_MOVE_KNOCK_BACK_ACK) == 0xFFFF) return;
|
||||||
if (ackWire == 0xFFFF) return;
|
owner_.socket->send(buildForceAck(Opcode::CMSG_MOVE_KNOCK_BACK_ACK, counter));
|
||||||
|
|
||||||
network::Packet ack(ackWire);
|
|
||||||
const bool legacyGuidAck =
|
|
||||||
isActiveExpansion("classic") || isActiveExpansion("tbc") || isActiveExpansion("turtle");
|
|
||||||
if (legacyGuidAck) {
|
|
||||||
ack.writeUInt64(owner_.playerGuid);
|
|
||||||
} else {
|
|
||||||
ack.writePackedGuid(owner_.playerGuid);
|
|
||||||
}
|
|
||||||
ack.writeUInt32(counter);
|
|
||||||
|
|
||||||
MovementInfo wire = movementInfo;
|
|
||||||
wire.time = nextMovementTimestampMs();
|
|
||||||
if (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
|
||||||
wire.transportTime = wire.time;
|
|
||||||
wire.transportTime2 = wire.time;
|
|
||||||
}
|
|
||||||
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 (wire.hasFlag(MovementFlags::ONTRANSPORT)) {
|
|
||||||
glm::vec3 serverTransport =
|
|
||||||
core::coords::canonicalToServer(glm::vec3(wire.transportX, wire.transportY, wire.transportZ));
|
|
||||||
wire.transportX = serverTransport.x;
|
|
||||||
wire.transportY = serverTransport.y;
|
|
||||||
wire.transportZ = serverTransport.z;
|
|
||||||
}
|
|
||||||
if (owner_.packetParsers_) owner_.packetParsers_->writeMovementPayload(ack, wire);
|
|
||||||
else MovementPacket::writeMovementPayload(ack, wire);
|
|
||||||
|
|
||||||
owner_.socket->send(ack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue