mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-08-02 02:41:11 -04:00
fix(taxi): time out a taxi activation reply that never arrives
Live-found while validating the activation-race fix against the TBC server: a CMSG_ACTIVATETAXI the server can't make sense of (e.g. a stale start node vs. the player's actual position - reproduced by requesting from a stale cached nearestNode after moving) can go completely unanswered, no SMSG_ACTIVATETAXIREPLY at all in either direction. Before activation was deferred to the reply, taxiActivatePending_ being permanently stuck true didn't matter - the speculative flight had already started regardless. Now that activation correctly waits for the reply, a dropped one left taxiActivatePending_ true forever, silently no-op'ing every future activateTaxi() call (the "already pending" guard) - a permanent soft-lock of the character's taxi system until relog. Live-confirmed the fix: forced the drop scenario, the warning fired at exactly 8.011s (kTaxiActivateReplyTimeoutSeconds=8.0f), pending state cleared, and a subsequent request flew normally.
This commit is contained in:
@@ -291,6 +291,9 @@ private:
|
||||
uint32_t taxiMountDisplayId_ = 0;
|
||||
bool taxiActivatePending_ = false;
|
||||
float taxiActivateTimer_ = 0.0f;
|
||||
// How long to wait for SMSG_ACTIVATETAXIREPLY before giving up - see
|
||||
// updateClientTaxi()'s comment on why a dropped reply needs this now.
|
||||
static constexpr float kTaxiActivateReplyTimeoutSeconds = 8.0f;
|
||||
bool taxiClientActive_ = false;
|
||||
float taxiLandingCooldown_ = 0.0f;
|
||||
float taxiStartGrace_ = 0.0f;
|
||||
|
||||
@@ -2426,6 +2426,35 @@ void MovementHandler::finishClientTaxiFlight(bool snapToFinalWaypoint) {
|
||||
}
|
||||
|
||||
void MovementHandler::updateClientTaxi(float deltaTime) {
|
||||
// Live-confirmed: a CMSG_ACTIVATETAXI the server can't make sense of (e.g.
|
||||
// a stale start node vs. the player's actual position) can go completely
|
||||
// unanswered - no SMSG_ACTIVATETAXIREPLY at all, success or failure. Before
|
||||
// activation was deferred to the reply (see activateTaxi()'s comment), the
|
||||
// speculative flight start accidentally "recovered" from this since it
|
||||
// never waited on a reply in the first place. Now that it correctly does,
|
||||
// a dropped reply left taxiActivatePending_ true forever - every future
|
||||
// activateTaxi() call silently no-ops on its pending-guard, permanently
|
||||
// soft-locking the player's taxi system until relog. Time out and clear
|
||||
// pending state the same way an explicit failure reply would.
|
||||
if (taxiActivatePending_) {
|
||||
taxiActivateTimer_ += deltaTime;
|
||||
if (taxiActivateTimer_ > kTaxiActivateReplyTimeoutSeconds) {
|
||||
LOG_WARNING("Taxi activation reply timed out after ",
|
||||
kTaxiActivateReplyTimeoutSeconds, "s - clearing pending state");
|
||||
taxiActivatePending_ = false;
|
||||
taxiActivateTimer_ = 0.0f;
|
||||
taxiClientPath_.clear();
|
||||
taxiClientIndex_ = 0;
|
||||
taxiClientSegmentProgress_ = 0.0f;
|
||||
if (taxiMountActive_ && owner_.mountCallbackRef()) {
|
||||
owner_.mountCallbackRef()(0);
|
||||
}
|
||||
taxiMountActive_ = false;
|
||||
taxiMountDisplayId_ = 0;
|
||||
onTaxiFlight_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!taxiClientActive_ || taxiClientPath_.size() < 2) return;
|
||||
auto playerEntity = owner_.getEntityManager().getEntity(owner_.getPlayerGuid());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user