diff options
Diffstat (limited to 'src/account-server')
-rw-r--r-- | src/account-server/flooritem.h | 66 | ||||
-rw-r--r-- | src/account-server/main-account.cpp | 5 | ||||
-rw-r--r-- | src/account-server/serverhandler.cpp | 52 | ||||
-rw-r--r-- | src/account-server/storage.cpp | 140 | ||||
-rw-r--r-- | src/account-server/storage.h | 33 |
5 files changed, 275 insertions, 21 deletions
diff --git a/src/account-server/flooritem.h b/src/account-server/flooritem.h new file mode 100644 index 00000000..436dedbc --- /dev/null +++ b/src/account-server/flooritem.h @@ -0,0 +1,66 @@ +/* + * The Mana Server + * Copyright (C) 2011 The Mana Development Team + * + * This file is part of The Mana Server. + * + * The Mana Server 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 Server 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 Server. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef FLOOR_ITEM_H +#define FLOOR_ITEM_H + +class FloorItem +{ +public: + FloorItem(): + mItemId(0), mItemAmount(0), mPosX(0), mPosY(0) + {} + + FloorItem(int itemId, int itemAmount, int posX, int posY): + mItemId(itemId), mItemAmount(itemAmount), mPosX(posX), mPosY(posY) + {} + + /** + * Returns the item id + */ + int getItemId() const + { return mItemId; } + + /** + * Returns the amount of items + */ + int getItemAmount() const + { return mItemAmount; } + + /** + * Returns the position x of the item(s) + */ + int getPosX() const + { return mPosX; } + + /** + * Returns the position x of the item(s) + */ + int getPosY() const + { return mPosY; } + +private: + int mItemId; + int mItemAmount; + int mPosX; + int mPosY; +}; + +#endif // FLOOR_ITEM_H diff --git a/src/account-server/main-account.cpp b/src/account-server/main-account.cpp index 01ec0cea..0adf1285 100644 --- a/src/account-server/main-account.cpp +++ b/src/account-server/main-account.cpp @@ -347,8 +347,9 @@ int main(int argc, char *argv[]) LOG_INFO("The Mana Account+Chat Server (unknown version)"); #endif LOG_INFO("Manaserv Protocol version " << ManaServ::PROTOCOL_VERSION - << ", " << "Enet version " << ENET_VERSION_MAJOR << "." - << ENET_VERSION_MINOR << "." << ENET_VERSION_PATCH); + << ", Enet version " << ENET_VERSION_MAJOR << "." + << ENET_VERSION_MINOR << "." << ENET_VERSION_PATCH + << ", Database version " << ManaServ::SUPPORTED_DB_VERSION); if (!options.verbosityChanged) options.verbosity = static_cast<Logger::Level>( diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp index e5bfdc40..6a41d715 100644 --- a/src/account-server/serverhandler.cpp +++ b/src/account-server/serverhandler.cpp @@ -27,6 +27,7 @@ #include "account-server/accountclient.h" #include "account-server/accounthandler.h" #include "account-server/character.h" +#include "account-server/flooritem.h" #include "account-server/storage.h" #include "chat-server/chathandler.h" #include "chat-server/post.h" @@ -241,9 +242,15 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) else { MessageOut outMsg(AGMSG_ACTIVE_MAP); + + // Map variables outMsg.writeInt16(id); std::map<std::string, std::string> variables; variables = storage->getAllWorldStateVars(id); + + // Map vars number + outMsg.writeInt16(variables.size()); + for (std::map<std::string, std::string>::iterator i = variables.begin(); i != variables.end(); i++) @@ -251,6 +258,23 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) outMsg.writeString(i->first); outMsg.writeString(i->second); } + + // Persistent Floor Items + std::list<FloorItem> items; + items = storage->getFloorItemsFromMap(id); + + outMsg.writeInt16(items.size()); //number of floor items + + // Send each map item: item_id, amount, pos_x, pos_y + for (std::list<FloorItem>::iterator i = items.begin(); + i != items.end(); ++i) + { + outMsg.writeInt32(i->getItemId()); + outMsg.writeInt16(i->getItemAmount()); + outMsg.writeInt16(i->getPosX()); + outMsg.writeInt16(i->getPosY()); + } + comp->send(outMsg); MapStatistics &m = server->maps[id]; m.nbThings = 0; @@ -549,6 +573,34 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) chatHandler->handlePartyInvite(msg); break; + case GAMSG_CREATE_ITEM_ON_MAP: + { + int mapId = msg.readInt32(); + int itemId = msg.readInt32(); + int amount = msg.readInt16(); + int posX = msg.readInt16(); + int posY = msg.readInt16(); + + LOG_DEBUG("Gameserver create item " << itemId + << " on map " << mapId); + + storage->addFloorItem(mapId, itemId, amount, posX, posY); + } break; + + case GAMSG_REMOVE_ITEM_ON_MAP: + { + int mapId = msg.readInt32(); + int itemId = msg.readInt32(); + int amount = msg.readInt16(); + int posX = msg.readInt16(); + int posY = msg.readInt16(); + + LOG_DEBUG("Gameserver removed item " << itemId + << " from map " << mapId); + + storage->removeFloorItem(mapId, itemId, amount, posX, posY); + } break; + default: LOG_WARN("ServerHandler::processMessage, Invalid message type: " << msg.getId()); diff --git a/src/account-server/storage.cpp b/src/account-server/storage.cpp index 3d6d4f51..a1d1694b 100644 --- a/src/account-server/storage.cpp +++ b/src/account-server/storage.cpp @@ -24,14 +24,17 @@ #include "account-server/storage.h" #include "account-server/account.h" +#include "account-server/flooritem.h" #include "chat-server/chatchannel.h" #include "chat-server/guild.h" #include "chat-server/post.h" #include "common/configuration.h" +#include "common/manaserv_protocol.h" #include "dal/dalexcept.h" #include "dal/dataproviderfactory.h" #include "utils/functors.h" #include "utils/point.h" +#include "utils/string.h" #include "utils/throwerror.h" #include "utils/xml.h" @@ -41,7 +44,6 @@ static const char *DEFAULT_ITEM_FILE = "items.xml"; // Defines the supported db version static const char *DB_VERSION_PARAMETER = "database_version"; -static const char *SUPPORTED_DB_VERSION = "16"; /* * MySQL specificities: @@ -89,6 +91,7 @@ static const char *AUCTION_TBL_NAME = "mana_auctions"; static const char *AUCTION_BIDS_TBL_NAME = "mana_auction_bids"; static const char *ONLINE_USERS_TBL_NAME = "mana_online_list"; static const char *TRANSACTION_TBL_NAME = "mana_transactions"; +static const char *FLOOR_ITEMS_TBL_NAME = "mana_floor_items"; Storage::Storage() : mDb(dal::DataProviderFactory::createDataProvider()), @@ -118,12 +121,14 @@ void Storage::open() mDb->connect(); // Check database version here - std::string dbversion = getWorldStateVar(DB_VERSION_PARAMETER); - if (dbversion != SUPPORTED_DB_VERSION) + int dbversion = utils::stringToInt( + getWorldStateVar(DB_VERSION_PARAMETER)); + int supportedDbVersion = ManaServ::SUPPORTED_DB_VERSION; + if (dbversion != supportedDbVersion) { std::ostringstream errmsg; errmsg << "Database version is not supported. " - << "Needed version: '" << SUPPORTED_DB_VERSION + << "Needed version: '" << supportedDbVersion << "', current version: '" << dbversion << "'"; utils::throwError(errmsg.str()); } @@ -135,6 +140,15 @@ void Storage::open() std::ostringstream sql; sql << "DELETE FROM " << ONLINE_USERS_TBL_NAME; mDb->execSql(sql.str()); + + // In case where the server shouldn't keep floor item in database, + // we remove remnants at startup + if (Configuration::getValue("game_floorItemDecayTime", 0) > 0) + { + sql.clear(); + sql << "DELETE FROM " << FLOOR_ITEMS_TBL_NAME; + mDb->execSql(sql.str()); + } } catch (const DbConnectionFailure& e) { @@ -490,17 +504,26 @@ Character *Storage::getCharacterBySQL(Account *owner) try { std::ostringstream sql; - sql << " select slot_type, inventory_slot from " + sql << " select slot_type, item_id, item_instance from " << CHAR_EQUIPS_TBL_NAME << " where owner_id = '" << character->getDatabaseID() << "' order by slot_type desc;"; + EquipData equipData; const dal::RecordSet &equipInfo = mDb->execSql(sql.str()); if (!equipInfo.isEmpty()) + { + EquipmentItem equipItem; for (int k = 0, size = equipInfo.rows(); k < size; ++k) - poss.equipSlots.insert(std::pair<unsigned int, unsigned int>( - toUint(equipInfo(k, 0)), - toUint(equipInfo(k, 1)))); + { + equipItem.itemId = toUint(equipInfo(k, 1)); + equipItem.itemInstance = toUint(equipInfo(k, 2)); + equipData.insert(std::pair<unsigned int, EquipmentItem>( + toUint(equipInfo(k, 0)), + equipItem)); + } + } + poss.setEquipment(equipData); } catch (const dal::DbSqlQueryExecFailure &e) { @@ -515,6 +538,7 @@ Character *Storage::getCharacterBySQL(Account *owner) << " where owner_id = '" << character->getDatabaseID() << "' order by slot asc;"; + InventoryData inventoryData; const dal::RecordSet &itemInfo = mDb->execSql(sql.str()); if (!itemInfo.isEmpty()) { @@ -524,9 +548,10 @@ Character *Storage::getCharacterBySQL(Account *owner) unsigned short slot = toUint(itemInfo(k, 2)); item.itemId = toUint(itemInfo(k, 3)); item.amount = toUint(itemInfo(k, 4)); - poss.inventory[slot] = item; + inventoryData[slot] = item; } } + poss.setInventory(inventoryData); } catch (const dal::DbSqlQueryExecFailure &e) { @@ -798,18 +823,18 @@ bool Storage::updateCharacter(Character *character) std::ostringstream sql; sql << "insert into " << CHAR_EQUIPS_TBL_NAME - << " (owner_id, slot_type, inventory_slot) values (" + << " (owner_id, slot_type, item_id, item_instance) values (" << character->getDatabaseID() << ", "; std::string base = sql.str(); const Possessions &poss = character->getPossessions(); - for (EquipData::const_iterator it = poss.equipSlots.begin(), - it_end = poss.equipSlots.end(); - it != it_end; - ++it) + const EquipData &equipData = poss.getEquipment(); + for (EquipData::const_iterator it = equipData.begin(), + it_end = equipData.end(); it != it_end; ++it) { sql.str(""); - sql << base << it->first << ", " << it->second << ");"; + sql << base << it->first << ", " << it->second.itemId + << ", " << it->second.itemInstance << ");"; mDb->execSql(sql.str()); } @@ -820,13 +845,14 @@ bool Storage::updateCharacter(Character *character) << character->getDatabaseID() << ", "; base = sql.str(); - for (InventoryData::const_iterator j = poss.inventory.begin(), - j_end = poss.inventory.end(); j != j_end; ++j) + const InventoryData &inventoryData = poss.getInventory(); + for (InventoryData::const_iterator j = inventoryData.begin(), + j_end = inventoryData.end(); j != j_end; ++j) { sql.str(""); unsigned short slot = j->first; - unsigned int itemId = j->second.itemId; - unsigned int amount = j->second.amount; + unsigned int itemId = j->second.itemId; + unsigned int amount = j->second.amount; assert(itemId); sql << base << slot << ", " << itemId << ", " << amount << ");"; mDb->execSql(sql.str()); @@ -1361,6 +1387,82 @@ void Storage::removeGuildMember(int guildId, int memberId) } } +void Storage::addFloorItem(int mapId, int itemId, int amount, + int posX, int posY) +{ + try + { + std::ostringstream sql; + sql << "INSERT INTO " << FLOOR_ITEMS_TBL_NAME + << " (map_id, item_id, amount, pos_x, pos_y)" + << " VALUES (" + << mapId << ", " + << itemId << ", " + << amount << ", " + << posX << ", " + << posY << ");"; + mDb->execSql(sql.str()); + } + catch (const dal::DbSqlQueryExecFailure& e) + { + utils::throwError("(DALStorage::addFloorItem) SQL query failure: ", e); + } +} + +void Storage::removeFloorItem(int mapId, int itemId, int amount, + int posX, int posY) +{ + try + { + std::ostringstream sql; + sql << "DELETE FROM " << FLOOR_ITEMS_TBL_NAME + << " WHERE map_id = " + << mapId << " AND item_id = " + << itemId << " AND amount = " + << amount << " AND pos_x = " + << posX << " AND pos_y = " + << posY << ";"; + mDb->execSql(sql.str()); + } + catch (const dal::DbSqlQueryExecFailure& e) + { + utils::throwError("(DALStorage::removeFloorItem) SQL query failure: ", + e); + } +} + +std::list<FloorItem> Storage::getFloorItemsFromMap(int mapId) +{ + std::list<FloorItem> floorItems; + + try + { + std::ostringstream sql; + sql << "SELECT * FROM " << FLOOR_ITEMS_TBL_NAME + << " WHERE map_id = " << mapId; + + string_to< unsigned > toUint; + const dal::RecordSet &itemInfo = mDb->execSql(sql.str()); + if (!itemInfo.isEmpty()) + { + for (int k = 0, size = itemInfo.rows(); k < size; ++k) + { + floorItems.push_back(FloorItem(toUint(itemInfo(k, 2)), + toUint(itemInfo(k, 3)), + toUint(itemInfo(k, 4)), + toUint(itemInfo(k, 5)))); + } + } + } + catch (const dal::DbSqlQueryExecFailure &e) + { + utils::throwError("DALStorage::getFloorItemsFromMap " + "SQL query failure: ", e); + } + + return floorItems; +} + void Storage::setMemberRights(int guildId, int memberId, int rights) { try diff --git a/src/account-server/storage.h b/src/account-server/storage.h index a44156a4..3c629920 100644 --- a/src/account-server/storage.h +++ b/src/account-server/storage.h @@ -32,6 +32,7 @@ class Account; class Character; class ChatChannel; +class FloorItem; class Guild; class Letter; class Post; @@ -288,6 +289,38 @@ class Storage std::list<Guild*> getGuildList(); /** + * Add a floor item to map. + * + * Used to keep the floor item persistently between two server restart. + * + * @param mapId The map id + * @param itemId The item id + * @param posX Position X of the item in pixels + * @param posY Position Y of the item in pixels + */ + void addFloorItem(int mapId, int itemId, int amount, + int posX, int posY); + + /** + * Remove item from map persistence + * + * @param mapId The map id + * @param itemId The item id + * @param posX Position X of the item in pixels + * @param posY Position Y of the item in pixels + */ + void removeFloorItem(int mapId, int itemId, int amount, + int posX, int posY); + + + /** + * Get all persistent items from the given map id + * + * @param mapId The map id + */ + std::list<FloorItem> getFloorItemsFromMap(int mapId); + + /** * Update an account to the database. * * @param Account object to update. |