From 8e01b628b167874118ce8aa3219b993cf1890ad0 Mon Sep 17 00:00:00 2001 From: Beats Date: Sun, 21 May 2023 20:53:25 -0400 Subject: [PATCH 1/5] fix: clone exit and not removing the player on the death screen --- src/creatures/players/player.cpp | 20 ++++++++++++++++++++ src/creatures/players/player.h | 3 +++ src/server/network/protocol/protocol.cpp | 4 +++- src/server/network/protocol/protocol.h | 4 ++-- src/server/network/protocol/protocolgame.cpp | 8 ++++++-- src/server/network/protocol/protocolgame.h | 6 ++++++ 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 197a6f4aa09..c20923628d0 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -38,6 +38,7 @@ Player::Player(ProtocolGame_ptr p) : } Player::~Player() { + g_game().removePlayerUniqueLogin(this); for (Item* item : inventory) { if (item) { item->setParent(nullptr); @@ -7382,6 +7383,25 @@ void Player::decrementeHazardSystemReference() { } } +void Player::checkPlayerActivity(int interval) { + if (this && !this->isDead() || client == nullptr || (client && !client->getIP())) { + return; + } + + if (!isAccessPlayer()) { + playerDeathTime += interval; + const int32_t kickAfterMinutes = g_configManager().getNumber(KICK_AFTER_MINUTES); + if (playerDeathTime > (kickAfterMinutes * 60000) + 60000) { + if (client) { + client->disconnect(); + } + return; + } + } + + g_scheduler().addEvent(createSchedulerTask(1000, std::bind(&Player::checkPlayerActivity, this, interval))); +} + /******************************************************************************* * Interfaces ******************************************************************************/ diff --git a/src/creatures/players/player.h b/src/creatures/players/player.h index abcd2191b32..6e638ad47c4 100644 --- a/src/creatures/players/player.h +++ b/src/creatures/players/player.h @@ -2372,6 +2372,8 @@ class Player final : public Creature, public Cylinder { void decrementeHazardSystemReference(); /*******************************************************************************/ + void checkPlayerActivity(int interval); + private: static uint32_t playerFirstID; static uint32_t playerLastID; @@ -2572,6 +2574,7 @@ class Player final : public Creature, public Cylinder { int8_t offlineTrainingSkill = SKILL_NONE; int32_t offlineTrainingTime = 0; int32_t idleTime = 0; + int32_t playerDeathTime = 0; uint32_t coinBalance = 0; uint32_t coinTransferableBalance = 0; uint16_t expBoostStamina = 0; diff --git a/src/server/network/protocol/protocol.cpp b/src/server/network/protocol/protocol.cpp index c25f08d8da3..c676f2596ec 100644 --- a/src/server/network/protocol/protocol.cpp +++ b/src/server/network/protocol/protocol.cpp @@ -198,7 +198,9 @@ bool Protocol::RSA_decrypt(NetworkMessage &msg) { uint32_t Protocol::getIP() const { if (auto protocolConnection = getConnection()) { - return protocolConnection->getIP(); + if (protocolConnection != nullptr) { + return protocolConnection->getIP(); + } } return 0; diff --git a/src/server/network/protocol/protocol.h b/src/server/network/protocol/protocol.h index 1b8f918b184..b19dec4c433 100644 --- a/src/server/network/protocol/protocol.h +++ b/src/server/network/protocol/protocol.h @@ -57,8 +57,8 @@ class Protocol : public std::enable_shared_from_this { protected: void disconnect() const { - if (auto connection = getConnection(); - connection != nullptr) { + auto connection = getConnection(); + if (connection != nullptr) { connection->close(); } } diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 91819ac42e3..2eec51309ae 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -286,7 +286,6 @@ void ProtocolGame::AddItem(NetworkMessage &msg, const Item* item) { void ProtocolGame::release() { // dispatcher thread if (player && player->client == shared_from_this()) { - g_game().removePlayerUniqueLogin(player); player->client.reset(); player->decrementReferenceCounter(); player = nullptr; @@ -420,7 +419,7 @@ void ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem) eventConnect = 0; Player* foundPlayer = g_game().getPlayerByID(playerId); - if (!foundPlayer || foundPlayer->client) { + if (!foundPlayer) { disconnectClient("You are already logged in."); return; } @@ -655,6 +654,10 @@ void ProtocolGame::parsePacket(NetworkMessage &msg) { } if (player->isDead() || player->getHealth() <= 0) { + if (playerDeathTime == 0) { + player->checkPlayerActivity(1000); + playerDeathTime++; + } g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parsePacketDead, getThis(), recvbyte))); return; } @@ -689,6 +692,7 @@ void ProtocolGame::parsePacketDead(uint8_t recvbyte) { g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::sendAddCreature, getThis(), player, player->getPosition(), 0, false))); g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::addBless, getThis()))); + resetPlayerDeathTime(); return; } diff --git a/src/server/network/protocol/protocolgame.h b/src/server/network/protocol/protocolgame.h index 275ab31b9a5..ffa00e9ed1e 100644 --- a/src/server/network/protocol/protocolgame.h +++ b/src/server/network/protocol/protocolgame.h @@ -490,6 +490,12 @@ class ProtocolGame final : public Protocol { // Hazard system void reloadHazardSystemIcon(uint16_t reference); + + uint8_t playerDeathTime = 0; + + void resetPlayerDeathTime() { + playerDeathTime = 0; + } }; #endif // SRC_SERVER_NETWORK_PROTOCOL_PROTOCOLGAME_H_ From 9c8b3a732386b40af04bc3b766ffefe021187411 Mon Sep 17 00:00:00 2001 From: Beats Date: Sun, 21 May 2023 21:23:21 -0400 Subject: [PATCH 2/5] improve: move funciton logic to the game class and change to player name instead of object --- src/creatures/players/player.cpp | 21 +------------- src/creatures/players/player.h | 2 -- src/game/game.cpp | 29 ++++++++++++++++++++ src/game/game.h | 1 + src/server/network/protocol/protocol.cpp | 4 +-- src/server/network/protocol/protocol.h | 4 +-- src/server/network/protocol/protocolgame.cpp | 6 +++- 7 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index c20923628d0..5a02a23b72c 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -38,7 +38,6 @@ Player::Player(ProtocolGame_ptr p) : } Player::~Player() { - g_game().removePlayerUniqueLogin(this); for (Item* item : inventory) { if (item) { item->setParent(nullptr); @@ -1716,6 +1715,7 @@ void Player::onRemoveCreature(Creature* creature, bool isLogout) { guild->removeMember(this); } + g_game().removePlayerUniqueLogin(this); loginPosition = getPosition(); lastLogout = time(nullptr); SPDLOG_INFO("{} has logged out", getName()); @@ -7383,25 +7383,6 @@ void Player::decrementeHazardSystemReference() { } } -void Player::checkPlayerActivity(int interval) { - if (this && !this->isDead() || client == nullptr || (client && !client->getIP())) { - return; - } - - if (!isAccessPlayer()) { - playerDeathTime += interval; - const int32_t kickAfterMinutes = g_configManager().getNumber(KICK_AFTER_MINUTES); - if (playerDeathTime > (kickAfterMinutes * 60000) + 60000) { - if (client) { - client->disconnect(); - } - return; - } - } - - g_scheduler().addEvent(createSchedulerTask(1000, std::bind(&Player::checkPlayerActivity, this, interval))); -} - /******************************************************************************* * Interfaces ******************************************************************************/ diff --git a/src/creatures/players/player.h b/src/creatures/players/player.h index 6e638ad47c4..f630b2d66a1 100644 --- a/src/creatures/players/player.h +++ b/src/creatures/players/player.h @@ -2372,8 +2372,6 @@ class Player final : public Creature, public Cylinder { void decrementeHazardSystemReference(); /*******************************************************************************/ - void checkPlayerActivity(int interval); - private: static uint32_t playerFirstID; static uint32_t playerLastID; diff --git a/src/game/game.cpp b/src/game/game.cpp index ab0e4df604b..d57fc7845cf 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -9126,6 +9126,35 @@ void Game::removePlayerUniqueLogin(Player* player) { m_uniqueLoginPlayerNames.erase(lowercase_name); } +void Game::playerCheckActivity(const std::string &playerName, int interval) { + Player* player = getPlayerUniqueLogin(playerName); + if (!player) { + return; + } + + if (player->getIP() == 0) { + g_game().removePlayerUniqueLogin(playerName); + IOLoginData::updateOnlineStatus(player->guid, false); + SPDLOG_INFO("Player with name '{}' has logged out due to exited in death screen", player->getName()); + player->disconnect(); + return; + } + + if (!player->isAccessPlayer()) { + player->playerDeathTime += interval; + const int32_t kickAfterMinutes = g_configManager().getNumber(KICK_AFTER_MINUTES); + if (player->playerDeathTime > (kickAfterMinutes * 60000) + 60000) { + SPDLOG_INFO("Player with name '{}' has logged out due to inactivity after death", player->getName()); + g_game().removePlayerUniqueLogin(playerName); + IOLoginData::updateOnlineStatus(player->guid, false); + player->disconnect(); + return; + } + } + + g_scheduler().addEvent(createSchedulerTask(1000, std::bind(&Game::playerCheckActivity, this, playerName, interval))); +} + void Game::playerRewardChestCollect(uint32_t playerId, const Position &pos, uint16_t itemId, uint8_t stackPos, uint32_t maxMoveItems /* = 0*/) { Player* player = getPlayerByID(playerId); if (!player) { diff --git a/src/game/game.h b/src/game/game.h index d320339ef20..c62a202f8b3 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -613,6 +613,7 @@ class Game { * @param player A pointer to the Player object to remove. */ void removePlayerUniqueLogin(Player* player); + void playerCheckActivity(const std::string &playerName, int interval); private: std::map forgeMonsterEventIds; diff --git a/src/server/network/protocol/protocol.cpp b/src/server/network/protocol/protocol.cpp index c676f2596ec..c25f08d8da3 100644 --- a/src/server/network/protocol/protocol.cpp +++ b/src/server/network/protocol/protocol.cpp @@ -198,9 +198,7 @@ bool Protocol::RSA_decrypt(NetworkMessage &msg) { uint32_t Protocol::getIP() const { if (auto protocolConnection = getConnection()) { - if (protocolConnection != nullptr) { - return protocolConnection->getIP(); - } + return protocolConnection->getIP(); } return 0; diff --git a/src/server/network/protocol/protocol.h b/src/server/network/protocol/protocol.h index b19dec4c433..e2ba8189f32 100644 --- a/src/server/network/protocol/protocol.h +++ b/src/server/network/protocol/protocol.h @@ -57,11 +57,11 @@ class Protocol : public std::enable_shared_from_this { protected: void disconnect() const { - auto connection = getConnection(); - if (connection != nullptr) { + if (auto connection = getConnection()) { connection->close(); } } + void enableXTEAEncryption() { encryptionEnabled = true; } diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 2eec51309ae..2cbc017be68 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -655,7 +655,7 @@ void ProtocolGame::parsePacket(NetworkMessage &msg) { if (player->isDead() || player->getHealth() <= 0) { if (playerDeathTime == 0) { - player->checkPlayerActivity(1000); + addGameTask(&Game::playerCheckActivity, player->getName(), 1000); playerDeathTime++; } g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parsePacketDead, getThis(), recvbyte))); @@ -704,6 +704,10 @@ void ProtocolGame::parsePacketDead(uint8_t recvbyte) { } void ProtocolGame::addBless() { + if (!player) { + return; + } + std::string bless = player->getBlessingsName(); std::ostringstream lostBlesses; (bless.length() == 0) ? lostBlesses << "You lost all your blessings." : lostBlesses << "You are still blessed with " << bless; From 18d8746a0d68c7a1d21b775f0e9af2ba3161eef3 Mon Sep 17 00:00:00 2001 From: Eduardo Dantas Date: Mon, 22 May 2023 16:21:21 -0300 Subject: [PATCH 3/5] fix: already login message --- src/server/network/protocol/protocolgame.cpp | 10 ++++++---- src/server/network/protocol/protocolgame.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 2cbc017be68..85383d7b99a 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -406,19 +406,19 @@ void ProtocolGame::login(const std::string &name, uint32_t accountId, OperatingS foundPlayer->disconnect(); foundPlayer->isConnecting = true; - eventConnect = g_scheduler().addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::connect, getThis(), foundPlayer->getID(), operatingSystem))); + eventConnect = g_scheduler().addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::connect, getThis(), foundPlayer->getName(), operatingSystem))); } else { - connect(foundPlayer->getID(), operatingSystem); + connect(foundPlayer->getName(), operatingSystem); } } OutputMessagePool::getInstance().addProtocolToAutosend(shared_from_this()); sendBosstiaryCooldownTimer(); } -void ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem) { +void ProtocolGame::connect(const std::string &playerName, OperatingSystem_t operatingSystem) { eventConnect = 0; - Player* foundPlayer = g_game().getPlayerByID(playerId); + Player* foundPlayer = g_game().getPlayerUniqueLogin(playerName); if (!foundPlayer) { disconnectClient("You are already logged in."); return; @@ -654,10 +654,12 @@ void ProtocolGame::parsePacket(NetworkMessage &msg) { } if (player->isDead() || player->getHealth() <= 0) { + // Check player activity on death screen if (playerDeathTime == 0) { addGameTask(&Game::playerCheckActivity, player->getName(), 1000); playerDeathTime++; } + g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parsePacketDead, getThis(), recvbyte))); return; } diff --git a/src/server/network/protocol/protocolgame.h b/src/server/network/protocol/protocolgame.h index ffa00e9ed1e..acd2fa0f6a8 100644 --- a/src/server/network/protocol/protocolgame.h +++ b/src/server/network/protocol/protocolgame.h @@ -78,7 +78,7 @@ class ProtocolGame final : public Protocol { ProtocolGame_ptr getThis() { return std::static_pointer_cast(shared_from_this()); } - void connect(uint32_t playerId, OperatingSystem_t operatingSystem); + void connect(const std::string &playerName, OperatingSystem_t operatingSystem); void disconnectClient(const std::string &message) const; void writeToOutputBuffer(const NetworkMessage &msg); From 647e9b4664b20b54243de32d7ba7b9c228590b9c Mon Sep 17 00:00:00 2001 From: Eduardo Dantas Date: Mon, 22 May 2023 18:38:35 -0300 Subject: [PATCH 4/5] add missing check --- src/game/game.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/game.cpp b/src/game/game.cpp index d57fc7845cf..1a63695e2d6 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -9140,6 +9140,10 @@ void Game::playerCheckActivity(const std::string &playerName, int interval) { return; } + if (!player->isDead() || player->client == nullptr) { + return; + } + if (!player->isAccessPlayer()) { player->playerDeathTime += interval; const int32_t kickAfterMinutes = g_configManager().getNumber(KICK_AFTER_MINUTES); From dcce10e1454fb36ea0510dd866c5932136e54148 Mon Sep 17 00:00:00 2001 From: Eduardo Dantas Date: Tue, 23 May 2023 08:41:51 -0300 Subject: [PATCH 5/5] fix: rename variables for better undestand --- src/creatures/players/player.h | 2 +- src/game/game.cpp | 4 ++-- src/server/network/protocol/protocolgame.cpp | 4 ++-- src/server/network/protocol/protocolgame.h | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/creatures/players/player.h b/src/creatures/players/player.h index f630b2d66a1..60fbfce80bf 100644 --- a/src/creatures/players/player.h +++ b/src/creatures/players/player.h @@ -2572,7 +2572,7 @@ class Player final : public Creature, public Cylinder { int8_t offlineTrainingSkill = SKILL_NONE; int32_t offlineTrainingTime = 0; int32_t idleTime = 0; - int32_t playerDeathTime = 0; + int32_t m_deathTime = 0; uint32_t coinBalance = 0; uint32_t coinTransferableBalance = 0; uint16_t expBoostStamina = 0; diff --git a/src/game/game.cpp b/src/game/game.cpp index 1a63695e2d6..71872219c63 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -9145,9 +9145,9 @@ void Game::playerCheckActivity(const std::string &playerName, int interval) { } if (!player->isAccessPlayer()) { - player->playerDeathTime += interval; + player->m_deathTime += interval; const int32_t kickAfterMinutes = g_configManager().getNumber(KICK_AFTER_MINUTES); - if (player->playerDeathTime > (kickAfterMinutes * 60000) + 60000) { + if (player->m_deathTime > (kickAfterMinutes * 60000) + 60000) { SPDLOG_INFO("Player with name '{}' has logged out due to inactivity after death", player->getName()); g_game().removePlayerUniqueLogin(playerName); IOLoginData::updateOnlineStatus(player->guid, false); diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index 85383d7b99a..05882534f45 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -655,9 +655,9 @@ void ProtocolGame::parsePacket(NetworkMessage &msg) { if (player->isDead() || player->getHealth() <= 0) { // Check player activity on death screen - if (playerDeathTime == 0) { + if (m_playerDeathTime == 0) { addGameTask(&Game::playerCheckActivity, player->getName(), 1000); - playerDeathTime++; + m_playerDeathTime++; } g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parsePacketDead, getThis(), recvbyte))); diff --git a/src/server/network/protocol/protocolgame.h b/src/server/network/protocol/protocolgame.h index acd2fa0f6a8..623b0ae4351 100644 --- a/src/server/network/protocol/protocolgame.h +++ b/src/server/network/protocol/protocolgame.h @@ -491,10 +491,10 @@ class ProtocolGame final : public Protocol { // Hazard system void reloadHazardSystemIcon(uint16_t reference); - uint8_t playerDeathTime = 0; + uint8_t m_playerDeathTime = 0; void resetPlayerDeathTime() { - playerDeathTime = 0; + m_playerDeathTime = 0; } };