summaryrefslogtreecommitdiff
path: root/src/game-server/gamehandler.cpp
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-08-17 12:56:44 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-08-17 12:56:44 +0000
commit89505d51a27dc68cbac42b5e528aa823cc835b70 (patch)
treea1f7cb35b2262ed8733a954593bf8e87eaed69f3 /src/game-server/gamehandler.cpp
parent0d187f7e18301901502fe5586ee3f7a30a2bac68 (diff)
downloadmanaserv-89505d51a27dc68cbac42b5e528aa823cc835b70.tar.gz
manaserv-89505d51a27dc68cbac42b5e528aa823cc835b70.tar.bz2
manaserv-89505d51a27dc68cbac42b5e528aa823cc835b70.tar.xz
manaserv-89505d51a27dc68cbac42b5e528aa823cc835b70.zip
Handled multiple connections by allowing client to take over characters.
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)
{