summaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/game-server/accountconnection.cpp2
-rw-r--r--src/game-server/gamehandler.cpp44
-rw-r--r--src/game-server/gamehandler.hpp12
3 files changed, 44 insertions, 14 deletions
diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp
index 842853b4..5b8b6f3d 100644
--- a/src/game-server/accountconnection.cpp
+++ b/src/game-server/accountconnection.cpp
@@ -75,7 +75,7 @@ void AccountConnection::processMessage(MessageIn &msg)
Character *ptr = new Character(msg);
ptr->setSpeed(250); // TODO
ptr->fillHitpoints();// TODO: the current hit points should be saved in the database. Otherwise players could heal their characters by logging in and out again.
- gameHandler->mTokenCollector.addPendingConnect(token, ptr);
+ gameHandler->addPendingCharacter(token, ptr);
} break;
case AGMSG_ACTIVE_MAP:
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)
{
diff --git a/src/game-server/gamehandler.hpp b/src/game-server/gamehandler.hpp
index f07e1ac9..0f88c485 100644
--- a/src/game-server/gamehandler.hpp
+++ b/src/game-server/gamehandler.hpp
@@ -55,10 +55,6 @@ class GameHandler: public ConnectionHandler
* Constructor
*/
GameHandler();
- /**
- * Processes messages and cleans outdated characters.
- */
- void process();
/**
* Starts the handler
@@ -87,13 +83,13 @@ class GameHandler: public ConnectionHandler
std::string const &address, int port);
/**
- * Map of character's and their id used for getting which character to
- * forward account server messages back to.
+ * Registers a character that should soon be claimed by a client.
+ * @param token token used by the client when connecting.
*/
- // std::map<int, Character*> messageMap;
+ void addPendingCharacter(std::string const &token, Character *);
/**
- * Combines a client with it's character.
+ * Combines a client with its character.
* (Needed for TokenCollector)
*/
void