summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--src/game-server/accountconnection.cpp2
-rw-r--r--src/game-server/gamehandler.cpp44
-rw-r--r--src/game-server/gamehandler.hpp12
4 files changed, 47 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index de07c8ff..22c66ab3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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