Fixed private instance memory leaks.

This commit is contained in:
dongresource 2020-10-19 04:30:12 +02:00
parent 55be58cc24
commit e97b58ccaf
4 changed files with 27 additions and 14 deletions

View File

@ -236,3 +236,19 @@ void ChunkManager::destroyInstance(uint64_t instanceID) {
destroyChunk(coords); destroyChunk(coords);
} }
} }
void ChunkManager::destroyInstanceIfEmpty(uint64_t instanceID) {
if (PLAYERID(instanceID) == 0)
return; // don't clean up overworld/IZ chunks
std::vector<std::tuple<int, int, uint64_t>> sourceChunkCoords = getChunksInMap(instanceID);
for (std::tuple<int, int, uint64_t>& coords : sourceChunkCoords) {
Chunk* chunk = chunks[coords];
if (chunk->players.size() > 0)
return; // there are still players inside
}
destroyInstance(instanceID);
}

View File

@ -40,4 +40,5 @@ namespace ChunkManager {
void createInstance(uint64_t); void createInstance(uint64_t);
void destroyInstance(uint64_t); void destroyInstance(uint64_t);
void destroyInstanceIfEmpty(uint64_t);
} }

View File

@ -628,16 +628,7 @@ void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) {
} }
// post-warp: check if the source instance has no more players in it and delete it if so // post-warp: check if the source instance has no more players in it and delete it if so
if (PLAYERID(fromInstance) == 0) ChunkManager::destroyInstanceIfEmpty(fromInstance);
return; // don't clean up overworld/IZ chunks
std::vector<std::tuple<int, int, uint64_t>> sourceChunkCoords = ChunkManager::getChunksInMap(fromInstance);
for (std::tuple<int, int, uint64_t>& coords : sourceChunkCoords) {
Chunk* chunk = ChunkManager::chunks[coords];
if (chunk->players.size() > 0)
return; // there are still players inside
}
ChunkManager::destroyInstance(fromInstance);
} }
/* /*

View File

@ -64,6 +64,7 @@ void PlayerManager::addPlayer(CNSocket* key, Player plr) {
void PlayerManager::removePlayer(CNSocket* key) { void PlayerManager::removePlayer(CNSocket* key) {
PlayerView& view = players[key]; PlayerView& view = players[key];
uint64_t fromInstance = view.plr->instanceID;
//MissionManager::failInstancedMissions(key); moved to enter //MissionManager::failInstancedMissions(key); moved to enter
GroupManager::groupKickPlayer(view.plr); GroupManager::groupKickPlayer(view.plr);
@ -71,9 +72,6 @@ void PlayerManager::removePlayer(CNSocket* key) {
// save player to DB // save player to DB
Database::updatePlayer(view.plr); Database::updatePlayer(view.plr);
INITSTRUCT(sP_FE2CL_PC_EXIT, exitPacket);
exitPacket.iID = players[key].plr->iID;
// remove players from all chunks // remove players from all chunks
removePlayerFromChunks(view.currentChunks, key); removePlayerFromChunks(view.currentChunks, key);
@ -87,6 +85,9 @@ void PlayerManager::removePlayer(CNSocket* key) {
delete view.plr; delete view.plr;
players.erase(key); players.erase(key);
// if the player was in a lair, clean it up
ChunkManager::destroyInstanceIfEmpty(fromInstance);
std::cout << players.size() << " players" << std::endl; std::cout << players.size() << " players" << std::endl;
} }
@ -230,6 +231,9 @@ void PlayerManager::updatePlayerChunk(CNSocket* sock, int X, int Y, uint64_t ins
void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z, uint64_t I) { void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z, uint64_t I) {
PlayerView& plrv = PlayerManager::players[sock]; PlayerView& plrv = PlayerManager::players[sock];
Player* plr = plrv.plr; Player* plr = plrv.plr;
uint64_t fromInstance = plr->instanceID;
plr->instanceID = I; plr->instanceID = I;
if (I != INSTANCE_OVERWORLD) { if (I != INSTANCE_OVERWORLD) {
INITSTRUCT(sP_FE2CL_INSTANCE_MAP_INFO, pkt); INITSTRUCT(sP_FE2CL_INSTANCE_MAP_INFO, pkt);
@ -250,7 +254,8 @@ void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z, uint64_t I
plrv.currentChunks.clear(); plrv.currentChunks.clear();
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC)); sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_WARP_USE_NPC_SUCC, sizeof(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC));
} }
ChunkManager::destroyInstanceIfEmpty(fromInstance);
} }
void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z) { void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z) {