summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorErik Schilling <ablu.erikschilling@googlemail.com>2013-09-15 13:35:35 +0200
committerErik Schilling <ablu.erikschilling@googlemail.com>2013-09-15 13:35:35 +0200
commit6de8fd28ecb23dccded9c3eabed2f80cde7eb122 (patch)
treebff3d63e9f3c6753e7fe56372c48e06e69314537 /src
parentd15190dc8cd8258fcdf06bb615de80bc97a5ac20 (diff)
downloadmanaserv-6de8fd28ecb23dccded9c3eabed2f80cde7eb122.tar.gz
manaserv-6de8fd28ecb23dccded9c3eabed2f80cde7eb122.tar.bz2
manaserv-6de8fd28ecb23dccded9c3eabed2f80cde7eb122.tar.xz
manaserv-6de8fd28ecb23dccded9c3eabed2f80cde7eb122.zip
Fixed handling of reconnects while the old connection is still valid
The old connection is now terminated. And the new connection will receive the character data properly.
Diffstat (limited to 'src')
-rw-r--r--src/common/manaserv_protocol.h3
-rw-r--r--src/game-server/charactercomponent.cpp18
-rw-r--r--src/game-server/charactercomponent.h6
-rw-r--r--src/game-server/gamehandler.cpp22
-rw-r--r--src/game-server/gamehandler.h2
-rw-r--r--src/game-server/state.cpp4
6 files changed, 34 insertions, 21 deletions
diff --git a/src/common/manaserv_protocol.h b/src/common/manaserv_protocol.h
index 2bfd8c70..411b08ca 100644
--- a/src/common/manaserv_protocol.h
+++ b/src/common/manaserv_protocol.h
@@ -308,7 +308,8 @@ enum {
ERRMSG_TIME_OUT, // data failed to arrive in due time
ERRMSG_LIMIT_REACHED, // limit reached
ERRMSG_ADMINISTRATIVE_LOGOFF, // kicked by server administrator
- ERRMSG_ALREADY_MEMBER // is already member of guild/party
+ ERRMSG_ALREADY_MEMBER, // is already member of guild/party
+ ERRMSG_LOGIN_WAS_TAKEN_OVER // a different connection took over
};
// used in AGMSG_REGISTER_RESPONSE to show state of item db
diff --git a/src/game-server/charactercomponent.cpp b/src/game-server/charactercomponent.cpp
index 8a50d7cd..23a1bd4b 100644
--- a/src/game-server/charactercomponent.cpp
+++ b/src/game-server/charactercomponent.cpp
@@ -107,13 +107,12 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg):
deserialize(entity, msg);
Inventory(&entity, mPossessions).initialize();
- modifiedAllAttributes(entity);;
beingComponent->signal_attribute_changed.connect(sigc::mem_fun(
this, &CharacterComponent::attributeChanged));
- for (auto &abilityIt : abilityComponent->getAbilities())
- mModifiedAbilities.insert(abilityIt.first);
+ entity.signal_inserted.connect(sigc::mem_fun(this,
+ &CharacterComponent::inserted));
}
CharacterComponent::~CharacterComponent()
@@ -452,6 +451,12 @@ void CharacterComponent::sendStatus(Entity &entity)
mModifiedAttributes.clear();
}
+void CharacterComponent::modifiedAllAbilities(Entity &entity)
+{
+ for (auto &abilityIt : entity.getComponent<AbilityComponent>()->getAbilities())
+ mModifiedAbilities.insert(abilityIt.first);
+}
+
void CharacterComponent::modifiedAllAttributes(Entity &entity)
{
auto *beingComponent = entity.getComponent<BeingComponent>();
@@ -581,3 +586,10 @@ void CharacterComponent::triggerLoginCallback(Entity &entity)
{
executeCallback(mLoginCallback, entity);
}
+
+void CharacterComponent::inserted(Entity *entity)
+{
+ Inventory(entity).sendFull();
+ modifiedAllAbilities(*entity);
+ modifiedAllAttributes(*entity);
+}
diff --git a/src/game-server/charactercomponent.h b/src/game-server/charactercomponent.h
index 9149e731..a739e691 100644
--- a/src/game-server/charactercomponent.h
+++ b/src/game-server/charactercomponent.h
@@ -167,9 +167,7 @@ class CharacterComponent : public Component
*/
void sendStatus(Entity &entity);
- /**
- * Marks all attributes as being modified.
- */
+ void modifiedAllAbilities(Entity &entity);
void modifiedAllAttributes(Entity &entity);
/**
@@ -291,6 +289,8 @@ class CharacterComponent : public Component
CharacterComponent(const CharacterComponent &);
CharacterComponent &operator=(const CharacterComponent &);
+ void inserted(Entity *entity);
+
void abilityStatusChanged(int id);
void abilityCooldownActivated();
diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp
index 913abf80..2cd1c704 100644
--- a/src/game-server/gamehandler.cpp
+++ b/src/game-server/gamehandler.cpp
@@ -79,14 +79,14 @@ void GameHandler::computerDisconnected(NetComputer *comp)
delete &computer;
}
-void GameHandler::kill(Entity *ch)
+void GameHandler::killConnection(Entity *ch)
{
auto *component = ch->getComponent<CharacterComponent>();
GameClient *client = component->getClient();
assert(client);
client->character = nullptr;
client->status = CLIENT_LOGIN;
- component->setClient(0);
+ component->setClient(nullptr);
}
void GameHandler::prepareServerChange(Entity *ch)
@@ -343,10 +343,9 @@ void GameHandler::addPendingCharacter(const std::string &token, Entity *ch)
int id = ch->getComponent<CharacterComponent>()->getDatabaseID();
- for (NetComputers::const_iterator i = clients.begin(),
- i_end = clients.end(); i != i_end; ++i)
+ for (NetComputer *i : clients)
{
- GameClient *c = static_cast< GameClient * >(*i);
+ GameClient *c = static_cast< GameClient * >(i);
Entity *old_ch = c->character;
if (old_ch && id == old_ch->getComponent<CharacterComponent>()->getDatabaseID())
{
@@ -363,8 +362,13 @@ void GameHandler::addPendingCharacter(const std::string &token, Entity *ch)
already present character, kill its current connection, and make
it available for a new connection. */
delete ch;
+
GameState::remove(old_ch);
- kill(old_ch);
+ killConnection(old_ch);
+ MessageOut msg(GPMSG_CONNECT_RESPONSE);
+ msg.writeInt8(ERRMSG_LOGIN_WAS_TAKEN_OVER);
+ c->disconnect(msg);
+
ch = old_ch;
break;
}
@@ -389,7 +393,7 @@ void GameHandler::tokenMatched(GameClient *computer, Entity *character)
if (!GameState::insert(character))
{
result.writeInt8(ERRMSG_SERVER_FULL);
- kill(character);
+ killConnection(character);
delete character;
computer->disconnect(result);
return;
@@ -399,10 +403,6 @@ void GameHandler::tokenMatched(GameClient *computer, Entity *character)
result.writeInt8(ERRMSG_OK);
computer->send(result);
-
- // Force sending the whole character to the client.
- Inventory(character).sendFull();
- characterComponent->modifiedAllAttributes(*character);
}
void GameHandler::deletePendingClient(GameClient *computer)
diff --git a/src/game-server/gamehandler.h b/src/game-server/gamehandler.h
index fea40398..b8a1b636 100644
--- a/src/game-server/gamehandler.h
+++ b/src/game-server/gamehandler.h
@@ -65,7 +65,7 @@ class GameHandler: public ConnectionHandler
/**
* Kills connection with given character.
*/
- void kill(Entity *);
+ void killConnection(Entity *);
/**
* Prepares a server change for given character.
diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp
index 8055c27d..281b80c2 100644
--- a/src/game-server/state.cpp
+++ b/src/game-server/state.cpp
@@ -524,7 +524,7 @@ void GameState::update(int tick)
if (o->getType() == OBJECT_CHARACTER)
{
o->getComponent<CharacterComponent>()->disconnected(*o);
- gameHandler->kill(o);
+ gameHandler->killConnection(o);
}
delete o;
break;
@@ -770,7 +770,7 @@ void GameState::warp(Entity *ptr, MapComposite *map, const Point &point)
if (!insert(ptr))
{
characterComponent->disconnected(*ptr);
- gameHandler->kill(ptr);
+ gameHandler->killConnection(ptr);
delete ptr;
}
}