diff options
Diffstat (limited to 'src/account-server')
-rw-r--r-- | src/account-server/account.cpp | 24 | ||||
-rw-r--r-- | src/account-server/account.hpp | 28 | ||||
-rw-r--r-- | src/account-server/accountclient.cpp | 8 | ||||
-rw-r--r-- | src/account-server/accountclient.hpp | 7 | ||||
-rw-r--r-- | src/account-server/accounthandler.cpp | 127 | ||||
-rw-r--r-- | src/account-server/characterdata.cpp | 62 | ||||
-rw-r--r-- | src/account-server/characterdata.hpp | 191 | ||||
-rw-r--r-- | src/account-server/dalstorage.cpp | 223 | ||||
-rw-r--r-- | src/account-server/dalstorage.hpp | 13 | ||||
-rw-r--r-- | src/account-server/dalstoragesql.hpp | 19 | ||||
-rw-r--r-- | src/account-server/main-account.cpp | 2 | ||||
-rw-r--r-- | src/account-server/serverhandler.cpp | 36 | ||||
-rw-r--r-- | src/account-server/serverhandler.hpp | 11 | ||||
-rw-r--r-- | src/account-server/storage.hpp | 15 |
14 files changed, 577 insertions, 189 deletions
diff --git a/src/account-server/account.cpp b/src/account-server/account.cpp index 256e5c73..6ca75535 100644 --- a/src/account-server/account.cpp +++ b/src/account-server/account.cpp @@ -20,9 +20,11 @@ * $Id$ */ +#include "account-server/account.hpp" + #include <cassert> -#include "account-server/account.hpp" +#include "account-server/accountclient.hpp" #include "utils/functors.h" /** @@ -49,7 +51,7 @@ Account::Account(const std::string& name, Account::Account(const std::string& name, const std::string& password, const std::string& email, - const Players& characters) + const Characters& characters) : mName(name), mPassword(password), mEmail(email), @@ -155,7 +157,7 @@ Account::getLevel(void) const * Set the characters. */ void -Account::setCharacters(const Players& characters) +Account::setCharacters(const Characters& characters) { mCharacters = characters; } @@ -165,7 +167,7 @@ Account::setCharacters(const Players& characters) * Add a new character. */ void -Account::addCharacter(PlayerPtr character) +Account::addCharacter(CharacterPtr character) { if (character.get() != 0) { mCharacters.push_back(character); @@ -177,10 +179,10 @@ Account::addCharacter(PlayerPtr character) */ bool Account::delCharacter(std::string const &name) { - Players::iterator + Characters::iterator end = mCharacters.end(), it = std::find_if(mCharacters.begin(), end, - std::bind2nd(obj_name_is<PlayerPtr>(), name)); + std::bind2nd(obj_name_is<CharacterPtr>(), name)); if (it == end) return false; mCharacters.erase(it); @@ -191,7 +193,7 @@ bool Account::delCharacter(std::string const &name) /** * Get all the characters. */ -Players &Account::getCharacters() +Characters &Account::getCharacters() { return mCharacters; } @@ -200,15 +202,15 @@ Players &Account::getCharacters() /** * Get a character by name. */ -PlayerPtr Account::getCharacter(const std::string& name) +CharacterPtr Account::getCharacter(const std::string& name) { - Players::iterator + Characters::iterator end = mCharacters.end(), it = std::find_if(mCharacters.begin(), end, - std::bind2nd(obj_name_is<PlayerPtr>(), name)); + std::bind2nd(obj_name_is<CharacterPtr>(), name)); if (it != end) return *it; - return PlayerPtr(); + return CharacterPtr(); } void Account::setID(int id) diff --git a/src/account-server/account.hpp b/src/account-server/account.hpp index e717e118..50129579 100644 --- a/src/account-server/account.hpp +++ b/src/account-server/account.hpp @@ -26,21 +26,10 @@ #include <string> #include "defines.h" -#include "playerdata.hpp" +#include "account-server/characterdata.hpp" #include "utils/countedptr.h" /** - * Type definition for a smart pointer to PlayerData. - */ -typedef utils::CountedPtr< PlayerData > PlayerPtr; - -/** - * Type definition for a list of Players. - */ -typedef std::vector< PlayerPtr > Players; - - -/** * Notes: * - change from the previous implementation: this class does not encrypt * passwords anymore and will just store the passwords as they are @@ -52,9 +41,8 @@ typedef std::vector< PlayerPtr > Players; * encrypt the password twice). */ - /** - * A player account. + * A player's account. */ class Account { @@ -83,7 +71,7 @@ class Account Account(const std::string& name, const std::string& password, const std::string& email, - const Players& characters); + const Characters& characters); /** @@ -170,7 +158,7 @@ class Account * @param characters a list of characters. */ void - setCharacters(const Players& characters); + setCharacters(const Characters& characters); /** @@ -179,7 +167,7 @@ class Account * @param character the new character. */ void - addCharacter(PlayerPtr character); + addCharacter(CharacterPtr character); /** * Remove a character. @@ -195,7 +183,7 @@ class Account * * @return all the characters. */ - Players& + Characters& getCharacters(); /** @@ -203,7 +191,7 @@ class Account * * @return the character if found, NULL otherwise. */ - PlayerPtr + CharacterPtr getCharacter(const std::string& name); /** @@ -231,7 +219,7 @@ class Account std::string mName; /**< user name */ std::string mPassword; /**< user password (encrypted) */ std::string mEmail; /**< user email address */ - Players mCharacters; /**< player data */ + Characters mCharacters; /**< Character data */ AccountLevel mLevel; /**< account level */ }; diff --git a/src/account-server/accountclient.cpp b/src/account-server/accountclient.cpp index 79d3cf0c..8be44289 100644 --- a/src/account-server/accountclient.cpp +++ b/src/account-server/accountclient.cpp @@ -21,9 +21,11 @@ * $Id$ */ -#include "account-server/account.hpp" #include "account-server/accountclient.hpp" + +#include "account-server/account.hpp" #include "account-server/accounthandler.hpp" +#include "account-server/characterdata.hpp" AccountClient::AccountClient(ENetPeer *peer): NetComputer(peer), @@ -44,7 +46,7 @@ void AccountClient::setAccount(AccountPtr acc) mAccountPtr = acc; } -void AccountClient::setCharacter(PlayerPtr ch) +void AccountClient::setCharacter(CharacterPtr ch) { unsetCharacter(); mCharacterPtr = ch; @@ -59,5 +61,5 @@ void AccountClient::unsetAccount() void AccountClient::unsetCharacter() { if (mCharacterPtr.get() == NULL) return; - mCharacterPtr = PlayerPtr(NULL); + mCharacterPtr = CharacterPtr(NULL); } diff --git a/src/account-server/accountclient.hpp b/src/account-server/accountclient.hpp index 8d42e0e4..eb88016c 100644 --- a/src/account-server/accountclient.hpp +++ b/src/account-server/accountclient.hpp @@ -27,6 +27,7 @@ #include <enet/enet.h> #include "account-server/account.hpp" +#include "account-server/characterdata.hpp" #include "net/netcomputer.hpp" class AccountHandler; @@ -70,7 +71,7 @@ class AccountClient : public NetComputer * Set the selected character associated with connection. */ void - setCharacter(PlayerPtr ch); + setCharacter(CharacterPtr ch); /** * Deselect the character associated with connection. @@ -81,7 +82,7 @@ class AccountClient : public NetComputer /** * Get character associated with the connection */ - PlayerPtr + CharacterPtr getCharacter() const { return mCharacterPtr; } private: @@ -89,7 +90,7 @@ class AccountClient : public NetComputer AccountPtr mAccountPtr; /** Selected character */ - PlayerPtr mCharacterPtr; + CharacterPtr mCharacterPtr; }; #endif diff --git a/src/account-server/accounthandler.cpp b/src/account-server/accounthandler.cpp index c6a086ea..d5d5d35f 100644 --- a/src/account-server/accounthandler.cpp +++ b/src/account-server/accounthandler.cpp @@ -28,6 +28,7 @@ #include "point.h" #include "account-server/account.hpp" #include "account-server/accountclient.hpp" +#include "account-server/characterdata.hpp" #include "account-server/serverhandler.hpp" #include "account-server/storage.hpp" #include "chat-server/chathandler.hpp" @@ -198,7 +199,7 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message) unsigned char charNum = message.readByte(); - Players &chars = computer.getAccount()->getCharacters(); + Characters &chars = computer.getAccount()->getCharacters(); // Character ID = 0 to Number of Characters - 1. if (charNum >= chars.size()) { // invalid char selection @@ -208,19 +209,22 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message) std::string address; short port; - if (!serverHandler->getGameServerFromMap(chars[charNum]->getMap(), address, port)) + if (!serverHandler->getGameServerFromMap( + chars[charNum]->getMapId(), address, port)) { result.writeByte(ERRMSG_FAILURE); - LOG_ERROR("Character Selection: No game server for the map."); + LOG_ERROR("Character Selection: " + << "No game server for the map."); break; } // set character computer.setCharacter(chars[charNum]); - PlayerPtr selectedChar = computer.getCharacter(); + CharacterPtr selectedChar = computer.getCharacter(); result.writeByte(ERRMSG_OK); - LOG_DEBUG(selectedChar->getName() << " is trying to enter the servers."); + LOG_DEBUG(selectedChar->getName() << + " is trying to enter the servers."); std::string magic_token(32, ' '); for (int i = 0; i < 32; ++i) { @@ -231,8 +235,10 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message) result.writeString(address); result.writeShort(port); // TODO: get correct address and port for the chat server - result.writeString(config.getValue("accountServerAddress", "localhost")); - result.writeShort(int(config.getValue("accountServerPort", DEFAULT_SERVER_PORT)) + 2); + result.writeString(config.getValue("accountServerAddress", + "localhost")); + result.writeShort(int(config.getValue("accountServerPort", + DEFAULT_SERVER_PORT)) + 2); serverHandler->registerGameClient(magic_token, selectedChar); registerChatClient(magic_token, selectedChar->getName(), @@ -253,7 +259,7 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message) unsigned char charNum = message.readByte(); - Players &chars = computer.getAccount()->getCharacters(); + Characters &chars = computer.getAccount()->getCharacters(); // Character ID = 0 to Number of Characters - 1. if (charNum >= chars.size()) { // invalid char selection @@ -262,11 +268,12 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message) } // Delete the character - // if the character to delete is the current character, get off of it in - // memory. + // If the character to delete is the current character, + // get off of it in memory. if ( computer.getCharacter().get() != NULL ) { - if ( computer.getCharacter()->getName() == chars[charNum].get()->getName() ) + if ( computer.getCharacter()->getName() == + chars[charNum].get()->getName() ) { computer.unsetCharacter(); } @@ -336,7 +343,7 @@ AccountHandler::handleLoginMessage(AccountClient &computer, MessageIn &msg) computer.send(reply); // Return information about available characters - Players &chars = computer.getAccount()->getCharacters(); + Characters &chars = computer.getAccount()->getCharacters(); // Send characters list for (unsigned int i = 0; i < chars.size(); i++) @@ -349,8 +356,8 @@ AccountHandler::handleLoginMessage(AccountClient &computer, MessageIn &msg) charInfo.writeByte(chars[i]->getHairColor()); charInfo.writeByte(chars[i]->getLevel()); charInfo.writeShort(chars[i]->getMoney()); - for (int j = 0; j < NB_RSTAT; ++j) - charInfo.writeShort(chars[i]->getRawStat(j)); + for (int j = 0; j < NB_ATTRIBUTES; ++j) + charInfo.writeShort(chars[i]->getAttribute(j)); computer.send(charInfo); } return; @@ -384,7 +391,8 @@ AccountHandler::handleReconnectMessage(AccountClient &computer, MessageIn &msg) if (computer.getAccount().get() == NULL) { std::string magic_token = msg.readString(32); - AccountPendingReconnects::iterator i = pendingReconnects.find(magic_token); + AccountPendingReconnects::iterator i = + pendingReconnects.find(magic_token); if (i == pendingReconnects.end()) { for (AccountPendingClients::iterator j = pendingClients.begin(), @@ -393,17 +401,15 @@ AccountHandler::handleReconnectMessage(AccountClient &computer, MessageIn &msg) if (j->second == &computer) return; //Allready inserted } pendingClients.insert(std::make_pair(magic_token, &computer)); - return; //Waiting for the gameserver, note: using return instead of an else + return; //Waiting for the gameserver } // Gameserver communication was faster, connect the client int accountID = i->second; pendingReconnects.erase(i); handleReconnectedAccount(computer, accountID); + return; } - else - { - LOG_WARN("Account tried to reconnect, but was allready logged in."); - } + LOG_WARN("Account tried to reconnect, but was allready logged in."); } void @@ -495,7 +501,8 @@ AccountHandler::handleUnregisterMessage(AccountClient &computer, // See if the account exists Storage &store = Storage::instance("tmw"); AccountPtr accPtr = store.getAccount(username); - LOG_INFO("Unregister for " << username << " with passwords #" << accPtr->getPassword() << "#" << password << "#"); + LOG_INFO("Unregister for " << username << " with passwords #" + << accPtr->getPassword() << "#" << password << "#"); if (!accPtr.get() || accPtr->getPassword() != password) { reply.writeByte(ERRMSG_INVALID_ARGUMENT); @@ -507,8 +514,8 @@ AccountHandler::handleUnregisterMessage(AccountClient &computer, store.delAccount(accPtr); reply.writeByte(ERRMSG_OK); - // If the account to delete is the current account we're logged in. - // Get out of it in memory. + // If the account to delete is the current account we're loggedin + // on, get out of it in memory. if (computer.getAccount().get() != NULL ) { if (computer.getAccount()->getName() == username) @@ -606,8 +613,8 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, return; } - // A player shouldn't have more than MAX_OF_CHARACTERS characters. - Players &chars = computer.getAccount()->getCharacters(); + // An account shouldn't have more than MAX_OF_CHARACTERS characters. + Characters &chars = computer.getAccount()->getCharacters(); if (chars.size() >= MAX_OF_CHARACTERS) { reply.writeByte(CREATE_TOO_MUCH_CHARACTERS); @@ -617,58 +624,60 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, // LATER_ON: Add race, face and maybe special attributes. - // Customization of player's stats... - RawStatistics rawStats; - for (int i = 0; i < NB_RSTAT; ++i) - rawStats.stats[i] = msg.readShort(); + // Customization of character's attributes... + unsigned short attributes[NB_ATTRIBUTES]; + for (int i = 0; i < NB_ATTRIBUTES; ++i) + attributes[i] = msg.readShort(); // We see if the difference between the lowest stat and the highest // isn't too big. - unsigned short lowestStat = 0; - unsigned short highestStat = 0; - unsigned int totalStats = 0; - bool validNonZeroRawStats = true; - for (int i = 0; i < NB_RSTAT; ++i) + unsigned short lowestAttribute = POINTS_TO_DISTRIBUTES_AT_LVL1; + unsigned short highestAttribute = 0; // start value + unsigned int totalAttributes = 0; + bool validNonZeroAttributes = true; + for (int i = 0; i < NB_ATTRIBUTES; ++i) { - unsigned short stat = rawStats.stats[i]; - // For good total stat check. - totalStats = totalStats + stat; + // For good total attributes check. + totalAttributes += attributes[i]; // For checking if all stats are at least > 0 - if (stat <= 0) validNonZeroRawStats = false; - if (lowestStat == 0 || lowestStat > stat) lowestStat = stat; - if (highestStat == 0 || highestStat < stat) highestStat = stat; + if (attributes[i] <= 0) validNonZeroAttributes = false; + if (lowestAttribute > attributes[i]) + lowestAttribute = attributes[i]; + if (highestAttribute < attributes[i]) + highestAttribute = attributes[i]; } - if (totalStats > POINTS_TO_DISTRIBUTES_AT_LVL1) + if (totalAttributes > POINTS_TO_DISTRIBUTES_AT_LVL1) { - reply.writeByte(CREATE_RAW_STATS_TOO_HIGH); + reply.writeByte(CREATE_ATTRIBUTES_TOO_HIGH); } - else if (totalStats < POINTS_TO_DISTRIBUTES_AT_LVL1) + else if (totalAttributes < POINTS_TO_DISTRIBUTES_AT_LVL1) { - reply.writeByte(CREATE_RAW_STATS_TOO_LOW); + reply.writeByte(CREATE_ATTRIBUTES_TOO_LOW); } - else if ((highestStat - lowestStat) > (signed) MAX_DIFF_BETWEEN_STATS) + else if ((highestAttribute - lowestAttribute) > + (signed) MAX_DIFF_BETWEEN_ATTRIBUTES) { - reply.writeByte(CREATE_RAW_STATS_INVALID_DIFF); + reply.writeByte(CREATE_ATTRIBUTES_INVALID_DIFF); } - else if (!validNonZeroRawStats) + else if (!validNonZeroAttributes) { - reply.writeByte(CREATE_RAW_STATS_EQUAL_TO_ZERO); + reply.writeByte(CREATE_ATTRIBUTES_EQUAL_TO_ZERO); } else { - PlayerPtr newCharacter(new PlayerData(name)); - for (int i = 0; i < NB_RSTAT; ++i) - newCharacter->setRawStat(i, rawStats.stats[i]); + CharacterPtr newCharacter(new CharacterData(name)); + for (int i = 0; i < NB_ATTRIBUTES; ++i) + newCharacter->setAttribute(i, attributes[i]); newCharacter->setMoney(0); newCharacter->setLevel(1); newCharacter->setGender(gender); newCharacter->setHairStyle(hairStyle); newCharacter->setHairColor(hairColor); - newCharacter->setMap((int) config.getValue("defaultMap", 1)); - Point startingPos = { (int) config.getValue("startX", 0), - (int) config.getValue("startY", 0) }; + newCharacter->setMapId((int) config.getValue("defaultMap", 1)); + Point startingPos((int) config.getValue("startX", 0), + (int) config.getValue("startY", 0)); newCharacter->setPos(startingPos); computer.getAccount()->addCharacter(newCharacter); @@ -689,8 +698,8 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, charInfo.writeByte(chars[slot]->getHairColor()); charInfo.writeByte(chars[slot]->getLevel()); charInfo.writeShort(chars[slot]->getMoney()); - for (int j = 0; j < NB_RSTAT; ++j) - charInfo.writeShort(chars[slot]->getRawStat(j)); + for (int j = 0; j < NB_ATTRIBUTES; ++j) + charInfo.writeShort(chars[slot]->getAttribute(j)); computer.send(charInfo); return; } @@ -731,7 +740,7 @@ handleReconnectedAccount(AccountClient &computer, int accountID) computer.send(reply); // Return information about available characters - Players &chars = computer.getAccount()->getCharacters(); + Characters &chars = computer.getAccount()->getCharacters(); // Send characters list for (unsigned int i = 0; i < chars.size(); i++) @@ -745,9 +754,9 @@ handleReconnectedAccount(AccountClient &computer, int accountID) charInfo.writeByte(chars[i]->getLevel()); charInfo.writeShort(chars[i]->getMoney()); - for (int j = 0; j < NB_RSTAT; ++j) + for (int j = 0; j < NB_ATTRIBUTES; ++j) { - charInfo.writeShort(chars[i]->getRawStat(j)); + charInfo.writeShort(chars[i]->getAttribute(j)); } computer.send(charInfo); } diff --git a/src/account-server/characterdata.cpp b/src/account-server/characterdata.cpp new file mode 100644 index 00000000..50d1562e --- /dev/null +++ b/src/account-server/characterdata.cpp @@ -0,0 +1,62 @@ +/* + * The Mana World Server + * Copyright 2007 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or any later version. + * + * The Mana World is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "account-server/characterdata.hpp" + +#include "net/messagein.hpp" + +CharacterData::CharacterData(std::string const &name, int id): + mDatabaseID(id), mAccountID(-1), mName(name), mGender(0), mHairStyle(0), + mHairColor(0), mLevel(0), mMoney(0), mMapId(0), mPos(0,0) +{ + for (int i = 0; i < NB_ATTRIBUTES; ++i) + { + mAttributes[i] = 0; + } +} + +CharacterData::CharacterData(MessageIn & msg): + mDatabaseID(-1), mAccountID(-1), mName(""), mGender(0), mHairStyle(0), + mHairColor(0), mLevel(0), mMoney(0), mMapId(0), mPos(0,0) +{ + for (int i = 0; i < NB_ATTRIBUTES; ++i) + { + mAttributes[i] = 0; + } + deserialize(msg); +} + +InventoryItem const & +CharacterData::getInventoryItem(unsigned short slot) const +{ + return mInventory[slot]; +} + +void +CharacterData::addItemToInventory(const InventoryItem& item) +{ + // Discard items if the inventory is full + if ((int)mInventory.size() < INVENTORY_SLOTS) + { + mInventory.push_back(item); + } +} diff --git a/src/account-server/characterdata.hpp b/src/account-server/characterdata.hpp new file mode 100644 index 00000000..8911cb21 --- /dev/null +++ b/src/account-server/characterdata.hpp @@ -0,0 +1,191 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or any later version. + * + * The Mana World is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMWSERV_CHARACTERDATA +#define _TMWSERV_CHARACTERDATA + +#include "abstractcharacterdata.hpp" + +#include <string> +#include <vector> + +#include "utils/countedptr.h" + +#include "point.h" + +class MessageIn; + +class CharacterData: public AbstractCharacterData +{ + public: + + CharacterData(std::string const &name, int id = -1); + + /** + * Constructor used for creating a character from a serialised message. + */ + CharacterData(MessageIn &); + + /** + * Get and set methods + */ + + /** Gets the database id of the character. */ + int + getDatabaseID() const { return mDatabaseID; } + + /** Sets the database id of the character. */ + void + setDatabaseID(int id) { mDatabaseID = id; } + + /** Gets the account id of the account the character belongs to. */ + int + getAccountID() const { return mAccountID; } + + /** Sets the account id of the account the character belongs to. */ + void + setAccountID(int id) { mAccountID = id; } + + /** Gets the name of the character. */ + std::string const & + getName() const { return mName; } + + /** Sets the name of the character. */ + void + setName(const std::string& name) { mName = name; } + + /** Gets the gender of the character (male / female). */ + int + getGender() const { return mGender; } + + /** Sets the gender of the character (male / female). */ + void + setGender(int gender) { mGender = gender; } + + /** Gets the hairstyle of the character. */ + int + getHairStyle() const { return mHairStyle; } + + /** Sets the hairstyle of the character. */ + void + setHairStyle(int style) { mHairStyle = style; } + + /** Gets the haircolor of the character. */ + int + getHairColor() const { return mHairColor; } + + /** Sets the haircolor of the character. */ + void + setHairColor(int color) { mHairColor = color; } + + /** Gets the level of the character. */ + int + getLevel() const { return mLevel; } + + /** Sets the level of the character. */ + void + setLevel(int level) { mLevel = level; } + + /** Gets the amount of money the character has. */ + int + getMoney() const { return mMoney; } + + /** Sets the amount of money the character has. */ + void + setMoney(int amount) { mMoney = amount; } + + /** Gets the value of an attribute of the character. */ + unsigned short + getAttribute(int attributeNumber) const + { return mAttributes[attributeNumber]; } + + /** Sets the value of an attribute of the character. */ + void + setAttribute(int attributeNumber, int value) + { mAttributes[attributeNumber] = value; } + + /** Gets the Id of the map that the character is on. */ + int + getMapId() const { return mMapId; } + + /** Sets the Id of the map that the character is on. */ + void + setMapId(int mapId) { mMapId = mapId; } + + /** Gets the position of the character on the map. */ + Point const & + getPos() const { return mPos; } + + /** Sets the position of the character on the map. */ + void + setPos(const Point &p) { mPos = p; } + + /** Returns the number of inventory items. */ + int + getNumberOfInventoryItems() const { return mInventory.size(); } + + /** Returns a reference to the item in inventory at slot. */ + InventoryItem const & + getInventoryItem(unsigned short slot) const; + + /** Clears the inventory, in preperation for an update. */ + void + clearInventory() { mInventory.clear(); } + + /** Adds an inventory item to the inventory. */ + void + addItemToInventory(const InventoryItem& item); + + private: + CharacterData(CharacterData const &); + CharacterData &operator=(CharacterData const &); + + int mDatabaseID; //!< Character database ID. + //!< (-1) if not set yet. + int mAccountID; //!< Account ID of the account the character + //!< belongs to. (-1) if not set yet. + std::string mName; //!< Name of the character. + unsigned char mGender; //!< Gender of the being. + unsigned char mHairStyle; //!< Hair Style of the being. + unsigned char mHairColor; //!< Hair Color of the being. + unsigned char mLevel; //!< Level of the being. + unsigned int mMoney; //!< Wealth of the being. + unsigned short mAttributes[NB_ATTRIBUTES]; //!< The attributes of the + //!< character. + unsigned short mMapId; //!< Map the being is on. + Point mPos; //!< Position the being is at. + std::vector< InventoryItem > mInventory; //!< All the possesions of + //!< the character. +}; + +//Utility typedefs +/** + * Type definition for a smart pointer to CharacterData. + */ +typedef utils::CountedPtr< CharacterData > CharacterPtr; + +/** + * Type definition for a list of Characters. + */ +typedef std::vector< CharacterPtr > Characters; + +#endif diff --git a/src/account-server/dalstorage.cpp b/src/account-server/dalstorage.cpp index 4b1e7ea6..cd63473c 100644 --- a/src/account-server/dalstorage.cpp +++ b/src/account-server/dalstorage.cpp @@ -20,11 +20,13 @@ * $Id$ */ +#include "account-server/dalstorage.hpp" + #include <cassert> #include "configuration.h" #include "point.h" -#include "account-server/dalstorage.hpp" +#include "account-server/characterdata.hpp" #include "account-server/dalstoragesql.hpp" #include "dal/dalexcept.h" #include "dal/dataproviderfactory.h" @@ -49,7 +51,7 @@ class account_by_name }; /** - * Functor used to search a Player by ID in Players. + * Functor used to search a character by ID in Characters. */ class character_by_id { @@ -58,7 +60,7 @@ class character_by_id : mID(id) {} - bool operator()(PlayerPtr const &elem) const + bool operator()(CharacterPtr const &elem) const { return elem->getDatabaseID() == mID; } private: @@ -242,24 +244,24 @@ DALStorage::getAccount(const std::string& userName) if (!charInfo.isEmpty()) { int size = charInfo.rows(); - Players players; + Characters characters; LOG_DEBUG(userName << "'s account has " << size << " character(s) in database."); // Two steps: it seems like multiple requests cannot be alive at the same time. - std::vector< unsigned > playerIDs; + std::vector< unsigned > characterIDs; for (int k = 0; k < size; ++k) { - playerIDs.push_back(toUint(charInfo(k, 0))); + characterIDs.push_back(toUint(charInfo(k, 0))); } for (int k = 0; k < size; ++k) { - players.push_back(getCharacter(playerIDs[k])); + characters.push_back(getCharacter(characterIDs[k])); } - account->setCharacters(players); + account->setCharacters(characters); } return account; @@ -322,24 +324,24 @@ DALStorage::getAccountByID(int accountID) if (!charInfo.isEmpty()) { int size = charInfo.rows(); - Players players; + Characters characters; LOG_DEBUG("AccountID: "<< accountID << "; has " << size << " character(s) in database."); // Two steps: it seems like multiple requests cannot be alive at the same time. - std::vector< unsigned > playerIDs; + std::vector< unsigned > characterIDs; for (int k = 0; k < size; ++k) { - playerIDs.push_back(toUint(charInfo(k, 0))); + characterIDs.push_back(toUint(charInfo(k, 0))); } for (int k = 0; k < size; ++k) { - players.push_back(getCharacter(playerIDs[k])); + characters.push_back(getCharacter(characterIDs[k])); } - account->setCharacters(players); + account->setCharacters(characters); } return account; @@ -353,13 +355,13 @@ DALStorage::getAccountByID(int accountID) /** * Gets a character by database ID. */ -PlayerPtr DALStorage::getCharacter(int id) +CharacterPtr DALStorage::getCharacter(int id) { // connect to the database (if not connected yet). open(); // look for the character in the list first. - Players::iterator it_end = mCharacters.end(), + Characters::iterator it_end = mCharacters.end(), it = std::find_if(mCharacters.begin(), it_end, character_by_id(id)); if (it != it_end) @@ -378,7 +380,7 @@ PlayerPtr DALStorage::getCharacter(int id) // we have no choice but to return nothing. if (charInfo.isEmpty()) { - return PlayerPtr(NULL); + return CharacterPtr(NULL); } // specialize the string_to functor to convert @@ -389,39 +391,39 @@ PlayerPtr DALStorage::getCharacter(int id) // a string to an unsigned short. string_to< unsigned short > toUshort; - PlayerData *player = new PlayerData(charInfo(0, 2), toUint(charInfo(0, 0))); - player->setAccountID(toUint(charInfo(0, 1))); - player->setGender(toUshort(charInfo(0, 3))); - player->setHairStyle(toUshort(charInfo(0, 4))); - player->setHairColor(toUshort(charInfo(0, 5))); - player->setLevel(toUshort(charInfo(0, 6))); - player->setMoney(toUint(charInfo(0, 7))); - Point pos = { toUshort(charInfo(0, 8)), toUshort(charInfo(0, 9)) }; - player->setPos(pos); - for (int i = 0; i < NB_RSTAT; ++i) + CharacterData *character = new CharacterData(charInfo(0, 2), toUint(charInfo(0, 0))); + character->setAccountID(toUint(charInfo(0, 1))); + character->setGender(toUshort(charInfo(0, 3))); + character->setHairStyle(toUshort(charInfo(0, 4))); + character->setHairColor(toUshort(charInfo(0, 5))); + character->setLevel(toUshort(charInfo(0, 6))); + character->setMoney(toUint(charInfo(0, 7))); + Point pos(toUshort(charInfo(0, 8)), toUshort(charInfo(0, 9))); + character->setPos(pos); + for (int i = 0; i < NB_ATTRIBUTES; ++i) { - player->setRawStat(i, toUshort(charInfo(0, 11 + i))); + character->setAttribute(i, toUshort(charInfo(0, 11 + i))); } int mapId = toUint(charInfo(0, 10)); if (mapId > 0) { - player->setMap(mapId); + character->setMapId(mapId); } else { - // Set player to default map and one of the default location + // Set character to default map and one of the default location // Default map is to be 1, as not found return value will be 0. - player->setMap((int)config.getValue("defaultMap", 1)); + character->setMapId((int)config.getValue("defaultMap", 1)); } - PlayerPtr ptr(player); + CharacterPtr ptr(character); mCharacters.push_back(ptr); return ptr; } catch (const DbSqlQueryExecFailure& e) { - return PlayerPtr(NULL); // TODO: Throw exception here + return CharacterPtr(NULL); // TODO: Throw exception here } } @@ -516,6 +518,122 @@ bool DALStorage::doesCharacterNameExist(const std::string& name) return true; } +bool +DALStorage::updateCharacter(CharacterPtr character) +{ + // If not opened already + open(); + + //Character data (see CharacterData for details) + try + { + std::ostringstream sqlUpdateCharacterInfo; + sqlUpdateCharacterInfo + << "update " << CHARACTERS_TBL_NAME << " " + << "set" + << "gender = " << character->getGender() + << ", " + << "hair_style = " << (int)character->getHairStyle() + << ", " + << "hair_color = " << (int)character->getHairColor() + << ", " + << "level = " << (int)character->getLevel() + << ", " + << "money = " << character->getMoney() + << ", " + << "x = " << character->getPos().x + << ", " + << "y = " << character->getPos().y + << ", " + << "map_id = " << character->getMapId() + << ", " + << "str = " << character->getAttribute(ATT_STRENGTH) + << ", " + << "agi = " << character->getAttribute(ATT_AGILITY) + << ", " + << "vit = " << character->getAttribute(ATT_VITALITY) + << ", " +#if defined(MYSQL_SUPPORT) || defined(POSTGRESQL_SUPPORT) + << "`int` = " +#else + << "int = " +#endif + << character->getAttribute(ATT_INTELLIGENCE) + << ", " + << "dex = " << character->getAttribute(ATT_DEXTERITY) + << ", " + << "luck = " << character->getAttribute(ATT_LUCK) + << "where id = " << character->getDatabaseID() + << ";"; + + mDb->execSql(sqlUpdateCharacterInfo.str()); + } + catch (const dal::DbSqlQueryExecFailure& e) + { + // TODO: throw an exception. + LOG_ERROR("SQL query failure: " << e.what()); + return false; + } + + /** + * Character's inventory + */ + + // Delete the old inventory first + try + { + std::ostringstream sqlDeleteCharacterInventory; + sqlDeleteCharacterInventory + << "delete * from " << INVENTORIES_TBL_NAME + << "where owner_id = " << character->getDatabaseID() << ";"; + + mDb->execSql(sqlDeleteCharacterInventory.str()); + } + catch (const dal::DbSqlQueryExecFailure& e) + { + // TODO: throw an exception. + LOG_ERROR("SQL query failure: " << e.what()); + return false; + } + + // Insert the new inventory data + try + { + if (character->getNumberOfInventoryItems()) + { + std::ostringstream sqlInsertCharacterInventory; + sqlInsertCharacterInventory + << "insert into " << INVENTORIES_TBL_NAME + << "(owner_id, class_id, amount, equipped) " + << "values "; + + for (int j = 0; ; ) + { + sqlInsertCharacterInventory + << "(" << character->getDatabaseID() << ", " + << character->getInventoryItem(j).itemClassId << ", " + << character->getInventoryItem(j).numberOfItemsInSlot + << ", " + << (unsigned short) + character->getInventoryItem(j).isEquiped + << ")"; + // Adding the comma only if it's needed + if (++j < character->getNumberOfInventoryItems()) + sqlInsertCharacterInventory << ", "; + } + + mDb->execSql(sqlInsertCharacterInventory.str()); + } + } + catch (const dal::DbSqlQueryExecFailure& e) + { + // TODO: throw an exception. + LOG_ERROR("SQL query failure: " << e.what()); + return false; + } + return true; +} + std::map<short, ChatChannel> DALStorage::getChannelList() { @@ -603,7 +721,8 @@ DALStorage::updateChannels(std::map<short, ChatChannel>& channelList) << i->second.getPassword() << "\", \"" << i->second.getPrivacy() << "\");"; - LOG_DEBUG("Channel (" << i->first << ") saved: " << i->second.getName() + LOG_DEBUG("Channel (" << i->first << ") saved: " + << i->second.getName() << ": " << i->second.getAnnouncement()); } @@ -724,10 +843,10 @@ void DALStorage::flush(AccountPtr const &account) mDb->execSql(sqlUpdateAccountTable.str()); // get the list of characters that belong to this account. - Players &characters = account->getCharacters(); + Characters &characters = account->getCharacters(); // insert or update the characters. - for (Players::const_iterator it = characters.begin(), + for (Characters::const_iterator it = characters.begin(), it_end = characters.end(); it != it_end; ++it) { if ((*it)->getDatabaseID() < 0) { @@ -748,13 +867,13 @@ void DALStorage::flush(AccountPtr const &account) << (*it)->getMoney() << ", " << (*it)->getPos().x << ", " << (*it)->getPos().y << ", " - << (*it)->getMap() << ", " - << (*it)->getRawStat(STAT_STRENGTH) << ", " - << (*it)->getRawStat(STAT_AGILITY) << ", " - << (*it)->getRawStat(STAT_VITALITY) << ", " - << (*it)->getRawStat(STAT_INTELLIGENCE) << ", " - << (*it)->getRawStat(STAT_DEXTERITY) << ", " - << (*it)->getRawStat(STAT_LUCK) << ");"; + << (*it)->getMapId() << ", " + << (*it)->getAttribute(ATT_STRENGTH) << ", " + << (*it)->getAttribute(ATT_AGILITY) << ", " + << (*it)->getAttribute(ATT_VITALITY) << ", " + << (*it)->getAttribute(ATT_INTELLIGENCE) << ", " + << (*it)->getAttribute(ATT_DEXTERITY) << ", " + << (*it)->getAttribute(ATT_LUCK) << ");"; mDb->execSql(sqlInsertCharactersTable.str()); } else { @@ -769,17 +888,17 @@ void DALStorage::flush(AccountPtr const &account) << " money = " << (*it)->getMoney() << ", " << " x = " << (*it)->getPos().x << ", " << " y = " << (*it)->getPos().y << ", " - << " map_id = " << (*it)->getMap() << ", " - << " str = " << (*it)->getRawStat(STAT_STRENGTH) << ", " - << " agi = " << (*it)->getRawStat(STAT_AGILITY) << ", " - << " vit = " << (*it)->getRawStat(STAT_VITALITY) << ", " + << " map_id = " << (*it)->getMapId() << ", " + << " str = " << (*it)->getAttribute(ATT_STRENGTH) << ", " + << " agi = " << (*it)->getAttribute(ATT_AGILITY) << ", " + << " vit = " << (*it)->getAttribute(ATT_VITALITY) << ", " #if defined(MYSQL_SUPPORT) || defined(POSTGRESQL_SUPPORT) - << " `int` = " << (*it)->getRawStat(STAT_INTELLIGENCE) << ", " + << " `int` = " << (*it)->getAttribute(ATT_INTELLIGENCE) << ", " #else - << " int = " << (*it)->getRawStat(STAT_INTELLIGENCE) << ", " + << " int = " << (*it)->getAttribute(ATT_INTELLIGENCE) << ", " #endif - << " dex = " << (*it)->getRawStat(STAT_DEXTERITY) << ", " - << " luck = " << (*it)->getRawStat(STAT_LUCK) + << " dex = " << (*it)->getAttribute(ATT_DEXTERITY) << ", " + << " luck = " << (*it)->getAttribute(ATT_LUCK) << " where id = " << (*it)->getDatabaseID() << ";"; mDb->execSql(sqlUpdateCharactersTable.str()); @@ -829,7 +948,7 @@ void DALStorage::flush(AccountPtr const &account) for (unsigned int i = 0; i < charInMemInfo.rows(); ++i) // in database { charFound = false; - for (Players::const_iterator it = characters.begin(), + for (Characters::const_iterator it = characters.begin(), it_end = characters.end(); it != it_end; ++it) // In memory { if (charInMemInfo(i, 0) == (*it)->getName()) @@ -878,7 +997,7 @@ void DALStorage::delAccount(AccountPtr const &account) { using namespace dal; - account->setCharacters(Players()); + account->setCharacters(Characters()); flush(account); mAccounts.erase(account->getID()); diff --git a/src/account-server/dalstorage.hpp b/src/account-server/dalstorage.hpp index 674b67f6..e6f6d185 100644 --- a/src/account-server/dalstorage.hpp +++ b/src/account-server/dalstorage.hpp @@ -24,6 +24,7 @@ #ifndef _TMWSERV_DALSTORAGE_H_ #define _TMWSERV_DALSTORAGE_H_ +#include "account-server/characterdata.hpp" #include "account-server/storage.hpp" #include "dal/dataprovider.h" @@ -82,7 +83,7 @@ class DALStorage: public Storage * * @return the character associated to the ID. */ - PlayerPtr getCharacter(int id); + CharacterPtr getCharacter(int id); /** * Add a new account. @@ -127,6 +128,16 @@ class DALStorage: public Storage bool doesCharacterNameExist(std::string const &name); /** + * Updates the data for a single character, does not update the + * owning account or the characters name. + * Primary usage should be storing characterdata received from a + * game server. + * returns true if succefull, false otherwise. + */ + bool + updateCharacter(CharacterPtr ptr); + + /** * Gives the list of opened public channels registered in database * @return a map of the public channels */ diff --git a/src/account-server/dalstoragesql.hpp b/src/account-server/dalstoragesql.hpp index 1511e20b..655cbac6 100644 --- a/src/account-server/dalstoragesql.hpp +++ b/src/account-server/dalstoragesql.hpp @@ -129,7 +129,7 @@ const std::string SQL_CHARACTERS_TABLE( "x SMALLINT UNSIGNED NOT NULL," "y SMALLINT UNSIGNED NOT NULL," "map_id TINYINT NOT NULL," - // stats + // attributes "str SMALLINT UNSIGNED NOT NULL," "agi SMALLINT UNSIGNED NOT NULL," "vit SMALLINT UNSIGNED NOT NULL," @@ -154,7 +154,7 @@ const std::string SQL_CHARACTERS_TABLE( "x INTEGER NOT NULL," "y INTEGER NOT NULL," "map_id INTEGER NOT NULL," - // stats + // attributes "str INTEGER NOT NULL," "agi INTEGER NOT NULL," "vit INTEGER NOT NULL," @@ -177,7 +177,7 @@ const std::string SQL_CHARACTERS_TABLE( "x INTEGER NOT NULL," "y INTEGER NOT NULL," "map_id INTEGER NOT NULL," - // stats + // attributes "str INTEGER NOT NULL," "agi INTEGER NOT NULL," "vit INTEGER NOT NULL," @@ -277,25 +277,26 @@ const std::string INVENTORIES_TBL_NAME("tmw_inventories"); const std::string SQL_INVENTORIES_TABLE( "CREATE TABLE tmw_inventories (" #if defined (MYSQL_SUPPORT) - "id SMALLINT NOT NULL," + "id INTEGER PRIMARY KEY AUTO_INCREMENT," "owner_id INTEGER NOT NULL," + "class_id INTEGER NOT NULL," "amount SMALLINT NOT NULL," "equipped TINYINT NOT NULL," - "FOREIGN KEY (id) REFERENCES tmw_items(id)," "FOREIGN KEY (owner_id) REFERENCES tmw_characters(id)" + "INDEX (id)" #elif defined (SQLITE_SUPPORT) - "id INTEGER NOT NULL," + "id INTEGER PRIMARY KEY," "owner_id INTEGER NOT NULL," + "class_id INTEGER NOT NULL," "amount INTEGER NOT NULL," "equipped INTEGER NOT NULL," - "FOREIGN KEY (id) REFERENCES tmw_items(id)," "FOREIGN KEY (owner_id) REFERENCES tmw_characters(id)" #elif defined (POSTGRESQL_SUPPORT) - "id INTEGER NOT NULL," + "id SERIAL PRIMARY KEY," "owner_id INTEGER NOT NULL," + "class_id INTEGER NOT NULL," "amount INTEGER NOT NULL," "equipped INTEGER NOT NULL," - "FOREIGN KEY (id) REFERENCES tmw_items(id)," "FOREIGN KEY (owner_id) REFERENCES tmw_characters(id)" #endif ");" diff --git a/src/account-server/main-account.cpp b/src/account-server/main-account.cpp index cf743688..6e2ef77a 100644 --- a/src/account-server/main-account.cpp +++ b/src/account-server/main-account.cpp @@ -45,7 +45,7 @@ #include "utils/stringfilter.h" // Default options that automake should be able to override. -#define DEFAULT_LOG_FILE "tmwserv.log" +#define DEFAULT_LOG_FILE "tmwserv-account.log" #define DEFAULT_CONFIG_FILE "tmwserv.xml" #define DEFAULT_ITEMSDB_FILE "items.xml" diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp index e4ec218f..9a6dd667 100644 --- a/src/account-server/serverhandler.cpp +++ b/src/account-server/serverhandler.cpp @@ -24,6 +24,7 @@ #include <cassert> #include <sstream> +#include "account-server/characterdata.hpp" #include "account-server/serverhandler.hpp" #include "account-server/storage.hpp" #include "net/messagein.hpp" @@ -73,14 +74,14 @@ bool ServerHandler::getGameServerFromMap(unsigned mapId, std::string &address, return true; } -void ServerHandler::registerGameClient(std::string const &token, PlayerPtr ptr) +void ServerHandler::registerGameClient(std::string const &token, CharacterPtr ptr) { - unsigned mapId = ptr->getMap(); + unsigned mapId = ptr->getMapId(); + MessageOut msg(AGMSG_PLAYER_ENTER); - msg.writeLong(ptr->getDatabaseID()); - msg.writeString(ptr->getName()); msg.writeString(token, 32); - ptr->serialize(msg); + ptr->serialize(msg); //Characterdata + Servers::const_iterator i = servers.find(mapId); assert(i != servers.end()); i->second.server->send(msg); @@ -123,19 +124,14 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) case GAMSG_PLAYER_DATA: { LOG_DEBUG("GAMSG_PLAYER_DATA"); - int id = msg.readLong(); + Storage &store = Storage::instance("tmw"); - PlayerPtr ptr = store.getCharacter(id); + CharacterPtr ptr(new CharacterData(msg)); + + if (!store.updateCharacter(ptr)) + LOG_ERROR("Received character data for non-existing" << + " character " << ptr->getDatabaseID() << "."); - if (ptr.get() != NULL) - { - ptr->deserialize(msg); - } - else - { - LOG_ERROR("Received player data for non-existing player " << - id << "."); - } } break; case GAMSG_REDIRECT: @@ -148,10 +144,10 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) magic_token[i] = 1 + (int)(127 * (rand() / (RAND_MAX + 1.0))); } Storage &store = Storage::instance("tmw"); - PlayerPtr ptr = store.getCharacter(id); + CharacterPtr ptr = store.getCharacter(id); std::string address; short port; - if (serverHandler->getGameServerFromMap(ptr->getMap(), address, + if (serverHandler->getGameServerFromMap(ptr->getMapId(), address, port)) { registerGameClient(magic_token, ptr); @@ -164,7 +160,7 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) else { LOG_ERROR("Server Change: No game server for map " << - ptr->getMap() << "."); + ptr->getMapId() << "."); } } break; @@ -175,7 +171,7 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) std::string magic_token = msg.readString(32); Storage &store = Storage::instance("tmw"); - PlayerPtr ptr = store.getCharacter(characterID); + CharacterPtr ptr = store.getCharacter(characterID); int accountID = ptr->getAccountID(); registerAccountReconnect(accountID, magic_token); diff --git a/src/account-server/serverhandler.hpp b/src/account-server/serverhandler.hpp index 30dadd65..cc269165 100644 --- a/src/account-server/serverhandler.hpp +++ b/src/account-server/serverhandler.hpp @@ -26,16 +26,11 @@ #include <map> -#include "playerdata.hpp" +#include "account-server/characterdata.hpp" #include "net/connectionhandler.hpp" #include "utils/countedptr.h" /** - * Type definition for a smart pointer to PlayerData. - */ -typedef utils::CountedPtr< PlayerData > PlayerPtr; - -/** * Manages communications with all the game servers. This class also keeps * track of the maps each game server supports. */ @@ -54,9 +49,9 @@ class ServerHandler: public ConnectionHandler bool getGameServerFromMap(unsigned, std::string &address, short &port); /** - * Sends a magic token and player data to the relevant game server. + * Sends a magic token and character data to the relevant game server. */ - void registerGameClient(std::string const &, PlayerPtr); + void registerGameClient(std::string const &, CharacterPtr); protected: /** diff --git a/src/account-server/storage.hpp b/src/account-server/storage.hpp index 031acf4d..15f0a5ff 100644 --- a/src/account-server/storage.hpp +++ b/src/account-server/storage.hpp @@ -28,6 +28,7 @@ #include <map> #include "account-server/account.hpp" +#include "account-server/characterdata.hpp" #include "chat-server/chatchannel.hpp" /** @@ -189,7 +190,7 @@ class Storage * * @return the character associated to the ID. */ - virtual PlayerPtr getCharacter(int id) = 0; + virtual CharacterPtr getCharacter(int id) = 0; /** * Add a new account. @@ -240,6 +241,16 @@ class Storage virtual bool doesCharacterNameExist(std::string const &name) = 0; /** + * Updates the data for a single character, does not update the + * owning account or the characters name. + * Primary usage should be storing characterdata received from a + * game server. + * returns true if succefull, false otherwise. + */ + virtual bool + updateCharacter(CharacterPtr ptr) = 0; + + /** * Gives the list of opened public channels registered in database * @return a map of the public channels */ @@ -295,7 +306,7 @@ class Storage protected: Accounts mAccounts; /**< list of accounts in memory */ - Players mCharacters; /**< the loaded characters */ + Characters mCharacters; /**< the loaded characters */ bool mIsOpen; /**< flag is true if the storage is open */ |