aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2019-08-01 23:41:45 +0200
committerTreeston <treeston.mmoc@gmail.com>2019-08-01 23:42:14 +0200
commitfedf1f557b2aa1cbb0f4bc722b24afb59cc30855 (patch)
tree257906ea9908c1f154cc943bbd20a31e959e2e99 /src
parent22c5419bf266790801cbeb62a619b2331be064ed (diff)
Core/Chat: Custom channel preservation rewrite. Channel data is now loaded at startup, and written to the DB periodically, instead of both things happening in real time.
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp6
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h3
-rw-r--r--src/server/game/Chat/Channels/Channel.cpp75
-rw-r--r--src/server/game/Chat/Channels/Channel.h18
-rw-r--r--src/server/game/Chat/Channels/ChannelMgr.cpp113
-rw-r--r--src/server/game/Chat/Channels/ChannelMgr.h4
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/World/World.cpp23
-rw-r--r--src/server/game/World/World.h2
-rw-r--r--src/server/worldserver/worldserver.conf.dist7
10 files changed, 162 insertions, 91 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index c7eab8ba321..e924eb907a3 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -226,11 +226,11 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, gender, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH);
// Chat channel handling
- PrepareStatement(CHAR_SEL_CHANNEL, "SELECT name, announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_INS_CHANNEL, "INSERT INTO channels(name, team, lastUsed) VALUES (?, ?, UNIX_TIMESTAMP())", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_CHANNEL, "UPDATE channels SET announce = ?, ownership = ?, password = ?, bannedList = ?, lastUsed = UNIX_TIMESTAMP() WHERE name = ? AND team = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_CHANNEL, "INSERT INTO channels (name, team, announce, ownership, password, bannedList, lastUsed) VALUES (?, ?, ?, ?, ?, ?, UNIX_TIMESTAMP()) "
+ "ON DUPLICATE KEY UPDATE announce=VALUES(announce), ownership=VALUES(ownership), password=VALUES(password), bannedList=VALUES(bannedList), lastUsed=VALUES(lastUsed)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHANNEL_USAGE, "UPDATE channels SET lastUsed = UNIX_TIMESTAMP() WHERE name = ? AND team = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHANNEL_OWNERSHIP, "UPDATE channels SET ownership = ? WHERE name LIKE ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHANNEL, "DELETE FROM channels WHERE name = ? AND team = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_OLD_CHANNELS, "DELETE FROM channels WHERE ownership = 1 AND lastUsed + ? < UNIX_TIMESTAMP()", CONNECTION_ASYNC);
// Equipmentsets
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h
index 2397b620a06..1936708a17d 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
@@ -191,11 +191,10 @@ enum CharacterDatabaseStatements : uint32
CHAR_DEL_GUILD_MEMBER_WITHDRAW,
CHAR_SEL_CHAR_DATA_FOR_GUILD,
- CHAR_SEL_CHANNEL,
- CHAR_INS_CHANNEL,
CHAR_UPD_CHANNEL,
CHAR_UPD_CHANNEL_USAGE,
CHAR_UPD_CHANNEL_OWNERSHIP,
+ CHAR_DEL_CHANNEL,
CHAR_DEL_OLD_CHANNELS,
CHAR_UPD_EQUIP_SET,
diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp
index d9fa3fc054b..d0e31732006 100644
--- a/src/server/game/Chat/Channels/Channel.cpp
+++ b/src/server/game/Chat/Channels/Channel.cpp
@@ -22,6 +22,7 @@
#include "Chat.h"
#include "DatabaseEnv.h"
#include "DBCStores.h"
+#include "GameTime.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "Language.h"
@@ -33,9 +34,10 @@
#include "World.h"
Channel::Channel(uint32 channelId, uint32 team /*= 0*/, AreaTableEntry const* zoneEntry /*= nullptr*/) :
+ _isDirty(false),
+ _nextActivityUpdateTime(0),
_announceEnabled(false), // no join/leave announces
_ownershipEnabled(false), // no ownership handout
- _persistentChannel(false),
_isOwnerInvisible(false),
_channelFlags(CHANNEL_FLAG_GENERAL), // for all built-in channels
_channelId(channelId),
@@ -59,9 +61,10 @@ Channel::Channel(uint32 channelId, uint32 team /*= 0*/, AreaTableEntry const* zo
}
Channel::Channel(std::string const& name, uint32 team /*= 0*/, std::string const& banList) :
+ _isDirty(false),
+ _nextActivityUpdateTime(0),
_announceEnabled(true),
_ownershipEnabled(true),
- _persistentChannel(sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS)),
_isOwnerInvisible(false),
_channelFlags(CHANNEL_FLAG_CUSTOM),
_channelId(0),
@@ -108,9 +111,10 @@ std::string Channel::GetName(LocaleConstant locale /*= DEFAULT_LOCALE*/) const
return result;
}
-void Channel::UpdateChannelInDB() const
+void Channel::UpdateChannelInDB()
{
- if (_persistentChannel)
+ time_t const now = GameTime::GetGameTime();
+ if (_isDirty)
{
std::ostringstream banlist;
for (BannedContainer::const_iterator iter = _bannedStore.begin(); iter != _bannedStore.end(); ++iter)
@@ -119,36 +123,29 @@ void Channel::UpdateChannelInDB() const
std::string banListStr = banlist.str();
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL);
- stmt->setBool(0, _announceEnabled);
- stmt->setBool(1, _ownershipEnabled);
- stmt->setString(2, _channelPassword);
- stmt->setString(3, banListStr);
- stmt->setString(4, _channelName);
- stmt->setUInt32(5, _channelTeam);
+ stmt->setString(0, _channelName);
+ stmt->setUInt32(1, _channelTeam);
+ stmt->setBool(2, _announceEnabled);
+ stmt->setBool(3, _ownershipEnabled);
+ stmt->setString(4, _channelPassword);
+ stmt->setString(5, banListStr);
CharacterDatabase.Execute(stmt);
-
- TC_LOG_DEBUG("chat.system", "Channel(%s) updated in database", _channelName.c_str());
}
-}
-
-void Channel::UpdateChannelUseageInDB() const
-{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL_USAGE);
- stmt->setString(0, _channelName);
- stmt->setUInt32(1, _channelTeam);
- CharacterDatabase.Execute(stmt);
-}
-
-void Channel::CleanOldChannelsInDB()
-{
- if (sWorld->getIntConfig(CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION) > 0)
+ else if (_nextActivityUpdateTime <= now)
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_OLD_CHANNELS);
- stmt->setUInt32(0, sWorld->getIntConfig(CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION) * DAY);
- CharacterDatabase.Execute(stmt);
-
- TC_LOG_DEBUG("chat.system", "Cleaned out unused custom chat channels.");
+ if (!_playersStore.empty())
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL_USAGE);
+ stmt->setString(0, _channelName);
+ stmt->setUInt32(1, _channelTeam);
+ CharacterDatabase.Execute(stmt);
+ }
}
+ else
+ return;
+
+ _isDirty = false;
+ _nextActivityUpdateTime = now + urand(1 * MINUTE, 6 * MINUTE) * std::max(1u, sWorld->getIntConfig(CONFIG_PRESERVE_CUSTOM_CHANNEL_INTERVAL));
}
void Channel::JoinChannel(Player* player, std::string const& pass)
@@ -203,6 +200,8 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
}
bool newChannel = _playersStore.empty();
+ if (newChannel)
+ _nextActivityUpdateTime = 0; // force activity update on next channel tick
PlayerInfo& pinfo = _playersStore[guid];
pinfo.flags = MEMBER_FLAG_NONE;
@@ -217,9 +216,6 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
// Custom channel handling
if (!IsConstant())
{
- // Update last_used timestamp in db
- UpdateChannelUseageInDB();
-
// If the channel has no owner yet and ownership is allowed, set the new owner.
// or if the owner was a GM with .gm visible off
// don't do this if the new player is, too, an invis GM, unless the channel was empty
@@ -271,9 +267,6 @@ void Channel::LeaveChannel(Player* player, bool send)
if (!IsConstant())
{
- // Update last_used timestamp in db
- UpdateChannelUseageInDB();
-
// If the channel owner left and there are players still inside, pick a new owner
// do not pick invisible gm owner unless there are only invisible gms in that channel (rare)
if (changeowner && _ownershipEnabled && !_playersStore.empty())
@@ -344,7 +337,7 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
if (ban && !IsBanned(victim))
{
_bannedStore.insert(victim);
- UpdateChannelInDB();
+ _isDirty = true;
if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL))
{
@@ -409,7 +402,7 @@ void Channel::UnBan(Player const* player, std::string const& badname)
ChannelNameBuilder<PlayerUnbannedAppend> builder(this, appender);
SendToAll(builder);
- UpdateChannelInDB();
+ _isDirty = true;
}
void Channel::Password(Player const* player, std::string const& pass)
@@ -440,7 +433,7 @@ void Channel::Password(Player const* player, std::string const& pass)
ChannelNameBuilder<PasswordChangedAppend> builder(this, appender);
SendToAll(builder);
- UpdateChannelInDB();
+ _isDirty = true;
}
void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bool set)
@@ -681,7 +674,7 @@ void Channel::Announce(Player const* player)
SendToAll(builder);
}
- UpdateChannelInDB();
+ _isDirty = true;
}
void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang) const
@@ -813,7 +806,7 @@ void Channel::SetOwner(ObjectGuid guid, bool exclaim)
SendToAll(ownerBuilder);
}
- UpdateChannelInDB();
+ _isDirty = true;
}
}
diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h
index 534b595ae21..31eb8d6fe21 100644
--- a/src/server/game/Chat/Channels/Channel.h
+++ b/src/server/game/Chat/Channels/Channel.h
@@ -21,6 +21,7 @@
#include "Common.h"
#include "ObjectGuid.h"
+#include <ctime>
#include <map>
#include <unordered_set>
@@ -164,6 +165,10 @@ class TC_GAME_API Channel
bool IsAnnounce() const { return _announceEnabled; }
void SetAnnounce(bool announce) { _announceEnabled = announce; }
+ // will be saved to DB on next channel save interval
+ void SetDirty() { _isDirty = true; }
+ void UpdateChannelInDB();
+
void SetPassword(std::string const& password) { _channelPassword = password; }
bool CheckPassword(std::string const& password) const { return _channelPassword.empty() || (_channelPassword == password); }
@@ -205,7 +210,6 @@ class TC_GAME_API Channel
void JoinNotify(ObjectGuid guid) const; // invisible notify
void LeaveNotify(ObjectGuid guid) const; // invisible notify
void SetOwnership(bool ownership) { _ownershipEnabled = ownership; }
- static void CleanOldChannelsInDB();
private:
@@ -218,11 +222,9 @@ class TC_GAME_API Channel
template<class Builder>
void SendToOne(Builder& builder, ObjectGuid who) const;
- bool IsOn(ObjectGuid who) const { return _playersStore.count(who) != 0; }
- bool IsBanned(ObjectGuid guid) const { return _bannedStore.count(guid) != 0; }
-
- void UpdateChannelInDB() const;
- void UpdateChannelUseageInDB() const;
+ bool IsOn(ObjectGuid who) const { return _playersStore.find(who) != _playersStore.end(); }
+ bool IsBanned(ObjectGuid guid) const { return _bannedStore.find(guid) != _bannedStore.end(); }
+
uint8 GetPlayerFlags(ObjectGuid guid) const
{
@@ -236,9 +238,11 @@ class TC_GAME_API Channel
typedef std::map<ObjectGuid, PlayerInfo> PlayerContainer;
typedef GuidUnorderedSet BannedContainer;
+ bool _isDirty; // whether the channel needs to be saved to DB
+ time_t _nextActivityUpdateTime;
+
bool _announceEnabled; //< Whether we should broadcast a packet whenever a player joins/exits the channel
bool _ownershipEnabled; //< Whether the channel has to maintain an owner
- bool _persistentChannel; //< Whether the channel is saved to DB
bool _isOwnerInvisible; //< Whether the channel is owned by invisible GM, ownership should change to first player that joins channel
uint8 _channelFlags;
diff --git a/src/server/game/Chat/Channels/ChannelMgr.cpp b/src/server/game/Chat/Channels/ChannelMgr.cpp
index ab93f9e396b..5fe43069310 100644
--- a/src/server/game/Chat/Channels/ChannelMgr.cpp
+++ b/src/server/game/Chat/Channels/ChannelMgr.cpp
@@ -34,7 +34,78 @@ ChannelMgr::~ChannelMgr()
delete itr->second;
}
-ChannelMgr* ChannelMgr::forTeam(uint32 team)
+/*static*/ void ChannelMgr::LoadFromDB()
+{
+ if (!sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 custom chat channels. Custom channel saving is disabled.");
+ return;
+ }
+
+ uint32 oldMSTime = getMSTime();
+ if (uint32 days = sWorld->getIntConfig(CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION))
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_OLD_CHANNELS);
+ stmt->setUInt32(0, days * DAY);
+ CharacterDatabase.Execute(stmt);
+ }
+
+ QueryResult result = CharacterDatabase.Query("SELECT name, team, announce, ownership, password, bannedList FROM channels");
+ if (!result)
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 custom chat channels. DB table `channels` is empty.");
+ return;
+ }
+
+ std::vector<std::pair<std::string, uint32>> toDelete;
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+ std::string dbName = fields[0].GetString(); // may be different - channel names are case insensitive
+ uint32 team = fields[1].GetUInt32();
+ bool dbAnnounce = fields[2].GetBool();
+ bool dbOwnership = fields[3].GetBool();
+ std::string dbPass = fields[4].GetString();
+ std::string dbBanned = fields[5].GetString();
+
+ std::wstring channelName;
+ if (!Utf8toWStr(dbName, channelName))
+ {
+ TC_LOG_ERROR("server.loading", "Failed to load custom chat channel '%s' from database - invalid utf8 sequence? Deleted.", dbName.c_str());
+ toDelete.push_back({ dbName, team });
+ continue;
+ }
+
+ ChannelMgr* mgr = forTeam(team);
+ if (!mgr)
+ {
+ TC_LOG_ERROR("server.loading", "Failed to load custom chat channel '%s' from database - invalid team %u. Deleted.", dbName.c_str());
+ toDelete.push_back({ dbName, team });
+ continue;
+ }
+
+ Channel* channel = new Channel(dbName, team, dbBanned);
+ channel->SetAnnounce(dbAnnounce);
+ channel->SetOwnership(dbOwnership);
+ channel->SetPassword(dbPass);
+ ASSERT_NOTNULL(forTeam(team))->_customChannels.emplace(channelName, channel);
+
+ ++count;
+ } while (result->NextRow());
+
+ for (auto pair : toDelete)
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHANNEL);
+ stmt->setString(0, pair.first);
+ stmt->setUInt32(1, pair.second);
+ CharacterDatabase.Execute(stmt);
+ }
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u custom chat channels in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+/*static*/ ChannelMgr* ChannelMgr::forTeam(uint32 team)
{
static ChannelMgr allianceChannelMgr(ALLIANCE);
static ChannelMgr hordeChannelMgr(HORDE);
@@ -74,6 +145,12 @@ Channel* ChannelMgr::GetChannelForPlayerByNamePart(std::string const& namePart,
return nullptr;
}
+void ChannelMgr::SaveToDB()
+{
+ for (auto pair : _customChannels)
+ pair.second->UpdateChannelInDB();
+}
+
Channel* ChannelMgr::GetSystemChannel(uint32 channelId, AreaTableEntry const* zoneEntry)
{
ChatChannelsEntry const* channelEntry = sChatChannelsStore.AssertEntry(channelId);
@@ -105,21 +182,13 @@ Channel* ChannelMgr::CreateCustomChannel(std::string const& name)
return nullptr;
Channel* newChannel = new Channel(name, _team);
-
- if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
- {
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHANNEL);
- stmt->setString(0, name);
- stmt->setUInt32(1, _team);
- CharacterDatabase.Execute(stmt);
- TC_LOG_DEBUG("chat.system", "Channel(%s) saved in database", name.c_str());
- }
+ newChannel->SetDirty();
c = newChannel;
return newChannel;
}
-Channel* ChannelMgr::GetCustomChannel(std::string const& name)
+Channel* ChannelMgr::GetCustomChannel(std::string const& name) const
{
std::wstring channelName;
if (!Utf8toWStr(name, channelName))
@@ -129,28 +198,6 @@ Channel* ChannelMgr::GetCustomChannel(std::string const& name)
auto itr = _customChannels.find(channelName);
if (itr != _customChannels.end())
return itr->second;
- else if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
- {
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHANNEL);
- stmt->setString(0, name);
- stmt->setUInt32(1, _team);
- if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
- {
- Field* fields = result->Fetch();
- std::string dbName = fields[0].GetString(); // may be different - channel names are case insensitive
- bool dbAnnounce = fields[1].GetBool();
- bool dbOwnership = fields[2].GetBool();
- std::string dbPass = fields[3].GetString();
- std::string dbBanned = fields[4].GetString();
-
- Channel* channel = new Channel(dbName, _team, dbBanned);
- channel->SetAnnounce(dbAnnounce);
- channel->SetOwnership(dbOwnership);
- channel->SetPassword(dbPass);
- _customChannels.emplace(channelName, channel);
- return channel;
- }
- }
return nullptr;
}
diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h
index d34e34ae47b..337069a37a1 100644
--- a/src/server/game/Chat/Channels/ChannelMgr.h
+++ b/src/server/game/Chat/Channels/ChannelMgr.h
@@ -38,12 +38,14 @@ class TC_GAME_API ChannelMgr
~ChannelMgr();
public:
+ static void LoadFromDB();
static ChannelMgr* forTeam(uint32 team);
static Channel* GetChannelForPlayerByNamePart(std::string const& namePart, Player* playerSearcher);
+ void SaveToDB();
Channel* GetSystemChannel(uint32 channelId, AreaTableEntry const* zoneEntry = nullptr);
Channel* CreateCustomChannel(std::string const& name);
- Channel* GetCustomChannel(std::string const& name);
+ Channel* GetCustomChannel(std::string const& name) const;
Channel* GetChannel(uint32 channelId, std::string const& name, Player* player, bool pkt = true, AreaTableEntry const* zoneEntry = nullptr) const;
void LeftChannel(std::string const& name);
void LeftChannel(uint32 channelId, AreaTableEntry const* zoneEntry);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 703f8e29beb..0ffc9ba31b4 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -20259,7 +20259,7 @@ void Player::UpdateSpeakTime()
bool Player::CanSpeak() const
{
- return GetSession()->m_muteTime <= time (nullptr);
+ return GetSession()->m_muteTime <= GameTime::GetGameTime();
}
/*********************************************************/
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 973fd3fac26..2e6cd80558a 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -30,7 +30,7 @@
#include "BattlefieldMgr.h"
#include "BattlegroundMgr.h"
#include "CalendarMgr.h"
-#include "Channel.h"
+#include "ChannelMgr.h"
#include "CharacterCache.h"
#include "CharacterDatabaseCleaner.h"
#include "Chat.h"
@@ -679,6 +679,7 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_MAIL_LEVEL_REQ] = sConfigMgr->GetIntDefault("LevelReq.Mail", 1);
m_bool_configs[CONFIG_PRESERVE_CUSTOM_CHANNELS] = sConfigMgr->GetBoolDefault("PreserveCustomChannels", false);
m_int_configs[CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION] = sConfigMgr->GetIntDefault("PreserveCustomChannelDuration", 14);
+ m_int_configs[CONFIG_PRESERVE_CUSTOM_CHANNEL_INTERVAL] = sConfigMgr->GetIntDefault("PreserveCustomChannelInterval", 5);
m_bool_configs[CONFIG_GRID_UNLOAD] = sConfigMgr->GetBoolDefault("GridUnload", true);
m_bool_configs[CONFIG_BASEMAP_LOAD_GRIDS] = sConfigMgr->GetBoolDefault("BaseMapLoadAllGrids", false);
if (m_bool_configs[CONFIG_BASEMAP_LOAD_GRIDS] && m_bool_configs[CONFIG_GRID_UNLOAD])
@@ -2076,6 +2077,8 @@ void World::SetInitialWorldSettings()
m_timers[WUPDATE_WHO_LIST].SetInterval(5 * IN_MILLISECONDS); // update who list cache every 5 seconds
+ m_timers[WUPDATE_CHANNEL_SAVE].SetInterval(getIntConfig(CONFIG_PRESERVE_CUSTOM_CHANNEL_INTERVAL) * MINUTE * IN_MILLISECONDS);
+
//to set mailtimer to return mails every day between 4 and 5 am
//mailtimer is increased when updating auctions
//one second is 1000 -(tested on win system)
@@ -2103,8 +2106,8 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Initialize AuctionHouseBot...");
sAuctionBot->Initialize();
- // Delete all custom channels which haven't been used for PreserveCustomChannelDuration days.
- Channel::CleanOldChannelsInDB();
+ TC_LOG_INFO("server.loading", "Initializing chat channels...");
+ ChannelMgr::LoadFromDB();
TC_LOG_INFO("server.loading", "Initializing Opcodes...");
opcodeTable.Initialize();
@@ -2280,6 +2283,20 @@ void World::Update(uint32 diff)
sWhoListStorageMgr->Update();
}
+ if (m_timers[WUPDATE_CHANNEL_SAVE].Passed())
+ {
+ m_timers[WUPDATE_CHANNEL_SAVE].Reset();
+
+ if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
+ {
+ ChannelMgr* mgr1 = ASSERT_NOTNULL(ChannelMgr::forTeam(ALLIANCE));
+ mgr1->SaveToDB();
+ ChannelMgr* mgr2 = ASSERT_NOTNULL(ChannelMgr::forTeam(HORDE));
+ if (mgr1 != mgr2)
+ mgr2->SaveToDB();
+ }
+ }
+
/// Handle daily quests reset time
if (currentGameTime > m_NextDailyQuestReset)
{
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index a8dd0dfe04f..edf310c408b 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -82,6 +82,7 @@ enum WorldTimers
WUPDATE_PINGDB,
WUPDATE_CHECK_FILECHANGES,
WUPDATE_WHO_LIST,
+ WUPDATE_CHANNEL_SAVE,
WUPDATE_COUNT
};
@@ -343,6 +344,7 @@ enum WorldIntConfigs
CONFIG_MAX_RESULTS_LOOKUP_COMMANDS,
CONFIG_DB_PING_INTERVAL,
CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION,
+ CONFIG_PRESERVE_CUSTOM_CHANNEL_INTERVAL,
CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS,
CONFIG_LFG_OPTIONSMASK,
CONFIG_MAX_INSTANCES_PER_HOUR,
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index d7c8efe1c4d..dc3051a06df 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -1962,6 +1962,13 @@ PartyLevelReq = 1
PreserveCustomChannels = 1
#
+# PreserveCustomChannelInterval
+# Description: Interval (in minutes) at which custom channel data is saved to the database
+# Default: 5 minutes
+
+PreserveCustomChannelInterval = 5
+
+#
# PreserveCustomChannelDuration
# Description: Time (in days) that needs to pass before the customs chat channels get
# cleaned up from the database. Only channels with ownership handout enabled