aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/database/Database/Field.cpp12
-rw-r--r--src/server/database/Database/Field.h3
-rw-r--r--src/server/database/Database/MySQLConnection.cpp16
-rw-r--r--src/server/database/Logging/AppenderDB.cpp2
-rw-r--r--src/server/database/Logging/AppenderDB.h6
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp7
-rw-r--r--src/server/game/BlackMarket/BlackMarketMgr.cpp7
-rw-r--r--src/server/game/Chat/Channels/Channel.cpp6
-rw-r--r--src/server/game/Chat/Chat.cpp8
-rw-r--r--src/server/game/Chat/LanguageMgr.cpp9
-rw-r--r--src/server/game/Conditions/DisableMgr.cpp21
-rw-r--r--src/server/game/DataStores/GameTables.cpp10
-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
-rw-r--r--src/server/game/Events/GameEventMgr.cpp7
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp86
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp20
-rw-r--r--src/server/game/Loot/LootItemStorage.cpp9
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.cpp13
-rw-r--r--src/server/game/Server/Packets/ChatPackets.cpp6
-rw-r--r--src/server/game/Server/Packets/ChatPackets.h4
-rw-r--r--src/server/scripts/Commands/cs_battlenet_account.cpp13
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp17
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp11
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp8
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp11
-rw-r--r--src/server/shared/Packets/ByteBuffer.h18
34 files changed, 278 insertions, 266 deletions
diff --git a/src/server/database/Database/Field.cpp b/src/server/database/Database/Field.cpp
index b9d25b3da1b..258bc2078fb 100644
--- a/src/server/database/Database/Field.cpp
+++ b/src/server/database/Database/Field.cpp
@@ -237,6 +237,18 @@ std::string Field::GetString() const
return std::string(string, data.length);
}
+std::string_view Field::GetStringView() const
+{
+ if (!data.value)
+ return {};
+
+ char const* const string = GetCString();
+ if (!string)
+ return {};
+
+ return { string, data.length };
+}
+
std::vector<uint8> Field::GetBinary() const
{
std::vector<uint8> result;
diff --git a/src/server/database/Database/Field.h b/src/server/database/Database/Field.h
index dcb03344031..a871ef64bfd 100644
--- a/src/server/database/Database/Field.h
+++ b/src/server/database/Database/Field.h
@@ -21,6 +21,8 @@
#include "Define.h"
#include "DatabaseEnvFwd.h"
#include <array>
+#include <string>
+#include <string_view>
#include <vector>
enum class DatabaseFieldTypes : uint8
@@ -104,6 +106,7 @@ class TC_DATABASE_API Field
double GetDouble() const;
char const* GetCString() const;
std::string GetString() const;
+ std::string_view GetStringView() const;
std::vector<uint8> GetBinary() const;
template <size_t S>
std::array<uint8, S> GetBinary() const
diff --git a/src/server/database/Database/MySQLConnection.cpp b/src/server/database/Database/MySQLConnection.cpp
index 96b00648ffa..2f41da9b70f 100644
--- a/src/server/database/Database/MySQLConnection.cpp
+++ b/src/server/database/Database/MySQLConnection.cpp
@@ -32,21 +32,19 @@
MySQLConnectionInfo::MySQLConnectionInfo(std::string const& infoString)
{
- Tokenizer tokens(infoString, ';');
+ std::vector<std::string_view> tokens = Trinity::Tokenize(infoString, ';', true);
if (tokens.size() != 5 && tokens.size() != 6)
return;
- uint8 i = 0;
-
- host.assign(tokens[i++]);
- port_or_socket.assign(tokens[i++]);
- user.assign(tokens[i++]);
- password.assign(tokens[i++]);
- database.assign(tokens[i++]);
+ host.assign(tokens[0]);
+ port_or_socket.assign(tokens[1]);
+ user.assign(tokens[2]);
+ password.assign(tokens[3]);
+ database.assign(tokens[4]);
if (tokens.size() == 6)
- ssl.assign(tokens[i++]);
+ ssl.assign(tokens[5]);
}
MySQLConnection::MySQLConnection(MySQLConnectionInfo& connInfo) :
diff --git a/src/server/database/Logging/AppenderDB.cpp b/src/server/database/Logging/AppenderDB.cpp
index 87910b49c30..5bac05b47e1 100644
--- a/src/server/database/Logging/AppenderDB.cpp
+++ b/src/server/database/Logging/AppenderDB.cpp
@@ -20,7 +20,7 @@
#include "LogMessage.h"
#include "PreparedStatement.h"
-AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level, AppenderFlags /*flags*/, std::vector<char const*> /*extraArgs*/)
+AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level, AppenderFlags /*flags*/, std::vector<std::string_view> const& /*args*/)
: Appender(id, name, level), realmId(0), enabled(false) { }
AppenderDB::~AppenderDB() { }
diff --git a/src/server/database/Logging/AppenderDB.h b/src/server/database/Logging/AppenderDB.h
index 093678ca7ff..f4880df659a 100644
--- a/src/server/database/Logging/AppenderDB.h
+++ b/src/server/database/Logging/AppenderDB.h
@@ -23,13 +23,13 @@
class TC_DATABASE_API AppenderDB: public Appender
{
public:
- typedef std::integral_constant<AppenderType, APPENDER_DB>::type TypeIndex;
+ static constexpr AppenderType type = APPENDER_DB;
- AppenderDB(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*> extraArgs);
+ AppenderDB(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args);
~AppenderDB();
void setRealmId(uint32 realmId) override;
- AppenderType getType() const override { return TypeIndex::value; }
+ AppenderType getType() const override { return type; }
private:
uint32 realmId;
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index cbc73da75e5..6affb4cb5ed 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -33,6 +33,7 @@
#include "Mail.h"
#include "ObjectMgr.h"
#include "RBAC.h"
+#include "StringConvert.h"
#include "World.h"
#include "WorldSession.h"
#include <sstream>
@@ -756,9 +757,9 @@ void GuildAchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, Prep
CompletedAchievementData& ca = _completedAchievements[achievementid];
ca.Date = fields[1].GetInt64();
- Tokenizer guids(fields[2].GetString(), ' ');
- for (uint32 i = 0; i < guids.size(); ++i)
- ca.CompletingPlayers.insert(ObjectGuid::Create<HighGuid::Player>(uint64(strtoull(guids[i], nullptr, 10))));
+ for (std::string_view guid : Trinity::Tokenize(fields[2].GetStringView(), ' ', false))
+ if (Optional<ObjectGuid::LowType> parsedGuid = Trinity::StringTo<ObjectGuid::LowType>(guid))
+ ca.CompletingPlayers.insert(ObjectGuid::Create<HighGuid::Player>(*parsedGuid));
ca.Changed = false;
diff --git a/src/server/game/BlackMarket/BlackMarketMgr.cpp b/src/server/game/BlackMarket/BlackMarketMgr.cpp
index a0a595c3616..f543f14bfe1 100644
--- a/src/server/game/BlackMarket/BlackMarketMgr.cpp
+++ b/src/server/game/BlackMarket/BlackMarketMgr.cpp
@@ -30,6 +30,7 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "Realm.h"
+#include "StringConvert.h"
#include "World.h"
#include "WorldSession.h"
#include <sstream>
@@ -368,10 +369,10 @@ bool BlackMarketTemplate::LoadFromDB(Field* fields)
Duration = static_cast<time_t>(fields[5].GetUInt32());
Chance = fields[6].GetFloat();
- Tokenizer bonusListIDsTok(fields[7].GetString(), ' ');
std::vector<int32> bonusListIDs;
- for (char const* token : bonusListIDsTok)
- bonusListIDs.push_back(int32(atol(token)));
+ for (std::string_view token : Trinity::Tokenize(fields[7].GetStringView(), ' ', false))
+ if (Optional<int32> bonusListID = Trinity::StringTo<int32>(token))
+ bonusListIDs.push_back(*bonusListID);
if (!bonusListIDs.empty())
{
diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp
index 7f5a6cc8aec..46a4df0df76 100644
--- a/src/server/game/Chat/Channels/Channel.cpp
+++ b/src/server/game/Chat/Channels/Channel.cpp
@@ -31,6 +31,7 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "SocialMgr.h"
+#include "StringConvert.h"
#include "World.h"
#include "WorldSession.h"
#include <sstream>
@@ -73,11 +74,10 @@ Channel::Channel(ObjectGuid const& guid, std::string const& name, uint32 team /*
_channelName(name),
_zoneEntry(nullptr)
{
- Tokenizer tokens(banList, ' ');
- for (auto const& token : tokens)
+ for (std::string_view guid : Trinity::Tokenize(banList, ' ', false))
{
// legacy db content might not have 0x prefix, account for that
- std::string bannedGuidStr(memcmp(token, "0x", 2) ? token + 2 : token);
+ std::string bannedGuidStr(guid.size() > 2 && guid.substr(0, 2) == "0x" ? guid.substr(2) : guid);
ObjectGuid banned;
banned.SetRawValue(uint64(strtoull(bannedGuidStr.substr(0, 16).c_str(), nullptr, 16)), uint64(strtoull(bannedGuidStr.substr(16).c_str(), nullptr, 16)));
if (!banned)
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 3a0e77bd294..75acbffcbd3 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -180,7 +180,7 @@ void ChatHandler::SendSysMessage(const char *str, bool escapeCharacters)
// Replace every "|" with "||" in msg
if (escapeCharacters && msg.find('|') != std::string::npos)
{
- Tokenizer tokens{msg, '|'};
+ std::vector<std::string_view> tokens = Trinity::Tokenize(msg, '|', true);
std::ostringstream stream;
for (size_t i = 0; i < tokens.size() - 1; ++i)
stream << tokens[i] << "||";
@@ -190,7 +190,7 @@ void ChatHandler::SendSysMessage(const char *str, bool escapeCharacters)
}
WorldPackets::Chat::Chat packet;
- for (const auto& line : Tokenizer{msg, '\n'})
+ for (std::string_view line : Trinity::Tokenize(str, '\n', true))
{
packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line);
m_session->SendPacket(packet.Write());
@@ -200,7 +200,7 @@ void ChatHandler::SendSysMessage(const char *str, bool escapeCharacters)
void ChatHandler::SendGlobalSysMessage(const char *str)
{
WorldPackets::Chat::Chat packet;
- for (const auto& line : Tokenizer{str, '\n'})
+ for (std::string_view line : Trinity::Tokenize(str, '\n', true))
{
packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line);
sWorld->SendGlobalMessage(packet.Write());
@@ -210,7 +210,7 @@ void ChatHandler::SendGlobalSysMessage(const char *str)
void ChatHandler::SendGlobalGMSysMessage(const char *str)
{
WorldPackets::Chat::Chat packet;
- for (const auto& line : Tokenizer{str, '\n'})
+ for (std::string_view line : Trinity::Tokenize(str, '\n', true))
{
packet.Initialize(CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line);
sWorld->SendGlobalGMMessage(packet.Write());
diff --git a/src/server/game/Chat/LanguageMgr.cpp b/src/server/game/Chat/LanguageMgr.cpp
index ec2a65f9013..c30cfa9b965 100644
--- a/src/server/game/Chat/LanguageMgr.cpp
+++ b/src/server/game/Chat/LanguageMgr.cpp
@@ -216,13 +216,12 @@ std::string LanguageMgr::Translate(std::string const& msg, uint32 language, Loca
std::string result;
result.reserve(textToTranslate.length());
- Tokenizer tokens(textToTranslate, ' ');
- for (char const* str : tokens)
+ for (std::string_view str : Trinity::Tokenize(textToTranslate, ' ', false))
{
- uint32 wordLen = std::min(18u, uint32(strlen(str)));
+ uint32 wordLen = std::min(18u, uint32(str.length()));
if (LanguageMgr::WordList const* wordGroup = FindWordGroup(language, wordLen))
{
- uint32 wordHash = SStrHash(str, true);
+ uint32 wordHash = SStrHash(str.data(), true);
uint8 idxInsideGroup = wordHash % wordGroup->size();
char const* replacementWord = (*wordGroup)[idxInsideGroup];
@@ -233,7 +232,7 @@ std::string LanguageMgr::Translate(std::string const& msg, uint32 language, Loca
case LOCALE_zhCN:
case LOCALE_zhTW:
{
- size_t length = std::min(strlen(str), strlen(replacementWord));
+ size_t length = std::min(str.length(), strlen(replacementWord));
for (size_t i = 0; i < length; ++i)
{
if (str[i] >= 'A' && str[i] <= 'Z')
diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp
index d3ba318cc1a..15af1065d2a 100644
--- a/src/server/game/Conditions/DisableMgr.cpp
+++ b/src/server/game/Conditions/DisableMgr.cpp
@@ -25,6 +25,7 @@
#include "OutdoorPvP.h"
#include "Player.h"
#include "SpellMgr.h"
+#include "StringConvert.h"
#include "VMapManager2.h"
#include "World.h"
@@ -109,16 +110,24 @@ void LoadDisables()
if (flags & SPELL_DISABLE_MAP)
{
- Tokenizer tokens(params_0, ',');
- for (uint8 i = 0; i < tokens.size(); )
- data.params[0].insert(atoi(tokens[i++]));
+ for (std::string_view mapStr : Trinity::Tokenize(params_0, ',', true))
+ {
+ if (Optional<uint32> mapId = Trinity::StringTo<uint32>(mapStr))
+ data.params[0].insert(*mapId);
+ else
+ TC_LOG_ERROR("sql.sql", "Disable map '%s' for spell %u is invalid, skipped.", std::string(mapStr).c_str(), entry);
+ }
}
if (flags & SPELL_DISABLE_AREA)
{
- Tokenizer tokens(params_1, ',');
- for (uint8 i = 0; i < tokens.size(); )
- data.params[1].insert(atoi(tokens[i++]));
+ for (std::string_view areaStr : Trinity::Tokenize(params_0, ',', true))
+ {
+ if (Optional<uint32> areaId = Trinity::StringTo<uint32>(areaStr))
+ data.params[1].insert(*areaId);
+ else
+ TC_LOG_ERROR("sql.sql", "Disable area '%s' for spell %u is invalid, skipped.", std::string(areaStr).c_str(), entry);
+ }
}
break;
diff --git a/src/server/game/DataStores/GameTables.cpp b/src/server/game/DataStores/GameTables.cpp
index d77b805d404..ba847f9197d 100644
--- a/src/server/game/DataStores/GameTables.cpp
+++ b/src/server/game/DataStores/GameTables.cpp
@@ -55,7 +55,7 @@ inline uint32 LoadGameTable(std::vector<std::string>& errors, GameTable<T>& stor
return 0;
}
- Tokenizer columnDefs(headers, '\t', 0, false);
+ std::vector<std::string_view> columnDefs = Trinity::Tokenize(headers, '\t', false);
ASSERT(columnDefs.size() - 1 == sizeof(T) / sizeof(float),
"GameTable '%s' has different count of columns " SZFMTD " than expected by size of C++ structure (" SZFMTD ").",
@@ -67,13 +67,13 @@ inline uint32 LoadGameTable(std::vector<std::string>& errors, GameTable<T>& stor
std::string line;
while (std::getline(stream, line))
{
- Tokenizer values(line, '\t', uint32(columnDefs.size()));
- if (!values.size())
+ std::vector<std::string_view> values = Trinity::Tokenize(line, '\t', true);
+ if (values.empty())
break;
// make end point just after last nonempty token
auto end = values.begin() + values.size() - 1;
- while (!strlen(*end) && end != values.begin())
+ while (end->empty() && end != values.begin())
--end;
if (values.begin() == end)
@@ -91,7 +91,7 @@ inline uint32 LoadGameTable(std::vector<std::string>& errors, GameTable<T>& stor
data.emplace_back();
float* row = reinterpret_cast<float*>(&data.back());
for (auto itr = values.begin() + 1; itr != end; ++itr)
- *row++ = strtof(*itr, nullptr);
+ *row++ = strtof(itr->data(), nullptr);
}
storage.SetData(std::move(data));
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
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 0450104364f..d27b7b12a4e 100644
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -30,6 +30,7 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "PoolMgr.h"
+#include "StringConvert.h"
#include "World.h"
#include "WorldStatePackets.h"
@@ -856,9 +857,9 @@ void GameEventMgr::LoadFromDB()
vItem.PlayerConditionId = fields[8].GetUInt32();
vItem.IgnoreFiltering = fields[9].GetBool();
- Tokenizer bonusListIDsTok(fields[7].GetString(), ' ');
- for (char const* token : bonusListIDsTok)
- vItem.BonusListIDs.push_back(int32(atol(token)));
+ for (std::string_view token : Trinity::Tokenize(fields[7].GetStringView(), ' ', false))
+ if (Optional<int32> bonusListID = Trinity::StringTo<int32>(token))
+ vItem.BonusListIDs.push_back(*bonusListID);
// check validity with event's npcflag
if (!sObjectMgr->IsVendorItemValid(entry, vItem, nullptr, nullptr, event_npc_flag))
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 67a025c4756..f92c7390848 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -58,6 +58,7 @@
#include "SpellInfo.h"
#include "SpellMgr.h"
#include "SpellScript.h"
+#include "StringConvert.h"
#include "TemporarySummon.h"
#include "Timer.h"
#include "TransportMgr.h"
@@ -675,34 +676,34 @@ void ObjectMgr::LoadCreatureTemplateAddons()
creatureAddon.meleeAnimKit = fields[8].GetUInt16();
creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[9].GetUInt8());
- Tokenizer tokens(fields[10].GetString(), ' ');
- creatureAddon.auras.reserve(tokens.size());
- for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
+ for (std::string_view aura : Trinity::Tokenize(fields[10].GetStringView(), ' ', false))
{
- uint32 spellId = uint32(atoul(*itr));
- SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
- if (!AdditionalSpellInfo)
+ SpellInfo const* spellInfo = nullptr;
+ if (Optional<uint32> spellId = Trinity::StringTo<uint32>(aura))
+ spellInfo = sSpellMgr->GetSpellInfo(*spellId, DIFFICULTY_NONE);
+
+ if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell %u defined in `auras` field in `creature_template_addon`.", entry, spellId);
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell '%s' defined in `auras` field in `creature_template_addon`.", entry, std::string(aura).c_str());
continue;
}
- if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_template_addon`.", entry, spellId);
+ if (spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_template_addon`.", entry, spellInfo->Id);
- if (std::find(creatureAddon.auras.begin(), creatureAddon.auras.end(), spellId) != creatureAddon.auras.end())
+ if (std::find(creatureAddon.auras.begin(), creatureAddon.auras.end(), spellInfo->Id) != creatureAddon.auras.end())
{
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has duplicate aura (spell %u) in `auras` field in `creature_template_addon`.", entry, spellId);
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has duplicate aura (spell %u) in `auras` field in `creature_template_addon`.", entry, spellInfo->Id);
continue;
}
- if (AdditionalSpellInfo->GetDuration() > 0)
+ if (spellInfo->GetDuration() > 0)
{
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has temporary aura (spell %u) in `auras` field in `creature_template_addon`.", entry, spellId);
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has temporary aura (spell %u) in `auras` field in `creature_template_addon`.", entry, spellInfo->Id);
continue;
}
- creatureAddon.auras.push_back(spellId);
+ creatureAddon.auras.push_back(spellInfo->Id);
}
if (creatureAddon.mount)
@@ -1220,34 +1221,34 @@ void ObjectMgr::LoadCreatureAddons()
creatureAddon.meleeAnimKit = fields[8].GetUInt16();
creatureAddon.visibilityDistanceType = VisibilityDistanceType(fields[9].GetUInt8());
- Tokenizer tokens(fields[10].GetString(), ' ');
- creatureAddon.auras.reserve(tokens.size());
- for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
+ for (std::string_view aura : Trinity::Tokenize(fields[10].GetStringView(), ' ', false))
{
- uint32 spellId = uint32(atoul(*itr));
- SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
- if (!AdditionalSpellInfo)
+ SpellInfo const* spellInfo = nullptr;
+ if (Optional<uint32> spellId = Trinity::StringTo<uint32>(aura))
+ spellInfo = sSpellMgr->GetSpellInfo(*spellId, DIFFICULTY_NONE);
+
+ if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has wrong spell %u defined in `auras` field in `creature_addon`.", guid, spellId);
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has wrong spell '%s' defined in `auras` field in `creature_addon`.", guid, std::string(aura).c_str());
continue;
}
- if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
- TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_addon`.", guid, spellId);
+ if (spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_addon`.", guid, spellInfo->Id);
- if (std::find(creatureAddon.auras.begin(), creatureAddon.auras.end(), spellId) != creatureAddon.auras.end())
+ if (std::find(creatureAddon.auras.begin(), creatureAddon.auras.end(), spellInfo->Id) != creatureAddon.auras.end())
{
- TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has duplicate aura (spell %u) in `auras` field in `creature_addon`.", guid, spellId);
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has duplicate aura (spell %u) in `auras` field in `creature_addon`.", guid, spellInfo->Id);
continue;
}
- if (AdditionalSpellInfo->GetDuration() > 0)
+ if (spellInfo->GetDuration() > 0)
{
- TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has temporary aura (spell %u) in `auras` field in `creature_addon`.", guid, spellId);
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has temporary aura (spell %u) in `auras` field in `creature_addon`.", guid, spellInfo->Id);
continue;
}
- creatureAddon.auras.push_back(spellId);
+ creatureAddon.auras.push_back(spellInfo->Id);
}
if (creatureAddon.mount)
@@ -2048,12 +2049,11 @@ void ObjectMgr::LoadTempSummons()
inline std::vector<Difficulty> ParseSpawnDifficulties(std::string const& difficultyString, std::string const& table, ObjectGuid::LowType spawnId, uint32 mapId,
std::set<Difficulty> const& mapDifficulties)
{
- Tokenizer tokens(difficultyString, ',', 0, false);
std::vector<Difficulty> difficulties;
bool isTransportMap = sObjectMgr->IsTransportMap(mapId);
- for (char const* token : tokens)
+ for (std::string_view token : Trinity::Tokenize(difficultyString, ',', false))
{
- Difficulty difficultyId = Difficulty(strtoul(token, nullptr, 10));
+ Difficulty difficultyId = Difficulty(Trinity::StringTo<std::underlying_type_t<Difficulty>>(token).value_or(DIFFICULTY_NONE));
if (difficultyId && !sDifficultyStore.LookupEntry(difficultyId))
{
TC_LOG_ERROR("sql.sql", "Table `%s` has %s (GUID: " UI64FMTD ") with non invalid difficulty id %u, skipped.",
@@ -9439,9 +9439,9 @@ uint32 ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set<uint32>
vItem.PlayerConditionId = fields[6].GetUInt32();
vItem.IgnoreFiltering = fields[7].GetBool();
- Tokenizer bonusListIDsTok(fields[5].GetString(), ' ');
- for (char const* token : bonusListIDsTok)
- vItem.BonusListIDs.push_back(int32(atol(token)));
+ for (std::string_view token : Trinity::Tokenize(fields[5].GetStringView(), ' ', false))
+ if (Optional<int32> bonusListID = Trinity::StringTo<int32>(token))
+ vItem.BonusListIDs.push_back(*bonusListID);
if (!IsVendorItemValid(vendor, vItem, nullptr, skip_vendors))
continue;
@@ -9496,9 +9496,9 @@ void ObjectMgr::LoadVendors()
vItem.PlayerConditionId = fields[7].GetUInt32();
vItem.IgnoreFiltering = fields[8].GetBool();
- Tokenizer bonusListIDsTok(fields[6].GetString(), ' ');
- for (char const* token : bonusListIDsTok)
- vItem.BonusListIDs.push_back(int32(atol(token)));
+ for (std::string_view token : Trinity::Tokenize(fields[6].GetStringView(), ' ', false))
+ if (Optional<int32> bonusListID = Trinity::StringTo<int32>(token))
+ vItem.BonusListIDs.push_back(*bonusListID);
if (!IsVendorItemValid(entry, vItem, nullptr, &skip_vendors))
continue;
@@ -10960,10 +10960,10 @@ void ObjectMgr::LoadPlayerChoices()
int32 choiceId = fields[0].GetInt32();
int32 responseId = fields[1].GetInt32();
uint32 itemId = fields[2].GetUInt32();
- Tokenizer bonusListIDsTok(fields[3].GetString(), ' ');
std::vector<int32> bonusListIds;
- for (char const* token : bonusListIDsTok)
- bonusListIds.push_back(int32(atol(token)));
+ for (std::string_view token : Trinity::Tokenize(fields[3].GetStringView(), ' ', false))
+ if (Optional<int32> bonusListID = Trinity::StringTo<int32>(token))
+ bonusListIds.push_back(*bonusListID);
int32 quantity = fields[4].GetInt32();
PlayerChoice* choice = Trinity::Containers::MapGetValuePtr(_playerChoices, choiceId);
@@ -11102,10 +11102,10 @@ void ObjectMgr::LoadPlayerChoices()
int32 choiceId = fields[0].GetInt32();
int32 responseId = fields[1].GetInt32();
uint32 itemId = fields[2].GetUInt32();
- Tokenizer bonusListIDsTok(fields[3].GetString(), ' ');
std::vector<int32> bonusListIds;
- for (char const* token : bonusListIDsTok)
- bonusListIds.push_back(int32(atol(token)));
+ for (std::string_view token : Trinity::Tokenize(fields[3].GetStringView(), ' ', false))
+ if (Optional<int32> bonusListID = Trinity::StringTo<int32>(token))
+ bonusListIds.push_back(*bonusListID);
int32 quantity = fields[4].GetInt32();
PlayerChoice* choice = Trinity::Containers::MapGetValuePtr(_playerChoices, choiceId);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 7e44225f8da..09e945981af 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -58,6 +58,7 @@
#include "ReputationMgr.h"
#include "ScriptMgr.h"
#include "SocialMgr.h"
+#include "StringConvert.h"
#include "SystemPackets.h"
#include "Util.h"
#include "World.h"
@@ -2505,11 +2506,20 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(std::shared_ptr<WorldPa
// Title conversion
if (!knownTitlesStr.empty())
{
+ std::vector<std::string_view> tokens = Trinity::Tokenize(knownTitlesStr, ' ', false);
std::vector<uint32> knownTitles;
- Tokenizer tokens(knownTitlesStr, ' ');
- for (uint32 index = 0; index < tokens.size(); ++index)
- knownTitles.push_back(atoul(tokens[index]));
+ for (std::string_view token : tokens)
+ {
+ if (Optional<uint32> thisMask = Trinity::StringTo<uint32>(token))
+ knownTitles.push_back(*thisMask);
+ else
+ {
+ TC_LOG_WARN("entities.player", "%s has invalid title data '%s' - skipped, this may result in titles being lost",
+ GetPlayerInfo().c_str(), std::string(token).c_str());
+ knownTitles.push_back(0);
+ }
+ }
for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeTitles.begin(); it != sObjectMgr->FactionChangeTitles.end(); ++it)
{
@@ -2553,8 +2563,8 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(std::shared_ptr<WorldPa
}
std::ostringstream ss;
- for (uint32 index = 0; index < knownTitles.size(); ++index)
- ss << knownTitles[index] << ' ';
+ for (uint32 mask : knownTitles)
+ ss << mask << ' ';
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TITLES_FACTION_CHANGE);
stmt->setString(0, ss.str());
diff --git a/src/server/game/Loot/LootItemStorage.cpp b/src/server/game/Loot/LootItemStorage.cpp
index 59881e178a7..3347dba6aa8 100644
--- a/src/server/game/Loot/LootItemStorage.cpp
+++ b/src/server/game/Loot/LootItemStorage.cpp
@@ -23,6 +23,7 @@
#include "LootMgr.h"
#include "ObjectMgr.h"
#include "Player.h"
+#include "StringConvert.h"
#include <sstream>
#include <unordered_map>
@@ -87,11 +88,9 @@ void LootItemStorage::LoadStorageFromDB()
lootItem.needs_quest = fields[8].GetBool();
lootItem.randomBonusListId = fields[9].GetUInt32();
lootItem.context = ItemContext(fields[10].GetUInt8());
- Tokenizer bonusLists(fields[11].GetString(), ' ');
- std::transform(bonusLists.begin(), bonusLists.end(), std::back_inserter(lootItem.BonusListIDs), [](char const* token)
- {
- return int32(strtol(token, nullptr, 10));
- });
+ for (std::string_view bonusList : Trinity::Tokenize(fields[11].GetStringView(), ' ', false))
+ if (Optional<int32> bonusListID = Trinity::StringTo<int32>(bonusList))
+ lootItem.BonusListIDs.push_back(*bonusListID);
storedContainer.AddLootItem(lootItem, trans);
diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp
index bde4aadf903..c73e2ef68ab 100644
--- a/src/server/game/Server/Packets/CharacterPackets.cpp
+++ b/src/server/game/Server/Packets/CharacterPackets.cpp
@@ -20,6 +20,7 @@
#include "Field.h"
#include "ObjectMgr.h"
#include "Player.h"
+#include "StringConvert.h"
#include "World.h"
namespace UF
@@ -132,7 +133,7 @@ EnumCharactersResult::CharacterInfo::CharacterInfo(Field* fields)
ProfessionIds[0] = 0;
ProfessionIds[1] = 0;
- Tokenizer equipment(fields[17].GetString(), ' ');
+ std::vector<std::string_view> equipment = Trinity::Tokenize(fields[17].GetStringView(), ' ', false);
ListPosition = fields[19].GetUInt8();
LastPlayedTime = fields[20].GetInt64();
if (ChrSpecializationEntry const* spec = sDB2Manager.GetChrSpecializationByIndex(ClassID, fields[21].GetUInt8()))
@@ -143,11 +144,11 @@ EnumCharactersResult::CharacterInfo::CharacterInfo(Field* fields)
for (uint8 slot = 0; slot < INVENTORY_SLOT_BAG_END; ++slot)
{
uint32 visualBase = slot * 5;
- VisualItems[slot].InvType = Player::GetUInt32ValueFromArray(equipment, visualBase);
- VisualItems[slot].DisplayID = Player::GetUInt32ValueFromArray(equipment, visualBase + 1);
- VisualItems[slot].DisplayEnchantID = Player::GetUInt32ValueFromArray(equipment, visualBase + 2);
- VisualItems[slot].Subclass = Player::GetUInt32ValueFromArray(equipment, visualBase + 3);
- VisualItems[slot].SecondaryItemModifiedAppearanceID = Player::GetUInt32ValueFromArray(equipment, visualBase + 4);
+ VisualItems[slot].InvType = Trinity::StringTo<uint8>(equipment[visualBase + 0]).value_or(0);
+ VisualItems[slot].DisplayID = Trinity::StringTo<uint32>(equipment[visualBase + 1]).value_or(0);
+ VisualItems[slot].DisplayEnchantID = Trinity::StringTo<uint32>(equipment[visualBase + 2]).value_or(0);
+ VisualItems[slot].Subclass = Trinity::StringTo<uint8>(equipment[visualBase + 3]).value_or(0);
+ VisualItems[slot].SecondaryItemModifiedAppearanceID = Trinity::StringTo<int32>(equipment[visualBase + 4]).value_or(0);
}
}
diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp
index 6ac809ecc95..efb1eb4809e 100644
--- a/src/server/game/Server/Packets/ChatPackets.cpp
+++ b/src/server/game/Server/Packets/ChatPackets.cpp
@@ -102,8 +102,8 @@ WorldPackets::Chat::Chat::Chat(Chat const& chat) : ServerPacket(SMSG_CHAT, chat.
{
}
-void WorldPackets::Chat::Chat::Initialize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string message,
- uint32 achievementId /*= 0*/, std::string channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string addonPrefix /*= ""*/)
+void WorldPackets::Chat::Chat::Initialize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string_view message,
+ uint32 achievementId /*= 0*/, std::string_view channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string_view addonPrefix /*= ""*/)
{
// Clear everything because same packet can be used multiple times
Clear();
@@ -131,7 +131,7 @@ void WorldPackets::Chat::Chat::Initialize(ChatMsg chatType, Language language, W
AchievementID = achievementId;
_Channel = std::move(channelName);
Prefix = std::move(addonPrefix);
- ChatText = std::move(message);
+ ChatText = message;
}
void WorldPackets::Chat::Chat::SetSender(WorldObject const* sender, LocaleConstant locale)
diff --git a/src/server/game/Server/Packets/ChatPackets.h b/src/server/game/Server/Packets/ChatPackets.h
index cb161ef3169..2b23f2f2562 100644
--- a/src/server/game/Server/Packets/ChatPackets.h
+++ b/src/server/game/Server/Packets/ChatPackets.h
@@ -149,8 +149,8 @@ namespace WorldPackets
Chat() : ServerPacket(SMSG_CHAT, 100) { }
Chat(Chat const& chat);
- void Initialize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string message, uint32 achievementId = 0,
- std::string channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string addonPrefix = "");
+ void Initialize(ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string_view message, uint32 achievementId = 0,
+ std::string_view channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string_view addonPrefix = "");
void SetSender(WorldObject const* sender, LocaleConstant locale);
void SetReceiver(WorldObject const* receiver, LocaleConstant locale);
diff --git a/src/server/scripts/Commands/cs_battlenet_account.cpp b/src/server/scripts/Commands/cs_battlenet_account.cpp
index c4f0dff6c01..03ff81c0a20 100644
--- a/src/server/scripts/Commands/cs_battlenet_account.cpp
+++ b/src/server/scripts/Commands/cs_battlenet_account.cpp
@@ -325,19 +325,8 @@ public:
return true;
}
- static bool HandleAccountLinkCommand(ChatHandler* handler, char const* args)
+ static bool HandleAccountLinkCommand(ChatHandler* handler, std::string const& bnetAccountName, std::string const& gameAccountName)
{
- Tokenizer tokens(args, ' ', 2);
- if (tokens.size() != 2)
- {
- handler->SendSysMessage(LANG_CMD_SYNTAX);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- std::string bnetAccountName = tokens[0];
- std::string gameAccountName = tokens[1];
-
switch (Battlenet::AccountMgr::LinkWithGameAccount(bnetAccountName, gameAccountName))
{
case AccountOpResult::AOR_OK:
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index b6dceef1101..99b507bb61c 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -1250,12 +1250,9 @@ public:
// semicolon separated bonuslist ids (parse them after all arguments are extracted by strtok!)
if (bonuses)
- {
- Tokenizer tokens(bonuses, ';');
- for (char const* token : tokens)
- if (int32 bonusListId = atoi(token))
- bonusListIDs.push_back(bonusListId);
- }
+ for (std::string_view token : Trinity::Tokenize(bonuses, ';', false))
+ if (Optional<int32> bonusListId = Trinity::StringTo<int32>(token))
+ bonusListIDs.push_back(*bonusListId);
ItemContext itemContext = ItemContext::NONE;
if (context)
@@ -1364,11 +1361,9 @@ public:
// semicolon separated bonuslist ids (parse them after all arguments are extracted by strtok!)
if (bonuses)
- {
- Tokenizer tokens(bonuses, ';');
- for (char const* token : tokens)
- bonusListIDs.push_back(atoul(token));
- }
+ for (std::string_view token : Trinity::Tokenize(bonuses, ';', false))
+ if (Optional<int32> bonusListId = Trinity::StringTo<int32>(token))
+ bonusListIDs.push_back(*bonusListId);
ItemContext itemContext = ItemContext::NONE;
if (context)
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index 84fbdd8cdfe..972c3761168 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -566,11 +566,16 @@ public:
if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
return false;
- int64 moneyToAdd = 0;
+ Optional<int64> moneyToAddO = 0;
if (strchr(args, 'g') || strchr(args, 's') || strchr(args, 'c'))
- moneyToAdd = MoneyStringToMoney(std::string(args));
+ moneyToAddO = MoneyStringToMoney(std::string(args));
else
- moneyToAdd = atoll(args);
+ moneyToAddO = Trinity::StringTo<int64>(args);
+
+ if (!moneyToAddO)
+ return false;
+
+ int64 moneyToAdd = *moneyToAddO;
uint64 targetMoney = target->GetMoney();
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index d30d77f4f39..8107ef086d6 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -304,11 +304,9 @@ public:
vItem.Type = type;
if (fbonuslist)
- {
- Tokenizer bonusListIDsTok(fbonuslist, ';');
- for (char const* token : bonusListIDsTok)
- vItem.BonusListIDs.push_back(int32(atol(token)));
- }
+ for (std::string_view token : Trinity::Tokenize(fbonuslist, ';', false))
+ if (Optional<int32> bonusListID = Trinity::StringTo<int32>(token))
+ vItem.BonusListIDs.push_back(*bonusListID);
if (!sObjectMgr->IsVendorItemValid(vendor_entry, vItem, handler->GetSession()->GetPlayer()))
{
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index 17992ddddba..c25403bd88f 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -46,6 +46,7 @@ EndScriptData */
#include "SkillExtraItems.h"
#include "SmartAI.h"
#include "SpellMgr.h"
+#include "StringConvert.h"
#include "SupportMgr.h"
#include "WaypointManager.h"
#include "World.h"
@@ -205,7 +206,7 @@ public:
HandleReloadGameTeleCommand(handler, "");
HandleReloadCreatureMovementOverrideCommand(handler, "");
- HandleReloadCreatureSummonGroupsCommand(handler, "");
+ HandleReloadCreatureSummonGroupsCommand(handler);
HandleReloadVehicleAccessoryCommand(handler, "");
HandleReloadVehicleTemplateAccessoryCommand(handler, "");
@@ -420,7 +421,7 @@ public:
return true;
}
- static bool HandleReloadCreatureSummonGroupsCommand(ChatHandler* handler, char const* /*args*/)
+ static bool HandleReloadCreatureSummonGroupsCommand(ChatHandler* handler)
{
TC_LOG_INFO("misc", "Reloading creature summon groups...");
sObjectMgr->LoadTempSummons();
@@ -433,11 +434,9 @@ public:
if (!*args)
return false;
- Tokenizer entries(std::string(args), ' ');
-
- for (Tokenizer::const_iterator itr = entries.begin(); itr != entries.end(); ++itr)
+ for (std::string_view entryStr : Trinity::Tokenize(args, ' ', false))
{
- uint32 entry = atoul(*itr);
+ uint32 entry = Trinity::StringTo<uint32>(entryStr).value_or(0);
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_TEMPLATE);
stmt->setUInt32(0, entry);
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 32f6bcbaee9..40c3782806d 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -300,20 +300,22 @@ class TC_SHARED_API ByteBuffer
return *this;
}
- ByteBuffer &operator<<(const std::string &value)
+ ByteBuffer &operator<<(std::string_view value)
{
if (size_t len = value.length())
- append((uint8 const*)value.c_str(), len);
- append<uint8>(0);
+ append(reinterpret_cast<uint8 const*>(value.data()), len);
+ append(static_cast<uint8>(0));
return *this;
}
- ByteBuffer &operator<<(const char *str)
+ ByteBuffer& operator<<(std::string const& str)
{
- if (size_t len = (str ? strlen(str) : 0))
- append((uint8 const*)str, len);
- append<uint8>(0);
- return *this;
+ return operator<<(std::string_view(str));
+ }
+
+ ByteBuffer &operator<<(char const* str)
+ {
+ return operator<<(std::string_view(str ? str : ""));
}
ByteBuffer &operator>>(bool &value)