TrinityCore
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"
19#include "CriteriaHandler.h"
21#include "DatabaseEnv.h"
22#include "DB2Stores.h"
23#include "Log.h"
24#include "World.h"
25#include "SpellMgr.h"
26#include "SpellInfo.h"
27#include <sstream>
28
30{
31 // config to disable
32 if (!sWorld->getBoolConfig(CONFIG_CLEAN_CHARACTER_DB))
33 return;
34
35 TC_LOG_INFO("misc", "Cleaning character database...");
36
37 uint32 oldMSTime = getMSTime();
38
40
41 // clean up
44
47
50
53
56
57 // NOTE: In order to have persistentFlags be set in worldstates for the next cleanup,
58 // you need to define them at least once in worldstates.
60 sWorld->SetPersistentWorldVariable(World::CharacterDatabaseCleaningFlagsVarId, flags);
61
62 sWorld->SetCleaningFlags(flags);
63
64 TC_LOG_INFO("server.loading", ">> Cleaned character database in {} ms", GetMSTimeDiffToNow(oldMSTime));
65}
66
67void CharacterDatabaseCleaner::CheckUnique(char const* column, char const* table, bool (*check)(uint32))
68{
69 QueryResult result = CharacterDatabase.PQuery("SELECT DISTINCT {} FROM {}", column, table);
70 if (!result)
71 {
72 TC_LOG_INFO("misc", "Table {} is empty.", table);
73 return;
74 }
75
76 bool found = false;
77 std::ostringstream ss;
78 do
79 {
80 Field* fields = result->Fetch();
81
82 uint32 id = fields[0].GetUInt32();
83
84 if (!check(id))
85 {
86 if (!found)
87 {
88 ss << "DELETE FROM " << table << " WHERE " << column << " IN (";
89 found = true;
90 }
91 else
92 ss << ',';
93
94 ss << id;
95 }
96 }
97 while (result->NextRow());
98
99 if (found)
100 {
101 ss << ')';
102 CharacterDatabase.Execute(ss.str().c_str());
103 }
104}
105
107{
108 return sCriteriaMgr->GetCriteria(criteria) != nullptr;
109}
110
112{
113 CheckUnique("criteria", "character_achievement_progress", &AchievementProgressCheck);
114}
115
117{
118 return sSkillLineStore.LookupEntry(skill) != nullptr;
119}
120
122{
123 CheckUnique("skill", "character_skills", &SkillCheck);
124}
125
127{
128 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id, DIFFICULTY_NONE);
129 return spellInfo && !spellInfo->HasAttribute(SPELL_ATTR0_CU_IS_TALENT);
130}
131
133{
134 CheckUnique("spell", "character_spell", &SpellCheck);
135}
136
138{
139 TalentEntry const* talentInfo = sTalentStore.LookupEntry(talent_id);
140 if (!talentInfo)
141 return false;
142
143 return sChrSpecializationStore.LookupEntry(talentInfo->SpecID) != nullptr;
144}
145
147{
148 CharacterDatabase.DirectPExecute("DELETE FROM character_talent WHERE talentGroup > {}", MAX_SPECIALIZATIONS);
149 CheckUnique("talentId", "character_talent", &TalentCheck);
150}
151
153{
154 CharacterDatabase.DirectExecute("DELETE FROM character_queststatus WHERE status = 0");
155}
#define sCriteriaMgr
DB2Storage< SkillLineEntry > sSkillLineStore("SkillLine.db2", &SkillLineLoadInfo::Instance)
DB2Storage< ChrSpecializationEntry > sChrSpecializationStore("ChrSpecialization.db2", &ChrSpecializationLoadInfo::Instance)
DB2Storage< TalentEntry > sTalentStore("Talent.db2", &TalentLoadInfo::Instance)
@ DIFFICULTY_NONE
Definition: DBCEnums.h:874
std::shared_ptr< ResultSet > QueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
uint32_t uint32
Definition: Define.h:142
uint16 flags
Definition: DisableMgr.cpp:49
#define TC_LOG_INFO(filterType__,...)
Definition: Log.h:159
#define MAX_SPECIALIZATIONS
@ SPELL_ATTR0_CU_IS_TALENT
Definition: SpellInfo.h:171
#define sSpellMgr
Definition: SpellMgr.h:849
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:90
uint32 GetUInt32() const
Definition: Field.cpp:62
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:449
static PersistentWorldVariable const CharacterDatabaseCleaningFlagsVarId
Definition: World.h:728
#define sWorld
Definition: World.h:931
@ CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS
Definition: World.h:380
@ CONFIG_CLEAN_CHARACTER_DB
Definition: World.h:106
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 void CleanCharacterQuestStatus()
TC_GAME_API bool TalentCheck(uint32 talent_id)
TC_GAME_API void CleanCharacterAchievementProgress()
TC_GAME_API bool AchievementProgressCheck(uint32 criteria)