Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/game/Server/DBCStores.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,18 @@ std::string AcceptableClientBuildsListStr()
return data.str();
}

static uint32 sDBCLoadedBuild = 0; ///< Client build of the DBC files loaded at startup

/**
* @brief Returns the client build of the DBC files loaded at startup.
*
* @return uint32 The loaded DBC build, or 0 before LoadDBCStores has run.
*/
uint32 GetDBCLoadedBuild()
{
return sDBCLoadedBuild;
}

static bool ReadDBCBuildFileText(const std::string& dbc_path, char const* localeName, std::string& text)
{
std::string filename = dbc_path + "component.wow-" + localeName + ".txt";
Expand Down Expand Up @@ -1019,6 +1031,10 @@ void LoadDBCStores(const std::string& dataPath)
exit(1);
}

// Remember the validated build for consumers like the character
// database cleaner (see GetDBCLoadedBuild).
sDBCLoadedBuild = build;

sLog.outString();
sLog.outString(">> Initialized %d data stores", DBCFilesCount);
}
Expand Down
6 changes: 6 additions & 0 deletions src/game/Server/DBCStores.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ bool IsAcceptableClientBuild(uint32 build);
*/
std::string AcceptableClientBuildsListStr();

/**
* Returns the client build of the DBC files loaded at startup,
* or 0 before LoadDBCStores has run.
*/
uint32 GetDBCLoadedBuild();

/**
* This function checks to see if there is a valid locale file (component.wow-<locale>.txt)
* and returns an index to the locale or -1 if not found
Expand Down
52 changes: 46 additions & 6 deletions src/game/Tools/CharacterDatabaseCleaner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
*
* The cleaner uses flags stored in the `saved_variables` table to determine
* which cleanup operations are needed. This allows incremental cleaning
* across server restarts.
* across server restarts. A change of the loaded DBC client build against
* `saved_variables`.`last_cleaned_dbc_build` schedules a full cleanup.
*
* @see CharacterDatabaseCleaner for the cleaner interface
* @see CLEANING_FLAG_* constants for available operations
Expand All @@ -55,8 +56,10 @@
* Performs database cleaning based on configuration and stored flags:
* 1. Checks if cleaning is enabled in config
* 2. Reads cleaning flags from saved_variables table
* 3. Executes appropriate cleanup routines
* 4. Resets cleaning flags when complete
* 3. Schedules a full cleanup when the loaded DBC build differs from
* saved_variables.last_cleaned_dbc_build (DBC data was swapped)
* 4. Executes appropriate cleanup routines
* 5. Resets cleaning flags and records the DBC build when complete
*
* @note Can be disabled via CONFIG_BOOL_CLEAN_CHARACTER_DB
*/
Expand All @@ -68,8 +71,6 @@ void CharacterDatabaseCleaner::CleanDatabase()
return;
}

sLog.outString("Cleaning character database...");

// Check which cleanups are needed
QueryResult* result = CharacterDatabase.PQuery("SELECT `cleaning_flags` FROM `saved_variables`");
if (!result)
Expand All @@ -79,6 +80,35 @@ void CharacterDatabaseCleaner::CleanDatabase()
uint32 flags = (*result)[0].GetUInt32();
delete result;

// Orphaned rows appear when the extracted DBC data is swapped for
// another client build, so a build change schedules a full cleanup.
bool hasBuildColumn = false;
uint32 const dbcBuild = GetDBCLoadedBuild();
result = CharacterDatabase.PQuery("SELECT `last_cleaned_dbc_build` FROM `saved_variables`");
if (result)
{
hasBuildColumn = true;
uint32 lastCleanedBuild = (*result)[0].GetUInt32();
delete result;

if (dbcBuild && lastCleanedBuild != dbcBuild)
{
sLog.outString("DBC build changed (%u -> %u), scheduling character database cleanup.", lastCleanedBuild, dbcBuild);
flags |= CLEANING_FLAG_ALL;
}
}
else
{
sLog.outErrorDb("saved_variables.last_cleaned_dbc_build is missing, DBC build-change cleanup disabled. Please apply the character database updates.");
}

if (!flags)
{
return;
}

sLog.outString("Cleaning character database...");

// clean up
if (flags & CLEANING_FLAG_ACHIEVEMENT_PROGRESS)
{
Expand All @@ -98,7 +128,17 @@ void CharacterDatabaseCleaner::CleanDatabase()
{
CleanCharacterTalent();
}
CharacterDatabase.Execute("UPDATE `saved_variables` SET `cleaning_flags` = 0");

// Only reset the flags and record the build after a completed run so
// an interrupted cleanup is retried on the next startup.
if (hasBuildColumn)
{
CharacterDatabase.PExecute("UPDATE `saved_variables` SET `cleaning_flags` = 0, `last_cleaned_dbc_build` = %u", dbcBuild);
}
else
{
CharacterDatabase.Execute("UPDATE `saved_variables` SET `cleaning_flags` = 0");
}
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/game/Tools/CharacterDatabaseCleaner.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ namespace CharacterDatabaseCleaner
CLEANING_FLAG_ACHIEVEMENT_PROGRESS = 0x1, ///< Clean Achievements
CLEANING_FLAG_SKILLS = 0x2, ///< Clean skills
CLEANING_FLAG_SPELLS = 0x4, ///< Clean spells
CLEANING_FLAG_TALENTS = 0x8 ///< Clean Talents
CLEANING_FLAG_TALENTS = 0x8, ///< Clean Talents
CLEANING_FLAG_ALL = 0xF ///< All cleanup categories
};

/**
Expand Down
2 changes: 2 additions & 0 deletions src/mangosd/mangosd.conf.dist.in
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ BindIP = "0.0.0.0"
#
# CleanCharacterDB
# Perform character db cleanups on start up
# Cleanups run when the loaded DBC client build changes or when
# cleaning_flags is set manually in the saved_variables table
# Default: 1 (Enable)
# 0 (Disabled)
#
Expand Down
4 changes: 2 additions & 2 deletions src/shared/revision_data.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@

#define CHAR_DB_VERSION_NR "22"
#define CHAR_DB_STRUCTURE_NR "3"
#define CHAR_DB_CONTENT_NR "2"
#define CHAR_DB_UPDATE_DESCRIPT "Add_Quest_Tracker_Table"
#define CHAR_DB_CONTENT_NR "3"
#define CHAR_DB_UPDATE_DESCRIPT "Add_Last_Cleaned_DBC_Build"

#define WORLD_DB_VERSION_NR "22"
#define WORLD_DB_STRUCTURE_NR "5"
Expand Down
Loading