summaryrefslogtreecommitdiff
path: root/src/game-server/gamehandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game-server/gamehandler.cpp')
-rw-r--r--src/game-server/gamehandler.cpp44
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)
{