From b379c150cedfbae4775c8358369ec590ad4033f4 Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Sun, 18 Aug 2013 19:34:41 +0200 Subject: Unshared the serialization of characters This getting annoying while trying to do multiple changes. Types/structures had to be shared all the time making it nessecary to find ugly workarounds. --- src/CMakeLists.txt | 1 - src/account-server/character.cpp | 161 ++++++++++++++++++++++++ src/account-server/character.h | 4 +- src/account-server/serverhandler.cpp | 5 +- src/game-server/accountconnection.cpp | 3 +- src/game-server/being.cpp | 7 -- src/game-server/being.h | 7 -- src/game-server/character.cpp | 164 +++++++++++++++++++++++- src/game-server/character.h | 226 +--------------------------------- src/serialize/characterdata.h | 194 ----------------------------- 10 files changed, 332 insertions(+), 440 deletions(-) delete mode 100644 src/serialize/characterdata.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5cc8f1a8..97c47f65 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -131,7 +131,6 @@ SET(SRCS net/messageout.cpp net/netcomputer.h net/netcomputer.cpp - serialize/characterdata.h utils/logger.h utils/logger.cpp utils/point.h 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::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::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 &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 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 " diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp index 06674780..eed02b89 100644 --- a/src/game-server/accountconnection.cpp +++ b/src/game-server/accountconnection.cpp @@ -32,7 +32,6 @@ #include "game-server/quest.h" #include "game-server/state.h" #include "net/messagein.h" -#include "serialize/characterdata.h" #include "utils/logger.h" #include "utils/tokendispenser.h" #include "utils/tokencollector.h" @@ -107,7 +106,7 @@ void AccountConnection::sendCharacterData(Entity *p) MessageOut msg(GAMSG_PLAYER_DATA); auto *characterComponent = p->getComponent(); msg.writeInt32(characterComponent->getDatabaseID()); - serializeCharacterData(CharacterData(p, characterComponent), msg); + characterComponent->serialize(*p, msg); send(msg); } diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index b49e3cba..9b45608c 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -405,13 +405,6 @@ double BeingComponent::getModifiedAttribute(unsigned id) const return ret->second.getModifiedAttribute(); } -void BeingComponent::setModAttribute(unsigned, double) -{ - // No-op to satisfy shared structure. - // The game-server calculates this manually. - return; -} - void BeingComponent::recalculateBaseAttribute(Entity &entity, unsigned attr) { LOG_DEBUG("Being: Received update attribute recalculation request for " diff --git a/src/game-server/being.h b/src/game-server/being.h index 8e245a34..f542e3ab 100644 --- a/src/game-server/being.h +++ b/src/game-server/being.h @@ -172,13 +172,6 @@ class BeingComponent : public Component */ double getModifiedAttribute(unsigned id) const; - /** - * No-op to satisfy shared structure. - * @note The game server calculates this manually, so nothing happens - * here. - */ - void setModAttribute(unsigned, double); - /** * Checks whether or not an attribute exists in this being. * @returns True if the attribute is present in the being, false otherwise. diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 48621ef4..a08b07ff 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -36,7 +36,6 @@ #include "scripting/scriptmanager.h" #include "net/messagein.h" #include "net/messageout.h" -#include "serialize/characterdata.h" #include "utils/logger.h" @@ -105,8 +104,7 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg): mDatabaseID = msg.readInt32(); beingComponent->setName(msg.readString()); - CharacterData characterData(&entity, this); - deserializeCharacterData(characterData, msg); + deserialize(entity, msg); Inventory(&entity, mPossessions).initialize(); modifiedAllAttributes(entity);; @@ -123,6 +121,166 @@ CharacterComponent::~CharacterComponent() delete mNpcThread; } +void CharacterComponent::deserialize(Entity &entity, MessageIn &msg) +{ + auto *beingComponent = entity.getComponent(); + + // general character properties + setAccountLevel(msg.readInt8()); + beingComponent->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(); + beingComponent->setAttribute(entity, id, base); + } + + // 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(); + beingComponent->applyStatusEffect(status, time); + } + + // location + auto *map = MapManager::getMap(msg.readInt16()); + entity.setMap(map); + + Point temporaryPoint; + temporaryPoint.x = msg.readInt16(); + temporaryPoint.y = msg.readInt16(); + entity.getComponent()->setPosition(entity, 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(); + for (int i = 0; i < abilitiesSize; i++) + { + const int id = msg.readInt32(); + entity.getComponent()->giveAbility(id); + } + + + Possessions &poss = getPossessions(); + EquipData equipData; + int equipSlotsSize = msg.readInt16(); + unsigned eqSlot; + EquipmentItem equipItem; + for (int j = 0; j < equipSlotsSize; ++j) + { + eqSlot = msg.readInt16(); + equipItem.itemId = msg.readInt16(); + equipItem.itemInstance = msg.readInt16(); + equipData.insert(equipData.end(), + std::make_pair(eqSlot, 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 CharacterComponent::serialize(Entity &entity, MessageOut &msg) +{ + auto *beingComponent = entity.getComponent(); + + // general character properties + msg.writeInt8(getAccountLevel()); + msg.writeInt8(beingComponent->getGender()); + msg.writeInt8(getHairStyle()); + msg.writeInt8(getHairColor()); + msg.writeInt16(getAttributePoints()); + msg.writeInt16(getCorrectionPoints()); + + + const AttributeMap &attributes = beingComponent->getAttributes(); + msg.writeInt16(attributes.size()); + for (auto attributeIt : attributes) + { + msg.writeInt16(attributeIt.first); + msg.writeDouble(attributeIt.second.getBase()); + msg.writeDouble(attributeIt.second.getModifiedAttribute()); + } + + // status effects currently affecting the character + auto &statusEffects = beingComponent->getStatusEffects(); + msg.writeInt16(statusEffects.size()); + for (auto &statusIt : statusEffects) + { + msg.writeInt16(statusIt.first); + msg.writeInt16(statusIt.second.time); + } + + // location + msg.writeInt16(entity.getMap()->getID()); + const Point &pos = entity.getComponent()->getPosition(); + msg.writeInt16(pos.x); + msg.writeInt16(pos.y); + + // kill count + msg.writeInt16(getKillCountSize()); + for (auto &killCountIt : mKillCount) + { + msg.writeInt16(killCountIt.first); + msg.writeInt32(killCountIt.second); + } + + // character abilities + auto &abilities = entity.getComponent()->getAbilities(); + msg.writeInt16(abilities.size()); + for (auto &abilityIt : abilities) { + msg.writeInt32(abilityIt.first); + } + + // 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 CharacterComponent::update(Entity &entity) { // Dead character: don't regenerate anything else diff --git a/src/game-server/character.h b/src/game-server/character.h index 860d53e2..799b0817 100644 --- a/src/game-server/character.h +++ b/src/game-server/character.h @@ -47,59 +47,6 @@ class MessageOut; class Point; class Trade; - -class CharacterData -{ -public: - CharacterData(Entity *entity, CharacterComponent *characterComponent); - - void setGender(BeingGender); - BeingGender getGender() const; - - void setMapId(int id); - int getMapId() const; - void setPosition(Point &point); - const Point &getPosition() const; - - void setAttribute(int id, int base); - void setModAttribute(int id, int mod); - const AttributeMap &getAttributes() const; - void setAttributePoints(int characterPoints); - int getAttributePoints() const; - void setCorrectionPoints(int correctionPoints); - int getCorrectionPoints() const; - - int getAccountLevel() const; - - void setHairStyle(int style); - int getHairStyle() const; - void setHairColor(int color); - int getHairColor() const; - - void setAccountLevel(int level); - - void applyStatusEffect(int status, int time); - int getStatusEffectSize() const; - const std::map::const_iterator getStatusEffectBegin() const; - const std::map::const_iterator getStatusEffectEnd() const; - - int getKillCountSize() const; - const std::map::const_iterator getKillCountBegin() const; - const std::map::const_iterator getKillCountEnd() const; - void setKillCount(int monsterId, int kills); - - void clearAbilities(); - void giveAbility(int id); - const std::set getAbilities() const; - - Possessions &getPossessions() const; - -private: - Entity *mEntity; - CharacterComponent *mCharacterComponent; -}; - - /** * The representation of a player's character in the game world. */ @@ -336,7 +283,11 @@ class CharacterComponent : public Component sigc::signal signal_disconnected; + void serialize(Entity &entity, MessageOut &msg); + private: + void deserialize(Entity &entity, MessageIn &msg); + double getAttrBase(AttributeMap::const_iterator it) const { return it->second.getBase(); } double getAttrMod(AttributeMap::const_iterator it) const @@ -406,175 +357,6 @@ class CharacterComponent : public Component }; -inline CharacterData::CharacterData(Entity *entity, - CharacterComponent *characterComponent): - mEntity(entity), - mCharacterComponent(characterComponent) -{} - -inline void CharacterData::setGender(BeingGender gender) -{ - mEntity->getComponent()->setGender(gender); -} - -inline BeingGender CharacterData::getGender() const -{ - return mEntity->getComponent()->getGender(); -} - -inline void CharacterData::setMapId(int id) -{ - mEntity->setMap(MapManager::getMap(id)); -} - -inline int CharacterData::getMapId() const -{ - return mEntity->getMap()->getID(); -} - -inline void CharacterData::setPosition(Point &point) -{ - mEntity->getComponent()->setPosition(*mEntity, point); -} - -inline const Point &CharacterData::getPosition() const -{ - return mEntity->getComponent()->getPosition(); -} - -inline void CharacterData::setAttribute(int id, int base) -{ - mEntity->getComponent()->setAttribute(*mEntity, id, base); -} - -inline void CharacterData::setModAttribute(int id, int mod) -{ - mEntity->getComponent()->setModAttribute(id, mod); -} - -inline const AttributeMap &CharacterData::getAttributes() const -{ - return mEntity->getComponent()->getAttributes(); -} - -inline void CharacterData::setAttributePoints(int characterPoints) -{ - mCharacterComponent->setAttributePoints(characterPoints); -} - -inline int CharacterData::getAttributePoints() const -{ - return mCharacterComponent->getAttributePoints(); -} - -inline void CharacterData::setCorrectionPoints(int correctionPoints) -{ - mCharacterComponent->setCorrectionPoints(correctionPoints); -} - -inline int CharacterData::getCorrectionPoints() const -{ - return mCharacterComponent->getCorrectionPoints(); -} - -inline int CharacterData::getAccountLevel() const -{ - return mCharacterComponent->getAccountLevel(); -} - -inline void CharacterData::setHairStyle(int style) -{ - mCharacterComponent->setHairStyle(style); -} - -inline int CharacterData::getHairStyle() const -{ - return mCharacterComponent->getHairStyle(); -} - -inline void CharacterData::setHairColor(int color) -{ - mCharacterComponent->setHairColor(color); -} - -inline int CharacterData::getHairColor() const -{ - return mCharacterComponent->getHairColor(); -} - -inline void CharacterData::setAccountLevel(int level) -{ - mCharacterComponent->setAccountLevel(level); -} - -inline void CharacterData::applyStatusEffect(int status, int time) -{ - mEntity->getComponent()->applyStatusEffect(status, time); -} - -inline int CharacterData::getStatusEffectSize() const -{ - return mEntity->getComponent()->getStatusEffects().size(); -} - -inline const std::map::const_iterator CharacterData::getStatusEffectBegin() const -{ - return mEntity->getComponent()->getStatusEffects().begin(); -} - -inline const std::map::const_iterator CharacterData::getStatusEffectEnd() const -{ - return mEntity->getComponent()->getStatusEffects().end(); -} - -inline int CharacterData::getKillCountSize() const -{ - return mCharacterComponent->getKillCountSize(); -} - -inline const std::map::const_iterator CharacterData::getKillCountBegin() const -{ - return mCharacterComponent->getKillCountBegin(); -} - -inline const std::map::const_iterator CharacterData::getKillCountEnd() const -{ - return mCharacterComponent->getKillCountEnd(); -} - -inline void CharacterData::setKillCount(int monsterId, int kills) -{ - mCharacterComponent->setKillCount(monsterId, kills); -} - -inline void CharacterData::clearAbilities() -{ - mEntity->getComponent()->clearAbilities(); -} - -inline void CharacterData::giveAbility(int id) -{ - mEntity->getComponent()->giveAbility(id); -} - -inline const std::set CharacterData::getAbilities() const -{ - // TODO: remove this coping when removing the shared characterdata.h - std::set abilities; - - for (auto &it : mEntity->getComponent()->getAbilities()) { - abilities.insert(it.first); - } - - return abilities; -} - -inline Possessions &CharacterData::getPossessions() const -{ - return mCharacterComponent->getPossessions(); -} - - inline void CharacterComponent::setAttributePoints(int points) { mSendAttributePointsStatus = true; diff --git a/src/serialize/characterdata.h b/src/serialize/characterdata.h deleted file mode 100644 index 2fbe256b..00000000 --- a/src/serialize/characterdata.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * The Mana Server - * Copyright (C) 2007-2010 The Mana World 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 . - */ - -#ifndef SERIALIZE_CHARACTERDATA_H -#define SERIALIZE_CHARACTERDATA_H - -#include - -#include "common/defines.h" -#include "common/inventorydata.h" -#include "common/manaserv_protocol.h" -#include "net/messagein.h" -#include "net/messageout.h" -#include "utils/point.h" - -template< class T > -void serializeCharacterData(const T &data, MessageOut &msg) -{ - // general character properties - msg.writeInt8(data.getAccountLevel()); - msg.writeInt8(data.getGender()); - msg.writeInt8(data.getHairStyle()); - msg.writeInt8(data.getHairColor()); - msg.writeInt16(data.getAttributePoints()); - msg.writeInt16(data.getCorrectionPoints()); - - - const AttributeMap &attributes = data.getAttributes(); - msg.writeInt16(attributes.size()); - for (auto attributeIt : attributes) - { - msg.writeInt16(attributeIt.first); - msg.writeDouble(attributeIt.second.getBase()); - msg.writeDouble(attributeIt.second.getModifiedAttribute()); - } - - // status effects currently affecting the character - msg.writeInt16(data.getStatusEffectSize()); - std::map::const_iterator status_it; - for (status_it = data.getStatusEffectBegin(); status_it != data.getStatusEffectEnd(); status_it++) - { - msg.writeInt16(status_it->first); - msg.writeInt16(status_it->second.time); - } - - // location - msg.writeInt16(data.getMapId()); - const Point &pos = data.getPosition(); - msg.writeInt16(pos.x); - msg.writeInt16(pos.y); - - // kill count - msg.writeInt16(data.getKillCountSize()); - std::map::const_iterator kills_it; - for (kills_it = data.getKillCountBegin(); kills_it != data.getKillCountEnd(); kills_it++) - { - msg.writeInt16(kills_it->first); - msg.writeInt32(kills_it->second); - } - - // character abilities - const std::set &abilities = data.getAbilities(); - msg.writeInt16(abilities.size()); - for (auto &abilityId : abilities) { - msg.writeInt32(abilityId); - } - - // inventory - must be last because size isn't transmitted - const Possessions &poss = data.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 - } -} - -template< class T > -void deserializeCharacterData(T &data, MessageIn &msg) -{ - // general character properties - data.setAccountLevel(msg.readInt8()); - data.setGender(ManaServ::getGender(msg.readInt8())); - data.setHairStyle(msg.readInt8()); - data.setHairColor(msg.readInt8()); - data.setAttributePoints(msg.readInt16()); - data.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(); - data.setAttribute(id, base); - data.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(); - data.applyStatusEffect(status, time); - } - - // location - data.setMapId(msg.readInt16()); - - Point temporaryPoint; - temporaryPoint.x = msg.readInt16(); - temporaryPoint.y = msg.readInt16(); - data.setPosition(temporaryPoint); - - // kill count - int killSize = msg.readInt16(); - for (int i = 0; i < killSize; i++) - { - int monsterId = msg.readInt16(); - int kills = msg.readInt32(); - data.setKillCount(monsterId, kills); - } - - // character abilities - int abilitiesSize = msg.readInt16(); - data.clearAbilities(); - for (int i = 0; i < abilitiesSize; i++) - { - const int id = msg.readInt32(); - data.giveAbility(id); - } - - - Possessions &poss = data.getPossessions(); - EquipData equipData; - int equipSlotsSize = msg.readInt16(); - unsigned eqSlot; - EquipmentItem equipItem; - for (int j = 0; j < equipSlotsSize; ++j) - { - eqSlot = msg.readInt16(); - equipItem.itemId = msg.readInt16(); - equipItem.itemInstance = msg.readInt16(); - equipData.insert(equipData.end(), - std::make_pair(eqSlot, 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); -} - -#endif // SERIALIZE_CHARACTERDATA_H -- cgit v1.2.3-60-g2f50