25#include <unordered_map>
26#include <unordered_set>
54 trans->Append(delStmt);
61 trans->Append(insStmt);
68 std::unordered_map<uint32, std::pair<std::vector<QuestPool>*,
uint32>> lookup;
77 QueryResult result =
WorldDatabase.Query(
"SELECT qpm.questId, qpm.poolId, qpm.poolIndex, qpt.numActive FROM quest_pool_members qpm LEFT JOIN quest_pool_template qpt ON qpm.poolId = qpt.poolId");
80 TC_LOG_INFO(
"server.loading",
">> Loaded 0 quest pools. DB table `quest_pool_members` is empty.");
86 Field* fields = result->Fetch();
87 if (fields[2].IsNull())
89 TC_LOG_ERROR(
"sql.sql",
"Table `quest_pool_members` contains reference to non-existing pool {}. Skipped.", fields[1].GetUInt32());
101 TC_LOG_ERROR(
"sql.sql",
"Table `quest_pool_members` contains reference to non-existing quest {}. Skipped.", questId);
106 TC_LOG_ERROR(
"sql.sql",
"Table `quest_pool_members` contains reference to quest {}, which is neither daily, weekly nor monthly. Skipped.", questId);
110 auto& pair = lookup[poolId];
114 pair.first->emplace_back();
115 pair.second = (pair.first->size()-1);
117 pair.first->back().poolId = poolId;
118 pair.first->back().numActive = numActive;
122 if (!(poolIndex < members.size()))
123 members.resize(poolIndex+1);
124 members[poolIndex].push_back(questId);
125 }
while (result->NextRow());
133 std::unordered_set<uint32> unknownPoolIds;
136 Field* fields = result->Fetch();
141 auto it = lookup.find(poolId);
142 if (it == lookup.end() || !it->second.first)
144 TC_LOG_ERROR(
"sql.sql",
"Table `pool_quest_save` contains reference to non-existant quest pool {}. Deleted.", poolId);
145 unknownPoolIds.insert(poolId);
149 (*it->second.first)[it->second.second].activeQuests.insert(questId);
150 }
while (result->NextRow());
153 for (
uint32 poolId : unknownPoolIds)
165 for (
auto const& pair : lookup)
167 if (!pair.second.first)
169 QuestPool& pool = (*pair.second.first)[pair.second.second];
172 TC_LOG_ERROR(
"sql.sql",
"Table `quest_pool_template` contains quest pool {} requesting {} spawns, but only has {} members. Requested spawns reduced.", pool.
poolId, pool.
numActive, pool.
members.size());
179 std::unordered_set<uint32> accountedFor;
181 for (
size_t i = pool.
members.size(); (i--);)
186 TC_LOG_ERROR(
"sql.sql",
"Table `quest_pool_members` contains no entries at index {} for quest pool {}. Index removed.", i, pool.
poolId);
198 accountedFor.insert(member[0]);
203 for (
auto it = member.begin(); (++it) != member.end();)
206 bool otherStatus = (itOther != pool.
activeQuests.end());
207 if (status != otherStatus)
208 TC_LOG_WARN(
"sql.sql",
"Table `pool_quest_save` {} quest {} (in pool {}, index {}) saved, but its index is{} active (because quest {} is{} in the table). Set quest {} to {}active.", (status ?
"does not have" :
"has"), *it, pool.
poolId, i, (status ?
"" :
" not"), member[0], (status ?
"" :
" not"), *it, (status ?
"" :
"in"));
212 accountedFor.insert(*it);
221 TC_LOG_WARN(
"sql.sql",
"Table `pool_quest_save` has saved quest {} for pool {}, but that quest is not part of the pool. Skipped.", quest, pool.
poolId);
229 TC_LOG_ERROR(
"sql.sql",
"Table `pool_quest_save` has {} active members saved for pool {}, which requests {} active members. Pool spawns re-generated.", activeCount, pool.
poolId, pool.
numActive);
241 for (
uint32 quest : member)
246 TC_LOG_ERROR(
"sql.sql",
"Table `quest_pool_members` lists quest {} as member of pool {}, but it is already a member of pool {}. Skipped.", quest, pool.
poolId, ref->
poolId);
273 auto lambda = [poolId](
QuestPool const& p) {
return (p.poolId == poolId); };
292 return (it->second->activeQuests.find(questId) != it->second->activeQuests.end());
@ CHAR_INS_POOL_QUEST_SAVE
@ CHAR_DEL_POOL_QUEST_SAVE
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
#define TC_LOG_WARN(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
#define TC_LOG_INFO(filterType__,...)
static void RegeneratePool(QuestPool &pool)
static void SaveToDB(QuestPool const &pool, CharacterDatabaseTransaction trans)
uint32 urand(uint32 min, uint32 max)
if(posix_memalign(&__mallocedMemory, __align, __size)) return NULL
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Class used to access individual fields of database query result.
void setUInt32(const uint8 index, const uint32 value)
std::vector< QuestPool > _dailyPools
std::vector< QuestPool > _weeklyPools
bool IsQuestActive(uint32 questId) const
std::unordered_map< uint32, QuestPool * > _poolLookup
std::vector< QuestPool > _monthlyPools
static QuestPoolMgr * instance()
void Regenerate(std::vector< QuestPool > &pools)
QuestPool const * FindQuestPool(uint32 poolId) const
bool IsDailyOrWeekly() const
std::vector< Member > Members
std::unordered_set< uint32 > activeQuests
std::vector< uint32 > Member