Attr_ReadValue Depot::readAttr(AttrTypes_t attr, PropStream& propStream) { if(attr != ATTR_DEPOT_ID) return Item::readAttr(attr, propStream); uint16_t depotId; if(!propStream.getShort(depotId)) return ATTR_READ_ERROR; setAttribute("depotid", depotId); return ATTR_READ_CONTINUE; }
bool ItemAttributes::unserializeMap(PropStream& stream) { uint16_t n; if(!stream.getShort(n)) return true; createAttributes(); while(n--) { std::string key; if(!stream.getString(key)) return false; ItemAttribute attr; if(!attr.unserialize(stream)) return false; (*attributes)[key] = attr; } return true; }
bool IOMapSerialize::loadItem(PropStream& propStream, Cylinder* parent, bool depotTransfer/* = false*/) { Tile* tile = NULL; if(!parent->getItem()) tile = parent->getTile(); uint16_t id = 0; propStream.getShort(id); Item* item = NULL; const ItemType& iType = Item::items[id]; if(iType.movable || iType.forceSerialize || (!depotTransfer && !tile)) { if(!(item = Item::CreateItem(id))) return true; if(!item->unserializeAttr(propStream)) { std::clog << "[Warning - IOMapSerialize::loadItem] Unserialization error [0] for item type " << id << std::endl; delete item; return false; } if(Container* container = item->getContainer()) { if(!loadContainer(propStream, container)) { delete item; return false; } } if(parent) { parent->__internalAddThing(item); item->__startDecaying(); } else delete item; return true; } if(tile) { //Stationary items if(TileItemVector* items = tile->getItemList()) { for(ItemVector::iterator it = items->begin(); it != items->end(); ++it) { if((*it)->getID() == id) { item = *it; break; } if(iType.isBed() && (*it)->getBed()) { item = *it; break; } if(iType.isDoor() && (*it)->getDoor()) { item = *it; break; } } } } if(item) { if(item->unserializeAttr(propStream)) { Container* container = item->getContainer(); if(container && !loadContainer(propStream, container)) return false; if(!item->getDoor() || item->getID() == iType.transformUseTo) item = g_game.transformItem(item, id); } else std::clog << "[Warning - IOMapSerialize::loadItem] Unserialization error [1] for item type " << id << std::endl; return true; } //The map changed since the last save, just read the attributes if(!(item = Item::CreateItem(id))) return true; item->unserializeAttr(propStream); if(Container* container = item->getContainer()) { if(!loadContainer(propStream, container)) { delete item; return false; } if(depotTransfer) { for(ItemList::const_iterator it = container->getItems(); it != container->getEnd(); ++it) parent->__addThing(NULL, (*it)); container->itemlist.clear(); } } delete item; return true; }
bool IOMapSerialize::loadMapBinaryTileBased(Map* map) { Database* db = Database::getInstance(); DBResult* result; DBQuery query; query << "SELECT `house_id`, `data` FROM `tile_store` WHERE `world_id` = " << g_config.getNumber(ConfigManager::WORLD_ID); if(!(result = db->storeQuery(query.str()))) return false; House* house = NULL; do { int32_t houseId = result->getDataInt("house_id"); house = Houses::getInstance()->getHouse(houseId); uint64_t attrSize = 0; const char* attr = result->getDataStream("data", attrSize); PropStream propStream; propStream.init(attr, attrSize); while(propStream.size()) { uint16_t x = 0, y = 0; uint8_t z = 0; propStream.getShort(x); propStream.getShort(y); propStream.getByte(z); uint32_t itemCount = 0; propStream.getLong(itemCount); Position pos(x, y, (int16_t)z); if(house && house->hasPendingTransfer()) { if(Player* player = g_game.getPlayerByGuidEx(house->getOwner())) { while(itemCount--) loadItem(propStream, player->getInbox(), true); if(player->isVirtual()) { IOLoginData::getInstance()->savePlayer(player); delete player; } } } else if(Tile* tile = map->getTile(pos)) { while(itemCount--) loadItem(propStream, tile, false); } else { std::clog << "[Error - IOMapSerialize::loadMapBinary] Unserialization of invalid tile" << " at position " << pos << std::endl; break; } } } while(result->next()); result->free(); return true; }
Attr_ReadValue Item::readAttr(AttrTypes_t attr, PropStream& propStream) { switch(attr) { case ATTR_COUNT: { uint8_t _count; if(!propStream.getByte(_count)) return ATTR_READ_ERROR; setSubType((uint16_t)_count); break; } case ATTR_ACTION_ID: { uint16_t aid; if(!propStream.getShort(aid)) return ATTR_READ_ERROR; setAttribute("aid", aid); break; } case ATTR_UNIQUE_ID: { uint16_t uid; if(!propStream.getShort(uid)) return ATTR_READ_ERROR; setUniqueId(uid); break; } case ATTR_NAME: { std::string name; if(!propStream.getString(name)) return ATTR_READ_ERROR; setAttribute("name", name); break; } case ATTR_PLURALNAME: { std::string name; if(!propStream.getString(name)) return ATTR_READ_ERROR; setAttribute("pluralname", name); break; } case ATTR_ARTICLE: { std::string article; if(!propStream.getString(article)) return ATTR_READ_ERROR; setAttribute("article", article); break; } case ATTR_ATTACK: { int32_t attack; if(!propStream.getLong((uint32_t&)attack)) return ATTR_READ_ERROR; setAttribute("attack", attack); break; } case ATTR_EXTRAATTACK: { int32_t attack; if(!propStream.getLong((uint32_t&)attack)) return ATTR_READ_ERROR; setAttribute("extraattack", attack); break; } case ATTR_DEFENSE: { int32_t defense; if(!propStream.getLong((uint32_t&)defense)) return ATTR_READ_ERROR; setAttribute("defense", defense); break; } case ATTR_EXTRADEFENSE: { int32_t defense; if(!propStream.getLong((uint32_t&)defense)) return ATTR_READ_ERROR; setAttribute("extradefense", defense); break; } case ATTR_ARMOR: { int32_t armor; if(!propStream.getLong((uint32_t&)armor)) return ATTR_READ_ERROR; setAttribute("armor", armor); break; } case ATTR_ATTACKSPEED: { int32_t attackSpeed; if(!propStream.getLong((uint32_t&)attackSpeed)) return ATTR_READ_ERROR; setAttribute("attackspeed", attackSpeed); break; } case ATTR_HITCHANCE: { int32_t hitChance; if(!propStream.getLong((uint32_t&)hitChance)) return ATTR_READ_ERROR; setAttribute("hitchance", hitChance); break; } case ATTR_SCRIPTPROTECTED: { uint8_t protection; if(!propStream.getByte(protection)) return ATTR_READ_ERROR; setAttribute("scriptprotected", protection != 0); break; } case ATTR_DUALWIELD: { uint8_t wield; if(!propStream.getByte(wield)) return ATTR_READ_ERROR; setAttribute("dualwield", wield != 0); break; } case ATTR_TEXT: { std::string text; if(!propStream.getString(text)) return ATTR_READ_ERROR; setAttribute("text", text); break; } case ATTR_WRITTENDATE: { int32_t date; if(!propStream.getLong((uint32_t&)date)) return ATTR_READ_ERROR; setAttribute("date", date); break; } case ATTR_WRITTENBY: { std::string writer; if(!propStream.getString(writer)) return ATTR_READ_ERROR; setAttribute("writer", writer); break; } case ATTR_DESC: { std::string text; if(!propStream.getString(text)) return ATTR_READ_ERROR; setAttribute("description", text); break; } case ATTR_RUNE_CHARGES: { uint8_t charges; if(!propStream.getByte(charges)) return ATTR_READ_ERROR; setSubType((uint16_t)charges); break; } case ATTR_CHARGES: { uint16_t charges; if(!propStream.getShort(charges)) return ATTR_READ_ERROR; setSubType(charges); break; } case ATTR_DURATION: { int32_t duration; if(!propStream.getLong((uint32_t&)duration)) return ATTR_READ_ERROR; setAttribute("duration", duration); break; } case ATTR_DECAYING_STATE: { uint8_t state; if(!propStream.getByte(state)) return ATTR_READ_ERROR; if((ItemDecayState_t)state != DECAYING_FALSE) setAttribute("decaying", (int32_t)DECAYING_PENDING); break; } //these should be handled through derived classes //if these are called then something has changed in the items.otb since the map was saved //just read the values //Depot class case ATTR_DEPOT_ID: { uint16_t depot; if(!propStream.getShort(depot)) return ATTR_READ_ERROR; break; } //Door class case ATTR_HOUSEDOORID: { uint8_t door; if(!propStream.getByte(door)) return ATTR_READ_ERROR; break; } //Teleport class case ATTR_TELE_DEST: { TeleportDest* dest; if(!propStream.getStruct(dest)) return ATTR_READ_ERROR; break; } //Bed class case ATTR_SLEEPERGUID: { uint32_t sleeper; if(!propStream.getLong(sleeper)) return ATTR_READ_ERROR; break; } case ATTR_SLEEPSTART: { uint32_t sleepStart; if(!propStream.getLong(sleepStart)) return ATTR_READ_ERROR; break; } //Container class case ATTR_CONTAINER_ITEMS: { uint32_t _count; propStream.getLong(_count); return ATTR_READ_ERROR; } //ItemAttributes class case ATTR_ATTRIBUTE_MAP: { bool unique = hasIntegerAttribute("uid"), ret = unserializeMap(propStream); if(!unique && hasIntegerAttribute("uid")) // unfortunately we have to do this ScriptEnviroment::addUniqueThing(this); // this attribute has a custom behavior as well if(getDecaying() != DECAYING_FALSE) setDecaying(DECAYING_PENDING); if(ret) break; } default: return ATTR_READ_ERROR; } return ATTR_READ_CONTINUE; }