aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2020-08-28 00:11:16 +0200
committerShauren <shauren.trinity@gmail.com>2022-02-04 00:27:14 +0100
commit9f97fdd31a3b9a06b6acfa1101d105e43687e824 (patch)
tree027f81c18e7733fa3554cf1dd704a0900d254725 /src/server/game/Entities
parent6e45c371c4098942e0085a71577a07b17725ee93 (diff)
Core/Common: Tokenizer -> Trinity::Tokenize (PR: #25327)
(cherry picked from commit 534a2388b7c662c8796aabb1ec8cb424879799b6)
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/Corpse/Corpse.cpp5
-rw-r--r--src/server/game/Entities/Item/Item.cpp31
-rw-r--r--src/server/game/Entities/Object/Object.cpp1
-rw-r--r--src/server/game/Entities/Player/Player.cpp95
-rw-r--r--src/server/game/Entities/Player/Player.h3
-rw-r--r--src/server/game/Entities/Player/PlayerTaxi.cpp47
-rw-r--r--src/server/game/Entities/Player/PlayerTaxi.h4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp26
-rw-r--r--src/server/game/Entities/Unit/UnitDefines.h2
9 files changed, 102 insertions, 112 deletions
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index 5fabe946041..2a6abe5a30a 100644
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -26,6 +26,7 @@
#include "ObjectAccessor.h"
#include "PhasingHandler.h"
#include "Player.h"
+#include "StringConvert.h"
#include "UpdateData.h"
#include "World.h"
#include <sstream>
@@ -185,10 +186,10 @@ bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
SetObjectScale(1.0f);
SetDisplayId(fields[5].GetUInt32());
- Tokenizer items(fields[6].GetString(), ' ', EQUIPMENT_SLOT_END);
+ std::vector<std::string_view> items = Trinity::Tokenize(fields[6].GetStringView(), ' ', EQUIPMENT_SLOT_END);
if (items.size() == EQUIPMENT_SLOT_END)
for (uint32 index = 0; index < EQUIPMENT_SLOT_END; ++index)
- SetItem(index, atoul(items[index]));
+ SetItem(index, Trinity::StringTo<uint32>(items[index]).value_or(0));
SetRace(fields[7].GetUInt8());
SetClass(fields[8].GetUInt8());
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 83725a16a78..8912559e0f0 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -40,6 +40,7 @@
#include "ScriptMgr.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
+#include "StringConvert.h"
#include "TradeData.h"
#include "UpdateData.h"
#include "World.h"
@@ -846,7 +847,10 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
ItemTemplate const* proto = GetTemplate();
if (!proto)
+ {
+ TC_LOG_ERROR("entities.item", "Invalid entry %u for item %s. Refusing to load.", GetEntry(), GetGUID().ToString().c_str());
return false;
+ }
_bonusData.Initialize(proto);
@@ -900,17 +904,18 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
SetContext(ItemContext(fields[17].GetUInt8()));
- Tokenizer bonusListString(fields[18].GetString(), ' ');
+ std::vector<std::string_view> bonusListString = Trinity::Tokenize(fields[18].GetStringView(), ' ', false);
std::vector<int32> bonusListIDs;
bonusListIDs.reserve(bonusListString.size());
- for (char const* token : bonusListString)
- bonusListIDs.push_back(atoi(token));
+ for (std::string_view token : bonusListString)
+ if (Optional<int32> bonusListID = Trinity::StringTo<int32>(token))
+ bonusListIDs.push_back(*bonusListID);
SetBonuses(std::move(bonusListIDs));
// load charges after bonuses, they can add more item effects
- Tokenizer tokens(fields[6].GetString(), ' ', proto->Effects.size());
+ std::vector<std::string_view> tokens = Trinity::Tokenize(fields[6].GetStringView(), ' ', false);
for (uint8 i = 0; i < m_itemData->SpellCharges.size() && i < _bonusData.EffectCount && i < tokens.size(); ++i)
- SetSpellCharges(i, atoi(tokens[i]));
+ SetSpellCharges(i, Trinity::StringTo<int32>(tokens[i]).value_or(0));
SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS, fields[19].GetUInt32());
SetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_SPEC_1, fields[20].GetUInt32());
@@ -939,11 +944,11 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
for (uint32 i = 0; i < MAX_GEM_SOCKETS; ++i)
{
gemData[i].ItemId = fields[37 + i * gemFields].GetUInt32();
- Tokenizer gemBonusListIDs(fields[38 + i * gemFields].GetString(), ' ');
+ std::vector<std::string_view> gemBonusListIDs = Trinity::Tokenize(fields[38 + i * gemFields].GetStringView(), ' ', false);
uint32 b = 0;
- for (char const* token : gemBonusListIDs)
- if (uint32 bonusListID = atoul(token))
- gemData[i].BonusListIDs[b++] = bonusListID;
+ for (std::string_view token : gemBonusListIDs)
+ if (Optional<uint16> bonusListID = Trinity::StringTo<uint16>(token))
+ gemData[i].BonusListIDs[b++] = *bonusListID;
gemData[i].Context = fields[39 + i * gemFields].GetUInt8();
if (gemData[i].ItemId)
@@ -954,15 +959,15 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
SetModifier(ITEM_MODIFIER_ARTIFACT_KNOWLEDGE_LEVEL, fields[50].GetUInt32());
// Enchants must be loaded after all other bonus/scaling data
- Tokenizer enchantmentTokens(fields[8].GetString(), ' ');
+ std::vector<std::string_view> enchantmentTokens = Trinity::Tokenize(fields[8].GetStringView(), ' ', false);
if (enchantmentTokens.size() == MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET)
{
for (uint32 i = 0; i < MAX_ENCHANTMENT_SLOT; ++i)
{
auto enchantmentField = m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::Enchantment, i);
- SetUpdateFieldValue(enchantmentField.ModifyValue(&UF::ItemEnchantment::ID), atoul(enchantmentTokens[i * MAX_ENCHANTMENT_OFFSET + 0]));
- SetUpdateFieldValue(enchantmentField.ModifyValue(&UF::ItemEnchantment::Duration), atoul(enchantmentTokens[i * MAX_ENCHANTMENT_OFFSET + 1]));
- SetUpdateFieldValue(enchantmentField.ModifyValue(&UF::ItemEnchantment::Charges), atoi(enchantmentTokens[i * MAX_ENCHANTMENT_OFFSET + 2]));
+ SetUpdateFieldValue(enchantmentField.ModifyValue(&UF::ItemEnchantment::ID), Trinity::StringTo<int32>(enchantmentTokens[i * MAX_ENCHANTMENT_OFFSET + 0]).value_or(0));
+ SetUpdateFieldValue(enchantmentField.ModifyValue(&UF::ItemEnchantment::Duration), Trinity::StringTo<uint32>(enchantmentTokens[i * MAX_ENCHANTMENT_OFFSET + 1]).value_or(0));
+ SetUpdateFieldValue(enchantmentField.ModifyValue(&UF::ItemEnchantment::Charges), Trinity::StringTo<int16>(enchantmentTokens[i * MAX_ENCHANTMENT_OFFSET + 2]).value_or(0));
}
}
m_randomBonusListId = fields[9].GetUInt32();
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index fe8e65b22d2..0831c4e4fb4 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -45,6 +45,7 @@
#include "SpellAuraEffects.h"
#include "SpellMgr.h"
#include "SpellPackets.h"
+#include "StringConvert.h"
#include "TemporarySummon.h"
#include "Totem.h"
#include "Transport.h"
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index a8ceac5faf8..be54db2944e 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -110,6 +110,7 @@
#include "SpellHistory.h"
#include "SpellMgr.h"
#include "SpellPackets.h"
+#include "StringConvert.h"
#include "TalentPackets.h"
#include "ToyPackets.h"
#include "TradeData.h"
@@ -6523,7 +6524,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
return true;
}
- // 'Inactive' this aura prevents the player from gaining honor points and battleground Tokenizer
+ // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens
if (HasAura(SPELL_AURA_PLAYER_INACTIVE))
return false;
@@ -17610,7 +17611,7 @@ void Player::_LoadArenaTeamInfo(PreparedQueryResult result)
ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
if (!arenaTeam)
{
- TC_LOG_ERROR("entities.player", "Player::_LoadArenaTeamInfo: couldn't load arenateam %u", arenaTeamId);
+ TC_LOG_ERROR("entities.player.loading", "Player::_LoadArenaTeamInfo: couldn't load arenateam %u", arenaTeamId);
continue;
}
@@ -17782,23 +17783,6 @@ void Player::SendPlayerBound(ObjectGuid const& binderGuid, uint32 areaId) const
SendDirectMessage(packet.Write());
}
-uint32 Player::GetUInt32ValueFromArray(Tokenizer const& data, uint16 index)
-{
- if (index >= data.size())
- return 0;
-
- return (uint32)atoi(data[index]);
-}
-
-float Player::GetFloatValueFromArray(Tokenizer const& data, uint16 index)
-{
- float result;
- uint32 temp = Player::GetUInt32ValueFromArray(data, index);
- memcpy(&result, &temp, sizeof(result));
-
- return result;
-}
-
bool Player::IsLoading() const
{
return GetSession()->PlayerLoading();
@@ -17811,7 +17795,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
{
std::string name = "<unknown>";
sCharacterCache->GetCharacterNameByGuid(guid, name);
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player '%s' (%s) not found in table `characters`, can't load. ", name.c_str(), guid.ToString().c_str());
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player '%s' (%s) not found in table `characters`, can't load. ", name.c_str(), guid.ToString().c_str());
return false;
}
@@ -17970,13 +17954,13 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
// player should be able to load/delete character only with correct account!
if (fields.account != GetSession()->GetAccountId())
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) loading from wrong account (is: %u, should be: %u)", guid.ToString().c_str(), GetSession()->GetAccountId(), fields.account);
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) loading from wrong account (is: %u, should be: %u)", guid.ToString().c_str(), GetSession()->GetAccountId(), fields.account);
return false;
}
if (holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BANNED))
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) is banned, can't load.", guid.ToString().c_str());
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) is banned, can't load.", guid.ToString().c_str());
return false;
}
@@ -18000,7 +17984,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
if (!IsValidGender(fields.gender))
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong gender (%u), can't load.", guid.ToString().c_str(), uint32(fields.gender));
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) has wrong gender (%u), can't load.", guid.ToString().c_str(), uint32(fields.gender));
return false;
}
@@ -18012,26 +17996,23 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(GetRace(), GetClass());
if (!info)
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong race/class (%u/%u), can't load.", guid.ToString().c_str(), GetRace(), GetClass());
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) has wrong race/class (%u/%u), can't load.", guid.ToString().c_str(), GetRace(), GetClass());
return false;
}
SetLevel(fields.level, false);
SetXP(fields.xp);
- Tokenizer exploredZones(fields.exploredZones, ' ');
+ std::vector<std::string_view> exploredZones = Trinity::Tokenize(fields.exploredZones, ' ', false);
if (exploredZones.size() == PLAYER_EXPLORED_ZONES_SIZE * 2)
for (std::size_t i = 0; i < exploredZones.size(); ++i)
SetUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::ExploredZones, i / 2),
- (uint64(atoul(exploredZones[i])) << (32 * (i % 2))));
+ Trinity::StringTo<uint64>(exploredZones[i]).value_or(UI64LIT(0)) << (32 * (i % 2)));
- Tokenizer knownTitles(fields.knownTitles, ' ');
- if (!(knownTitles.size() % 2))
- {
- for (std::size_t i = 0; i < knownTitles.size(); ++i)
- SetUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::KnownTitles, i / 2),
- (uint64(atoul(knownTitles[i])) << (32 * (i % 2))));
- }
+ std::vector<std::string_view> knownTitles = Trinity::Tokenize(fields.knownTitles, ' ', false);
+ for (std::size_t i = 0; i < knownTitles.size(); ++i)
+ SetUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::KnownTitles, i / 2),
+ Trinity::StringTo<uint64>(knownTitles[i]).value_or(UI64LIT(0)) << (32 * (i % 2)));
SetObjectScale(1.0f);
SetHoverHeight(1.0f);
@@ -18069,7 +18050,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
if (!GetSession()->ValidateAppearance(Races(GetRace()), Classes(GetClass()), fields.gender, MakeChrCustomizationChoiceRange(customizations)))
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong Appearance values (Hair/Skin/Color), can't load.", guid.ToString().c_str());
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) has wrong Appearance values (Hair/Skin/Color), can't load.", guid.ToString().c_str());
return false;
}
@@ -18114,7 +18095,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
SetRaidDifficultyID(CheckLoadedRaidDifficultyID(fields.raidDifficulty));
SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID(fields.legacyRaidDifficulty));
-#define RelocateToHomebind(){ mapId = m_homebind.GetMapId(); instanceId = 0; WorldRelocate(m_homebind); }
+ auto RelocateToHomebind = [this, &mapId, &instanceId]() { mapId = m_homebind.GetMapId(); instanceId = 0; WorldRelocate(m_homebind); };
_LoadGroup(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GROUP));
@@ -18133,7 +18114,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
bool player_at_bg = false;
if (!mapEntry || !IsPositionValid())
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has invalid coordinates (MapId: %u X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) has invalid coordinates (MapId: %u X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",
guid.ToString().c_str(), mapId, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
RelocateToHomebind();
}
@@ -18179,7 +18160,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
//if (mapId == MAPID_INVALID) -- code kept for reference
if (int16(mapId) == int16(-1)) // Battleground Entry Point not found (???)
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) was in BG in database, but BG was not found and entry point was invalid! Teleport to default race/class locations.",
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) was in BG in database, but BG was not found and entry point was invalid! Teleport to default race/class locations.",
guid.ToString().c_str());
RelocateToHomebind();
}
@@ -18211,7 +18192,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
std::fabs(m_movementInfo.transport.pos.GetPositionY()) > 250.0f ||
std::fabs(m_movementInfo.transport.pos.GetPositionZ()) > 250.0f)
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to bind location.",
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) has invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to bind location.",
guid.ToString().c_str(), x, y, z, o);
m_movementInfo.transport.Reset();
@@ -18228,7 +18209,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
}
else
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has problems with transport guid (" UI64FMTD "). Teleport to bind location.",
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) has problems with transport guid (" UI64FMTD "). Teleport to bind location.",
guid.ToString().c_str(), fields.transguid);
RelocateToHomebind();
@@ -18254,12 +18235,12 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
if (!nodeEntry) // don't know taxi start node, teleport to homebind
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has wrong data in taxi destination list, teleport to homebind.", GetGUID().ToString().c_str());
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) has wrong data in taxi destination list (%s), teleport to homebind.", GetGUID().ToString().c_str(), fields.taxi_path.c_str());
RelocateToHomebind();
}
else // has start node, teleport to it
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) has too short taxi destination list, teleport to original node.", GetGUID().ToString().c_str());
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player (%s) has too short taxi destination list (%s), teleport to original node.", GetGUID().ToString().c_str(), fields.taxi_path.c_str());
mapId = nodeEntry->ContinentID;
Relocate(nodeEntry->Pos.X, nodeEntry->Pos.Y, nodeEntry->Pos.Z, 0.0f);
}
@@ -18365,7 +18346,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
map = sMapMgr->CreateMap(mapId, this);
if (!map)
{
- TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player '%s' (%s) Map: %u, X: %f, Y: %f, Z: %f, O: %f. Invalid default map coordinates or instance couldn't be created.",
+ TC_LOG_ERROR("entities.player.loading", "Player::LoadFromDB: Player '%s' (%s) Map: %u, X: %f, Y: %f, Z: %f, O: %f. Invalid default map coordinates or instance couldn't be created.",
m_name.c_str(), guid.ToString().c_str(), mapId, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
return false;
}
@@ -18409,7 +18390,8 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
SetTalentResetCost(fields.resettalents_cost);
SetTalentResetTime(fields.resettalents_time);
- m_taxi.LoadTaxiMask(fields.taximask); // must be before InitTaxiNodesForLevel
+ if (!m_taxi.LoadTaxiMask(fields.taximask)) // must be before InitTaxiNodesForLevel
+ TC_LOG_WARN("entities.player.loading", "Player::LoadFromDB: Player (%s) has invalid taximask (%s) in DB. Forced partial load.", GetGUID().ToString().c_str(), fields.taximask.c_str());
uint32 extraflags = fields.extra_flags;
@@ -19161,9 +19143,9 @@ void Player::_LoadVoidStorage(PreparedQueryResult result)
uint32 artifactKnowledgeLevel = fields[6].GetUInt32();
ItemContext context = ItemContext(fields[7].GetUInt8());
std::vector<int32> bonusListIDs;
- Tokenizer bonusListIdTokens(fields[8].GetString(), ' ');
- for (char const* token : bonusListIdTokens)
- bonusListIDs.push_back(atoul(token));
+ for (std::string_view bonusListIDtoken : Trinity::Tokenize(fields[8].GetStringView(), ' ', false))
+ if (Optional<int32> bonusListID = Trinity::StringTo<int32>(bonusListIDtoken))
+ bonusListIDs.push_back(*bonusListID);
if (!itemId)
{
@@ -19253,7 +19235,7 @@ Item* Player::_LoadItem(CharacterDatabaseTransaction& trans, uint32 zoneId, uint
}
else
{
- TC_LOG_DEBUG("entities.player.loading", "Player::_LoadInventory: player (%s, name: '%s') has item (%s) with refundable flags, but without data in item_refund_instance. Removing flag.",
+ TC_LOG_WARN("entities.player.loading", "Player::_LoadInventory: player (%s, name: '%s') has item (%s) with refundable flags, but without data in item_refund_instance. Removing flag.",
GetGUID().ToString().c_str(), GetName().c_str(), item->GetGUID().ToString().c_str());
item->RemoveItemFlag(ITEM_FIELD_FLAG_REFUNDABLE);
}
@@ -19265,11 +19247,9 @@ Item* Player::_LoadItem(CharacterDatabaseTransaction& trans, uint32 zoneId, uint
stmt->setUInt64(0, item->GetGUID().GetCounter());
if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
{
- std::string strGUID = (*result)[0].GetString();
- Tokenizer GUIDlist(strGUID, ' ');
GuidSet looters;
- for (Tokenizer::const_iterator itr = GUIDlist.begin(); itr != GUIDlist.end(); ++itr)
- looters.insert(ObjectGuid::Create<HighGuid::Player>(uint64(strtoull(*itr, nullptr, 10))));
+ for (std::string_view guidStr : Trinity::Tokenize((*result)[0].GetStringView(), ' ', false))
+ looters.insert(ObjectGuid::Create<HighGuid::Player>(Trinity::StringTo<uint64>(guidStr).value_or(UI64LIT(0))));
if (looters.size() > 1 && item->GetTemplate()->GetMaxStackSize() == 1 && item->IsSoulBound())
{
@@ -19281,7 +19261,7 @@ Item* Player::_LoadItem(CharacterDatabaseTransaction& trans, uint32 zoneId, uint
}
else
{
- TC_LOG_DEBUG("entities.player.loading", "Player::_LoadInventory: player (%s, name: '%s') has item (%s) with ITEM_FLAG_BOP_TRADEABLE flag, but without data in item_soulbound_trade_data. Removing flag.",
+ TC_LOG_WARN("entities.player.loading", "Player::_LoadInventory: player (%s, name: '%s') has item (%s) with ITEM_FLAG_BOP_TRADEABLE flag, but without data in item_soulbound_trade_data. Removing flag.",
GetGUID().ToString().c_str(), GetName().c_str(), item->GetGUID().ToString().c_str());
item->RemoveItemFlag(ITEM_FIELD_FLAG_BOP_TRADEABLE);
}
@@ -21650,17 +21630,6 @@ void Player::SavePositionInDB(WorldLocation const& loc, uint16 zoneId, ObjectGui
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
-void Player::SetUInt32ValueInArray(Tokenizer& Tokenizer, uint16 index, uint32 value)
-{
- char buf[11];
- snprintf(buf, 11, "%u", value);
-
- if (index >= Tokenizer.size())
- return;
-
- Tokenizer[index] = buf;
-}
-
void Player::SendAttackSwingCantAttack() const
{
SendDirectMessage(WorldPackets::Combat::AttackSwingError(WorldPackets::Combat::AttackSwingError::CantAttack).Write());
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 8efa94ff758..f79818ffec8 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1664,8 +1664,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder);
bool IsLoading() const override;
- static uint32 GetUInt32ValueFromArray(Tokenizer const& data, uint16 index);
- static float GetFloatValueFromArray(Tokenizer const& data, uint16 index);
static uint32 GetZoneIdFromDB(ObjectGuid guid);
static bool LoadPositionFromDB(uint32& mapid, float& x, float& y, float& z, float& o, bool& in_flight, ObjectGuid guid);
@@ -1684,7 +1682,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
static void SaveCustomizations(CharacterDatabaseTransaction trans, ObjectGuid::LowType guid,
Trinity::IteratorPair<UF::ChrCustomizationChoice const*> customizations);
- static void SetUInt32ValueInArray(Tokenizer& data, uint16 index, uint32 value);
static void SavePositionInDB(WorldLocation const& loc, uint16 zoneId, ObjectGuid guid, CharacterDatabaseTransaction& trans);
static void DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRealmChars = true, bool deleteFinally = false);
diff --git a/src/server/game/Entities/Player/PlayerTaxi.cpp b/src/server/game/Entities/Player/PlayerTaxi.cpp
index 7bd13b6c759..729edb9dfb4 100644
--- a/src/server/game/Entities/Player/PlayerTaxi.cpp
+++ b/src/server/game/Entities/Player/PlayerTaxi.cpp
@@ -19,6 +19,7 @@
#include "DB2Stores.h"
#include "ObjectMgr.h"
#include "Player.h"
+#include "StringConvert.h"
#include "TaxiPackets.h"
#include <limits>
#include <sstream>
@@ -95,16 +96,26 @@ void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint8 level
SetTaximaskNode(213); //Shattered Sun Staging Area
}
-void PlayerTaxi::LoadTaxiMask(std::string const &data)
+bool PlayerTaxi::LoadTaxiMask(std::string const& data)
{
- Tokenizer tokens(data, ' ');
-
- std::size_t index = 0;
- for (Tokenizer::const_iterator iter = tokens.begin(); index < TaxiMaskSize && iter != tokens.end(); ++iter, ++index)
+ bool warn = false;
+ std::vector<std::string_view> tokens = Trinity::Tokenize(data, ' ', false);
+ for (size_t index = 0; (index < TaxiMaskSize) && (index < tokens.size()); ++index)
{
- // load and set bits only for existing taxi nodes
- m_taximask[index] = sTaxiNodesMask[index] & atoul(*iter);
+ if (Optional<uint32> mask = Trinity::StringTo<uint32>(tokens[index]))
+ {
+ // load and set bits only for existing taxi nodes
+ m_taximask[index] = sTaxiNodesMask[index] & *mask;
+ if (m_taximask[index] != *mask)
+ warn = true;
+ }
+ else
+ {
+ m_taximask[index] = 0;
+ warn = true;
+ }
}
+ return !warn;
}
void PlayerTaxi::AppendTaximaskTo(WorldPackets::Taxi::ShowTaxiNodes& data, bool all)
@@ -125,16 +136,22 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString(const std::string& values, uint3
{
ClearTaxiDestinations();
- Tokenizer tokens(values, ' ');
- auto iter = tokens.begin();
- if (iter != tokens.end())
- m_flightMasterFactionId = atoul(*iter);
+ std::vector<std::string_view> tokens = Trinity::Tokenize(values, ' ', false);
+ auto itr = tokens.begin();
+ if (itr != tokens.end())
+ {
+ if (Optional<uint32> faction = Trinity::StringTo<uint32>(*itr))
+ m_flightMasterFactionId = *faction;
+ else
+ return false;
+ }
- ++iter;
- for (; iter != tokens.end(); ++iter)
+ while ((++itr) != tokens.end())
{
- uint32 node = atoul(*iter);
- AddTaxiDestination(node);
+ if (Optional<uint32> node = Trinity::StringTo<uint32>(*itr))
+ AddTaxiDestination(*node);
+ else
+ return false;
}
if (m_TaxiDestinations.empty())
diff --git a/src/server/game/Entities/Player/PlayerTaxi.h b/src/server/game/Entities/Player/PlayerTaxi.h
index fd962967f8b..16a238a02da 100644
--- a/src/server/game/Entities/Player/PlayerTaxi.h
+++ b/src/server/game/Entities/Player/PlayerTaxi.h
@@ -40,7 +40,7 @@ class TC_GAME_API PlayerTaxi
~PlayerTaxi() { }
// Nodes
void InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint8 level);
- void LoadTaxiMask(std::string const& data);
+ bool LoadTaxiMask(std::string const& data);
bool IsTaximaskNodeKnown(uint32 nodeidx) const
{
@@ -64,7 +64,7 @@ class TC_GAME_API PlayerTaxi
TaxiMask const& GetTaxiMask() const { return m_taximask; }
// Destinations
- bool LoadTaxiDestinationsFromString(std::string const& values, uint32 team);
+ [[nodiscard]] bool LoadTaxiDestinationsFromString(std::string const& values, uint32 team);
std::string SaveTaxiDestinationsToString();
void ClearTaxiDestinations() { m_TaxiDestinations.clear(); }
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index c5bee109aff..c4206927bbe 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -75,6 +75,7 @@
#include "SpellInfo.h"
#include "SpellMgr.h"
#include "SpellPackets.h"
+#include "StringConvert.h"
#include "TemporarySummon.h"
#include "Totem.h"
#include "Transport.h"
@@ -9531,29 +9532,28 @@ void CharmInfo::LoadPetActionBar(const std::string& data)
{
InitPetActionBar();
- Tokenizer tokens(data, ' ');
-
+ std::vector<std::string_view> tokens = Trinity::Tokenize(data, ' ', false);
if (tokens.size() != (ACTION_BAR_INDEX_END-ACTION_BAR_INDEX_START) * 2)
return; // non critical, will reset to default
- uint8 index = ACTION_BAR_INDEX_START;
- Tokenizer::const_iterator iter = tokens.begin();
- for (; index < ACTION_BAR_INDEX_END; ++iter, ++index)
+ auto iter = tokens.begin();
+ for (uint8 index = ACTION_BAR_INDEX_START; index < ACTION_BAR_INDEX_END; ++index)
{
- // use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion
- ActiveStates type = ActiveStates(atol(*iter));
- ++iter;
- uint32 action = atoul(*iter);
+ Optional<uint8> type = Trinity::StringTo<uint8>(*(iter++));
+ Optional<uint32> action = Trinity::StringTo<uint32>(*(iter++));
+
+ if (!type || !action)
+ continue;
- PetActionBar[index].SetActionAndType(action, type);
+ PetActionBar[index].SetActionAndType(*action, static_cast<ActiveStates>(*type));
// check correctness
if (PetActionBar[index].IsActionBarForSpell())
{
- SpellInfo const* spelInfo = sSpellMgr->GetSpellInfo(PetActionBar[index].GetAction(), _unit->GetMap()->GetDifficultyID());
- if (!spelInfo)
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(PetActionBar[index].GetAction(), _unit->GetMap()->GetDifficultyID());
+ if (!spellInfo)
SetActionBar(index, 0, ACT_PASSIVE);
- else if (!spelInfo->IsAutocastable())
+ else if (!spellInfo->IsAutocastable())
SetActionBar(index, PetActionBar[index].GetAction(), ACT_PASSIVE);
}
}
diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h
index 60babf771db..f19ca62a94d 100644
--- a/src/server/game/Entities/Unit/UnitDefines.h
+++ b/src/server/game/Entities/Unit/UnitDefines.h
@@ -370,7 +370,7 @@ struct DeclinedName
std::string name[MAX_DECLINED_NAME_CASES];
};
-enum ActiveStates
+enum ActiveStates : uint8
{
ACT_PASSIVE = 0x01, // 0x01 - passive
ACT_DISABLED = 0x81, // 0x80 - castable