diff options
Diffstat (limited to 'src/account-server')
-rw-r--r-- | src/account-server/character.cpp | 161 | ||||
-rw-r--r-- | src/account-server/character.h | 4 | ||||
-rw-r--r-- | src/account-server/serverhandler.cpp | 5 |
3 files changed, 166 insertions, 4 deletions
diff --git a/src/account-server/character.cpp b/src/account-server/character.cpp index 98fe9bd2..47bca5da 100644 --- a/src/account-server/character.cpp +++ b/src/account-server/character.cpp @@ -22,6 +22,9 @@ #include "account-server/account.h" +#include "net/messagein.h" +#include "net/messageout.h" + CharacterData::CharacterData(const std::string &name, int id): mName(name), mDatabaseID(id), @@ -38,6 +41,164 @@ CharacterData::CharacterData(const std::string &name, int id): { } +void CharacterData::serialize(MessageOut &msg) +{ + // general character properties + msg.writeInt8(getAccountLevel()); + msg.writeInt8(getGender()); + msg.writeInt8(getHairStyle()); + msg.writeInt8(getHairColor()); + msg.writeInt16(getAttributePoints()); + msg.writeInt16(getCorrectionPoints()); + + + const AttributeMap &attributes = getAttributes(); + msg.writeInt16(attributes.size()); + for (auto attributeIt : attributes) + { + msg.writeInt16(attributeIt.first); + msg.writeDouble(attributeIt.second.getBase()); + } + + // status effects currently affecting the character + msg.writeInt16(getStatusEffectSize()); + std::map<int, Status>::const_iterator status_it; + for (status_it = getStatusEffectBegin(); status_it != getStatusEffectEnd(); status_it++) + { + msg.writeInt16(status_it->first); + msg.writeInt16(status_it->second.time); + } + + // location + msg.writeInt16(getMapId()); + const Point &pos = getPosition(); + msg.writeInt16(pos.x); + msg.writeInt16(pos.y); + + // kill count + msg.writeInt16(getKillCountSize()); + std::map<int, int>::const_iterator kills_it; + for (kills_it = getKillCountBegin(); kills_it != getKillCountEnd(); kills_it++) + { + msg.writeInt16(kills_it->first); + msg.writeInt32(kills_it->second); + } + + // character abilities + const std::set<int> &abilities = getAbilities(); + msg.writeInt16(abilities.size()); + for (auto &abilityId : abilities) { + msg.writeInt32(abilityId); + } + + // inventory - must be last because size isn't transmitted + const Possessions &poss = getPossessions(); + const EquipData &equipData = poss.getEquipment(); + msg.writeInt16(equipData.size()); // number of equipment + for (EquipData::const_iterator k = equipData.begin(), + k_end = equipData.end(); k != k_end; ++k) + { + msg.writeInt16(k->first); // Equip slot id + msg.writeInt16(k->second.itemId); // ItemId + msg.writeInt16(k->second.itemInstance); // Item Instance id + } + + const InventoryData &inventoryData = poss.getInventory(); + for (InventoryData::const_iterator j = inventoryData.begin(), + j_end = inventoryData.end(); j != j_end; ++j) + { + msg.writeInt16(j->first); // slot id + msg.writeInt16(j->second.itemId); // item id + msg.writeInt16(j->second.amount); // amount + } +} + +void CharacterData::deserialize(MessageIn &msg) +{ + // general character properties + setAccountLevel(msg.readInt8()); + setGender(ManaServ::getGender(msg.readInt8())); + setHairStyle(msg.readInt8()); + setHairColor(msg.readInt8()); + setAttributePoints(msg.readInt16()); + setCorrectionPoints(msg.readInt16()); + + // character attributes + unsigned attrSize = msg.readInt16(); + for (unsigned i = 0; i < attrSize; ++i) + { + unsigned id = msg.readInt16(); + double base = msg.readDouble(), + mod = msg.readDouble(); + setAttribute(id, base); + setModAttribute(id, mod); + } + + // status effects currently affecting the character + int statusSize = msg.readInt16(); + + for (int i = 0; i < statusSize; i++) + { + int status = msg.readInt16(); + int time = msg.readInt16(); + applyStatusEffect(status, time); + } + + // location + setMapId(msg.readInt16()); + + Point temporaryPoint; + temporaryPoint.x = msg.readInt16(); + temporaryPoint.y = msg.readInt16(); + setPosition(temporaryPoint); + + // kill count + int killSize = msg.readInt16(); + for (int i = 0; i < killSize; i++) + { + int monsterId = msg.readInt16(); + int kills = msg.readInt32(); + setKillCount(monsterId, kills); + } + + // character abilities + int abilitiesSize = msg.readInt16(); + clearAbilities(); + for (int i = 0; i < abilitiesSize; i++) + { + const int id = msg.readInt32(); + giveAbility(id); + } + + + Possessions &poss = getPossessions(); + EquipData equipData; + int equipSlotsSize = msg.readInt16(); + unsigned equipSlot; + EquipmentItem equipItem; + for (int j = 0; j < equipSlotsSize; ++j) + { + equipSlot = msg.readInt16(); + equipItem.itemId = msg.readInt16(); + equipItem.itemInstance = msg.readInt16(); + equipData.insert(equipData.end(), + std::make_pair(equipSlot, equipItem)); + } + poss.setEquipment(equipData); + + // Loads inventory - must be last because size isn't transmitted + InventoryData inventoryData; + while (msg.getUnreadLength()) + { + InventoryItem i; + int slotId = msg.readInt16(); + i.itemId = msg.readInt16(); + i.amount = msg.readInt16(); + inventoryData.insert(inventoryData.end(), std::make_pair(slotId, i)); + } + poss.setInventory(inventoryData); +} + void CharacterData::setAccount(Account *acc) { mAccount = acc; diff --git a/src/account-server/character.h b/src/account-server/character.h index ff29ffe5..f61b8380 100644 --- a/src/account-server/character.h +++ b/src/account-server/character.h @@ -72,9 +72,11 @@ typedef std::map<unsigned, AttributeValue> AttributeMap; class CharacterData { public: - CharacterData(const std::string &name, int id = -1); + void serialize(MessageOut &msg); + void deserialize(MessageIn &msg); + /** * Gets the database id of the character. */ diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp index 19c32fda..273642b2 100644 --- a/src/account-server/serverhandler.cpp +++ b/src/account-server/serverhandler.cpp @@ -39,7 +39,6 @@ #include "net/connectionhandler.h" #include "net/messageout.h" #include "net/netcomputer.h" -#include "serialize/characterdata.h" #include "utils/logger.h" #include "utils/tokendispenser.h" @@ -162,7 +161,7 @@ static void registerGameClient(GameServer *s, const std::string &token, msg.writeString(token, MAGIC_TOKEN_LENGTH); msg.writeInt32(ptr->getDatabaseID()); msg.writeString(ptr->getName()); - serializeCharacterData(*ptr, msg); + ptr->serialize(msg); s->send(msg); } @@ -291,7 +290,7 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) int id = msg.readInt32(); if (CharacterData *ptr = storage->getCharacter(id, nullptr)) { - deserializeCharacterData(*ptr, msg); + ptr->deserialize(msg); if (!storage->updateCharacter(ptr)) { LOG_ERROR("Failed to update character " |