summaryrefslogtreecommitdiffstats
path: root/src/account-server/accounthandler.cpp
diff options
context:
space:
mode:
authorYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2010-12-29 07:41:49 +0100
committerYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2010-12-29 07:41:49 +0100
commit5f03e73484a50c9689956b32ef97630b56d2a00d (patch)
treeca6d3d7467d4582a2f64be4a45c056f55642fd17 /src/account-server/accounthandler.cpp
parent4ead8e0b6af924132a6fb227325a868db0df335c (diff)
downloadmanaserv-5f03e73484a50c9689956b32ef97630b56d2a00d.tar.gz
manaserv-5f03e73484a50c9689956b32ef97630b56d2a00d.tar.xz
manaserv-5f03e73484a50c9689956b32ef97630b56d2a00d.zip
Made the server handle properly the characters slots.
I turned the vector storing character data into a map, keeping the character's slot. Fixed a memleak along the way. Reviewed-by: Crush.
Diffstat (limited to 'src/account-server/accounthandler.cpp')
-rw-r--r--src/account-server/accounthandler.cpp88
1 files changed, 51 insertions, 37 deletions
diff --git a/src/account-server/accounthandler.cpp b/src/account-server/accounthandler.cpp
index 1463b37..3a61077 100644
--- a/src/account-server/accounthandler.cpp
+++ b/src/account-server/accounthandler.cpp
@@ -114,8 +114,10 @@ public:
*/
TokenCollector<AccountHandler, AccountClient *, int> mTokenCollector;
- static void sendCharacterData(AccountClient &client, int slot,
- const Character &ch);
+ /**
+ * Send the character data to the client.
+ */
+ static void sendCharacterData(AccountClient &client, const Character &ch);
protected:
/**
@@ -274,11 +276,11 @@ void AccountHandler::computerDisconnected(NetComputer *comp)
delete client; // ~AccountClient unsets the account
}
-void AccountHandler::sendCharacterData(AccountClient &client, int slot,
+void AccountHandler::sendCharacterData(AccountClient &client,
const Character &ch)
{
MessageOut charInfo(APMSG_CHAR_INFO);
- charInfo.writeInt8(slot);
+ charInfo.writeInt8(ch.getCharacterSlot());
charInfo.writeString(ch.getName());
charInfo.writeInt8(ch.getGender());
charInfo.writeInt8(ch.getHairStyle());
@@ -396,10 +398,9 @@ void AccountHandler::handleLoginMessage(AccountClient &client, MessageIn &msg)
Characters &chars = acc->getCharacters();
// Send characters list
- for (unsigned int i = 0; i < chars.size(); i++)
- {
- sendCharacterData(client, i, *chars[i]);
- }
+ for (Characters::const_iterator i = chars.begin(), i_end = chars.end();
+ i != i_end; ++i)
+ sendCharacterData(client, *(*i).second);
}
void AccountHandler::handleLogoutMessage(AccountClient &client)
@@ -685,12 +686,18 @@ void AccountHandler::handleCharacterCreateMessage(AccountClient &client,
int hairStyle = msg.readInt8();
int hairColor = msg.readInt8();
int gender = msg.readInt8();
+
+ // Avoid creation of character from old clients.
+ int slot = -1;
+ if (msg.getUnreadLength() > 7)
+ slot = msg.readInt8();
+
int numHairStyles = Configuration::getValue("char_numHairStyles", 17);
int numHairColors = Configuration::getValue("char_numHairColors", 11);
int numGenders = Configuration::getValue("char_numGenders", 2);
unsigned int minNameLength = Configuration::getValue("char_minNameLength", 4);
unsigned int maxNameLength = Configuration::getValue("char_maxNameLength", 25);
- unsigned int maxCharacters = Configuration::getValue("account_maxCharacters", 3);
+ int maxCharacters = Configuration::getValue("account_maxCharacters", 3);
MessageOut reply(APMSG_CHAR_CREATE_RESPONSE);
@@ -733,9 +740,18 @@ void AccountHandler::handleCharacterCreateMessage(AccountClient &client,
return;
}
- // An account shouldn't have more than MAX_OF_CHARACTERS characters.
+ // An account shouldn't have more
+ // than <account_maxCharacters> characters.
Characters &chars = acc->getCharacters();
- if (chars.size() >= maxCharacters)
+ if (slot < 1 || slot > maxCharacters
+ || !acc->isSlotEmpty((unsigned int) slot))
+ {
+ reply.writeInt8(CREATE_INVALID_SLOT);
+ client.send(reply);
+ return;
+ }
+
+ if ((int)chars.size() >= maxCharacters)
{
reply.writeInt8(CREATE_TOO_MUCH_CHARACTERS);
client.send(reply);
@@ -783,6 +799,7 @@ void AccountHandler::handleCharacterCreateMessage(AccountClient &client,
(double) (attributes[i]))));
newCharacter->mAttributes.insert(defAttr.begin(), defAttr.end());
newCharacter->setAccount(acc);
+ newCharacter->setCharacterSlot(slot);
newCharacter->setLevel(1);
newCharacter->setCharacterPoints(0);
newCharacter->setCorrectionPoints(0);
@@ -812,8 +829,7 @@ void AccountHandler::handleCharacterCreateMessage(AccountClient &client,
client.send(reply);
// Send new characters infos back to client
- int slot = chars.size() - 1;
- sendCharacterData(client, slot, *chars[slot]);
+ sendCharacterData(client, *chars[slot]);
return;
}
}
@@ -834,19 +850,18 @@ void AccountHandler::handleCharacterSelectMessage(AccountClient &client,
return; // not logged in
}
- unsigned charNum = msg.readInt8();
+ int slot = msg.readInt8();
Characters &chars = acc->getCharacters();
- // Character ID = 0 to Number of Characters - 1.
- if (charNum >= chars.size())
+ if (slot < 1 || slot > (int)chars.size())
{
- // invalid char selection
+ // Invalid char selection
reply.writeInt8(ERRMSG_INVALID_ARGUMENT);
client.send(reply);
return;
}
- Character *selectedChar = chars[charNum];
+ Character *selectedChar = chars[slot];
std::string address;
int port;
@@ -908,33 +923,33 @@ void AccountHandler::handleCharacterDeleteMessage(AccountClient &client,
return; // not logged in
}
- unsigned charNum = msg.readInt8();
+ int slot = msg.readInt8();
Characters &chars = acc->getCharacters();
- // Character ID = 0 to Number of Characters - 1.
- if (charNum >= chars.size())
+ if (slot < 1 || acc->isSlotEmpty(slot))
{
- // invalid char selection
+ // Invalid char selection
reply.writeInt8(ERRMSG_INVALID_ARGUMENT);
client.send(reply);
- return; // not logged in
+ return;
}
- LOG_INFO("Character deleted:" << chars[charNum]->getName());
+ std::string characterName = chars[slot]->getName();
+ LOG_INFO("Character deleted:" << characterName);
- acc->delCharacter(charNum);
- storage->flush(acc);
-
- reply.writeInt8(ERRMSG_OK);
- client.send(reply);
-
- // log transaction
+ // Log transaction
Transaction trans;
- trans.mCharacterId = chars[charNum]->getDatabaseID();
+ trans.mCharacterId = chars[slot]->getDatabaseID();
trans.mAction = TRANS_CHAR_DELETED;
- trans.mMessage = chars[charNum]->getName() + " deleted by ";
+ trans.mMessage = chars[slot]->getName() + " deleted by ";
trans.mMessage.append(acc->getName());
storage->addTransaction(trans);
+
+ acc->delCharacter(slot);
+ storage->flush(acc);
+
+ reply.writeInt8(ERRMSG_OK);
+ client.send(reply);
}
void AccountHandler::tokenMatched(AccountClient *client, int accountID)
@@ -953,10 +968,9 @@ void AccountHandler::tokenMatched(AccountClient *client, int accountID)
Characters &chars = acc->getCharacters();
// Send characters list
- for (unsigned int i = 0; i < chars.size(); i++)
- {
- sendCharacterData(*client, i, *chars[i]);
- }
+ for (Characters::const_iterator i = chars.begin(), i_end = chars.end();
+ i != i_end; ++i)
+ sendCharacterData(*client, *(*i).second);
}
void AccountHandler::deletePendingClient(AccountClient *client)