From fd2eed248518a5a6f856be14164cc20ccb33763e Mon Sep 17 00:00:00 2001 From: Eduardo Dantas Date: Fri, 1 Nov 2024 17:33:19 -0300 Subject: [PATCH 1/3] fix: some conflict errors (#3048) Fixed some issues caused by git conflicts. --- src/creatures/combat/spells.hpp | 1 - src/creatures/players/player.cpp | 4 +--- src/io/functions/iologindata_save_player.cpp | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/creatures/combat/spells.hpp b/src/creatures/combat/spells.hpp index c12c3af3686..ab34fa6dbce 100644 --- a/src/creatures/combat/spells.hpp +++ b/src/creatures/combat/spells.hpp @@ -50,7 +50,6 @@ class Spells final : public Scripts { std::list getSpellsByVocation(uint16_t vocationId); [[nodiscard]] const std::map> &getInstantSpells() const; - ; [[nodiscard]] bool hasInstantSpell(const std::string &word) const; diff --git a/src/creatures/players/player.cpp b/src/creatures/players/player.cpp index 65ace44f5f6..dfdf467aa97 100644 --- a/src/creatures/players/player.cpp +++ b/src/creatures/players/player.cpp @@ -9138,8 +9138,6 @@ void Player::forgeTransferItemTier(ForgeAction_t actionType, uint16_t donorItemI g_logger().error("[Log 8] Failed to remove transfer dusts from player with name {}", getName()); sendForgeError(RETURNVALUE_CONTACTADMINISTRATOR); return; - } else { - setForgeDusts(getForgeDusts() - g_configManager().getNumber(configKey)); } setForgeDusts(getForgeDusts() - g_configManager().getNumber(configKey)); @@ -10073,7 +10071,7 @@ bool Player::setAccount(uint32_t accountId) { } uint8_t Player::getAccountType() const { - return account ? account->getAccountType() : static_cast(AccountType::ACCOUNT_TYPE_NORMAL); + return account ? account->getAccountType() : AccountType::ACCOUNT_TYPE_NORMAL; } uint32_t Player::getAccountId() const { diff --git a/src/io/functions/iologindata_save_player.cpp b/src/io/functions/iologindata_save_player.cpp index c6b92514969..b38e6e2b84c 100644 --- a/src/io/functions/iologindata_save_player.cpp +++ b/src/io/functions/iologindata_save_player.cpp @@ -127,7 +127,6 @@ bool IOLoginDataSave::saveItems(const std::shared_ptr &player, const Ite // Serialize item attributes propWriteStream.clear(); item->serializeAttr(propWriteStream); - item->stopDecaying(); size_t attributesSize; const char* attributes = propWriteStream.getStream(attributesSize); From 9bed23d6c019364b72f699b3ab124696e0524107 Mon Sep 17 00:00:00 2001 From: Eduardo Dantas Date: Sat, 2 Nov 2024 21:02:53 -0300 Subject: [PATCH 2/3] improve: load player town and fix player badge escape string (#3055) Simplified the town assignment logic when loading player data: - If the town ID associated with the player is invalid, the system will first attempt to assign the town "Thais". If "Thais" is unavailable, the player is assigned the first valid town from the list. - This change reduces the chain of conditional checks, making the logic more readable and efficient, while ensuring a player is assigned to a valid town whenever possible. Fix for Escaping Strings in PlayerBadge: - Added proper string escaping using `g_database().escapeString()` in `PlayerBadge::getPlayersInfoByAccount()` to prevent SQL syntax errors when player names contain special characters. - This fix addresses issues with malformed queries that previously resulted in SQL syntax errors. --- .../players/cyclopedia/player_badge.cpp | 3 ++- src/io/functions/iologindata_load_player.cpp | 24 ++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/creatures/players/cyclopedia/player_badge.cpp b/src/creatures/players/cyclopedia/player_badge.cpp index 0d97747a248..c27e98cb1aa 100644 --- a/src/creatures/players/cyclopedia/player_badge.cpp +++ b/src/creatures/players/cyclopedia/player_badge.cpp @@ -127,7 +127,8 @@ std::vector> PlayerBadge::getPlayersInfoByAccount(const if (!namesList.empty()) { namesList += ", "; } - namesList += fmt::format("'{}'", name); + std::string escapedName = g_database().escapeString(name); + namesList += fmt::format("{}", escapedName); } auto query = fmt::format("SELECT name, level, vocation FROM players WHERE name IN ({})", namesList); diff --git a/src/io/functions/iologindata_load_player.cpp b/src/io/functions/iologindata_load_player.cpp index 02f58bec04b..477572dfbc8 100644 --- a/src/io/functions/iologindata_load_player.cpp +++ b/src/io/functions/iologindata_load_player.cpp @@ -179,10 +179,28 @@ bool IOLoginDataLoad::loadPlayerBasicInfo(const std::shared_ptr &player, player->setOfflineTrainingSkill(skill); const auto &town = g_game().map.towns.getTown(result->getNumber("town_id")); if (!town) { - g_logger().error("Player {} has town id {} which doesn't exist", player->name, result->getNumber("town_id")); - return false; + g_logger().error("Player {} has invalid town id {}. Attempting to set the correct town.", player->name, result->getNumber("town_id")); + + const auto &thaisTown = g_game().map.towns.getTown("Thais"); + if (thaisTown) { + player->town = thaisTown; + g_logger().warn("Assigned town 'Thais' to player {}", player->name); + } else { + for (const auto &[townId, currentTown] : g_game().map.towns.getTowns()) { + if (townId != 0 && currentTown) { + player->town = currentTown; + g_logger().warn("Assigned first valid town {} (id: {}) to player {}", currentTown->getName(), townId, player->name); + } + } + + if (!player->town) { + g_logger().error("Player {} has invalid town id {}. No valid town found to assign.", player->name, result->getNumber("town_id")); + return false; + } + } + } else { + player->town = town; } - player->town = town; const Position &loginPos = player->loginPosition; if (loginPos.x == 0 && loginPos.y == 0 && loginPos.z == 0) { From b82568a619b27e5835ea191e98eb1a169ccf652a Mon Sep 17 00:00:00 2001 From: "Leilani A." <168607226+kaleohanopahala@users.noreply.github.com> Date: Sun, 3 Nov 2024 15:00:47 -0300 Subject: [PATCH 3/3] fix: prevent crash in condition light division (#3053) Fix #3047 Now min light level is always 1, prevent division by zero. --- src/creatures/combat/condition.cpp | 10 +++++++--- src/creatures/combat/condition.hpp | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/creatures/combat/condition.cpp b/src/creatures/combat/condition.cpp index e49a6662991..da90b03f65a 100644 --- a/src/creatures/combat/condition.cpp +++ b/src/creatures/combat/condition.cpp @@ -2540,7 +2540,7 @@ void ConditionLight::addCondition(std::shared_ptr creature, const std: const auto &conditionLight = condition->static_self_cast(); lightInfo.level = conditionLight->lightInfo.level; lightInfo.color = conditionLight->lightInfo.color; - lightChangeInterval = ticks / lightInfo.level; + lightChangeInterval = ticks / std::max(1, lightInfo.level); internalLightTicks = 0; creature->setCreatureLight(lightInfo); g_game().changeLight(creature); @@ -2558,9 +2558,13 @@ bool ConditionLight::setParam(ConditionParam_t param, int32_t value) { } switch (param) { - case CONDITION_PARAM_LIGHT_LEVEL: - lightInfo.level = value; + case CONDITION_PARAM_LIGHT_LEVEL: { + if (value < 1) { + g_logger().warn("[ConditionLight::setParam] Trying to set invalid light value: '{}', defaulting to 1.", value); + } + lightInfo.level = std::max(1, static_cast(value)); return true; + } case CONDITION_PARAM_LIGHT_COLOR: lightInfo.color = value; diff --git a/src/creatures/combat/condition.hpp b/src/creatures/combat/condition.hpp index 1cc798624e3..50d072059a2 100644 --- a/src/creatures/combat/condition.hpp +++ b/src/creatures/combat/condition.hpp @@ -391,7 +391,7 @@ class ConditionLight final : public Condition { bool unserializeProp(ConditionAttr_t attr, PropStream &propStream) override; private: - LightInfo lightInfo; + LightInfo lightInfo { 1, 215 }; uint32_t internalLightTicks = 0; uint32_t lightChangeInterval = 0; };