mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-27 05:23:51 +00:00
fix(movement): reject server teleports to corrupted near-origin positions
Some checks failed
Build / Build (arm64) (push) Has been cancelled
Build / Build (x86-64) (push) Has been cancelled
Build / Build (macOS arm64) (push) Has been cancelled
Build / Build (windows-arm64) (push) Has been cancelled
Build / Build (windows-x86-64) (push) Has been cancelled
Security / CodeQL (C/C++) (push) Has been cancelled
Security / Semgrep (push) Has been cancelled
Security / Sanitizer Build (ASan/UBSan) (push) Has been cancelled
Some checks failed
Build / Build (arm64) (push) Has been cancelled
Build / Build (x86-64) (push) Has been cancelled
Build / Build (macOS arm64) (push) Has been cancelled
Build / Build (windows-arm64) (push) Has been cancelled
Build / Build (windows-x86-64) (push) Has been cancelled
Security / CodeQL (C/C++) (push) Has been cancelled
Security / Semgrep (push) Has been cancelled
Security / Sanitizer Build (ASan/UBSan) (push) Has been cancelled
The server can persist a corrupted near-origin position on map 0 (from a faulty area-trigger destination) across sessions. On re-login it sends the bad position via LOGIN_VERIFY_WORLD; if the player walks into the offending trigger again the server re-teleports there, and our heartbeats reinforce the bad save — creating a permanent teleport loop. Defenses added: - handleTeleportAck rejects MSG_MOVE_TELEPORT to near-origin on map 0 (no position update, no ACK, no world reload) - applyPlayerTransportState rejects player UPDATE_OBJECT MOVEMENT blocks pushing the same bad position - sendMovement blocks heartbeats originating from near-origin so the server cannot persist the bad save - 10-second area-trigger cooldown after teleport / world entry / login (replaces the one-shot suppress flag that re-fired on jitter) - Immediate STOP+HEARTBEAT after teleport ACK / WORLDPORT ACK / login to sync the real position with the server promptly - CMSG_AREATRIGGER firing now logged at WARNING level for diagnosis
This commit is contained in:
parent
f9f02569d6
commit
d138269a35
5 changed files with 97 additions and 20 deletions
|
|
@ -611,6 +611,14 @@ void EntityController::applyPlayerTransportState(const UpdateBlock& block,
|
|||
const std::shared_ptr<Entity>& entity,
|
||||
const glm::vec3& canonicalPos, float oCanonical,
|
||||
bool updateMovementInfoPos) {
|
||||
// Reject server-pushed position corrections to near-origin on map 0.
|
||||
// The server stores a corrupted position from a faulty area-trigger
|
||||
// destination; accepting it lets heartbeats reinforce the bad save.
|
||||
auto positionIsBad = [&](float x, float y) {
|
||||
return owner_.getCurrentMapId() == 0 &&
|
||||
std::abs(x) < 1000.0f && std::abs(y) < 1000.0f;
|
||||
};
|
||||
|
||||
if (block.onTransport) {
|
||||
// Convert transport offset from server → canonical coordinates
|
||||
glm::vec3 serverOffset(block.transportX, block.transportY, block.transportZ);
|
||||
|
|
@ -623,18 +631,28 @@ void EntityController::applyPlayerTransportState(const UpdateBlock& block,
|
|||
owner_.movementInfoRef().y = composed.y;
|
||||
owner_.movementInfoRef().z = composed.z;
|
||||
} else if (updateMovementInfoPos) {
|
||||
owner_.movementInfoRef().x = canonicalPos.x;
|
||||
owner_.movementInfoRef().y = canonicalPos.y;
|
||||
owner_.movementInfoRef().z = canonicalPos.z;
|
||||
if (positionIsBad(canonicalPos.x, canonicalPos.y)) {
|
||||
LOG_WARNING("REJECTED player UPDATE_OBJECT to near-origin canonical=(",
|
||||
canonicalPos.x, ", ", canonicalPos.y, ", ", canonicalPos.z, ")");
|
||||
} else {
|
||||
owner_.movementInfoRef().x = canonicalPos.x;
|
||||
owner_.movementInfoRef().y = canonicalPos.y;
|
||||
owner_.movementInfoRef().z = canonicalPos.z;
|
||||
}
|
||||
}
|
||||
LOG_INFO("Player on transport: 0x", std::hex, owner_.playerTransportGuidRef(), std::dec,
|
||||
" offset=(", owner_.playerTransportOffsetRef().x, ", ", owner_.playerTransportOffsetRef().y,
|
||||
", ", owner_.playerTransportOffsetRef().z, ")");
|
||||
} else {
|
||||
if (updateMovementInfoPos) {
|
||||
owner_.movementInfoRef().x = canonicalPos.x;
|
||||
owner_.movementInfoRef().y = canonicalPos.y;
|
||||
owner_.movementInfoRef().z = canonicalPos.z;
|
||||
if (positionIsBad(canonicalPos.x, canonicalPos.y)) {
|
||||
LOG_WARNING("REJECTED player UPDATE_OBJECT to near-origin canonical=(",
|
||||
canonicalPos.x, ", ", canonicalPos.y, ", ", canonicalPos.z, ")");
|
||||
} else {
|
||||
owner_.movementInfoRef().x = canonicalPos.x;
|
||||
owner_.movementInfoRef().y = canonicalPos.y;
|
||||
owner_.movementInfoRef().z = canonicalPos.z;
|
||||
}
|
||||
}
|
||||
// Don't clear client-side M2 transport boarding (trams) —
|
||||
// the server doesn't know about client-detected transport attachment.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue