Merge pull request #2330 from mod-playerbots/test-staging

Revert "Feat: Reintroduce timed logouts" (#2329)
This commit is contained in:
Keleborn 2026-04-24 12:45:15 -07:00 committed by GitHub
commit a4d2c83d85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 67 deletions

View File

@ -243,22 +243,10 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
nextAICheckDelay = 0;
// Early return if bot is in invalid state
if (!bot || !bot->GetSession() || !bot->IsInWorld() || bot->IsBeingTeleported() || bot->IsDuringRemoveFromWorld())
if (!bot || !bot->GetSession() || !bot->IsInWorld() || bot->IsBeingTeleported() ||
bot->GetSession()->isLogingOut() || bot->IsDuringRemoveFromWorld())
return;
// During timed logout countdown, cancel if bot enters combat (this cancellation is handled client-side for real players).
if (bot->GetSession()->isLogingOut())
{
bool canLogoutInCombat = bot->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING);
if (bot->IsInCombat() && !canLogoutInCombat)
{
WorldPackets::Character::LogoutCancel cancelData = WorldPacket(CMSG_LOGOUT_CANCEL);
bot->GetSession()->HandleLogoutCancelOpcode(cancelData);
}
else
return;
}
// Handle cheat options (set bot health and power if cheats are enabled)
if (bot->IsAlive() &&
(static_cast<uint32>(GetCheat()) > 0 || static_cast<uint32>(sPlayerbotAIConfig.botCheatMask) > 0))
@ -727,9 +715,30 @@ void PlayerbotAI::HandleCommand(uint32 type, const std::string& text, Player& fr
Reset(true);
}
// Commented-out logout commands blocks removed from here and implemented in HandleCommand.
// Remaining is a commented-out action delay command block.
/*
// TODO: missing implementation to port
/*else if (filtered == "logout")
{
if (!(bot->IsStunnedByLogout() || bot->GetSession()->isLogingOut()))
{
if (type == CHAT_MSG_WHISPER)
TellPlayer(&fromPlayer, BOT_TEXT("logout_start"));
if (master && master->GetPlayerbotMgr())
SetShouldLogOut(true);
}
}
else if (filtered == "logout cancel")
{
if (bot->IsStunnedByLogout() || bot->GetSession()->isLogingOut())
{
if (type == CHAT_MSG_WHISPER)
TellPlayer(&fromPlayer, BOT_TEXT("logout_cancel"));
WorldPacket p;
bot->GetSession()->HandleLogoutCancelOpcode(p);
SetShouldLogOut(false);
}
}
else if ((filtered.size() > 5) && (filtered.substr(0, 5) == "wait ") && (filtered.find("wait for attack") ==
std::string::npos))
{
@ -1075,7 +1084,7 @@ void PlayerbotAI::HandleCommand(uint32 type, std::string const text, Player* fro
TellMaster(message);
}
}
else if (filtered == "cancel logout" || filtered == "logout cancel")
else if (filtered == "logout cancel")
{
if (!bot->GetSession()->isLogingOut())
return;
@ -1091,7 +1100,9 @@ void PlayerbotAI::HandleCommand(uint32 type, std::string const text, Player* fro
bot->GetSession()->HandleLogoutCancelOpcode(data);
}
else
{
chatCommands.push_back(ChatCommandHolder(filtered, fromPlayer, type));
}
}
void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)

View File

@ -299,11 +299,6 @@ void PlayerbotHolder::LogoutAllBots()
if (!botAI || botAI->IsRealPlayer())
continue;
// If bot is mid-countdown, cancel the timer so LogoutPlayerBot proceeds immediately.
WorldSession* session = bot->GetSession();
if (session && session->isLogingOut())
session->SetLogoutStartTime(0);
LogoutPlayerBot(bot->GetGUID());
}
}
@ -366,50 +361,36 @@ void PlayerbotHolder::LogoutPlayerBot(ObjectGuid guid)
WorldSession* botWorldSessionPtr = bot->GetSession();
WorldSession* masterWorldSessionPtr = nullptr;
// If already in timed logout countdown, complete it once the 20-second timer expires.
if (botWorldSessionPtr->isLogingOut())
{
if (botWorldSessionPtr->ShouldLogOut(time(nullptr)))
{
std::string message = PlayerbotTextMgr::instance().GetBotTextOrDefault(
"goodbye", "Goodbye!", {});
botAI->TellMaster(message);
RemoveFromPlayerbotsMap(guid);
botWorldSessionPtr->LogoutPlayer(true);
delete botWorldSessionPtr;
}
return;
}
Player* master = botAI->GetMaster();
if (master)
masterWorldSessionPtr = master->GetSession();
// Instant logout checking:
bool logout =
bot->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ||
bot->HasUnitState(UNIT_STATE_IN_FLIGHT) ||
(masterWorldSessionPtr && !masterWorldSessionPtr->GetPlayer()) ||
// Master's socket is already gone (EXIT GAME -> EXIT NOW is the most typical cause).
// Force instant logout. Without this, the bot restarts its 20-second countdown and fires LogoutPlayer() 20 seconds
// after the master's Player object has been deleted, causing the bot's logout to crash on the now deleted master.
(masterWorldSessionPtr && masterWorldSessionPtr->IsSocketClosed()) ||
(masterWorldSessionPtr && masterWorldSessionPtr->ShouldLogOut(time(nullptr))) ||
// If the bot's master has security clearance for `InstantLogout` in worldserver.conf, so does the bot.
(master &&
(master->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ||
master->HasUnitState(UNIT_STATE_IN_FLIGHT) ||
(masterWorldSessionPtr &&
masterWorldSessionPtr->GetSecurity() >= (AccountTypes)sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))));
// TODO: Review whether or not to implement timed logout.
// Unused block. Useful only for timed logout.
/*
// check for instant logout
bool logout = botWorldSessionPtr->ShouldLogOut(time(nullptr));
if (!logout)
{
// Start the 20-second logout countdown. CancelLogout() can interrupt this.
WorldPackets::Character::LogoutRequest data = WorldPacket(CMSG_LOGOUT_REQUEST);
botWorldSessionPtr->HandleLogoutRequestOpcode(data);
return;
}
if (masterWorldSessionPtr && masterWorldSessionPtr->ShouldLogOut(time(nullptr)))
logout = true;
if (masterWorldSessionPtr && !masterWorldSessionPtr->GetPlayer())
logout = true;
if (bot->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || bot->HasUnitState(UNIT_STATE_IN_FLIGHT) ||
botWorldSessionPtr->GetSecurity() >= (AccountTypes)sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))
logout = true;
if (master &&
(master->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || master->HasUnitState(UNIT_STATE_IN_FLIGHT) ||
(masterWorldSessionPtr &&
masterWorldSessionPtr->GetSecurity() >= (AccountTypes)sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))))
logout = true;
*/
// Instant logout (the only option right now)
{
std::string message = PlayerbotTextMgr::instance().GetBotTextOrDefault(
"goodbye", "Goodbye!", {});
@ -1497,15 +1478,6 @@ void PlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/)
{
SetNextCheckDelay(sPlayerbotAIConfig.reactDelay);
CheckTellErrors(elapsed);
// Complete timed logouts for added bots once the 20-second countdown has elapsed.
std::vector<ObjectGuid> expiredLogouts;
for (auto const& [botGuid, bot] : playerBots)
if (bot && bot->GetSession() && bot->GetSession()->ShouldLogOut(time(nullptr)))
expiredLogouts.push_back(botGuid);
for (ObjectGuid const& guid : expiredLogouts)
LogoutPlayerBot(guid);
}
void PlayerbotMgr::HandleCommand(uint32 type, std::string const text)