diff options
Diffstat (limited to 'src/account-server/accounthandler.cpp')
-rw-r--r-- | src/account-server/accounthandler.cpp | 106 |
1 files changed, 88 insertions, 18 deletions
diff --git a/src/account-server/accounthandler.cpp b/src/account-server/accounthandler.cpp index 002803e6..99faad62 100644 --- a/src/account-server/accounthandler.cpp +++ b/src/account-server/accounthandler.cpp @@ -29,16 +29,20 @@ #include "account-server/serverhandler.hpp" #include "chat-server/chathandler.hpp" #include "common/configuration.hpp" +#include "common/resourcemanager.hpp" #include "common/transaction.hpp" #include "net/connectionhandler.hpp" #include "net/messagein.hpp" #include "net/messageout.hpp" #include "net/netcomputer.hpp" +#include "utils/functors.h" #include "utils/logger.h" #include "utils/stringfilter.h" #include "utils/tokencollector.hpp" #include "utils/tokendispenser.hpp" #include "utils/sha256.h" +#include "utils/string.hpp" +#include "utils/xml.hpp" static void addUpdateHost(MessageOut *msg) { @@ -46,13 +50,27 @@ static void addUpdateHost(MessageOut *msg) msg->writeString(updateHost); } + +// List of attributes that the client can send at account creation. + +static std::vector< unsigned int > initAttr; + +/* + * Map attribute ids to values that they need to be initialised to at account + * creation. + * The pair contains two elements of the same value (the default) so that the + * iterators can be used to copy a range. + */ + +static std::map< unsigned int, std::pair< double, double> > defAttr; + class AccountHandler : public ConnectionHandler { public: /** * Constructor. */ - AccountHandler(); + AccountHandler(const std::string &attrFile); /** * Called by the token collector in order to associate a client to its @@ -77,6 +95,9 @@ public: */ TokenCollector<AccountHandler, AccountClient *, int> mTokenCollector; + static void sendCharacterData(AccountClient &client, int slot, + const Character &ch); + protected: /** * Processes account related messages. @@ -106,14 +127,54 @@ private: static AccountHandler *accountHandler; -AccountHandler::AccountHandler(): +AccountHandler::AccountHandler(const std::string &attrFile): mTokenCollector(this) { + // Probably not the best place for this, but I don't have a lot of time. + if (initAttr.empty()) + { + std::string absPathFile; + xmlNodePtr node; + + absPathFile = ResourceManager::resolve(attrFile); + if (absPathFile.empty()) { + LOG_FATAL("Account handler: Could not find " << attrFile << "!"); + exit(3); + return; + } + + XML::Document doc(absPathFile, int()); + node = doc.rootNode(); + + if (!node || !xmlStrEqual(node->name, BAD_CAST "stats")) + { + LOG_FATAL("Account handler: " << attrFile + << " is not a valid database file!"); + exit(3); + return; + } + for_each_xml_child_node(attributenode, node) + if (xmlStrEqual(attributenode->name, BAD_CAST "stat")) + { + unsigned int id = XML::getProperty(attributenode, "id", 0); + if (!id) continue; + if (utils::toupper(XML::getProperty(attributenode, "modifiable", "false")) == "TRUE") + initAttr.push_back(id); + // Store as string initially to check that the property is defined. + std::string defStr = XML::getProperty(attributenode, "default", ""); + if (!defStr.empty()) + { + double val = string_to<double>()(defStr); + defAttr.insert(std::make_pair(id, std::make_pair(val, val))); + } + } + } } -bool AccountClientHandler::initialize(int port, const std::string &host) +bool AccountClientHandler::initialize(const std::string &configFile, int port, + const std::string &host) { - accountHandler = new AccountHandler; + accountHandler = new AccountHandler(configFile); LOG_INFO("Account handler started:"); return accountHandler->startListen(port, host); @@ -151,7 +212,7 @@ void AccountHandler::computerDisconnected(NetComputer *comp) delete client; // ~AccountClient unsets the account } -static void sendCharacterData(AccountClient &client, int slot, +void AccountHandler::sendCharacterData(AccountClient &client, int slot, const Character &ch) { MessageOut charInfo(APMSG_CHAR_INFO); @@ -163,11 +224,16 @@ static void sendCharacterData(AccountClient &client, int slot, charInfo.writeShort(ch.getLevel()); charInfo.writeShort(ch.getCharacterPoints()); charInfo.writeShort(ch.getCorrectionPoints()); - charInfo.writeLong(ch.getPossessions().money); - for (int j = CHAR_ATTR_BEGIN; j < CHAR_ATTR_END; ++j) + for (AttributeMap::const_iterator it = ch.mAttributes.begin(), + it_end = ch.mAttributes.end(); + it != it_end; + ++it) { - charInfo.writeShort(ch.getAttribute(j)); + // {id, base value in 256ths, modified value in 256ths }* + charInfo.writeLong(it->first); + charInfo.writeLong((int) (it->second.first * 256)); + charInfo.writeLong((int) (it->second.second * 256)); } client.send(charInfo); @@ -552,10 +618,10 @@ void AccountHandler::handleCharacterCreateMessage(AccountClient &client, Message int numHairStyles = Configuration::getValue("char_numHairStyles", 17); int numHairColors = Configuration::getValue("char_numHairColors", 11); int numGenders = Configuration::getValue("char_numGenders", 2); - unsigned minNameLength = Configuration::getValue("char_minNameLength", 4); - unsigned maxNameLength = Configuration::getValue("char_maxNameLength", 25); - unsigned maxCharacters = Configuration::getValue("char_maxCharacters", 3); - unsigned startingPoints = Configuration::getValue("char_startingPoints", 60); + unsigned int minNameLength = Configuration::getValue("char_minNameLength", 4); + unsigned int maxNameLength = Configuration::getValue("char_maxNameLength", 25); + unsigned int maxCharacters = Configuration::getValue("char_maxCharacters", 3); + unsigned int startingPoints = Configuration::getValue("char_startingPoints", 60); MessageOut reply(APMSG_CHAR_CREATE_RESPONSE); @@ -611,16 +677,16 @@ void AccountHandler::handleCharacterCreateMessage(AccountClient &client, Message // LATER_ON: Add race, face and maybe special attributes. // Customization of character's attributes... - int attributes[CHAR_ATTR_NB]; - for (int i = 0; i < CHAR_ATTR_NB; ++i) + std::vector< unsigned int > attributes = std::vector<unsigned int>(initAttr.size(), 0); + for (unsigned int i = 0; i < initAttr.size(); ++i) attributes[i] = msg.readShort(); unsigned int totalAttributes = 0; bool validNonZeroAttributes = true; - for (int i = 0; i < CHAR_ATTR_NB; ++i) + for (unsigned int i = 0; i < initAttr.size(); ++i) { // For good total attributes check. - totalAttributes += attributes[i]; + totalAttributes += attributes.at(i); // For checking if all stats are at least > 0 if (attributes[i] <= 0) validNonZeroAttributes = false; @@ -641,8 +707,12 @@ void AccountHandler::handleCharacterCreateMessage(AccountClient &client, Message else { Character *newCharacter = new Character(name); - for (int i = CHAR_ATTR_BEGIN; i < CHAR_ATTR_END; ++i) - newCharacter->setAttribute(i, attributes[i - CHAR_ATTR_BEGIN]); + for (unsigned int i = 0; i < initAttr.size(); ++i) + newCharacter->mAttributes.insert(std::make_pair( + (unsigned int) (initAttr.at(i)), + std::make_pair((double) (attributes[i]), + (double) (attributes[i])))); + newCharacter->mAttributes.insert(defAttr.begin(), defAttr.end()); newCharacter->setAccount(acc); newCharacter->setLevel(1); newCharacter->setCharacterPoints(0); |