diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | src/game-server/accountconnection.cpp | 2 | ||||
-rw-r--r-- | src/game-server/gamehandler.cpp | 44 | ||||
-rw-r--r-- | src/game-server/gamehandler.hpp | 12 |
4 files changed, 47 insertions, 14 deletions
@@ -2,6 +2,9 @@ * src/scripting/lua.cpp, data/test.lua: Added Lua function for trading between players and NPCs. + * src/game-server/gamehandler.cpp, src/game-server/gamehandler.hpp, + src/game-server/accountconnection.cpp: Handled multiple connections by + allowing clients to take over characters. 2007-08-16 Guillaume Melquiond <guillaume.melquiond@gmail.com> 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 |