[Server] Fix invalidation of iterators

experimental-mono
Koncord 6 years ago
parent 343dd8b5ea
commit b3456a8841

@ -53,18 +53,21 @@ void Cell::addPlayer(Player *player)
players.push_back(player); players.push_back(player);
} }
void Cell::removePlayer(Player *player) void Cell::removePlayer(Player *player, bool cleanPlayer)
{ {
for (Iterator it = begin(); it != end(); it++) for (Iterator it = begin(); it != end(); it++)
{ {
if (*it == player) if (*it == player)
{ {
auto it2 = find(player->cells.begin(), player->cells.end(), this); if (cleanPlayer)
if (it2 != player->cells.end())
{ {
LOG_APPEND(Log::LOG_INFO, "- Removing %s from Player %s", getDescription().c_str(), player->npc.mName.c_str()); auto it2 = find(player->cells.begin(), player->cells.end(), this);
if (it2 != player->cells.end())
{
LOG_APPEND(Log::LOG_INFO, "- Removing %s from Player %s", getDescription().c_str(), player->npc.mName.c_str());
player->cells.erase(it2); player->cells.erase(it2);
}
} }
LOG_APPEND(Log::LOG_INFO, "- Removing %s from Cell %s", player->npc.mName.c_str(), getDescription().c_str()); LOG_APPEND(Log::LOG_INFO, "- Removing %s from Cell %s", player->npc.mName.c_str(), getDescription().c_str());

@ -28,7 +28,7 @@ public:
Iterator end() const; Iterator end() const;
void addPlayer(Player *player); void addPlayer(Player *player);
void removePlayer(Player *player); void removePlayer(Player *player, bool cleanPlayer = true);
void readActorList(unsigned char packetID, const mwmp::BaseActorList *newActorList); void readActorList(unsigned char packetID, const mwmp::BaseActorList *newActorList);
bool containsActor(int refNum, int mpNum); bool containsActor(int refNum, int mpNum);

@ -136,26 +136,38 @@ void CellController::removeCell(Cell *cell)
void CellController::removePlayer(Cell *cell, Player *player) void CellController::removePlayer(Cell *cell, Player *player)
{ {
cell->removePlayer(player); //cell->removePlayer(player);
if (cell->players.empty())
{
LOG_APPEND(Log::LOG_INFO, "- Cell %s has no players left", cell->getDescription().c_str());
removeCell(cell);
}
} }
void CellController::deletePlayer(Player *player) void CellController::deletePlayer(Player *player)
{ {
LOG_APPEND(Log::LOG_INFO, "- Iterating through Cells from Player %s", player->npc.mName.c_str()); LOG_APPEND(Log::LOG_INFO, "- Iterating through Cells from Player %s", player->npc.mName.c_str());
for (auto it = player->getCells()->begin(); player->getCells()->size() != 0; ++it) std::vector<Cell*> toDelete;
removePlayer(*it, player);
auto it = player->getCells()->begin();
const auto endIter = player->getCells()->end();
for (; it != endIter; ++it)
{
Cell *c = *it;
c->removePlayer(player, false);
if (c->players.empty())
toDelete.push_back(c);
}
for (auto &&cell : toDelete)
{
LOG_APPEND(Log::LOG_INFO, "- Cell %s has no players left", cell->getDescription().c_str());
removeCell(cell);
}
} }
void CellController::update(Player *player) void CellController::update(Player *player)
{ {
for (auto cell : player->cellStateChanges.cellStates) std::vector<Cell*> toDelete;
for (auto &&cell : player->cellStateChanges.cellStates)
{ {
if (cell.type == mwmp::CellState::LOAD) if (cell.type == mwmp::CellState::LOAD)
{ {
@ -171,7 +183,16 @@ void CellController::update(Player *player)
c = getCellByXY(cell.cell.getGridX(), cell.cell.getGridY()); c = getCellByXY(cell.cell.getGridX(), cell.cell.getGridY());
if (c != nullptr) if (c != nullptr)
removePlayer(c, player); {
c->removePlayer(player);
if (c->players.empty())
toDelete.push_back(c);
}
} }
} }
for (auto &&cell : toDelete)
{
LOG_APPEND(Log::LOG_INFO, "- Cell %s has no players left", cell->getDescription().c_str());
removeCell(cell);
}
} }

Loading…
Cancel
Save