From 79b39f9655111088a741185c4dabd31dae7d85ea Mon Sep 17 00:00:00 2001 From: AG <43139552+AGandrup@users.noreply.github.com> Date: Fri, 27 Oct 2023 00:32:15 +0200 Subject: [PATCH] fix(Core/Grid): Implement missing GridUnload setting (#17569) * Implement GridUnload setting * Minor fixes - Use GetOption instead of deprecated GetBoolDefault. - Added a missing check for instances in LoadMap - Replaced some numbers with global defines * Possible crashfix + minor improvements - Initialized initialOrientation which I had forgotten (likely cause of crash) - Readded a previous check in UpdateSplineMovement - Made i_objectsToRemove and i_worldObjects tos sets as they were previously, instead of unordered_set. * Update worldserver.conf.dist * Fix high CPU usage with preload grid enabled. This should be it. --- .../apps/worldserver/worldserver.conf.dist | 19 ++++++++++++----- src/server/game/Entities/Unit/Unit.cpp | 9 ++++++-- src/server/game/Maps/Map.cpp | 14 +++++++------ src/server/game/Maps/Map.h | 4 ++-- src/server/game/Maps/MapMgr.cpp | 4 ++-- src/server/game/Movement/Spline/Spline.h | 9 ++++++-- src/server/game/World/IWorld.h | 1 + src/server/game/World/World.cpp | 21 ++++++++++--------- 8 files changed, 52 insertions(+), 29 deletions(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 8e728460b..01e9fa84b 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -1372,13 +1372,22 @@ DetectPosCollision = 1 CheckGameObjectLoS = 1 +# +# GridUnload +# Description: Unload grids to save memory. Can be disabled if enough memory is available +# to speed up moving players to new grids. +# Default: 1 - (enable, Unload grids) +# 0 - (disable, Do not unload grids) + +GridUnload = 1 + # # PreloadAllNonInstancedMapGrids -# Description: Preload all grids on all non-instanced maps. This will take a great amount -# of additional RAM (ca. 9 GB) and causes the server to take longer to start, -# but can increase performance if used on a server with a high amount of players. -# It will also activate all creatures which are set active (e.g. the Fel Reavers -# in Hellfire Peninsula) on server start. +# Description: Preload all grids on all non-instanced maps. Requires GridUnload to be disabled. +# This will take a great amount of additional RAM (ca. 9 GB) and causes the server +# to take longer to start, but can increase performance if used on a server with a +# high amount of players. It will also activate all creatures which are set active +# (e.g. the Fel Reavers in Hellfire Peninsula) on server start. # Default: 0 - (Disabled) # 1 - (Enabled) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index be8dc1941..06ef9593b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -567,6 +567,13 @@ void Unit::UpdateSplineMovement(uint32 t_diff) // this code cant be placed inside EscortMovementGenerator, because we cant delete active MoveGen while it is updated SplineHandler handler(this); movespline->updateState(t_diff, handler); + // Xinef: Spline was cleared by StopMoving, return + if (!movespline->Initialized()) { + DisableSpline(); + return; + } + + bool arrived = movespline->Finalized(); if (movespline->isCyclic()) { @@ -582,8 +589,6 @@ void Unit::UpdateSplineMovement(uint32 t_diff) } } - bool arrived = movespline->Finalized(); - if (arrived) { DisableSpline(); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 643c884d1..68e54d3ea 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -195,7 +195,8 @@ void Map::LoadMap(int gx, int gy, bool reload) return; // load grid map for base map - m_parentMap->EnsureGridCreated(GridCoord(63 - gx, 63 - gy)); + if (!m_parentMap->GridMaps[gx][gy]) + m_parentMap->EnsureGridCreated(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - gx, (MAX_NUMBER_OF_GRIDS - 1) - gy)); ((MapInstanced*)(m_parentMap))->AddGridMapReference(GridCoord(gx, gy)); GridMaps[gx][gy] = m_parentMap->GridMaps[gx][gy]; @@ -460,7 +461,8 @@ void Map::EnsureGridCreated_i(const GridCoord& p) { LOG_DEBUG("maps", "Creating grid[{}, {}] for map {} instance {}", p.x_coord, p.y_coord, GetId(), i_InstanceId); - setNGrid(new NGridType(p.x_coord * MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry), p.x_coord, p.y_coord); + NGridType* ngrid = new NGridType(p.x_coord * MAX_NUMBER_OF_GRIDS + p.y_coord, p.x_coord, p.y_coord, i_gridExpiry, sWorld->getBoolConfig(CONFIG_GRID_UNLOAD)); + setNGrid(ngrid, p.x_coord, p.y_coord); // build a linkage between this map and NGridType buildNGridLinkage(getNGrid(p.x_coord, p.y_coord)); @@ -2403,11 +2405,11 @@ inline LiquidData const GridMap::GetLiquidData(float x, float y, float z, float GridMap* Map::GetGrid(float x, float y) { // half opt method - int gx = (int)(32 - x / SIZE_OF_GRIDS); //grid x - int gy = (int)(32 - y / SIZE_OF_GRIDS); //grid y + int gx = (int)(CENTER_GRID_ID - x / SIZE_OF_GRIDS); //grid x + int gy = (int)(CENTER_GRID_ID - y / SIZE_OF_GRIDS); //grid y // ensure GridMap is loaded - EnsureGridCreated(GridCoord(63 - gx, 63 - gy)); + EnsureGridCreated(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - gx, (MAX_NUMBER_OF_GRIDS - 1) - gy)); return GridMaps[gx][gy]; } @@ -3135,7 +3137,7 @@ void Map::RemoveAllObjectsInRemoveList() //LOG_DEBUG("maps", "Object remover 1 check."); while (!i_objectsToRemove.empty()) { - std::unordered_set::iterator itr = i_objectsToRemove.begin(); + std::set::iterator itr = i_objectsToRemove.begin(); WorldObject* obj = *itr; switch (obj->GetTypeId()) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index fff1c5785..c3b64f01a 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -768,9 +768,9 @@ private: void ProcessRelocationNotifies(uint32 diff); bool i_scriptLock; - std::unordered_set i_objectsToRemove; + std::set i_objectsToRemove; std::map i_objectsToSwitch; - std::unordered_set i_worldObjects; + std::set i_worldObjects; typedef std::multimap ScriptScheduleMap; ScriptScheduleMap m_scriptSchedule; diff --git a/src/server/game/Maps/MapMgr.cpp b/src/server/game/Maps/MapMgr.cpp index 5c95475fb..96368486a 100644 --- a/src/server/game/Maps/MapMgr.cpp +++ b/src/server/game/Maps/MapMgr.cpp @@ -303,8 +303,8 @@ bool MapMgr::ExistMapAndVMap(uint32 mapid, float x, float y) { GridCoord p = Acore::ComputeGridCoord(x, y); - int gx = 63 - p.x_coord; - int gy = 63 - p.y_coord; + int gx = (MAX_NUMBER_OF_GRIDS - 1) - p.x_coord; + int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord; return Map::ExistMap(mapid, gx, gy) && Map::ExistVMap(mapid, gx, gy); } diff --git a/src/server/game/Movement/Spline/Spline.h b/src/server/game/Movement/Spline/Spline.h index afefffe62..38dcd9293 100644 --- a/src/server/game/Movement/Spline/Spline.h +++ b/src/server/game/Movement/Spline/Spline.h @@ -48,7 +48,7 @@ namespace Movement uint8 m_mode{UninitializedMode}; bool cyclic{false}; - float initialOrientation; + float initialOrientation{0.f}; enum { @@ -198,7 +198,12 @@ namespace Movement } /** Returns length of the whole spline. */ - [[nodiscard]] length_type length() const { return lengths[index_hi];} + [[nodiscard]] length_type length() const + { + if (lengths.empty()) + return 0; + return lengths[index_hi]; + } /** Returns length between given nodes. */ [[nodiscard]] length_type length(index_type first, index_type last) const { return lengths[last] - lengths[first];} [[nodiscard]] length_type length(index_type Idx) const { return lengths[Idx];} diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h index f2ed3289b..394875058 100644 --- a/src/server/game/World/IWorld.h +++ b/src/server/game/World/IWorld.h @@ -72,6 +72,7 @@ enum WorldBoolConfigs CONFIG_ADDON_CHANNEL, CONFIG_ALLOW_PLAYER_COMMANDS, CONFIG_CLEAN_CHARACTER_DB, + CONFIG_GRID_UNLOAD, CONFIG_STATS_SAVE_ONLY_ON_LOGOUT, CONFIG_ALLOW_TWO_SIDE_ACCOUNTS, CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR, diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index d301a1d26..79f56d46a 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1420,8 +1420,16 @@ void World::LoadConfigSettings(bool reload) // Prevent players AFK from being logged out _int_configs[CONFIG_AFK_PREVENT_LOGOUT] = sConfigMgr->GetOption("PreventAFKLogout", 0); + // Unload grids to save memory. Can be disabled if enough memory is available to speed up moving players to new grids. + _bool_configs[CONFIG_GRID_UNLOAD] = sConfigMgr->GetOption("GridUnload", true); + // Preload all grids of all non-instanced maps _bool_configs[CONFIG_PRELOAD_ALL_NON_INSTANCED_MAP_GRIDS] = sConfigMgr->GetOption("PreloadAllNonInstancedMapGrids", false); + if (_bool_configs[CONFIG_PRELOAD_ALL_NON_INSTANCED_MAP_GRIDS] && _bool_configs[CONFIG_GRID_UNLOAD]) + { + LOG_ERROR("server.loading", "PreloadAllNonInstancedMapGrids enabled, but GridUnload also enabled. GridUnload must be disabled to enable base map pre-loading. Base map pre-loading disabled"); + _bool_configs[CONFIG_PRELOAD_ALL_NON_INSTANCED_MAP_GRIDS] = false; + } // ICC buff override _int_configs[CONFIG_ICC_BUFF_HORDE] = sConfigMgr->GetOption("ICC.Buff.Horde", 73822); @@ -2164,21 +2172,14 @@ void World::SetInitialWorldSettings() { LOG_INFO("server.loading", "Loading All Grids For All Non-Instanced Maps..."); - for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i) - { - MapEntry const* mapEntry = sMapStore.LookupEntry(i); - - if (mapEntry && !mapEntry->Instanceable()) + sMapMgr->DoForAllMaps([](Map* map) { - Map* map = sMapMgr->CreateBaseMap(mapEntry->MapID); - - if (map) + if (!map->Instanceable()) { LOG_INFO("server.loading", ">> Loading All Grids For Map {}", map->GetId()); map->LoadAllCells(); } - } - } + }); } uint32 startupDuration = GetMSTimeDiffToNow(startupBegin);