diff options
Diffstat (limited to 'src/game-server/gamehandler.cpp')
-rw-r--r-- | src/game-server/gamehandler.cpp | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index 54598d8a..2913e3f0 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -81,6 +81,7 @@ void GameHandler::kill(Character *ch) assert(client != NULL); client->character = NULL; client->status = CLIENT_LOGIN; + ch->setClient(NULL); } void GameHandler::prepareServerChange(Character *ch) @@ -113,11 +114,6 @@ void GameHandler::completeServerChange(int id, std::string const &token, } } -void GameHandler::process() -{ - ConnectionHandler::process(); -} - static MovingObject *findBeingNear(Object *p, int id) { MapComposite *map = p->getMap(); @@ -442,6 +438,44 @@ void GameHandler::sendTo(Character *beingPtr, MessageOut &msg) client->send(msg); } +void GameHandler::addPendingCharacter(std::string const &token, Character *ch) +{ + /* First, check if the character is already on the map. This may happen if + a client just lost its connection, and logged to the account server + again, yet the game server has not yet detected the lost connection. */ + + int id = ch->getDatabaseID(); + for (NetComputers::const_iterator i = clients.begin(), + i_end = clients.end(); i != i_end; ++i) + { + GameClient *c = static_cast< GameClient * >(*i); + Character *old_ch = c->character; + if (old_ch && old_ch->getDatabaseID() == id) + { + if (c->status != CLIENT_CONNECTED) + { + /* Either the server is confused, or the client is up to no + good. So ignore the request, and wait for the connections + to properly time out. */ + return; + } + + /* As the connection was not properly closed, the account server + has not yet updated its data, so ignore them. Instead, take the + already present character, kill its current connection, and make + it available for a new connection. */ + delete ch; + GameState::remove(old_ch); + kill(old_ch); + ch = old_ch; + break; + } + } + + // Mark the character as pending a connection. + mTokenCollector.addPendingConnect(token, ch); +} + void GameHandler::tokenMatched(GameClient* computer, Character* character) { |