mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Fixed SMSG_TALENTS_INFO packet Fixed talents saving to DB Renamed 'talent spec' to 'talent group' since this name was shadowing character specializations (and new name is correct according to JAM) Enabled loading of MinorTalent.dbc (will be used later) Added additional specialization check in LearnTalent
159 lines
4.6 KiB
C++
159 lines
4.6 KiB
C++
/*
|
|
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
|
|
* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "Common.h"
|
|
#include "AchievementMgr.h"
|
|
#include "CharacterDatabaseCleaner.h"
|
|
#include "World.h"
|
|
#include "Database/DatabaseEnv.h"
|
|
#include "SpellMgr.h"
|
|
#include "DBCStores.h"
|
|
|
|
void CharacterDatabaseCleaner::CleanDatabase()
|
|
{
|
|
// config to disable
|
|
if (!sWorld->getBoolConfig(CONFIG_CLEAN_CHARACTER_DB))
|
|
return;
|
|
|
|
TC_LOG_INFO("misc", "Cleaning character database...");
|
|
|
|
uint32 oldMSTime = getMSTime();
|
|
|
|
// check flags which clean ups are necessary
|
|
QueryResult result = CharacterDatabase.PQuery("SELECT value FROM worldstates WHERE entry = %d", WS_CLEANING_FLAGS);
|
|
if (!result)
|
|
return;
|
|
|
|
uint32 flags = (*result)[0].GetUInt32();
|
|
|
|
// clean up
|
|
if (flags & CLEANING_FLAG_ACHIEVEMENT_PROGRESS)
|
|
CleanCharacterAchievementProgress();
|
|
|
|
if (flags & CLEANING_FLAG_SKILLS)
|
|
CleanCharacterSkills();
|
|
|
|
if (flags & CLEANING_FLAG_SPELLS)
|
|
CleanCharacterSpell();
|
|
|
|
if (flags & CLEANING_FLAG_TALENTS)
|
|
CleanCharacterTalent();
|
|
|
|
if (flags & CLEANING_FLAG_QUESTSTATUS)
|
|
CleanCharacterQuestStatus();
|
|
|
|
// NOTE: In order to have persistentFlags be set in worldstates for the next cleanup,
|
|
// you need to define them at least once in worldstates.
|
|
flags &= sWorld->getIntConfig(CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS);
|
|
CharacterDatabase.DirectPExecute("UPDATE worldstates SET value = %u WHERE entry = %d", flags, WS_CLEANING_FLAGS);
|
|
|
|
sWorld->SetCleaningFlags(flags);
|
|
|
|
TC_LOG_INFO("server.loading", ">> Cleaned character database in %u ms", GetMSTimeDiffToNow(oldMSTime));
|
|
}
|
|
|
|
void CharacterDatabaseCleaner::CheckUnique(const char* column, const char* table, bool (*check)(uint32))
|
|
{
|
|
QueryResult result = CharacterDatabase.PQuery("SELECT DISTINCT %s FROM %s", column, table);
|
|
if (!result)
|
|
{
|
|
TC_LOG_INFO("misc", "Table %s is empty.", table);
|
|
return;
|
|
}
|
|
|
|
bool found = false;
|
|
std::ostringstream ss;
|
|
do
|
|
{
|
|
Field* fields = result->Fetch();
|
|
|
|
uint32 id = fields[0].GetUInt32();
|
|
|
|
if (!check(id))
|
|
{
|
|
if (!found)
|
|
{
|
|
ss << "DELETE FROM " << table << " WHERE " << column << " IN (";
|
|
found = true;
|
|
}
|
|
else
|
|
ss << ',';
|
|
|
|
ss << id;
|
|
}
|
|
}
|
|
while (result->NextRow());
|
|
|
|
if (found)
|
|
{
|
|
ss << ')';
|
|
CharacterDatabase.Execute(ss.str().c_str());
|
|
}
|
|
}
|
|
|
|
bool CharacterDatabaseCleaner::AchievementProgressCheck(uint32 criteria)
|
|
{
|
|
return sAchievementMgr->GetAchievementCriteria(criteria) != nullptr;
|
|
}
|
|
|
|
void CharacterDatabaseCleaner::CleanCharacterAchievementProgress()
|
|
{
|
|
CheckUnique("criteria", "character_achievement_progress", &AchievementProgressCheck);
|
|
}
|
|
|
|
bool CharacterDatabaseCleaner::SkillCheck(uint32 skill)
|
|
{
|
|
return sSkillLineStore.LookupEntry(skill) != nullptr;
|
|
}
|
|
|
|
void CharacterDatabaseCleaner::CleanCharacterSkills()
|
|
{
|
|
CheckUnique("skill", "character_skills", &SkillCheck);
|
|
}
|
|
|
|
bool CharacterDatabaseCleaner::SpellCheck(uint32 spell_id)
|
|
{
|
|
return sSpellMgr->GetSpellInfo(spell_id) && GetTalentBySpellID(spell_id) != nullptr;
|
|
}
|
|
|
|
void CharacterDatabaseCleaner::CleanCharacterSpell()
|
|
{
|
|
CheckUnique("spell", "character_spell", &SpellCheck);
|
|
}
|
|
|
|
bool CharacterDatabaseCleaner::TalentCheck(uint32 talent_id)
|
|
{
|
|
TalentEntry const* talentInfo = sTalentStore.LookupEntry(talent_id);
|
|
if (!talentInfo)
|
|
return false;
|
|
|
|
return sChrSpecializationStore.LookupEntry(talentInfo->SpecID) != nullptr;
|
|
}
|
|
|
|
void CharacterDatabaseCleaner::CleanCharacterTalent()
|
|
{
|
|
CharacterDatabase.DirectPExecute("DELETE FROM character_talent WHERE spec > %u", MAX_TALENT_GROUPS);
|
|
CheckUnique("spell", "character_talent", &TalentCheck);
|
|
}
|
|
|
|
void CharacterDatabaseCleaner::CleanCharacterQuestStatus()
|
|
{
|
|
CharacterDatabase.DirectExecute("DELETE FROM character_queststatus WHERE status = 0");
|
|
}
|
|
|