PageRenderTime 76ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 1ms

/src/server/game/World/World.cpp

https://gitlab.com/IlluminatiCore/IlluminatiCore
C++ | 3320 lines | 2456 code | 615 blank | 249 comment | 415 complexity | 6c2eeb98ac9178a83534f1e962231a9b MD5 | raw file
Possible License(s): GPL-2.0, BSD-2-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
  3. * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but WITHOUT
  11. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. * more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /** \file
  19. \ingroup world
  20. */
  21. #include "World.h"
  22. #include "AchievementMgr.h"
  23. #include "ArenaTeamMgr.h"
  24. #include "AuctionHouseBot.h"
  25. #include "AuctionHouseMgr.h"
  26. #include "BattlefieldMgr.h"
  27. #include "BattlegroundMgr.h"
  28. #include "CalendarMgr.h"
  29. #include "Channel.h"
  30. #include "CharacterDatabaseCleaner.h"
  31. #include "Chat.h"
  32. #include "Config.h"
  33. #include "CreatureAIRegistry.h"
  34. #include "CreatureGroups.h"
  35. #include "CreatureTextMgr.h"
  36. #include "DatabaseEnv.h"
  37. #include "DisableMgr.h"
  38. #include "GameEventMgr.h"
  39. #include "GridNotifiersImpl.h"
  40. #include "GroupMgr.h"
  41. #include "GuildFinderMgr.h"
  42. #include "InstanceSaveMgr.h"
  43. #include "Language.h"
  44. #include "LFGMgr.h"
  45. #include "MapManager.h"
  46. #include "Memory.h"
  47. #include "MMapFactory.h"
  48. #include "ObjectMgr.h"
  49. #include "OutdoorPvPMgr.h"
  50. #include "Player.h"
  51. #include "PoolMgr.h"
  52. #include "ScriptMgr.h"
  53. #include "SkillDiscovery.h"
  54. #include "SkillExtraItems.h"
  55. #include "SmartAI.h"
  56. #include "SystemConfig.h"
  57. #include "TicketMgr.h"
  58. #include "TransportMgr.h"
  59. #include "Unit.h"
  60. #include "VMapFactory.h"
  61. #include "WardenCheckMgr.h"
  62. #include "WaypointMovementGenerator.h"
  63. #include "WeatherMgr.h"
  64. #include "WorldSession.h"
  65. std::atomic<bool> World::m_stopEvent(false);
  66. uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE;
  67. std::atomic<uint32> World::m_worldLoopCounter(0);
  68. float World::m_MaxVisibleDistanceOnContinents = DEFAULT_VISIBILITY_DISTANCE;
  69. float World::m_MaxVisibleDistanceInInstances = DEFAULT_VISIBILITY_INSTANCE;
  70. float World::m_MaxVisibleDistanceInBGArenas = DEFAULT_VISIBILITY_BGARENAS;
  71. int32 World::m_visibility_notify_periodOnContinents = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
  72. int32 World::m_visibility_notify_periodInInstances = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
  73. int32 World::m_visibility_notify_periodInBGArenas = DEFAULT_VISIBILITY_NOTIFY_PERIOD;
  74. /// World constructor
  75. World::World()
  76. {
  77. m_playerLimit = 0;
  78. m_allowedSecurityLevel = SEC_PLAYER;
  79. m_allowMovement = true;
  80. m_ShutdownMask = 0;
  81. m_ShutdownTimer = 0;
  82. m_gameTime = time(NULL);
  83. m_startTime = m_gameTime;
  84. m_maxActiveSessionCount = 0;
  85. m_maxQueuedSessionCount = 0;
  86. m_PlayerCount = 0;
  87. m_MaxPlayerCount = 0;
  88. m_NextDailyQuestReset = 0;
  89. m_NextWeeklyQuestReset = 0;
  90. m_NextMonthlyQuestReset = 0;
  91. m_NextRandomBGReset = 0;
  92. m_NextGuildReset = 0;
  93. m_NextCurrencyReset = 0;
  94. m_defaultDbcLocale = LOCALE_enUS;
  95. m_availableDbcLocaleMask = 0;
  96. mail_timer = 0;
  97. mail_timer_expires = 0;
  98. m_updateTime = 0;
  99. m_updateTimeSum = 0;
  100. m_updateTimeCount = 0;
  101. m_currentTime = 0;
  102. m_isClosed = false;
  103. m_CleaningFlags = 0;
  104. memset(rate_values, 0, sizeof(rate_values));
  105. memset(m_int_configs, 0, sizeof(m_int_configs));
  106. memset(m_bool_configs, 0, sizeof(m_bool_configs));
  107. memset(m_float_configs, 0, sizeof(m_float_configs));
  108. }
  109. /// World destructor
  110. World::~World()
  111. {
  112. ///- Empty the kicked session set
  113. while (!m_sessions.empty())
  114. {
  115. // not remove from queue, prevent loading new sessions
  116. delete m_sessions.begin()->second;
  117. m_sessions.erase(m_sessions.begin());
  118. }
  119. CliCommandHolder* command = NULL;
  120. while (cliCmdQueue.next(command))
  121. delete command;
  122. VMAP::VMapFactory::clear();
  123. MMAP::MMapFactory::clear();
  124. /// @todo free addSessQueue
  125. }
  126. /// Find a player in a specified zone
  127. Player* World::FindPlayerInZone(uint32 zone)
  128. {
  129. ///- circle through active sessions and return the first player found in the zone
  130. SessionMap::const_iterator itr;
  131. for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
  132. {
  133. if (!itr->second)
  134. continue;
  135. Player* player = itr->second->GetPlayer();
  136. if (!player)
  137. continue;
  138. if (player->IsInWorld() && player->GetZoneId() == zone)
  139. return player;
  140. }
  141. return NULL;
  142. }
  143. bool World::IsClosed() const
  144. {
  145. return m_isClosed;
  146. }
  147. void World::SetClosed(bool val)
  148. {
  149. m_isClosed = val;
  150. // Invert the value, for simplicity for scripters.
  151. sScriptMgr->OnOpenStateChange(!val);
  152. }
  153. void World::SetMotd(const std::string& motd)
  154. {
  155. m_motd = motd;
  156. sScriptMgr->OnMotdChange(m_motd);
  157. }
  158. const char* World::GetMotd() const
  159. {
  160. return m_motd.c_str();
  161. }
  162. /// Find a session by its id
  163. WorldSession* World::FindSession(uint32 id) const
  164. {
  165. SessionMap::const_iterator itr = m_sessions.find(id);
  166. if (itr != m_sessions.end())
  167. return itr->second; // also can return NULL for kicked session
  168. else
  169. return NULL;
  170. }
  171. /// Remove a given session
  172. bool World::RemoveSession(uint32 id)
  173. {
  174. ///- Find the session, kick the user, but we can't delete session at this moment to prevent iterator invalidation
  175. SessionMap::const_iterator itr = m_sessions.find(id);
  176. if (itr != m_sessions.end() && itr->second)
  177. {
  178. if (itr->second->PlayerLoading())
  179. return false;
  180. itr->second->KickPlayer();
  181. }
  182. return true;
  183. }
  184. void World::AddSession(WorldSession* s)
  185. {
  186. addSessQueue.add(s);
  187. }
  188. void World::AddSession_(WorldSession* s)
  189. {
  190. ASSERT(s);
  191. //NOTE - Still there is race condition in WorldSession* being used in the Sockets
  192. ///- kick already loaded player with same account (if any) and remove session
  193. ///- if player is in loading and want to load again, return
  194. if (!RemoveSession (s->GetAccountId()))
  195. {
  196. s->KickPlayer();
  197. delete s; // session not added yet in session list, so not listed in queue
  198. return;
  199. }
  200. // decrease session counts only at not reconnection case
  201. bool decrease_session = true;
  202. // if session already exist, prepare to it deleting at next world update
  203. // NOTE - KickPlayer() should be called on "old" in RemoveSession()
  204. {
  205. SessionMap::const_iterator old = m_sessions.find(s->GetAccountId());
  206. if (old != m_sessions.end())
  207. {
  208. // prevent decrease sessions count if session queued
  209. if (RemoveQueuedPlayer(old->second))
  210. decrease_session = false;
  211. // not remove replaced session form queue if listed
  212. delete old->second;
  213. }
  214. }
  215. m_sessions[s->GetAccountId()] = s;
  216. uint32 Sessions = GetActiveAndQueuedSessionCount();
  217. uint32 pLimit = GetPlayerAmountLimit();
  218. uint32 QueueSize = GetQueuedSessionCount(); //number of players in the queue
  219. //so we don't count the user trying to
  220. //login as a session and queue the socket that we are using
  221. if (decrease_session)
  222. --Sessions;
  223. if (pLimit > 0 && Sessions >= pLimit && !s->HasPermission(rbac::RBAC_PERM_SKIP_QUEUE) && !HasRecentlyDisconnected(s))
  224. {
  225. AddQueuedPlayer(s);
  226. UpdateMaxSessionCounters();
  227. TC_LOG_INFO("misc", "PlayerQueue: Account id %u is in Queue Position (%u).", s->GetAccountId(), ++QueueSize);
  228. return;
  229. }
  230. s->SendAuthResponse(AUTH_OK, false);
  231. s->SendAddonsInfo();
  232. s->SendClientCacheVersion(sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION));
  233. s->SendTutorialsData();
  234. UpdateMaxSessionCounters();
  235. // Updates the population
  236. if (pLimit > 0)
  237. {
  238. float popu = (float)GetActiveSessionCount(); // updated number of users on the server
  239. popu /= pLimit;
  240. popu *= 2;
  241. TC_LOG_INFO("misc", "Server Population (%f).", popu);
  242. }
  243. }
  244. bool World::HasRecentlyDisconnected(WorldSession* session)
  245. {
  246. if (!session)
  247. return false;
  248. if (uint32 tolerance = getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE))
  249. {
  250. for (DisconnectMap::iterator i = m_disconnects.begin(); i != m_disconnects.end();)
  251. {
  252. if (difftime(i->second, time(NULL)) < tolerance)
  253. {
  254. if (i->first == session->GetAccountId())
  255. return true;
  256. ++i;
  257. }
  258. else
  259. m_disconnects.erase(i++);
  260. }
  261. }
  262. return false;
  263. }
  264. int32 World::GetQueuePos(WorldSession* sess)
  265. {
  266. uint32 position = 1;
  267. for (Queue::const_iterator iter = m_QueuedPlayer.begin(); iter != m_QueuedPlayer.end(); ++iter, ++position)
  268. if ((*iter) == sess)
  269. return position;
  270. return 0;
  271. }
  272. void World::AddQueuedPlayer(WorldSession* sess)
  273. {
  274. sess->SetInQueue(true);
  275. m_QueuedPlayer.push_back(sess);
  276. // The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
  277. sess->SendAuthResponse(AUTH_WAIT_QUEUE, true, GetQueuePos(sess));
  278. }
  279. bool World::RemoveQueuedPlayer(WorldSession* sess)
  280. {
  281. // sessions count including queued to remove (if removed_session set)
  282. uint32 sessions = GetActiveSessionCount();
  283. uint32 position = 1;
  284. Queue::iterator iter = m_QueuedPlayer.begin();
  285. // search to remove and count skipped positions
  286. bool found = false;
  287. for (; iter != m_QueuedPlayer.end(); ++iter, ++position)
  288. {
  289. if (*iter == sess)
  290. {
  291. sess->SetInQueue(false);
  292. sess->ResetTimeOutTime();
  293. iter = m_QueuedPlayer.erase(iter);
  294. found = true; // removing queued session
  295. break;
  296. }
  297. }
  298. // iter point to next socked after removed or end()
  299. // position store position of removed socket and then new position next socket after removed
  300. // if session not queued then we need decrease sessions count
  301. if (!found && sessions)
  302. --sessions;
  303. // accept first in queue
  304. if ((!m_playerLimit || sessions < m_playerLimit) && !m_QueuedPlayer.empty())
  305. {
  306. WorldSession* pop_sess = m_QueuedPlayer.front();
  307. pop_sess->SetInQueue(false);
  308. pop_sess->ResetTimeOutTime();
  309. pop_sess->SendAuthWaitQue(0);
  310. pop_sess->SendAddonsInfo();
  311. pop_sess->SendClientCacheVersion(sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION));
  312. pop_sess->SendAccountDataTimes(GLOBAL_CACHE_MASK);
  313. pop_sess->SendTutorialsData();
  314. m_QueuedPlayer.pop_front();
  315. // update iter to point first queued socket or end() if queue is empty now
  316. iter = m_QueuedPlayer.begin();
  317. position = 1;
  318. }
  319. // update position from iter to end()
  320. // iter point to first not updated socket, position store new position
  321. for (; iter != m_QueuedPlayer.end(); ++iter, ++position)
  322. (*iter)->SendAuthWaitQue(position);
  323. return found;
  324. }
  325. /// Initialize config values
  326. void World::LoadConfigSettings(bool reload)
  327. {
  328. if (reload)
  329. {
  330. std::string configError;
  331. if (!sConfigMgr->Reload(configError))
  332. {
  333. TC_LOG_ERROR("misc", "World settings reload fail: %s.", configError.c_str());
  334. return;
  335. }
  336. sLog->LoadFromConfig();
  337. }
  338. m_defaultDbcLocale = LocaleConstant(sConfigMgr->GetIntDefault("DBC.Locale", 0));
  339. if (m_defaultDbcLocale >= TOTAL_LOCALES)
  340. {
  341. TC_LOG_ERROR("server.loading", "Incorrect DBC.Locale! Must be >= 0 and < %d (set to 0)", TOTAL_LOCALES);
  342. m_defaultDbcLocale = LOCALE_enUS;
  343. }
  344. TC_LOG_INFO("server.loading", "Using %s DBC Locale", localeNames[m_defaultDbcLocale]);
  345. ///- Read the player limit and the Message of the day from the config file
  346. SetPlayerAmountLimit(sConfigMgr->GetIntDefault("PlayerLimit", 100));
  347. SetMotd(sConfigMgr->GetStringDefault("Motd", "Welcome to a Trinity Core Server."));
  348. ///- Read ticket system setting from the config file
  349. m_bool_configs[CONFIG_ALLOW_TICKETS] = sConfigMgr->GetBoolDefault("AllowTickets", true);
  350. ///- Get string for new logins (newly created characters)
  351. SetNewCharString(sConfigMgr->GetStringDefault("PlayerStart.String", ""));
  352. ///- Send server info on login?
  353. m_int_configs[CONFIG_ENABLE_SINFO_LOGIN] = sConfigMgr->GetIntDefault("Server.LoginInfo", 0);
  354. ///- Read all rates from the config file
  355. rate_values[RATE_HEALTH] = sConfigMgr->GetFloatDefault("Rate.Health", 1.0f);
  356. if (rate_values[RATE_HEALTH] < 0)
  357. {
  358. TC_LOG_ERROR("server.loading", "Rate.Health (%f) must be > 0. Using 1 instead.", rate_values[RATE_HEALTH]);
  359. rate_values[RATE_HEALTH] = 1;
  360. }
  361. rate_values[RATE_POWER_MANA] = sConfigMgr->GetFloatDefault("Rate.Mana", 1.0f);
  362. if (rate_values[RATE_POWER_MANA] < 0)
  363. {
  364. TC_LOG_ERROR("server.loading", "Rate.Mana (%f) must be > 0. Using 1 instead.", rate_values[RATE_POWER_MANA]);
  365. rate_values[RATE_POWER_MANA] = 1;
  366. }
  367. rate_values[RATE_POWER_RAGE_INCOME] = sConfigMgr->GetFloatDefault("Rate.Rage.Income", 1.0f);
  368. rate_values[RATE_POWER_RAGE_LOSS] = sConfigMgr->GetFloatDefault("Rate.Rage.Loss", 1.0f);
  369. if (rate_values[RATE_POWER_RAGE_LOSS] < 0)
  370. {
  371. TC_LOG_ERROR("server.loading", "Rate.Rage.Loss (%f) must be > 0. Using 1 instead.", rate_values[RATE_POWER_RAGE_LOSS]);
  372. rate_values[RATE_POWER_RAGE_LOSS] = 1;
  373. }
  374. rate_values[RATE_POWER_RUNICPOWER_INCOME] = sConfigMgr->GetFloatDefault("Rate.RunicPower.Income", 1.0f);
  375. rate_values[RATE_POWER_RUNICPOWER_LOSS] = sConfigMgr->GetFloatDefault("Rate.RunicPower.Loss", 1.0f);
  376. if (rate_values[RATE_POWER_RUNICPOWER_LOSS] < 0)
  377. {
  378. TC_LOG_ERROR("server.loading", "Rate.RunicPower.Loss (%f) must be > 0. Using 1 instead.", rate_values[RATE_POWER_RUNICPOWER_LOSS]);
  379. rate_values[RATE_POWER_RUNICPOWER_LOSS] = 1;
  380. }
  381. rate_values[RATE_POWER_FOCUS] = sConfigMgr->GetFloatDefault("Rate.Focus", 1.0f);
  382. rate_values[RATE_POWER_ENERGY] = sConfigMgr->GetFloatDefault("Rate.Energy", 1.0f);
  383. rate_values[RATE_SKILL_DISCOVERY] = sConfigMgr->GetFloatDefault("Rate.Skill.Discovery", 1.0f);
  384. rate_values[RATE_DROP_ITEM_POOR] = sConfigMgr->GetFloatDefault("Rate.Drop.Item.Poor", 1.0f);
  385. rate_values[RATE_DROP_ITEM_NORMAL] = sConfigMgr->GetFloatDefault("Rate.Drop.Item.Normal", 1.0f);
  386. rate_values[RATE_DROP_ITEM_UNCOMMON] = sConfigMgr->GetFloatDefault("Rate.Drop.Item.Uncommon", 1.0f);
  387. rate_values[RATE_DROP_ITEM_RARE] = sConfigMgr->GetFloatDefault("Rate.Drop.Item.Rare", 1.0f);
  388. rate_values[RATE_DROP_ITEM_EPIC] = sConfigMgr->GetFloatDefault("Rate.Drop.Item.Epic", 1.0f);
  389. rate_values[RATE_DROP_ITEM_LEGENDARY] = sConfigMgr->GetFloatDefault("Rate.Drop.Item.Legendary", 1.0f);
  390. rate_values[RATE_DROP_ITEM_ARTIFACT] = sConfigMgr->GetFloatDefault("Rate.Drop.Item.Artifact", 1.0f);
  391. rate_values[RATE_DROP_ITEM_REFERENCED] = sConfigMgr->GetFloatDefault("Rate.Drop.Item.Referenced", 1.0f);
  392. rate_values[RATE_DROP_ITEM_REFERENCED_AMOUNT] = sConfigMgr->GetFloatDefault("Rate.Drop.Item.ReferencedAmount", 1.0f);
  393. rate_values[RATE_DROP_MONEY] = sConfigMgr->GetFloatDefault("Rate.Drop.Money", 1.0f);
  394. rate_values[RATE_XP_KILL] = sConfigMgr->GetFloatDefault("Rate.XP.Kill", 1.0f);
  395. rate_values[RATE_XP_QUEST] = sConfigMgr->GetFloatDefault("Rate.XP.Quest", 1.0f);
  396. rate_values[RATE_XP_EXPLORE] = sConfigMgr->GetFloatDefault("Rate.XP.Explore", 1.0f);
  397. rate_values[RATE_REPAIRCOST] = sConfigMgr->GetFloatDefault("Rate.RepairCost", 1.0f);
  398. if (rate_values[RATE_REPAIRCOST] < 0.0f)
  399. {
  400. TC_LOG_ERROR("server.loading", "Rate.RepairCost (%f) must be >=0. Using 0.0 instead.", rate_values[RATE_REPAIRCOST]);
  401. rate_values[RATE_REPAIRCOST] = 0.0f;
  402. }
  403. rate_values[RATE_REPUTATION_GAIN] = sConfigMgr->GetFloatDefault("Rate.Reputation.Gain", 1.0f);
  404. rate_values[RATE_REPUTATION_LOWLEVEL_KILL] = sConfigMgr->GetFloatDefault("Rate.Reputation.LowLevel.Kill", 1.0f);
  405. rate_values[RATE_REPUTATION_LOWLEVEL_QUEST] = sConfigMgr->GetFloatDefault("Rate.Reputation.LowLevel.Quest", 1.0f);
  406. rate_values[RATE_REPUTATION_RECRUIT_A_FRIEND_BONUS] = sConfigMgr->GetFloatDefault("Rate.Reputation.RecruitAFriendBonus", 0.1f);
  407. rate_values[RATE_CREATURE_NORMAL_DAMAGE] = sConfigMgr->GetFloatDefault("Rate.Creature.Normal.Damage", 1.0f);
  408. rate_values[RATE_CREATURE_ELITE_ELITE_DAMAGE] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.Elite.Damage", 1.0f);
  409. rate_values[RATE_CREATURE_ELITE_RAREELITE_DAMAGE] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.RAREELITE.Damage", 1.0f);
  410. rate_values[RATE_CREATURE_ELITE_WORLDBOSS_DAMAGE] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.WORLDBOSS.Damage", 1.0f);
  411. rate_values[RATE_CREATURE_ELITE_RARE_DAMAGE] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.RARE.Damage", 1.0f);
  412. rate_values[RATE_CREATURE_NORMAL_HP] = sConfigMgr->GetFloatDefault("Rate.Creature.Normal.HP", 1.0f);
  413. rate_values[RATE_CREATURE_ELITE_ELITE_HP] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.Elite.HP", 1.0f);
  414. rate_values[RATE_CREATURE_ELITE_RAREELITE_HP] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.RAREELITE.HP", 1.0f);
  415. rate_values[RATE_CREATURE_ELITE_WORLDBOSS_HP] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.WORLDBOSS.HP", 1.0f);
  416. rate_values[RATE_CREATURE_ELITE_RARE_HP] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.RARE.HP", 1.0f);
  417. rate_values[RATE_CREATURE_NORMAL_SPELLDAMAGE] = sConfigMgr->GetFloatDefault("Rate.Creature.Normal.SpellDamage", 1.0f);
  418. rate_values[RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.Elite.SpellDamage", 1.0f);
  419. rate_values[RATE_CREATURE_ELITE_RAREELITE_SPELLDAMAGE] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.RAREELITE.SpellDamage", 1.0f);
  420. rate_values[RATE_CREATURE_ELITE_WORLDBOSS_SPELLDAMAGE] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.WORLDBOSS.SpellDamage", 1.0f);
  421. rate_values[RATE_CREATURE_ELITE_RARE_SPELLDAMAGE] = sConfigMgr->GetFloatDefault("Rate.Creature.Elite.RARE.SpellDamage", 1.0f);
  422. rate_values[RATE_CREATURE_AGGRO] = sConfigMgr->GetFloatDefault("Rate.Creature.Aggro", 1.0f);
  423. rate_values[RATE_REST_INGAME] = sConfigMgr->GetFloatDefault("Rate.Rest.InGame", 1.0f);
  424. rate_values[RATE_REST_OFFLINE_IN_TAVERN_OR_CITY] = sConfigMgr->GetFloatDefault("Rate.Rest.Offline.InTavernOrCity", 1.0f);
  425. rate_values[RATE_REST_OFFLINE_IN_WILDERNESS] = sConfigMgr->GetFloatDefault("Rate.Rest.Offline.InWilderness", 1.0f);
  426. rate_values[RATE_DAMAGE_FALL] = sConfigMgr->GetFloatDefault("Rate.Damage.Fall", 1.0f);
  427. rate_values[RATE_AUCTION_TIME] = sConfigMgr->GetFloatDefault("Rate.Auction.Time", 1.0f);
  428. rate_values[RATE_AUCTION_DEPOSIT] = sConfigMgr->GetFloatDefault("Rate.Auction.Deposit", 1.0f);
  429. rate_values[RATE_AUCTION_CUT] = sConfigMgr->GetFloatDefault("Rate.Auction.Cut", 1.0f);
  430. rate_values[RATE_HONOR] = sConfigMgr->GetFloatDefault("Rate.Honor", 1.0f);
  431. rate_values[RATE_INSTANCE_RESET_TIME] = sConfigMgr->GetFloatDefault("Rate.InstanceResetTime", 1.0f);
  432. rate_values[RATE_TALENT] = sConfigMgr->GetFloatDefault("Rate.Talent", 1.0f);
  433. if (rate_values[RATE_TALENT] < 0.0f)
  434. {
  435. TC_LOG_ERROR("server.loading", "Rate.Talent (%f) must be > 0. Using 1 instead.", rate_values[RATE_TALENT]);
  436. rate_values[RATE_TALENT] = 1.0f;
  437. }
  438. rate_values[RATE_MOVESPEED] = sConfigMgr->GetFloatDefault("Rate.MoveSpeed", 1.0f);
  439. if (rate_values[RATE_MOVESPEED] < 0)
  440. {
  441. TC_LOG_ERROR("server.loading", "Rate.MoveSpeed (%f) must be > 0. Using 1 instead.", rate_values[RATE_MOVESPEED]);
  442. rate_values[RATE_MOVESPEED] = 1.0f;
  443. }
  444. for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i) playerBaseMoveSpeed[i] = baseMoveSpeed[i] * rate_values[RATE_MOVESPEED];
  445. rate_values[RATE_CORPSE_DECAY_LOOTED] = sConfigMgr->GetFloatDefault("Rate.Corpse.Decay.Looted", 0.5f);
  446. rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = sConfigMgr->GetFloatDefault("TargetPosRecalculateRange", 1.5f);
  447. if (rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] < CONTACT_DISTANCE)
  448. {
  449. TC_LOG_ERROR("server.loading", "TargetPosRecalculateRange (%f) must be >= %f. Using %f instead.", rate_values[RATE_TARGET_POS_RECALCULATION_RANGE], CONTACT_DISTANCE, CONTACT_DISTANCE);
  450. rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = CONTACT_DISTANCE;
  451. }
  452. else if (rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] > NOMINAL_MELEE_RANGE)
  453. {
  454. TC_LOG_ERROR("server.loading", "TargetPosRecalculateRange (%f) must be <= %f. Using %f instead.",
  455. rate_values[RATE_TARGET_POS_RECALCULATION_RANGE], NOMINAL_MELEE_RANGE, NOMINAL_MELEE_RANGE);
  456. rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = NOMINAL_MELEE_RANGE;
  457. }
  458. rate_values[RATE_DURABILITY_LOSS_ON_DEATH] = sConfigMgr->GetFloatDefault("DurabilityLoss.OnDeath", 10.0f);
  459. if (rate_values[RATE_DURABILITY_LOSS_ON_DEATH] < 0.0f)
  460. {
  461. TC_LOG_ERROR("server.loading", "DurabilityLoss.OnDeath (%f) must be >=0. Using 0.0 instead.", rate_values[RATE_DURABILITY_LOSS_ON_DEATH]);
  462. rate_values[RATE_DURABILITY_LOSS_ON_DEATH] = 0.0f;
  463. }
  464. if (rate_values[RATE_DURABILITY_LOSS_ON_DEATH] > 100.0f)
  465. {
  466. TC_LOG_ERROR("server.loading", "DurabilityLoss.OnDeath (%f) must be <= 100. Using 100.0 instead.", rate_values[RATE_DURABILITY_LOSS_ON_DEATH]);
  467. rate_values[RATE_DURABILITY_LOSS_ON_DEATH] = 0.0f;
  468. }
  469. rate_values[RATE_DURABILITY_LOSS_ON_DEATH] = rate_values[RATE_DURABILITY_LOSS_ON_DEATH] / 100.0f;
  470. rate_values[RATE_DURABILITY_LOSS_DAMAGE] = sConfigMgr->GetFloatDefault("DurabilityLossChance.Damage", 0.5f);
  471. if (rate_values[RATE_DURABILITY_LOSS_DAMAGE] < 0.0f)
  472. {
  473. TC_LOG_ERROR("server.loading", "DurabilityLossChance.Damage (%f) must be >=0. Using 0.0 instead.", rate_values[RATE_DURABILITY_LOSS_DAMAGE]);
  474. rate_values[RATE_DURABILITY_LOSS_DAMAGE] = 0.0f;
  475. }
  476. rate_values[RATE_DURABILITY_LOSS_ABSORB] = sConfigMgr->GetFloatDefault("DurabilityLossChance.Absorb", 0.5f);
  477. if (rate_values[RATE_DURABILITY_LOSS_ABSORB] < 0.0f)
  478. {
  479. TC_LOG_ERROR("server.loading", "DurabilityLossChance.Absorb (%f) must be >=0. Using 0.0 instead.", rate_values[RATE_DURABILITY_LOSS_ABSORB]);
  480. rate_values[RATE_DURABILITY_LOSS_ABSORB] = 0.0f;
  481. }
  482. rate_values[RATE_DURABILITY_LOSS_PARRY] = sConfigMgr->GetFloatDefault("DurabilityLossChance.Parry", 0.05f);
  483. if (rate_values[RATE_DURABILITY_LOSS_PARRY] < 0.0f)
  484. {
  485. TC_LOG_ERROR("server.loading", "DurabilityLossChance.Parry (%f) must be >=0. Using 0.0 instead.", rate_values[RATE_DURABILITY_LOSS_PARRY]);
  486. rate_values[RATE_DURABILITY_LOSS_PARRY] = 0.0f;
  487. }
  488. rate_values[RATE_DURABILITY_LOSS_BLOCK] = sConfigMgr->GetFloatDefault("DurabilityLossChance.Block", 0.05f);
  489. if (rate_values[RATE_DURABILITY_LOSS_BLOCK] < 0.0f)
  490. {
  491. TC_LOG_ERROR("server.loading", "DurabilityLossChance.Block (%f) must be >=0. Using 0.0 instead.", rate_values[RATE_DURABILITY_LOSS_BLOCK]);
  492. rate_values[RATE_DURABILITY_LOSS_BLOCK] = 0.0f;
  493. }
  494. rate_values[RATE_MONEY_QUEST] = sConfigMgr->GetFloatDefault("Rate.Quest.Money.Reward", 1.0f);
  495. if (rate_values[RATE_MONEY_QUEST] < 0.0f)
  496. {
  497. TC_LOG_ERROR("server.loading", "Rate.Quest.Money.Reward (%f) must be >=0. Using 0 instead.", rate_values[RATE_MONEY_QUEST]);
  498. rate_values[RATE_MONEY_QUEST] = 0.0f;
  499. }
  500. rate_values[RATE_MONEY_MAX_LEVEL_QUEST] = sConfigMgr->GetFloatDefault("Rate.Quest.Money.Max.Level.Reward", 1.0f);
  501. if (rate_values[RATE_MONEY_MAX_LEVEL_QUEST] < 0.0f)
  502. {
  503. TC_LOG_ERROR("server.loading", "Rate.Quest.Money.Max.Level.Reward (%f) must be >=0. Using 0 instead.", rate_values[RATE_MONEY_MAX_LEVEL_QUEST]);
  504. rate_values[RATE_MONEY_MAX_LEVEL_QUEST] = 0.0f;
  505. }
  506. ///- Read other configuration items from the config file
  507. m_bool_configs[CONFIG_DURABILITY_LOSS_IN_PVP] = sConfigMgr->GetBoolDefault("DurabilityLoss.InPvP", false);
  508. m_int_configs[CONFIG_COMPRESSION] = sConfigMgr->GetIntDefault("Compression", 1);
  509. if (m_int_configs[CONFIG_COMPRESSION] < 1 || m_int_configs[CONFIG_COMPRESSION] > 9)
  510. {
  511. TC_LOG_ERROR("server.loading", "Compression level (%i) must be in range 1..9. Using default compression level (1).", m_int_configs[CONFIG_COMPRESSION]);
  512. m_int_configs[CONFIG_COMPRESSION] = 1;
  513. }
  514. m_bool_configs[CONFIG_ADDON_CHANNEL] = sConfigMgr->GetBoolDefault("AddonChannel", true);
  515. m_bool_configs[CONFIG_CLEAN_CHARACTER_DB] = sConfigMgr->GetBoolDefault("CleanCharacterDB", false);
  516. m_int_configs[CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS] = sConfigMgr->GetIntDefault("PersistentCharacterCleanFlags", 0);
  517. m_int_configs[CONFIG_CHAT_CHANNEL_LEVEL_REQ] = sConfigMgr->GetIntDefault("ChatLevelReq.Channel", 1);
  518. m_int_configs[CONFIG_CHAT_WHISPER_LEVEL_REQ] = sConfigMgr->GetIntDefault("ChatLevelReq.Whisper", 1);
  519. m_int_configs[CONFIG_CHAT_SAY_LEVEL_REQ] = sConfigMgr->GetIntDefault("ChatLevelReq.Say", 1);
  520. m_int_configs[CONFIG_TRADE_LEVEL_REQ] = sConfigMgr->GetIntDefault("LevelReq.Trade", 1);
  521. m_int_configs[CONFIG_TICKET_LEVEL_REQ] = sConfigMgr->GetIntDefault("LevelReq.Ticket", 1);
  522. m_int_configs[CONFIG_AUCTION_LEVEL_REQ] = sConfigMgr->GetIntDefault("LevelReq.Auction", 1);
  523. m_int_configs[CONFIG_MAIL_LEVEL_REQ] = sConfigMgr->GetIntDefault("LevelReq.Mail", 1);
  524. m_bool_configs[CONFIG_PRESERVE_CUSTOM_CHANNELS] = sConfigMgr->GetBoolDefault("PreserveCustomChannels", false);
  525. m_int_configs[CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION] = sConfigMgr->GetIntDefault("PreserveCustomChannelDuration", 14);
  526. m_bool_configs[CONFIG_GRID_UNLOAD] = sConfigMgr->GetBoolDefault("GridUnload", true);
  527. m_int_configs[CONFIG_INTERVAL_SAVE] = sConfigMgr->GetIntDefault("PlayerSaveInterval", 15 * MINUTE * IN_MILLISECONDS);
  528. m_int_configs[CONFIG_INTERVAL_DISCONNECT_TOLERANCE] = sConfigMgr->GetIntDefault("DisconnectToleranceInterval", 0);
  529. m_bool_configs[CONFIG_STATS_SAVE_ONLY_ON_LOGOUT] = sConfigMgr->GetBoolDefault("PlayerSave.Stats.SaveOnlyOnLogout", true);
  530. m_int_configs[CONFIG_MIN_LEVEL_STAT_SAVE] = sConfigMgr->GetIntDefault("PlayerSave.Stats.MinLevel", 0);
  531. if (m_int_configs[CONFIG_MIN_LEVEL_STAT_SAVE] > MAX_LEVEL)
  532. {
  533. TC_LOG_ERROR("server.loading", "PlayerSave.Stats.MinLevel (%i) must be in range 0..80. Using default, do not save character stats (0).", m_int_configs[CONFIG_MIN_LEVEL_STAT_SAVE]);
  534. m_int_configs[CONFIG_MIN_LEVEL_STAT_SAVE] = 0;
  535. }
  536. m_int_configs[CONFIG_INTERVAL_GRIDCLEAN] = sConfigMgr->GetIntDefault("GridCleanUpDelay", 5 * MINUTE * IN_MILLISECONDS);
  537. if (m_int_configs[CONFIG_INTERVAL_GRIDCLEAN] < MIN_GRID_DELAY)
  538. {
  539. TC_LOG_ERROR("server.loading", "GridCleanUpDelay (%i) must be greater %u. Use this minimal value.", m_int_configs[CONFIG_INTERVAL_GRIDCLEAN], MIN_GRID_DELAY);
  540. m_int_configs[CONFIG_INTERVAL_GRIDCLEAN] = MIN_GRID_DELAY;
  541. }
  542. if (reload)
  543. sMapMgr->SetGridCleanUpDelay(m_int_configs[CONFIG_INTERVAL_GRIDCLEAN]);
  544. m_int_configs[CONFIG_INTERVAL_MAPUPDATE] = sConfigMgr->GetIntDefault("MapUpdateInterval", 100);
  545. if (m_int_configs[CONFIG_INTERVAL_MAPUPDATE] < MIN_MAP_UPDATE_DELAY)
  546. {
  547. TC_LOG_ERROR("server.loading", "MapUpdateInterval (%i) must be greater %u. Use this minimal value.", m_int_configs[CONFIG_INTERVAL_MAPUPDATE], MIN_MAP_UPDATE_DELAY);
  548. m_int_configs[CONFIG_INTERVAL_MAPUPDATE] = MIN_MAP_UPDATE_DELAY;
  549. }
  550. if (reload)
  551. sMapMgr->SetMapUpdateInterval(m_int_configs[CONFIG_INTERVAL_MAPUPDATE]);
  552. m_int_configs[CONFIG_INTERVAL_CHANGEWEATHER] = sConfigMgr->GetIntDefault("ChangeWeatherInterval", 10 * MINUTE * IN_MILLISECONDS);
  553. if (reload)
  554. {
  555. uint32 val = sConfigMgr->GetIntDefault("WorldServerPort", 8085);
  556. if (val != m_int_configs[CONFIG_PORT_WORLD])
  557. TC_LOG_ERROR("server.loading", "WorldServerPort option can't be changed at worldserver.conf reload, using current value (%u).", m_int_configs[CONFIG_PORT_WORLD]);
  558. }
  559. else
  560. m_int_configs[CONFIG_PORT_WORLD] = sConfigMgr->GetIntDefault("WorldServerPort", 8085);
  561. m_int_configs[CONFIG_SOCKET_TIMEOUTTIME] = sConfigMgr->GetIntDefault("SocketTimeOutTime", 900000);
  562. m_int_configs[CONFIG_SESSION_ADD_DELAY] = sConfigMgr->GetIntDefault("SessionAddDelay", 10000);
  563. m_float_configs[CONFIG_GROUP_XP_DISTANCE] = sConfigMgr->GetFloatDefault("MaxGroupXPDistance", 74.0f);
  564. m_float_configs[CONFIG_MAX_RECRUIT_A_FRIEND_DISTANCE] = sConfigMgr->GetFloatDefault("MaxRecruitAFriendBonusDistance", 100.0f);
  565. /// @todo Add MonsterSight and GuarderSight (with meaning) in worldserver.conf or put them as define
  566. m_float_configs[CONFIG_SIGHT_MONSTER] = sConfigMgr->GetFloatDefault("MonsterSight", 50.0f);
  567. m_float_configs[CONFIG_SIGHT_GUARDER] = sConfigMgr->GetFloatDefault("GuarderSight", 50.0f);
  568. if (reload)
  569. {
  570. uint32 val = sConfigMgr->GetIntDefault("GameType", 0);
  571. if (val != m_int_configs[CONFIG_GAME_TYPE])
  572. TC_LOG_ERROR("server.loading", "GameType option can't be changed at worldserver.conf reload, using current value (%u).", m_int_configs[CONFIG_GAME_TYPE]);
  573. }
  574. else
  575. m_int_configs[CONFIG_GAME_TYPE] = sConfigMgr->GetIntDefault("GameType", 0);
  576. if (reload)
  577. {
  578. uint32 val = sConfigMgr->GetIntDefault("RealmZone", REALM_ZONE_DEVELOPMENT);
  579. if (val != m_int_configs[CONFIG_REALM_ZONE])
  580. TC_LOG_ERROR("server.loading", "RealmZone option can't be changed at worldserver.conf reload, using current value (%u).", m_int_configs[CONFIG_REALM_ZONE]);
  581. }
  582. else
  583. m_int_configs[CONFIG_REALM_ZONE] = sConfigMgr->GetIntDefault("RealmZone", REALM_ZONE_DEVELOPMENT);
  584. m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR]= sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Calendar", false);
  585. m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL] = sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Channel", false);
  586. m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP] = sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Group", false);
  587. m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD] = sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Guild", false);
  588. m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION] = sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Auction", false);
  589. m_bool_configs[CONFIG_ALLOW_TWO_SIDE_TRADE] = sConfigMgr->GetBoolDefault("AllowTwoSide.Trade", false);
  590. m_int_configs[CONFIG_STRICT_PLAYER_NAMES] = sConfigMgr->GetIntDefault ("StrictPlayerNames", 0);
  591. m_int_configs[CONFIG_STRICT_CHARTER_NAMES] = sConfigMgr->GetIntDefault ("StrictCharterNames", 0);
  592. m_int_configs[CONFIG_STRICT_PET_NAMES] = sConfigMgr->GetIntDefault ("StrictPetNames", 0);
  593. m_int_configs[CONFIG_MIN_PLAYER_NAME] = sConfigMgr->GetIntDefault ("MinPlayerName", 2);
  594. if (m_int_configs[CONFIG_MIN_PLAYER_NAME] < 1 || m_int_configs[CONFIG_MIN_PLAYER_NAME] > MAX_PLAYER_NAME)
  595. {
  596. TC_LOG_ERROR("server.loading", "MinPlayerName (%i) must be in range 1..%u. Set to 2.", m_int_configs[CONFIG_MIN_PLAYER_NAME], MAX_PLAYER_NAME);
  597. m_int_configs[CONFIG_MIN_PLAYER_NAME] = 2;
  598. }
  599. m_int_configs[CONFIG_MIN_CHARTER_NAME] = sConfigMgr->GetIntDefault ("MinCharterName", 2);
  600. if (m_int_configs[CONFIG_MIN_CHARTER_NAME] < 1 || m_int_configs[CONFIG_MIN_CHARTER_NAME] > MAX_CHARTER_NAME)
  601. {
  602. TC_LOG_ERROR("server.loading", "MinCharterName (%i) must be in range 1..%u. Set to 2.", m_int_configs[CONFIG_MIN_CHARTER_NAME], MAX_CHARTER_NAME);
  603. m_int_configs[CONFIG_MIN_CHARTER_NAME] = 2;
  604. }
  605. m_int_configs[CONFIG_MIN_PET_NAME] = sConfigMgr->GetIntDefault ("MinPetName", 2);
  606. if (m_int_configs[CONFIG_MIN_PET_NAME] < 1 || m_int_configs[CONFIG_MIN_PET_NAME] > MAX_PET_NAME)
  607. {
  608. TC_LOG_ERROR("server.loading", "MinPetName (%i) must be in range 1..%u. Set to 2.", m_int_configs[CONFIG_MIN_PET_NAME], MAX_PET_NAME);
  609. m_int_configs[CONFIG_MIN_PET_NAME] = 2;
  610. }
  611. m_int_configs[CONFIG_CHARACTER_CREATING_DISABLED] = sConfigMgr->GetIntDefault("CharacterCreating.Disabled", 0);
  612. m_int_configs[CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK] = sConfigMgr->GetIntDefault("CharacterCreating.Disabled.RaceMask", 0);
  613. m_int_configs[CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK] = sConfigMgr->GetIntDefault("CharacterCreating.Disabled.ClassMask", 0);
  614. m_int_configs[CONFIG_CHARACTERS_PER_REALM] = sConfigMgr->GetIntDefault("CharactersPerRealm", 10);
  615. if (m_int_configs[CONFIG_CHARACTERS_PER_REALM] < 1 || m_int_configs[CONFIG_CHARACTERS_PER_REALM] > 10)
  616. {
  617. TC_LOG_ERROR("server.loading", "CharactersPerRealm (%i) must be in range 1..10. Set to 10.", m_int_configs[CONFIG_CHARACTERS_PER_REALM]);
  618. m_int_configs[CONFIG_CHARACTERS_PER_REALM] = 10;
  619. }
  620. // must be after CONFIG_CHARACTERS_PER_REALM
  621. m_int_configs[CONFIG_CHARACTERS_PER_ACCOUNT] = sConfigMgr->GetIntDefault("CharactersPerAccount", 50);
  622. if (m_int_configs[CONFIG_CHARACTERS_PER_ACCOUNT] < m_int_configs[CONFIG_CHARACTERS_PER_REALM])
  623. {
  624. TC_LOG_ERROR("server.loading", "CharactersPerAccount (%i) can't be less than CharactersPerRealm (%i).", m_int_configs[CONFIG_CHARACTERS_PER_ACCOUNT], m_int_configs[CONFIG_CHARACTERS_PER_REALM]);
  625. m_int_configs[CONFIG_CHARACTERS_PER_ACCOUNT] = m_int_configs[CONFIG_CHARACTERS_PER_REALM];
  626. }
  627. m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = sConfigMgr->GetIntDefault("HeroicCharactersPerRealm", 1);
  628. if (int32(m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]) < 0 || m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] > 10)
  629. {
  630. TC_LOG_ERROR("server.loading", "HeroicCharactersPerRealm (%i) must be in range 0..10. Set to 1.", m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]);
  631. m_int_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = 1;
  632. }
  633. m_int_configs[CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER] = sConfigMgr->GetIntDefault("CharacterCreating.MinLevelForHeroicCharacter", 55);
  634. m_int_configs[CONFIG_SKIP_CINEMATICS] = sConfigMgr->GetIntDefault("SkipCinematics", 0);
  635. if (int32(m_int_configs[CONFIG_SKIP_CINEMATICS]) < 0 || m_int_configs[CONFIG_SKIP_CINEMATICS] > 2)
  636. {
  637. TC_LOG_ERROR("server.loading", "SkipCinematics (%i) must be in range 0..2. Set to 0.", m_int_configs[CONFIG_SKIP_CINEMATICS]);
  638. m_int_configs[CONFIG_SKIP_CINEMATICS] = 0;
  639. }
  640. if (reload)
  641. {
  642. uint32 val = sConfigMgr->GetIntDefault("MaxPlayerLevel", DEFAULT_MAX_LEVEL);
  643. if (val != m_int_configs[CONFIG_MAX_PLAYER_LEVEL])
  644. TC_LOG_ERROR("server.loading", "MaxPlayerLevel option can't be changed at config reload, using current value (%u).", m_int_configs[CONFIG_MAX_PLAYER_LEVEL]);
  645. }
  646. else
  647. m_int_configs[CONFIG_MAX_PLAYER_LEVEL] = sConfigMgr->GetIntDefault("MaxPlayerLevel", DEFAULT_MAX_LEVEL);
  648. if (m_int_configs[CONFIG_MAX_PLAYER_LEVEL] > MAX_LEVEL)
  649. {
  650. TC_LOG_ERROR("server.loading", "MaxPlayerLevel (%i) must be in range 1..%u. Set to %u.", m_int_configs[CONFIG_MAX_PLAYER_LEVEL], MAX_LEVEL, MAX_LEVEL);
  651. m_int_configs[CONFIG_MAX_PLAYER_LEVEL] = MAX_LEVEL;
  652. }
  653. m_int_configs[CONFIG_MIN_DUALSPEC_LEVEL] = sConfigMgr->GetIntDefault("MinDualSpecLevel", 40);
  654. m_int_configs[CONFIG_START_PLAYER_LEVEL] = sConfigMgr->GetIntDefault("StartPlayerLevel", 1);
  655. if (m_int_configs[CONFIG_START_PLAYER_LEVEL] < 1)
  656. {
  657. TC_LOG_ERROR("server.loading", "StartPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to 1.", m_int_configs[CONFIG_START_PLAYER_LEVEL], m_int_configs[CONFIG_MAX_PLAYER_LEVEL]);
  658. m_int_configs[CONFIG_START_PLAYER_LEVEL] = 1;
  659. }
  660. else if (m_int_configs[CONFIG_START_PLAYER_LEVEL] > m_int_configs[CONFIG_MAX_PLAYER_LEVEL])
  661. {
  662. TC_LOG_ERROR("server.loading", "StartPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.", m_int_configs[CONFIG_START_PLAYER_LEVEL], m_int_configs[CONFIG_MAX_PLAYER_LEVEL], m_int_configs[CONFIG_MAX_PLAYER_LEVEL]);
  663. m_int_configs[CONFIG_START_PLAYER_LEVEL] = m_int_configs[CONFIG_MAX_PLAYER_LEVEL];
  664. }
  665. m_int_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = sConfigMgr->GetIntDefault("StartHeroicPlayerLevel", 55);
  666. if (m_int_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] < 1)
  667. {
  668. TC_LOG_ERROR("server.loading", "StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to 55.",
  669. m_int_configs[CONFIG_START_HEROIC_PLAYER_LEVEL], m_int_configs[CONFIG_MAX_PLAYER_LEVEL]);
  670. m_int_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = 55;
  671. }
  672. else if (m_int_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] > m_int_configs[CONFIG_MAX_PLAYER_LEVEL])
  673. {
  674. TC_LOG_ERROR("server.loading", "StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.",
  675. m_int_configs[CONFIG_START_HEROIC_PLAYER_LEVEL], m_int_configs[CONFIG_MAX_PLAYER_LEVEL], m_int_configs[CONFIG_MAX_PLAYER_LEVEL]);
  676. m_int_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = m_int_configs[CONFIG_MAX_PLAYER_LEVEL];
  677. }
  678. m_int_configs[CONFIG_START_PLAYER_MONEY] = sConfigMgr->GetIntDefault("StartPlayerMoney", 0);
  679. if (int32(m_int_configs[CONFIG_START_PLAYER_MONEY]) < 0)
  680. {
  681. TC_LOG_ERROR("server.loading", "StartPlayerMoney (%i) must be in range 0.." UI64FMTD ". Set to %u.", m_int_configs[CONFIG_START_PLAYER_MONEY], uint64(MAX_MONEY_AMOUNT), 0);
  682. m_int_configs[CONFIG_START_PLAYER_MONEY] = 0;
  683. }
  684. else if (m_int_configs[CONFIG_START_PLAYER_MONEY] > 0x7FFFFFFF-1) // TODO: (See MAX_MONEY_AMOUNT)
  685. {
  686. TC_LOG_ERROR("server.loading", "StartPlayerMoney (%i) must be in range 0..%u. Set to %u.",
  687. m_int_configs[CONFIG_START_PLAYER_MONEY], 0x7FFFFFFF-1, 0x7FFFFFFF-1);
  688. m_int_configs[CONFIG_START_PLAYER_MONEY] = 0x7FFFFFFF-1;
  689. }
  690. m_int_configs[CONFIG_CURRENCY_RESET_HOUR] = sConfigMgr->GetIntDefault("Currency.ResetHour", 3);
  691. if (m_int_configs[CONFIG_CURRENCY_RESET_HOUR] > 23)
  692. {
  693. TC_LOG_ERROR("server.loading", "Currency.ResetHour (%i) can't be load. Set to 6.", m_int_configs[CONFIG_CURRENCY_RESET_HOUR]);
  694. m_int_configs[CONFIG_CURRENCY_RESET_HOUR] = 3;
  695. }
  696. m_int_configs[CONFIG_CURRENCY_RESET_DAY] = sConfigMgr->GetIntDefault("Currency.ResetDay", 3);
  697. if (m_int_configs[CONFIG_CURRENCY_RESET_DAY] > 6)
  698. {
  699. TC_LOG_ERROR("server.loading", "Currency.ResetDay (%i) can't be load. Set to 3.", m_int_configs[CONFIG_CURRENCY_RESET_DAY]);
  700. m_int_configs[CONFIG_CURRENCY_RESET_DAY] = 3;
  701. }
  702. m_int_configs[CONFIG_CURRENCY_RESET_INTERVAL] = sConfigMgr->GetIntDefault("Currency.ResetInterval", 7);
  703. if (int32(m_int_configs[CONFIG_CURRENCY_RESET_INTERVAL]) <= 0)
  704. {
  705. TC_LOG_ERROR("server.loading", "Currency.ResetInterval (%i) must be > 0, set to default 7.", m_int_configs[CONFIG_CURRENCY_RESET_INTERVAL]);
  706. m_int_configs[CONFIG_CURRENCY_RESET_INTERVAL] = 7;
  707. }
  708. m_int_configs[CONFIG_CURRENCY_START_HONOR_POINTS] = sConfigMgr->GetIntDefault("Currency.StartHonorPoints", 0);
  709. if (int32(m_int_configs[CONFIG_CURRENCY_START_HONOR_POINTS]) < 0)
  710. {
  711. TC_LOG_ERROR("server.loading", "Currency.StartHonorPoints (%i) must be >= 0, set to default 0.", m_int_configs[CONFIG_CURRENCY_START_HONOR_POINTS]);
  712. m_int_configs[CONFIG_CURRENCY_START_HONOR_POINTS] = 0;
  713. }
  714. m_int_configs[CONFIG_CURRENCY_MAX_HONOR_POINTS] = sConfigMgr->GetIntDefault("Currency.MaxHonorPoints", 4000);
  715. if (int32(m_int_configs[CONFIG_CURRENCY_MAX_HONOR_POINTS]) < 0)
  716. {
  717. TC_LOG_ERROR("server.loading", "Currency.MaxHonorPoints (%i) can't be negative. Set to default 4000.", m_int_configs[CONFIG_CURRENCY_MAX_HONOR_POINTS]);
  718. m_int_configs[CONFIG_CURRENCY_MAX_HONOR_POINTS] = 4000;
  719. }
  720. m_int_configs[CONFIG_CURRENCY_MAX_HONOR_POINTS] *= 100; //precision mod
  721. m_int_configs[CONFIG_CURRENCY_START_JUSTICE_POINTS] = sConfigMgr->GetIntDefault("Currency.StartJusticePoints", 0);
  722. if (int32(m_int_configs[CONFIG_CURRENCY_START_JUSTICE_POINTS]) < 0)
  723. {
  724. TC_LOG_ERROR("server.loading", "Currency.StartJusticePoints (%i) must be >= 0, set to default 0.", m_int_configs[CONFIG_CURRENCY_START_JUSTICE_POINTS]);
  725. m_int_configs[CONFIG_CURRENCY_START_JUSTICE_POINTS] = 0;
  726. }
  727. m_int_configs[CONFIG_CURRENCY_MAX_JUSTICE_POINTS] = sConfigMgr->GetIntDefault("Currency.MaxJusticePoints", 4000);
  728. if (int32(m_int_configs[CONFIG_CURRENCY_MAX_JUSTICE_POINTS]) < 0)
  729. {
  730. TC_LOG_ERROR("server.loading", "Currency.MaxJusticePoints (%i) can't be negative. Set to default 4000.", m_int_configs[CONFIG_CURRENCY_MAX_JUSTICE_POINTS]);
  731. m_int_configs[CONFIG_CURRENCY_MAX_JUSTICE_POINTS] = 4000;
  732. }
  733. m_int_configs[CONFIG_CURRENCY_MAX_JUSTICE_POINTS] *= 100; //precision mod
  734. m_int_configs[CONFIG_CURRENCY_START_CONQUEST_POINTS] = sConfigMgr->GetIntDefault("Currency.StartConquestPoints", 0);
  735. if (int32(m_int_configs[CONFIG_CURRENCY_START_CONQUEST_POINTS]) < 0)
  736. {
  737. TC_LOG_ERROR("server.loading", "Currency.StartConquestPoints (%i) must be >= 0, set to default 0.", m_int_configs[CONFIG_CURRENCY_START_CONQUEST_POINTS]);
  738. m_int_configs[CONFIG_CURRENCY_START_CONQUEST_POINTS] = 0;
  739. }
  740. m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP] = sConfigMgr->GetIntDefault("Currency.ConquestPointsWeekCap", 1650);
  741. if (int32(m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP]) <= 0)
  742. {
  743. TC_LOG_ERROR("server.loading", "Currency.ConquestPointsWeekCap (%i) must be > 0, set to default 1650.", m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP]);
  744. m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP] = 1650;
  745. }
  746. m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP] *= 100; //precision mod
  747. m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD] = sConfigMgr->GetIntDefault("Currency.ConquestPointsArenaReward", 180);
  748. if (int32(m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD]) <= 0)
  749. {
  750. TC_LOG_ERROR("server.loading", "Currency.ConquestPointsArenaReward (%i) must be > 0, set to default 180.", m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD]);
  751. m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD] = 180;
  752. }
  753. m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD] *= 100; //precision mod
  754. m_int_configs[CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL] = sConfigMgr->GetIntDefault("RecruitAFriend.MaxLevel", 60);
  755. if (m_int_configs[CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL] > m_int_configs[CONFIG_MAX_PLAYER_LEVEL])
  756. {
  757. TC_LOG_ERROR("server.loading", "RecruitAFriend.MaxLevel (%i) must be in the range 0..MaxLevel(%u). Set to %u.",
  758. m_int_configs[CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL], m_int_configs[CONFIG_MAX_PLAYER_LEVEL], 60);
  759. m_int_configs[CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL] = 60;
  760. }
  761. m_int_configs[CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL_DIFFERENCE] = sConfigMgr->GetIntDefault("RecruitAFriend.MaxDifference", 4);
  762. m_bool_configs[CONFIG_ALL_TAXI_PATHS] = sConfigMgr->GetBoolDefault("AllFlightPaths", false);
  763. m_bool_configs[CONFIG_INSTANT_TAXI] = sConfigMgr->GetBoolDefault("InstantFlightPaths", false);
  764. m_bool_configs[CONFIG_INSTANCE_IGNORE_LEVEL] = sConfigMgr->GetBoolDefault("Instance.IgnoreLevel", false);
  765. m_bool_configs[CONFIG_INSTANCE_IGNORE_RAID] = sConfigMgr->GetBoolDefault("Instance.IgnoreRaid", false);
  766. m_bool_configs[CONFIG_CAST_UNSTUCK] = sConfigMgr->GetBoolDefault("CastUnstuck", true);
  767. m_int_configs[CONFIG_INSTANCE_RESET_TIME_HOUR] = sConfigMgr->GetIntDefault("Instance.ResetTimeHour", 4);
  768. m_int_configs[CONFIG_INSTANCE_UNLOAD_DELAY] = sConfigMgr->GetIntDefault("Instance.UnloadDelay", 30 * MINUTE * IN_MILLISECONDS);
  769. m_int_configs[CONFIG_MAX_PRIMARY_TRADE_SKILL] = sConfigMgr->GetIntDefault("MaxPrimaryTradeSkill", 2);
  770. m_int_configs[CONFIG_MIN_PETITION_SIGNS] = sConfigMgr->GetIntDefault("MinPetitionSigns", 9);
  771. if (m_int_configs[CONFIG_MIN_PETITION_SIGNS] > 9)
  772. {
  773. TC_LOG_ERROR("server.loading", "MinPetitionSigns (%i) must be in range 0..9. Set to 9.", m_int_configs[CONFIG_MIN_PETITION_SIGNS]);
  774. m_int_configs[CONFIG_MIN_PETITION_SIGNS] = 9;
  775. }
  776. m_int_configs[CONFIG_GM_LOGIN_STATE] = sConfigMgr->GetIntDefault("GM.LoginState", 2);
  777. m_int_configs[CONFIG_GM_VISIBLE_STATE] = sConfigMgr->GetIntDefault("GM.Visible", 2);
  778. m_int_configs[CONFIG_GM_CHAT] = sConfigMgr->GetIntDefault("GM.Chat", 2);
  779. m_int_configs[CONFIG_GM_WHISPERING_TO] = sConfigMgr->GetIntDefault("GM.WhisperingTo", 2);
  780. m_int_configs[CONFIG_GM_FREEZE_DURATION] = sConfigMgr->GetIntDefault("GM.FreezeAuraDuration", 0);
  781. m_int_configs[CONFIG_GM_LEVEL_IN_GM_LIST] = sConfigMgr->GetIntDefault("GM.InGMList.Level", SEC_ADMINISTRATOR);
  782. m_int_configs[CONFIG_GM_LEVEL_IN_WHO_LIST] = sConfigMgr->GetIntDefault("GM.InWhoList.Level", SEC_ADMINISTRATOR);
  783. m_int_configs[CONFIG_START_GM_LEVEL] = sConfigMgr->GetIntDefault("GM.StartLevel", 1);
  784. if (m_int_configs[CONFIG_START_GM_LEVEL] < m_int_configs[CONFIG_START_PLAYER_LEVEL])
  785. {
  786. TC_LOG_ERROR("server.loading", "GM.StartLevel (%i) must be in range StartPlayerLevel(%u)..%u. Set to %u.",
  787. m_int_configs[CONFIG_START_GM_LEVEL], m_int_configs[CONFIG_START_PLAYER_LEVEL], MAX_LEVEL, m_int_configs[CONFIG_START_PLAYER_LEVEL]);
  788. m_int_configs[CONFIG_START_GM_LEVEL] = m_int_configs[CONFIG_START_PLAYER_LEVEL];
  789. }
  790. else if (m_int_configs[CONFIG_START_GM_LEVEL] > MAX_LEVEL)
  791. {
  792. TC_LOG_ERROR("server.loading", "GM.StartLevel (%i) must be in range 1..%u. Set to %u.", m_int_configs[CONFIG_START_GM_LEVEL], MAX_LEVEL, MAX_LEVEL);
  793. m_int_configs[CONFIG_START_GM_LEVEL] = MAX_LEVEL;
  794. }
  795. m_bool_configs[CONFIG_ALLOW_GM_GROUP] = sConfigMgr->GetBoolDefault("GM.AllowInvite", false);
  796. m_bool_configs[CONFIG_GM_LOWER_SECURITY] = sConfigMgr->GetBoolDefault("GM.LowerSecurity", false);
  797. m_float_configs[CONFIG_CHANCE_OF_GM_SURVEY] = sConfigMgr->GetFloatDefault("GM.TicketSystem.ChanceOfGMSurvey", 50.0f);
  798. m_int_configs[CONFIG_GROUP_VISIBILITY] = sConfigMgr->GetIntDefault("Visibility.GroupMode", 1);
  799. m_int_configs[CONFIG_MAIL_DELIVERY_DELAY] = sConfigMgr->GetIntDefault("MailDeliveryDelay", HOUR);
  800. m_int_configs[CONFIG_UPTIME_UPDATE] = sConfigMgr->GetIntDefault("UpdateUptimeInterval", 10);
  801. if (int32(m_int_configs[CONFIG_UPTIME_UPDATE]) <= 0)
  802. {
  803. TC_LOG_ERROR("server.loading", "UpdateUptimeInterval (%i) must be > 0, set to default 10.", m_int_configs[CONFIG_UPTIME_UPDATE]);
  804. m_int_configs[CONFIG_UPTIME_UPDATE] = 10;
  805. }
  806. if (reload)
  807. {
  808. m_timers[WUPDATE_UPTIME].SetInterval(m_int_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILLISECONDS);
  809. m_timers[WUPDATE_UPTIME].Reset();
  810. }
  811. // log db cleanup interval
  812. m_int_configs[CONFIG_LOGDB_CLEARINTERVAL] = sConfigMgr->GetIntDefault("LogDB.Opt.ClearInterval", 10);
  813. if (int32(m_int_configs[CONFIG_LOGDB_CLEARINTERVAL]) <= 0)
  814. {
  815. TC_LOG_ERROR("server.loading", "LogDB.Opt.ClearInterval (%i) must be > 0, set to default 10.", m_int_configs[CONFIG_LOGDB_CLEARINTERVAL]);
  816. m_int_configs[CONFIG_LOGDB_CLEARINTERVAL] = 10;
  817. }
  818. if (reload)
  819. {
  820. m_timers[WUPDATE_CLEANDB].SetInterval(m_int_configs[CONFIG_LOGDB_CLEARINTERVAL] * MINUTE * IN_MILLISECONDS);
  821. m_timers[WUPDATE_CLEANDB].Reset();
  822. }
  823. m_int_configs[CONFIG_LOGDB_CLEARTIME] = sConfigMgr->GetIntDefault("LogDB.Opt.ClearTime", 1209600); // 14 days default
  824. TC_LOG_INFO("server.loading", "Will clear `logs` table of entries older than %i seconds every %u minutes.",
  825. m_int_configs[CONFIG_LOGDB_CLEARTIME], m_int_configs[CONFIG_LOGDB_CLEARINTERVAL]);
  826. m_int_configs[CONFIG_SKILL_CHANCE_ORANGE] = sConfigMgr->GetIntDefault("SkillChance.Orange", 100);
  827. m_int_configs[CONFIG_SKILL_CHANCE_YELLOW] = sConfigMgr->GetIntDefault("SkillChance.Yellow", 75);
  828. m_int_configs[CONFIG_SKILL_CHANCE_GREEN] = sConfigMgr->GetIntDefault("SkillChance.Green", 25);
  829. m_int_configs[CONFIG_SKILL_CHANCE_GREY] = sConfigMgr->GetIntDefault("SkillChance.Grey", 0);
  830. m_int_configs[CONFIG_SKILL_CHANCE_MINING_STEPS] = sConfigMgr->GetIntDefault("SkillChance.MiningSteps", 75);
  831. m_int_configs[CONFIG_SKILL_CHANCE_SKINNING_STEPS] = sConfigMgr->GetIntDefault("SkillChance.SkinningSteps", 75);
  832. m_bool_configs[CONFIG_SKILL_PROSPECTING] = sConfigMgr->GetBoolDefault("SkillChance.Prospecting", false);
  833. m_bool_configs[CONFIG_SKILL_MILLING] = sConfigMgr->GetBoolDefault("SkillChance.Milling", false);
  834. m_int_configs[CONFIG_SKILL_GAIN_CRAFTING] = sConfigMgr->GetIntDefault("SkillGain.Crafting", 1);
  835. m_int_configs[CONFIG_SKILL_GAIN_GATHERING] = sConfigMgr->GetIntDefault("SkillGain.Gathering", 1);
  836. m_int_configs[CONFIG_MAX_OVERSPEED_PINGS] = sConfigMgr->GetIntDefault("MaxOverspeedPings", 2);
  837. if (m_int_configs[CONFIG_MAX_OVERSPEED_PINGS] != 0 && m_int_configs[CONFIG_MAX_OVERSPEED_PINGS] < 2)
  838. {
  839. TC_LOG_ERROR("server.loading", "MaxOverspeedPings (%i) must be in range 2..infinity (or 0 to disable check). Set to 2.", m_int_configs[CONFIG_MAX_OVERSPEED_PINGS]);
  840. m_int_configs[CONFIG_MAX_OVERSPEED_PINGS] = 2;
  841. }
  842. m_bool_configs[CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY] = sConfigMgr->GetBoolDefault("SaveRespawnTimeImmediately", true);
  843. m_bool_configs[

Large files files are truncated, but you can click here to view the full file