From cce1bf656fb6b40e518e3a80f5001897e3b3a4c0 Mon Sep 17 00:00:00 2001 From: Beats <61994374+beats-dh@users.noreply.github.com> Date: Sat, 3 Dec 2022 17:19:46 -0300 Subject: [PATCH] Fixed random crashes generated by protocolgame.cpp (#625) Fixed random crashes and fixed death window when canceling --- src/server/network/protocol/protocolgame.cpp | 88 +++++++++++--------- src/server/network/protocol/protocolgame.h | 3 + 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/src/server/network/protocol/protocolgame.cpp b/src/server/network/protocol/protocolgame.cpp index b59f65e2e53..6b9dc7d515d 100644 --- a/src/server/network/protocol/protocolgame.cpp +++ b/src/server/network/protocol/protocolgame.cpp @@ -633,59 +633,69 @@ void ProtocolGame::parsePacket(NetworkMessage& msg) if (recvbyte == 0x0F) { disconnect(); } - return; } - // A dead player can not performs actions if (player->isDead() || player->getHealth() <= 0) { - if (recvbyte == 0x14) { - disconnect(); - return; - } + g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parsePacketDead, getThis(), recvbyte))); + return; + } - if (recvbyte == 0x0F) { - if (!player) { - return; - } - - if (!player->spawn()) { - disconnect(); - g_game().removeCreature(player); - return; - } + // Modules system + if (player && recvbyte != 0xD3) { + g_dispatcher().addTask(createTask(std::bind(&Modules::executeOnRecvbyte, &g_modules(), player->getID(), msg, recvbyte))); + } - sendAddCreature(player, player->getPosition(), 0, false); - - std::string bless = player->getBlessingsName(); - std::ostringstream lostBlesses; - (bless.length() == 0) ? lostBlesses << "You lost all your blessings." : lostBlesses << "You are still blessed with " << bless; - player->sendTextMessage(MESSAGE_EVENT_ADVANCE, lostBlesses.str()); - if (player->getLevel() < g_configManager().getNumber(ADVENTURERSBLESSING_LEVEL)) { - for (uint8_t i = 2; i <= 6; i++) { - if (!player->hasBlessing(i)) { - player->addBlessing(i, 1); - } - } - sendBlessStatus(); - } + g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parsePacketFromDispatcher, getThis(), msg, recvbyte))); +} + +void ProtocolGame::parsePacketDead(uint8_t recvbyte) +{ + if (recvbyte == 0x14) { + disconnect(); + g_dispatcher().addTask(createTask(std::bind(&IOLoginData::updateOnlineStatus, player->getGUID(), false))); + return; + } + + if (recvbyte == 0x0F) { + if (!player) { return; } - if (recvbyte != 0x1D && recvbyte != 0x1E) { - // keep the connection alive - g_scheduler().addEvent(createSchedulerTask(500, std::bind(&ProtocolGame::sendPing, getThis()))); - g_scheduler().addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::sendPingBack, getThis()))); + g_scheduler().addEvent(createSchedulerTask(100, std::bind(&ProtocolGame::sendPing, getThis()))); + + if (!player->spawn()) { + disconnect(); + addGameTask(&Game::removeCreature, player, true); return; } + + g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::sendAddCreature, getThis(), player, player->getPosition(), 0, false))); + g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::addBless, getThis()))); + return; } - // Modules system - if (player && recvbyte != 0xD3) { - g_dispatcher().addTask(createTask(std::bind(&Modules::executeOnRecvbyte, &g_modules(), player->getID(), msg, recvbyte))); + if (recvbyte == 0x1D) { + // keep the connection alive + g_scheduler().addEvent(createSchedulerTask(100, std::bind(&ProtocolGame::sendPingBack, getThis()))); + return; } +} - g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::parsePacketFromDispatcher, getThis(), msg, recvbyte))); +void ProtocolGame::addBless() +{ + std::string bless = player->getBlessingsName(); + std::ostringstream lostBlesses; + (bless.length() == 0) ? lostBlesses << "You lost all your blessings." : lostBlesses << "You are still blessed with " << bless; + player->sendTextMessage(MESSAGE_EVENT_ADVANCE, lostBlesses.str()); + if (player->getLevel() < g_configManager().getNumber(ADVENTURERSBLESSING_LEVEL)) { + for (uint8_t i = 2; i <= 6; i++) { + if (!player->hasBlessing(i)) { + player->addBlessing(i, 1); + } + } + sendBlessStatus(); + } } void ProtocolGame::parsePacketFromDispatcher(NetworkMessage msg, uint8_t recvbyte) @@ -696,7 +706,7 @@ void ProtocolGame::parsePacketFromDispatcher(NetworkMessage msg, uint8_t recvbyt if (!player || player->isRemoved() || player->getHealth() <= 0) { return; -} + } switch (recvbyte) { case 0x14: g_dispatcher().addTask(createTask(std::bind(&ProtocolGame::logout, getThis(), true, false))); break; diff --git a/src/server/network/protocol/protocolgame.h b/src/server/network/protocol/protocolgame.h index de2233ea9a2..0f9ec82ba09 100644 --- a/src/server/network/protocol/protocolgame.h +++ b/src/server/network/protocol/protocolgame.h @@ -472,6 +472,9 @@ class ProtocolGame final : public Protocol void sendOpenStash(); void parseStashWithdraw(NetworkMessage &msg); void sendSpecialContainersAvailable(); + void addBless(); + void parsePacketDead(uint8_t recvbyte); + }; #endif // SRC_SERVER_NETWORK_PROTOCOL_PROTOCOLGAME_H_