Skip to content
Open
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
23 changes: 23 additions & 0 deletions sql/migrations/20241108102245_characters.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
DROP PROCEDURE IF EXISTS add_migration;
DELIMITER ??
CREATE PROCEDURE `add_migration`()
BEGIN
DECLARE v INT DEFAULT 1;
SET v = (SELECT COUNT(*) FROM `migrations` WHERE `id`='20241108102245');
IF v = 0 THEN
INSERT INTO `migrations` VALUES ('20241108102245');
-- Add your query below.

DROP TABLE IF EXISTS `world_persistent_variables`;
CREATE TABLE `world_persistent_variables` (
`index` int(10) unsigned NOT NULL DEFAULT 0,
`value` int(10) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`index`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='War Effort, Stranglethorn Vale Fishing, ...';

-- End of migration.
END IF;
END??
DELIMITER ;
CALL add_migration();
DROP PROCEDURE IF EXISTS add_migration;
19 changes: 19 additions & 0 deletions sql/migrations/20241108102245_world.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
DROP PROCEDURE IF EXISTS add_migration;
DELIMITER ??
CREATE PROCEDURE `add_migration`()
BEGIN
DECLARE v INT DEFAULT 1;
SET v = (SELECT COUNT(*) FROM `migrations` WHERE `id`='20241108102245');
IF v = 0 THEN
INSERT INTO `migrations` VALUES ('20241108102245');
-- Add your query below.

-- Moved to characters db (world_persistent_variables)
DROP TABLE IF EXISTS `variables`;

-- End of migration.
END IF;
END??
DELIMITER ;
CALL add_migration();
DROP PROCEDURE IF EXISTS add_migration;
2 changes: 1 addition & 1 deletion src/game/Commands/ServerCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1890,7 +1890,7 @@ bool ChatHandler::HandleReloadPetitions(char*)
bool ChatHandler::HandleReloadVariablesCommand(char*)
{
sObjectMgr.LoadSavedVariable();
SendSysMessage("Table `variables` has been reloaded.");
SendSysMessage("Table `world_persistent_variables` has been reloaded.");
return true;
}

Expand Down
112 changes: 38 additions & 74 deletions src/game/ObjectMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,108 +541,71 @@ void ObjectMgr::SetPlayerWorldMask(uint64 const guid, uint32 newWorldMask)

uint32 ObjectMgr::GetSavedVariable(uint32 index, uint32 defaultValue, bool* exist)
{
SavedVariablesVector::iterator it;
for (it = m_SavedVariables.begin(); it != m_SavedVariables.end(); ++it)
auto it = m_SavedVariables.find(index);
if (it != m_SavedVariables.end())
{
if (it->uiIndex == index)
{
if (exist)
(*exist) = true;
return it->uiValue;
}
if (exist)
*exist = true;
return it->second.uiValue;
}

if (exist)
(*exist) = false;
*exist = false;
return defaultValue;
}

SavedVariable& ObjectMgr::_InsertVariable(uint32 index, uint32 value, bool saved)
void ObjectMgr::_SaveVariable(uint32 index, SavedVariable& toSave)
{
SavedVariable tmp;
tmp.uiIndex = index;
tmp.uiValue = value;
tmp.bSavedInDb = saved;

m_SavedVariables.push_back(tmp);
return m_SavedVariables[m_SavedVariables.size()-1];
}

void ObjectMgr::_SaveVariable(SavedVariable const& toSave)
{
// Must do this in a transaction, else if worker threads > 1 we could do one before the other
// when order is important...
WorldDatabase.BeginTransaction();
WorldDatabase.PExecute("DELETE FROM `variables` WHERE `index` = %u", toSave.uiIndex);
WorldDatabase.PExecute("INSERT INTO `variables` (`index`, `value`) VALUES (%u, %u)", toSave.uiIndex, toSave.uiValue);
WorldDatabase.CommitTransaction();
CharacterDatabase.PExecute("REPLACE INTO `world_persistent_variables` (`index`, `value`) VALUES (%u, %u)", index, toSave.uiValue);
toSave.bSavedInDb = true;
}

void ObjectMgr::InitSavedVariable(uint32 index, uint32 value)
{
SavedVariablesVector::iterator it;
// Already registered?
for (it = m_SavedVariables.begin(); it != m_SavedVariables.end(); ++it)
if (it->uiIndex == index)
return;

// If we are there, it means that the variable does not exist.
SavedVariable& variable = _InsertVariable(index, value, true);
_SaveVariable(variable);
// Only insert if not already registered
auto result = m_SavedVariables.emplace(index, SavedVariable{value, false});
if (result.second)
_SaveVariable(index, result.first->second);
}

void ObjectMgr::SetSavedVariable(uint32 index, uint32 value, bool autoSave)
{
for (auto& itr : m_SavedVariables)
{
if (itr.uiIndex == index)
{
// If the value has not changed.
if (itr.uiValue == value)
return;
auto it = m_SavedVariables.find(index);

itr.uiValue = value;
if (autoSave)
_SaveVariable(itr);
else
itr.bSavedInDb = false;
if (it != m_SavedVariables.end())
{
// If the value has not changed.
if (it->second.uiValue == value)
return;
}

it->second.uiValue = value;
if (autoSave)
_SaveVariable(index, it->second);
else
it->second.bSavedInDb = false;
return;
}
// If we are here, it means that the variable does not exist.
SavedVariable& variable = _InsertVariable(index, value, autoSave);

// Variable does not exist yet, create it.
auto& variable = m_SavedVariables[index] = {value, autoSave};
if (autoSave)
_SaveVariable(variable);
_SaveVariable(index, variable);
}

void ObjectMgr::LoadVariable(uint32 index, uint32* variable, uint32 defaultValue, uint32 maxValue, uint32 minValue)
{
bool inIndex = false;
(*variable) = GetSavedVariable(index, defaultValue, &inIndex);
uint32 originalValue = (*variable);
if (maxValue != 0 && (*variable) > maxValue)
(*variable) = defaultValue;
if ((*variable) < minValue)
(*variable) = defaultValue;
if (!inIndex)
_InsertVariable(index, (*variable), true);
if (originalValue != (*variable))
SetSavedVariable(index, (*variable), true);
}
void ObjectMgr::SaveVariables()
{
SavedVariablesVector::iterator it;
for (it = m_SavedVariables.begin(); it != m_SavedVariables.end(); ++it)
for (auto& it : m_SavedVariables)
{
if (!it->bSavedInDb)
_SaveVariable(*it);
if (!it.second.bSavedInDb)
_SaveVariable(it.first, it.second);
}
}

void ObjectMgr::LoadSavedVariable()
{
m_SavedVariables.clear();

std::unique_ptr<QueryResult> result(WorldDatabase.Query("SELECT `index`, `value` FROM `variables`"));
std::unique_ptr<QueryResult> result(CharacterDatabase.Query("SELECT `index`, `value` FROM `world_persistent_variables`"));

uint32 total_count = 0;

Expand All @@ -652,23 +615,24 @@ void ObjectMgr::LoadSavedVariable()
bar.step();

sLog.Out(LOG_BASIC, LOG_LVL_MINIMAL, "");
sLog.Out(LOG_BASIC, LOG_LVL_MINIMAL, ">> Loaded %u saved variables", total_count);
sLog.Out(LOG_BASIC, LOG_LVL_MINIMAL, ">> Loaded %u world persistent variables", total_count);
return;
}

m_SavedVariables.reserve(result->GetRowCount());
BarGoLink bar(result->GetRowCount());

do
{
bar.step();
Field* fields = result->Fetch();
_InsertVariable(fields[0].GetUInt32(), fields[1].GetUInt32(), true);
m_SavedVariables.emplace(fields[0].GetUInt32(), SavedVariable{fields[1].GetUInt32(), true});
++total_count;
}
while (result->NextRow());

sLog.Out(LOG_BASIC, LOG_LVL_MINIMAL, "");
sLog.Out(LOG_BASIC, LOG_LVL_MINIMAL, ">> Loaded %u saved variables", total_count);
sLog.Out(LOG_BASIC, LOG_LVL_MINIMAL, ">> Loaded %u world persistent variables", total_count);
}

// Caching player data
Expand Down
9 changes: 3 additions & 6 deletions src/game/ObjectMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,11 +434,10 @@ class IdGenerator

struct SavedVariable
{
uint32 uiIndex;
uint32 uiValue;
bool bSavedInDb;
};
typedef std::vector<SavedVariable> SavedVariablesVector;
typedef std::unordered_map<uint32 /*index*/, SavedVariable> SavedVariablesMap;

struct PlayerCacheData
{
Expand Down Expand Up @@ -1316,17 +1315,15 @@ class ObjectMgr
std::map<uint32, uint32> m_PlayerPhases;

// Saving Variables
SavedVariable& _InsertVariable(uint32 index, uint32 value, bool saved);
void _SaveVariable(SavedVariable const& toSave);
void _SaveVariable(uint32 index, SavedVariable& toSave);

void InitSavedVariable(uint32 index, uint32 value);
uint32 GetSavedVariable(uint32 index, uint32 defaultValue = 0, bool* exist = nullptr);
void SetSavedVariable(uint32 index, uint32 value, bool SaveToDb = false);
void LoadVariable(uint32 index, uint32* variable, uint32 defaultValue, uint32 maxValue=0, uint32 minValue=0);

void LoadSavedVariable();
void SaveVariables();
SavedVariablesVector m_SavedVariables;
SavedVariablesMap m_SavedVariables;

// Caching Player Data
void LoadPlayerCacheData(uint32 lowGuid = 0);
Expand Down
4 changes: 2 additions & 2 deletions src/game/World.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1340,8 +1340,8 @@ void World::SetInitialWorldSettings()
sLog.Out(LOG_BASIC, LOG_LVL_MINIMAL, "");
sInstanceStatistics.LoadFromDB();

// Chargements des variables (necessaire pour le OutdoorJcJ)
sLog.Out(LOG_BASIC, LOG_LVL_MINIMAL, "Loading saved variables ...");
// Loads world persistent variables (War Effort, Stranglethorn Vale Fishing, ...)
sLog.Out(LOG_BASIC, LOG_LVL_MINIMAL, "Loading world_persistent_variables...");
sObjectMgr.LoadSavedVariable();


Expand Down