diff options
author | Andreas Habel <mail@exceptionfault.de> | 2008-11-05 11:40:43 +0000 |
---|---|---|
committer | Andreas Habel <mail@exceptionfault.de> | 2008-11-05 11:40:43 +0000 |
commit | 94bf187c196769b87fbbfa9a9c083f94def82ccf (patch) | |
tree | cd18513307b2b230ae73e177f6286d40e6e52f3d /src | |
parent | bdf512bbe314e301b55ed52b1628415fa55cebe5 (diff) | |
download | manaserv-94bf187c196769b87fbbfa9a9c083f94def82ccf.tar.gz manaserv-94bf187c196769b87fbbfa9a9c083f94def82ccf.tar.bz2 manaserv-94bf187c196769b87fbbfa9a9c083f94def82ccf.tar.xz manaserv-94bf187c196769b87fbbfa9a9c083f94def82ccf.zip |
Added version information to item database. Gameserver reports its local version to account server during registration and gets notified if the version is up-to-date or outdated to prevent inconsistencies.
Diffstat (limited to 'src')
-rw-r--r-- | src/account-server/dalstorage.cpp | 53 | ||||
-rw-r--r-- | src/account-server/dalstorage.hpp | 7 | ||||
-rw-r--r-- | src/account-server/serverhandler.cpp | 20 | ||||
-rw-r--r-- | src/defines.h | 11 | ||||
-rw-r--r-- | src/game-server/accountconnection.cpp | 17 | ||||
-rw-r--r-- | src/game-server/itemmanager.cpp | 27 | ||||
-rw-r--r-- | src/game-server/itemmanager.hpp | 7 |
7 files changed, 139 insertions, 3 deletions
diff --git a/src/account-server/dalstorage.cpp b/src/account-server/dalstorage.cpp index 5d3f9577..a928d1bf 100644 --- a/src/account-server/dalstorage.cpp +++ b/src/account-server/dalstorage.cpp @@ -36,6 +36,11 @@ #include "dal/dataproviderfactory.h" #include "utils/functors.h" #include "utils/logger.h" +#include "utils/xml.hpp" + +// TODO: make data/items.xml a constant or read it from config file +#define DEFAULT_ITEM_FILE "data/items.xml" + /** * Constructor. @@ -1440,3 +1445,51 @@ void DALStorage::deletePost(Letter* letter) LOG_ERROR("(DALStorage::deletePost) SQL query failure: " << e.what()); } } + +unsigned int DALStorage::getItemDatabaseVersion(void) +{ + int version; + + // TODO: make data/items.xml a constant or read it from config file + xmlDocPtr doc = xmlReadFile(DEFAULT_ITEM_FILE, NULL, 0); + if (!doc) + { + LOG_ERROR("Item Manager: Error while parsing item database (items.xml)!"); + return 0; + } + + xmlNodePtr node = xmlDocGetRootElement(doc); + if (!node || !xmlStrEqual(node->name, BAD_CAST "items")) + { + LOG_ERROR("Item Manager:(items.xml) is not a valid database file!"); + xmlFreeDoc(doc); + return 0; + } + + for (node = node->xmlChildrenNode; node != NULL; node = node->next) + { + // Try to load the version of the item database. The version is defined + // as subversion tag embedded as XML attribute. So every modification + // to the items.xml file will increase the revision automatically. + if (xmlStrEqual(node->name, BAD_CAST "version")) + { + std::string revision = XML::getProperty(node, "revision", std::string()); + size_t found = revision.find("$Revision: "); + + if (found == std::string::npos) + { + LOG_ERROR("Itemdatabase has wrong version format string!"); + xmlFreeDoc(doc); + return 0; + } + // position 11 is the first numeric character in the SVN tag + version = atoi(revision.substr(11).c_str()); + + LOG_INFO("Loading item database version " << version); + xmlFreeDoc(doc); + return version; + } + } + xmlFreeDoc(doc); + return 0; +} diff --git a/src/account-server/dalstorage.hpp b/src/account-server/dalstorage.hpp index 253c025a..5a879bf6 100644 --- a/src/account-server/dalstorage.hpp +++ b/src/account-server/dalstorage.hpp @@ -331,6 +331,13 @@ class DALStorage */ void addAuctionItem(unsigned int itemId, int playerId, unsigned int gold); + /** + * Gets the version of the local item database. + * + * @return Version of the item database. + */ + unsigned int getItemDatabaseVersion(void); + private: /** * Copy constructor. diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp index 2e472b81..4bbe4cc4 100644 --- a/src/account-server/serverhandler.cpp +++ b/src/account-server/serverhandler.cpp @@ -177,6 +177,26 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) // TODO: check the credentials of the game server server->address = msg.readString(); server->port = msg.readShort(); + + // checks the version of the remote item database with our local copy + unsigned int dbversion = msg.readLong(); + LOG_INFO("Game server uses itemsdatabase with version " << dbversion); + + LOG_DEBUG("AGMSG_REGISTER_RESPONSE"); + MessageOut outMsg(AGMSG_REGISTER_RESPONSE); + if (dbversion == storage->getItemDatabaseVersion()) + { + LOG_DEBUG("Item databases between account server and " + "gameserver are in sync"); + outMsg.writeShort(DATA_VERSION_OK); + } + else + { + LOG_DEBUG("Item database of game server has a wrong version"); + outMsg.writeShort(DATA_VERSION_OUTDATED); + } + comp->send(outMsg); + LOG_INFO("Game server " << server->address << ':' << server->port << " wants to register " << (msg.getUnreadLength() / 2) << " maps."); diff --git a/src/defines.h b/src/defines.h index 498bad4c..15b51505 100644 --- a/src/defines.h +++ b/src/defines.h @@ -254,8 +254,9 @@ enum { GPMSG_GET_POST_RESPONSE = 0x04A3, // { S sender name, S letter, { W attachment id } } // Inter-server - GAMSG_REGISTER = 0x0500, // S address, W port, { W map id }* - AGMSG_ACTIVE_MAP = 0x0501, // W map id + GAMSG_REGISTER = 0x0500, // S address, W port, L items db revision, { W map id }* + AGMSG_REGISTER_RESPONSE = 0x0501, // C item version + AGMSG_ACTIVE_MAP = 0x0502, // W map id AGMSG_PLAYER_ENTER = 0x0510, // B*32 token, L id, S name, serialised character data GAMSG_PLAYER_DATA = 0x0520, // L id, serialised character data GAMSG_REDIRECT = 0x0530, // L id @@ -293,6 +294,12 @@ enum { ERRMSG_TOO_MANY_ATTACHMENTS // too many attachments in letter }; +// used in AGMSG_REGISTER_RESPONSE to show state of item db +enum { + DATA_VERSION_OK = 0x00, + DATA_VERSION_OUTDATED = 0x01 +}; + // Login specific return values enum { LOGIN_INVALID_VERSION = 0x40, // the user is using an incompatible protocol diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp index 492d2a1a..772369ef 100644 --- a/src/game-server/accountconnection.cpp +++ b/src/game-server/accountconnection.cpp @@ -30,6 +30,7 @@ #include "game-server/map.hpp" #include "game-server/mapcomposite.hpp" #include "game-server/mapmanager.hpp" +#include "game-server/itemmanager.hpp" #include "game-server/postman.hpp" #include "game-server/quest.hpp" #include "game-server/state.hpp" @@ -64,6 +65,7 @@ bool AccountConnection::start() MessageOut msg(GAMSG_REGISTER); msg.writeString(gameServerAddress); msg.writeShort(gameServerPort); + msg.writeLong(ItemManager::GetDatabaseVersion()); MapManager::Maps const &m = MapManager::getMaps(); for (MapManager::Maps::const_iterator i = m.begin(), i_end = m.end(); i != i_end; ++i) @@ -87,6 +89,21 @@ void AccountConnection::processMessage(MessageIn &msg) { switch (msg.getId()) { + case AGMSG_REGISTER_RESPONSE: + { + if (msg.readShort() != DATA_VERSION_OK) + { + LOG_ERROR("Item database is outdated! Please update to " + "prevent inconsistencies"); + stop(); // disconnect gracefully from account server + exit(1); // stop gameserver to prevent inconsistencies + } + else + { + LOG_DEBUG("Local item database is in sync with account server."); + } + } break; + case AGMSG_PLAYER_ENTER: { std::string token = msg.readString(MAGIC_TOKEN_LENGTH); diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index 019f4c92..a86a01ed 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -39,7 +39,7 @@ typedef std::map< int, ItemClass * > ItemClasses; static ItemClasses itemClasses; /**< Item reference */ static std::string itemReferenceFile; - +static unsigned int itemDatabaseVersion = 0; /**< Version of the loaded items database file.*/ void ItemManager::initialize(std::string const &file) { @@ -81,6 +81,26 @@ void ItemManager::reload() unsigned nbItems = 0; for (node = node->xmlChildrenNode; node != NULL; node = node->next) { + // Try to load the version of the item database. The version is defined + // as subversion tag embedded as XML attribute. So every modification + // to the items.xml file will increase the revision automatically. + if (xmlStrEqual(node->name, BAD_CAST "version")) + { + std::string revision = XML::getProperty(node, "revision", std::string()); + size_t found = revision.find("$Revision: "); + + if (found==std::string::npos) + { + LOG_ERROR("Itemdatabase has wrong version format string!"); + continue; + } + // position 11 is the first numeric character in the SVN tag + itemDatabaseVersion = atoi(revision.substr(11).c_str()); + + LOG_INFO("Loading item database version " << itemDatabaseVersion); + continue; + } + if (!xmlStrEqual(node->name, BAD_CAST "item")) { continue; @@ -263,3 +283,8 @@ ItemClass *ItemManager::getItem(int itemId) ItemClasses::const_iterator i = itemClasses.find(itemId); return i != itemClasses.end() ? i->second : NULL; } + +unsigned int ItemManager::GetDatabaseVersion(void) +{ + return itemDatabaseVersion; +} diff --git a/src/game-server/itemmanager.hpp b/src/game-server/itemmanager.hpp index a4743d6e..7e92e3f2 100644 --- a/src/game-server/itemmanager.hpp +++ b/src/game-server/itemmanager.hpp @@ -30,6 +30,8 @@ class ItemClass; namespace ItemManager { + + /** * Loads item reference file. */ @@ -49,6 +51,11 @@ namespace ItemManager * Gets the ItemClass having the given ID. */ ItemClass *getItem(int itemId); + + /** + * Gets the version of the loaded item database. + */ + unsigned int GetDatabaseVersion(void); } #endif |