forked from teamnwah/openmw-tes3coop
[Server] Fix invalidation of iterators
This commit is contained in:
parent
343dd8b5ea
commit
b3456a8841
3 changed files with 41 additions and 17 deletions
|
@ -53,11 +53,13 @@ void Cell::addPlayer(Player *player)
|
|||
players.push_back(player);
|
||||
}
|
||||
|
||||
void Cell::removePlayer(Player *player)
|
||||
void Cell::removePlayer(Player *player, bool cleanPlayer)
|
||||
{
|
||||
for (Iterator it = begin(); it != end(); it++)
|
||||
{
|
||||
if (*it == player)
|
||||
{
|
||||
if (cleanPlayer)
|
||||
{
|
||||
auto it2 = find(player->cells.begin(), player->cells.end(), this);
|
||||
if (it2 != player->cells.end())
|
||||
|
@ -66,6 +68,7 @@ void Cell::removePlayer(Player *player)
|
|||
|
||||
player->cells.erase(it2);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
void addPlayer(Player *player);
|
||||
void removePlayer(Player *player);
|
||||
void removePlayer(Player *player, bool cleanPlayer = true);
|
||||
|
||||
void readActorList(unsigned char packetID, const mwmp::BaseActorList *newActorList);
|
||||
bool containsActor(int refNum, int mpNum);
|
||||
|
|
|
@ -136,26 +136,38 @@ void CellController::removeCell(Cell *cell)
|
|||
|
||||
void CellController::removePlayer(Cell *cell, Player *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);
|
||||
}
|
||||
//cell->removePlayer(player);
|
||||
}
|
||||
|
||||
void CellController::deletePlayer(Player *player)
|
||||
{
|
||||
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)
|
||||
removePlayer(*it, player);
|
||||
std::vector<Cell*> toDelete;
|
||||
|
||||
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)
|
||||
{
|
||||
for (auto cell : player->cellStateChanges.cellStates)
|
||||
std::vector<Cell*> toDelete;
|
||||
|
||||
for (auto &&cell : player->cellStateChanges.cellStates)
|
||||
{
|
||||
if (cell.type == mwmp::CellState::LOAD)
|
||||
{
|
||||
|
@ -171,7 +183,16 @@ void CellController::update(Player *player)
|
|||
c = getCellByXY(cell.cell.getGridX(), cell.cell.getGridY());
|
||||
|
||||
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…
Reference in a new issue