mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-27 05:23:51 +00:00
movement: track fallTime and jump fields in movement packets
Previously movementInfo.fallTime was always 0 and jumpVelocity/jumpSinAngle/ jumpCosAngle/jumpXYSpeed were never populated. The server reads fallTime unconditionally from every movement packet and uses it to compute fall damage and anti-cheat heuristics; the jump fields are required when FALLING is set. Changes: - Add isFalling_ / fallStartMs_ to track fall state across packets - MSG_MOVE_JUMP: set isFalling_=true, record fallStartMs_, populate jump fields (jumpVelocity=7.96, direction from facing angle, jumpXYSpeed from server run speed or walk speed when WALKING flag is set) - MSG_MOVE_FALL_LAND: clear all fall/jump fields - sendMovement: update movementInfo.fallTime = (time - fallStartMs_) each call so every heartbeat and position packet carries the correct elapsed fall time - World entry: reset all fall/jump fields alongside the flag reset
This commit is contained in:
parent
70abb12398
commit
4cf73a6def
2 changed files with 53 additions and 0 deletions
|
|
@ -1686,6 +1686,12 @@ private:
|
||||||
uint32_t lastMovementTimestampMs_ = 0;
|
uint32_t lastMovementTimestampMs_ = 0;
|
||||||
bool serverMovementAllowed_ = true;
|
bool serverMovementAllowed_ = true;
|
||||||
|
|
||||||
|
// Fall/jump tracking for movement packet correctness.
|
||||||
|
// fallTime must be the elapsed ms since the FALLING flag was set; the server
|
||||||
|
// uses it for fall-damage calculations and anti-cheat validation.
|
||||||
|
bool isFalling_ = false;
|
||||||
|
uint32_t fallStartMs_ = 0; // movementInfo.time value when FALLING started
|
||||||
|
|
||||||
// Inventory
|
// Inventory
|
||||||
Inventory inventory;
|
Inventory inventory;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6113,6 +6113,13 @@ void GameHandler::handleLoginVerifyWorld(network::Packet& packet) {
|
||||||
movementClockStart_ = std::chrono::steady_clock::now();
|
movementClockStart_ = std::chrono::steady_clock::now();
|
||||||
lastMovementTimestampMs_ = 0;
|
lastMovementTimestampMs_ = 0;
|
||||||
movementInfo.time = nextMovementTimestampMs();
|
movementInfo.time = nextMovementTimestampMs();
|
||||||
|
isFalling_ = false;
|
||||||
|
fallStartMs_ = 0;
|
||||||
|
movementInfo.fallTime = 0;
|
||||||
|
movementInfo.jumpVelocity = 0.0f;
|
||||||
|
movementInfo.jumpSinAngle = 0.0f;
|
||||||
|
movementInfo.jumpCosAngle = 0.0f;
|
||||||
|
movementInfo.jumpXYSpeed = 0.0f;
|
||||||
resurrectPending_ = false;
|
resurrectPending_ = false;
|
||||||
resurrectRequestPending_ = false;
|
resurrectRequestPending_ = false;
|
||||||
onTaxiFlight_ = false;
|
onTaxiFlight_ = false;
|
||||||
|
|
@ -7230,6 +7237,21 @@ void GameHandler::sendMovement(Opcode opcode) {
|
||||||
break;
|
break;
|
||||||
case Opcode::MSG_MOVE_JUMP:
|
case Opcode::MSG_MOVE_JUMP:
|
||||||
movementInfo.flags |= static_cast<uint32_t>(MovementFlags::FALLING);
|
movementInfo.flags |= static_cast<uint32_t>(MovementFlags::FALLING);
|
||||||
|
// Record fall start and capture horizontal velocity for jump fields.
|
||||||
|
isFalling_ = true;
|
||||||
|
fallStartMs_ = movementInfo.time;
|
||||||
|
movementInfo.fallTime = 0;
|
||||||
|
// jumpVelocity: WoW convention is the upward speed at launch.
|
||||||
|
movementInfo.jumpVelocity = 7.96f; // WOW_JUMP_VELOCITY from CameraController
|
||||||
|
{
|
||||||
|
// Facing direction encodes the horizontal movement direction at launch.
|
||||||
|
const float facingRad = movementInfo.orientation;
|
||||||
|
movementInfo.jumpCosAngle = std::cos(facingRad);
|
||||||
|
movementInfo.jumpSinAngle = std::sin(facingRad);
|
||||||
|
// Use server run speed as the horizontal speed at jump time.
|
||||||
|
const bool isWalking = (movementInfo.flags & static_cast<uint32_t>(MovementFlags::WALKING)) != 0;
|
||||||
|
movementInfo.jumpXYSpeed = isWalking ? 2.5f : (serverRunSpeed_ > 0.0f ? serverRunSpeed_ : 7.0f);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Opcode::MSG_MOVE_START_TURN_LEFT:
|
case Opcode::MSG_MOVE_START_TURN_LEFT:
|
||||||
movementInfo.flags |= static_cast<uint32_t>(MovementFlags::TURN_LEFT);
|
movementInfo.flags |= static_cast<uint32_t>(MovementFlags::TURN_LEFT);
|
||||||
|
|
@ -7243,6 +7265,13 @@ void GameHandler::sendMovement(Opcode opcode) {
|
||||||
break;
|
break;
|
||||||
case Opcode::MSG_MOVE_FALL_LAND:
|
case Opcode::MSG_MOVE_FALL_LAND:
|
||||||
movementInfo.flags &= ~static_cast<uint32_t>(MovementFlags::FALLING);
|
movementInfo.flags &= ~static_cast<uint32_t>(MovementFlags::FALLING);
|
||||||
|
isFalling_ = false;
|
||||||
|
fallStartMs_ = 0;
|
||||||
|
movementInfo.fallTime = 0;
|
||||||
|
movementInfo.jumpVelocity = 0.0f;
|
||||||
|
movementInfo.jumpSinAngle = 0.0f;
|
||||||
|
movementInfo.jumpCosAngle = 0.0f;
|
||||||
|
movementInfo.jumpXYSpeed = 0.0f;
|
||||||
break;
|
break;
|
||||||
case Opcode::MSG_MOVE_HEARTBEAT:
|
case Opcode::MSG_MOVE_HEARTBEAT:
|
||||||
// No flag changes — just sends current position
|
// No flag changes — just sends current position
|
||||||
|
|
@ -7251,6 +7280,24 @@ void GameHandler::sendMovement(Opcode opcode) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep fallTime current: it must equal the elapsed milliseconds since FALLING
|
||||||
|
// was set, so the server can compute fall damage correctly.
|
||||||
|
if (isFalling_ && movementInfo.hasFlag(MovementFlags::FALLING)) {
|
||||||
|
// movementInfo.time is the strictly-increasing client clock (ms).
|
||||||
|
// Subtract fallStartMs_ to get elapsed fall time; clamp to non-negative.
|
||||||
|
uint32_t elapsed = (movementInfo.time >= fallStartMs_)
|
||||||
|
? (movementInfo.time - fallStartMs_)
|
||||||
|
: 0u;
|
||||||
|
movementInfo.fallTime = elapsed;
|
||||||
|
} else if (!movementInfo.hasFlag(MovementFlags::FALLING)) {
|
||||||
|
// Ensure fallTime is zeroed whenever we're not falling.
|
||||||
|
if (isFalling_) {
|
||||||
|
isFalling_ = false;
|
||||||
|
fallStartMs_ = 0;
|
||||||
|
}
|
||||||
|
movementInfo.fallTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (onTaxiFlight_ || taxiMountActive_ || taxiActivatePending_ || taxiClientActive_) {
|
if (onTaxiFlight_ || taxiMountActive_ || taxiActivatePending_ || taxiClientActive_) {
|
||||||
sanitizeMovementForTaxi();
|
sanitizeMovementForTaxi();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue