TrinityCore
Loading...
Searching...
No Matches
CharacterDatabaseCleaner.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Common.h"
20#include "DatabaseEnv.h"
21#include "DBCStores.h"
22#include "Log.h"
23#include "SpellInfo.h"
24#include "SpellMgr.h"
25#include "World.h"
26
28{
29 // config to disable
30 if (!sWorld->getBoolConfig(CONFIG_CLEAN_CHARACTER_DB))
31 return;
32
33 TC_LOG_INFO("misc", "Cleaning character database...");
34
35 uint32 oldMSTime = getMSTime();
36
37 // check flags which clean ups are necessary
38 QueryResult result = CharacterDatabase.PQuery("SELECT value FROM worldstates WHERE entry = {}", WS_CLEANING_FLAGS);
39 if (!result)
40 return;
41
42 uint32 flags = (*result)[0].GetUInt32();
43
44 // clean up
47
50
53
56
59
60 // NOTE: In order to have persistentFlags be set in worldstates for the next cleanup,
61 // you need to define them at least once in worldstates.
63 CharacterDatabase.DirectPExecute("UPDATE worldstates SET value = {} WHERE entry = {}", flags, WS_CLEANING_FLAGS);
64
65 sWorld->SetCleaningFlags(flags);
66
67 TC_LOG_INFO("server.loading", ">> Cleaned character database in {} ms", GetMSTimeDiffToNow(oldMSTime));
68}
69
70void CharacterDatabaseCleaner::CheckUnique(char const* column, char const* table, bool (*check)(uint32))
71{
72 QueryResult result = CharacterDatabase.PQuery("SELECT DISTINCT {} FROM {}", column, table);
73 if (!result)
74 {
75 TC_LOG_INFO("misc", "Table {} is empty.", table);
76 return;
77 }
78
79 bool found = false;
80 std::ostringstream ss;
81 do
82 {
83 Field* fields = result->Fetch();
84
85 uint32 id = fields[0].GetUInt32();
86
87 if (!check(id))
88 {
89 if (!found)
90 {
91 ss << "DELETE FROM " << table << " WHERE " << column << " IN (";
92 found = true;
93 }
94 else
95 ss << ',';
96
97 ss << id;
98 }
99 }
100 while (result->NextRow());
101
102 if (found)
103 {
104 ss << ')';
105 CharacterDatabase.Execute(ss.str().c_str());
106 }
107}
108
110{
111 return sAchievementCriteriaStore.LookupEntry(criteria) != nullptr;
112}
113
115{
116 CheckUnique("criteria", "character_achievement_progress", &AchievementProgressCheck);
117}
118
120{
121 return sSkillLineStore.LookupEntry(skill) != nullptr;
122}
123
125{
126 CheckUnique("skill", "character_skills", &SkillCheck);
127}
128
130{
131 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
132 return spellInfo && !spellInfo->HasAttribute(SPELL_ATTR0_CU_IS_TALENT);
133}
134
136{
137 CheckUnique("spell", "character_spell", &SpellCheck);
138}
139
141{
142 TalentEntry const* talentInfo = sTalentStore.LookupEntry(talent_id);
143 if (!talentInfo)
144 return false;
145
146 return sTalentTabStore.LookupEntry(talentInfo->TabID) != nullptr;
147}
148
150{
151 CharacterDatabase.DirectPExecute("DELETE FROM character_talent WHERE talentGroup > {}", MAX_TALENT_GROUPS);
152 CheckUnique("spell", "character_talent", &TalentCheck);
153}
154
156{
157 CharacterDatabase.DirectExecute("DELETE FROM character_queststatus WHERE status = 0");
158}
DBCStorage< AchievementCriteriaEntry > sAchievementCriteriaStore(AchievementCriteriafmt)
DBCStorage< TalentTabEntry > sTalentTabStore(TalentTabEntryfmt)
DBCStorage< SkillLineEntry > sSkillLineStore(SkillLinefmt)
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
uint32_t uint32
Definition Define.h:133
uint16 flags
#define TC_LOG_INFO(filterType__,...)
Definition Log.h:159
#define MAX_TALENT_GROUPS
@ WS_CLEANING_FLAGS
@ SPELL_ATTR0_CU_IS_TALENT
Definition SpellInfo.h:164
#define sSpellMgr
Definition SpellMgr.h:738
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition Timer.h:57
uint32 getMSTime()
Definition Timer.h:33
Class used to access individual fields of database query result.
Definition Field.h:92
uint32 GetUInt32() const
Definition Field.cpp:61
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:375
#define sWorld
Definition World.h:901
@ CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS
Definition World.h:355
@ CONFIG_CLEAN_CHARACTER_DB
Definition World.h:93
TC_GAME_API bool SpellCheck(uint32 spell_id)
TC_GAME_API bool SkillCheck(uint32 skill)
TC_GAME_API void CheckUnique(char const *column, char const *table, bool(*check)(uint32))
TC_GAME_API bool TalentCheck(uint32 talent_id)
TC_GAME_API void CleanCharacterAchievementProgress()
TC_GAME_API bool AchievementProgressCheck(uint32 criteria)