bool ConditionAttributes::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { switch(attr) { case CONDITIONATTR_SKILLS: { int32_t value = 0; if(!propStream.GET_VALUE(value)) return false; skills[currentSkill++] = value; return true; } case CONDITIONATTR_STATS: { int32_t value = 0; if(!propStream.GET_VALUE(value)) return false; stats[currentStat++] = value; return true; } default: break; } return ConditionGeneric::unserializeProp(attr, propStream); }
bool Condition::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { switch (attr) { case CONDITIONATTR_TYPE: { int32_t value; if (!propStream.GET_VALUE(value)) { return false; } conditionType = (ConditionType_t)value; return true; } case CONDITIONATTR_ID: { int32_t value; if (!propStream.GET_VALUE(value)) { return false; } id = (ConditionId_t)value; return true; } case CONDITIONATTR_TICKS: { int32_t value; if (!propStream.GET_VALUE(value)) { return false; } ticks = value; return true; } case CONDITIONATTR_ISBUFF: { int8_t value; if (!propStream.GET_VALUE(value)) { return false; } isBuff = value != 0; return true; } case CONDITIONATTR_SUBID: { int32_t value; if (!propStream.GET_VALUE(value)) { return false; } subId = value; return true; } case CONDITIONATTR_END: return true; default: return false; } }
bool ConditionSoul::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { switch(attr) { case CONDITIONATTR_SOULGAIN: { uint32_t value = 0; if(!propStream.GET_VALUE(value)) return false; soulGain = value; return true; } case CONDITIONATTR_SOULTICKS: { uint32_t value = 0; if(!propStream.GET_VALUE(value)) return false; soulTicks = value; return true; } default: break; } return ConditionGeneric::unserializeProp(attr, propStream); }
bool IOMap::parseWaypoints(OTB::Loader& loader, const OTB::Node& waypointsNode, Map& map) { PropStream propStream; for (auto& node : waypointsNode.children) { if (node.type != OTBM_WAYPOINT) { setLastErrorString("Unknown waypoint node."); return false; } if (!loader.getProps(node, propStream)) { setLastErrorString("Could not read waypoint data."); return false; } std::string name; if (!propStream.readString(name)) { setLastErrorString("Could not read waypoint name."); return false; } OTBM_Destination_coords waypoint_coords; if (!propStream.read(waypoint_coords)) { setLastErrorString("Could not read waypoint coordinates."); return false; } map.waypoints[name] = Position(waypoint_coords.x, waypoint_coords.y, waypoint_coords.z); } return true; }
void IOLoginData::loadItems(ItemMap& itemMap, DBResult* result) { do { int32_t sid = result->getDataInt("sid"); int32_t pid = result->getDataInt("pid"); int32_t type = result->getDataInt("itemtype"); int32_t count = result->getDataInt("count"); unsigned long attrSize = 0; const char* attr = result->getDataStream("attributes", attrSize); PropStream propStream; propStream.init(attr, attrSize); Item* item = Item::CreateItem(type, count); if (item) { if (!item->unserializeAttr(propStream)) { std::cout << "WARNING: Serialize error in IOLoginData::loadItems" << std::endl; } std::pair<Item*, int32_t> pair(item, pid); itemMap[sid] = pair; } } while (result->next()); }
bool ConditionSpeed::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { switch(attr) { case CONDITIONATTR_SPEEDDELTA: { int32_t value = 0; if(!propStream.GET_VALUE(value)) return false; speedDelta = value; return true; } case CONDITIONATTR_FORMULA_MINA: { float value = 0; if(!propStream.GET_VALUE(value)) return false; mina = value; return true; } case CONDITIONATTR_FORMULA_MINB: { float value = 0; if(!propStream.GET_VALUE(value)) return false; minb = value; return true; } case CONDITIONATTR_FORMULA_MAXA: { float value = 0; if(!propStream.GET_VALUE(value)) return false; maxa = value; return true; } case CONDITIONATTR_FORMULA_MAXB: { float value = 0; if(!propStream.GET_VALUE(value)) return false; maxb = value; return true; } default: break; } return ConditionOutfit::unserializeProp(attr, propStream); }
bool ConditionAttributes::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { if (attr == CONDITIONATTR_SKILLS) { int32_t value = 0; if (!propStream.GET_VALUE(value)) { return false; } skills[currentSkill] = value; ++currentSkill; return true; } else if (attr == CONDITIONATTR_STATS) { int32_t value = 0; if (!propStream.GET_VALUE(value)) { return false; } stats[currentStat] = value; ++currentStat; return true; } return Condition::unserializeProp(attr, propStream); }
bool ConditionSoul::unserializeProp(const ConditionAttr_t& attr, PropStream& propStream) { if (attr == CONDITIONATTR_SOULGAIN) { uint32_t value = 0; if (!propStream.GET_UINT32(value)) { return false; } soulGain = value; return true; } else if (attr == CONDITIONATTR_SOULTICKS) { uint32_t value = 0; if (!propStream.GET_UINT32(value)) { return false; } soulTicks = value; return true; } return Condition::unserializeProp(attr, propStream); }
bool FileLoader::getProps(const NODE node, PropStream& props) { size_t size; if (const uint8_t* a = getProps(node, size)) { props.init((char*)a, size); return true; } props.init(nullptr, 0); return false; }
Attr_ReadValue Teleport::readAttr(AttrTypes_t attr, PropStream& propStream) { if (ATTR_TELE_DEST == attr) { if (!propStream.GET_USHORT(destPos.x) || !propStream.GET_USHORT(destPos.y) || !propStream.GET_UCHAR(destPos.z)) { return ATTR_READ_ERROR; } return ATTR_READ_CONTINUE; } else { return Item::readAttr(attr, propStream); } }
bool FileLoader::getProps(const NODE node, PropStream& props) { size_t size; if (const uint8_t* a = getProps(node, size)) { props.init(reinterpret_cast<const char*>(a), size); // does not break strict aliasing return true; } props.init(nullptr, 0); return false; }
bool IOMapSerialize::loadMap(Map* map) { int64_t start = OTSYS_TIME(); Database* db = Database::getInstance(); std::ostringstream query; DBResult* result = db->storeQuery("SELECT `id` FROM `houses`"); if (!result) { return true; } do { query.str(""); query << "SELECT `data` FROM `tile_store` WHERE `house_id` = " << result->getDataInt("id"); DBResult* tileResult = db->storeQuery(query.str()); if (!tileResult) { continue; } do { unsigned long attrSize = 0; const char* attr = tileResult->getDataStream("data", attrSize); PropStream propStream; propStream.init(attr, attrSize); uint16_t x = 0, y = 0; uint8_t z = 0; propStream.GET_USHORT(x); propStream.GET_USHORT(y); propStream.GET_UCHAR(z); if (x == 0 || y == 0) { continue; } Tile* tile = map->getTile(x, y, z); if (!tile) { continue; } uint32_t item_count = 0; propStream.GET_ULONG(item_count); while (item_count--) { loadItem(propStream, tile); } } while (tileResult->next()); db->freeResult(tileResult); } while (result->next()); db->freeResult(result); std::cout << "> Loaded house items in: " << (OTSYS_TIME() - start) / (1000.) << " s" << std::endl; return true; }
bool ConditionRegeneration::unserializeProp(const ConditionAttr_t& attr, PropStream& propStream) { if (attr == CONDITIONATTR_HEALTHTICKS) { uint32_t value = 0; if (!propStream.GET_UINT32(value)) { return false; } healthTicks = value; return true; } else if (attr == CONDITIONATTR_HEALTHGAIN) { uint32_t value = 0; if (!propStream.GET_UINT32(value)) { return false; } healthGain = value; return true; } else if (attr == CONDITIONATTR_MANATICKS) { uint32_t value = 0; if (!propStream.GET_UINT32(value)) { return false; } manaTicks = value; return true; } else if (attr == CONDITIONATTR_MANAGAIN) { uint32_t value = 0; if (!propStream.GET_UINT32(value)) { return false; } manaGain = value; return true; } return Condition::unserializeProp(attr, propStream); }
bool ConditionLight::unserializeProp(const ConditionAttr_t& attr, PropStream& propStream) { if (attr == CONDITIONATTR_LIGHTCOLOR) { uint32_t value = 0; if (!propStream.GET_UINT32(value)) { return false; } lightInfo.color = value; return true; } else if (attr == CONDITIONATTR_LIGHTLEVEL) { uint32_t value = 0; if (!propStream.GET_UINT32(value)) { return false; } lightInfo.level = value; return true; } else if (attr == CONDITIONATTR_LIGHTTICKS) { uint32_t value = 0; if (!propStream.GET_UINT32(value)) { return false; } internalLightTicks = value; return true; } else if (attr == CONDITIONATTR_LIGHTINTERVAL) { uint32_t value = 0; if (!propStream.GET_UINT32(value)) { return false; } lightChangeInterval = value; return true; } return Condition::unserializeProp(attr, propStream); }
bool ConditionDamage::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { switch(attr) { case CONDITIONATTR_DELAYED: { bool value = false; if(!propStream.getType(value)) return false; delayed = value; return true; } case CONDITIONATTR_PERIODDAMAGE: { int32_t value = 0; if(!propStream.getType(value)) return false; periodDamage = value; return true; } case CONDITIONATTR_OWNER: { uint32_t value = 0; if(!propStream.getType(value)) return false; owner = value; return true; } case CONDITIONATTR_INTERVALDATA: { IntervalInfo damageInfo; if(!propStream.getType(damageInfo)) return false; damageList.push_back(damageInfo); if(getTicks() != -1) setTicks(getTicks() + damageInfo.interval); return true; } default: break; } return Condition::unserializeProp(attr, propStream); }
bool FileLoader::getProps(const NODE node, PropStream &props) { unsigned long size; const unsigned char* a = getProps(node, size); if(!a){ props.init(NULL, 0); return false; } else{ props.init((char*)a, size); return true; } }
bool ConditionSpeed::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { if (attr == CONDITIONATTR_SPEEDDELTA) { int32_t value = 0; if (!propStream.GET_VALUE(value)) { return false; } speedDelta = value; return true; } else if (attr == CONDITIONATTR_FORMULA_MINA) { float value = 0; if (!propStream.GET_VALUE(value)) { return false; } mina = value; return true; } else if (attr == CONDITIONATTR_FORMULA_MINB) { float value = 0; if (!propStream.GET_VALUE(value)) { return false; } minb = value; return true; } else if (attr == CONDITIONATTR_FORMULA_MAXA) { float value = 0; if (!propStream.GET_VALUE(value)) { return false; } maxa = value; return true; } else if (attr == CONDITIONATTR_FORMULA_MAXB) { float value = 0; if (!propStream.GET_VALUE(value)) { return false; } maxb = value; return true; } return Condition::unserializeProp(attr, propStream); }
bool ConditionLight::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { switch(attr) { case CONDITIONATTR_LIGHTCOLOR: { uint32_t value = 0; if(!propStream.getType(value)) return false; lightInfo.color = value; return true; } case CONDITIONATTR_LIGHTLEVEL: { uint32_t value = 0; if(!propStream.getType(value)) return false; lightInfo.level = value; return true; } case CONDITIONATTR_LIGHTTICKS: { uint32_t value = 0; if(!propStream.getType(value)) return false; internalLightTicks = value; return true; } case CONDITIONATTR_LIGHTINTERVAL: { uint32_t value = 0; if(!propStream.getType(value)) return false; lightChangeInterval = value; return true; } default: break; } return Condition::unserializeProp(attr, propStream); }
bool ConditionRegeneration::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { switch(attr) { case CONDITIONATTR_HEALTHTICKS: { uint32_t value = 0; if(!propStream.getType(value)) return false; healthTicks = value; return true; } case CONDITIONATTR_HEALTHGAIN: { uint32_t value = 0; if(!propStream.getType(value)) return false; healthGain = value; return true; } case CONDITIONATTR_MANATICKS: { uint32_t value = 0; if(!propStream.getType(value)) return false; manaTicks = value; return true; } case CONDITIONATTR_MANAGAIN: { uint32_t value = 0; if(!propStream.getType(value)) return false; manaGain = value; return true; } default: break; } return ConditionGeneric::unserializeProp(attr, propStream); }
bool IOMap::parseMapDataAttributes(OTB::Loader& loader, const OTB::Node& mapNode, Map& map, const std::string& fileName) { PropStream propStream; if (!loader.getProps(mapNode, propStream)) { setLastErrorString("Could not read map data attributes."); return false; } std::string mapDescription; std::string tmp; uint8_t attribute; while (propStream.read<uint8_t>(attribute)) { switch (attribute) { case OTBM_ATTR_DESCRIPTION: if (!propStream.readString(mapDescription)) { setLastErrorString("Invalid description tag."); return false; } break; case OTBM_ATTR_EXT_SPAWN_FILE: if (!propStream.readString(tmp)) { setLastErrorString("Invalid spawn tag."); return false; } map.spawnfile = fileName.substr(0, fileName.rfind('/') + 1); map.spawnfile += tmp; break; case OTBM_ATTR_EXT_HOUSE_FILE: if (!propStream.readString(tmp)) { setLastErrorString("Invalid house tag."); return false; } map.housefile = fileName.substr(0, fileName.rfind('/') + 1); map.housefile += tmp; break; default: setLastErrorString("Unknown header node."); return false; } } return true; }
bool ConditionOutfit::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { if (attr == CONDITIONATTR_OUTFIT) { return propStream.GET_VALUE(this->outfit); } return Condition::unserializeProp(attr, propStream); }
bool ConditionDamage::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { if (attr == CONDITIONATTR_DELAYED) { uint8_t value; if (!propStream.read<uint8_t>(value)) { return false; } delayed = (value != 0); return true; } else if (attr == CONDITIONATTR_PERIODDAMAGE) { return propStream.read<int32_t>(periodDamage); } else if (attr == CONDITIONATTR_OWNER) { return propStream.skip(4); } else if (attr == CONDITIONATTR_INTERVALDATA) { IntervalInfo damageInfo; if (!propStream.read<IntervalInfo>(damageInfo)) { return false; } damageList.push_back(damageInfo); if (ticks != -1) { setTicks(ticks + damageInfo.interval); } return true; } return Condition::unserializeProp(attr, propStream); }
bool ConditionDamage::unserializeProp(ConditionAttr_t attr, PropStream& propStream) { if (attr == CONDITIONATTR_DELAYED) { bool value = false; if (!propStream.GET_VALUE(value)) { return false; } delayed = value; return true; } else if (attr == CONDITIONATTR_PERIODDAMAGE) { int32_t value = 0; if (!propStream.GET_VALUE(value)) { return false; } periodDamage = value; return true; } else if (attr == CONDITIONATTR_OWNER) { uint32_t value = 0; if (!propStream.GET_VALUE(value)) { return false; } // owner = value; return true; } else if (attr == CONDITIONATTR_INTERVALDATA) { IntervalInfo damageInfo; if (!propStream.GET_VALUE(damageInfo)) { return false; } damageList.push_back(damageInfo); if (getTicks() != -1) { setTicks(getTicks() + damageInfo.interval); } return true; } return Condition::unserializeProp(attr, propStream); }
bool ItemAttribute::unserialize(PropStream& stream) { uint8_t type = 0; stream.getByte(type); switch(type) { case STRING: { std::string v; if(!stream.getLongString(v)) return false; set(v); break; } case INTEGER: { uint32_t v; if(!stream.getLong(v)) return false; set(*reinterpret_cast<int32_t*>(&v)); break; } case FLOAT: { float v; if(!stream.getFloat(v)) return false; set(*reinterpret_cast<float*>(&v)); break; } case BOOLEAN: { uint8_t v; if(!stream.getByte(v)) return false; set(v != 0); } default: break; } return true; }
Attr_ReadValue Teleport::readAttr(AttrTypes_t attr, PropStream& propStream) { if(ATTR_TELE_DEST == attr){ TeleportDest tele_dest; if( !propStream.GET_UINT16(tele_dest._x) || !propStream.GET_UINT16(tele_dest._y) || !propStream.GET_UINT8(tele_dest._z)) { return ATTR_READ_ERROR; } setDestPos(Position(tele_dest._x, tele_dest._y, tele_dest._z)); return ATTR_READ_CONTINUE; } else return Item::readAttr(attr, propStream); }
bool IOMap::parseTowns(OTB::Loader& loader, const OTB::Node& townsNode, Map& map) { for (auto& townNode : townsNode.children) { PropStream propStream; if (townNode.type != OTBM_TOWN) { setLastErrorString("Unknown town node."); return false; } if (!loader.getProps(townNode, propStream)) { setLastErrorString("Could not read town data."); return false; } uint32_t townId; if (!propStream.read<uint32_t>(townId)) { setLastErrorString("Could not read town id."); return false; } Town* town = map.towns.getTown(townId); if (!town) { town = new Town(townId); map.towns.addTown(townId, town); } std::string townName; if (!propStream.readString(townName)) { setLastErrorString("Could not read town name."); return false; } town->setName(townName); OTBM_Destination_coords town_coords; if (!propStream.read(town_coords)) { setLastErrorString("Could not read town coordinates."); return false; } town->setTemplePos(Position(town_coords.x, town_coords.y, town_coords.z)); } return true; }
bool ItemAttribute::unserialize(PropStream& stream) { // dealloc possible string value dealloc(); // read type stream.GET_UCHAR(reinterpret_cast<uint8_t&>(m_type)); // do not call here set(...) or any other function depending on m_type which may result in deallocating phantom string ! // read contents switch(m_type){ case STRING: { m_var.string = new std::string; if(!stream.GET_LSTRING(*m_var.string)) return false; break; } case INTEGER: case FLOAT: { if(!stream.GET_ULONG(m_var.unsignedInteger)) return false; break; } case BOOLEAN: { if(!stream.GET_UCHAR(m_var.unsignedChar)) return false; break; } default: { m_type = NONE; break; } } return true; }
bool Condition::unserialize(PropStream& propStream) { uint8_t attr_type; while(propStream.GET_UCHAR(attr_type) && attr_type != CONDITIONATTR_END) { if(!unserializeProp((ConditionAttr_t)attr_type, propStream)) return false; } return true; }
bool ItemAttributes::unserializeAttributeMap(PropStream& stream) { uint16_t n; if(stream.GET_USHORT(n)){ createAttributes(); std::string key; ItemAttribute attrib; while(n--){ if(!stream.GET_STRING(key)) return false; if(!attrib.unserialize(stream)) return false; (*attributes)[key] = attrib; } } return true; }
Attr_ReadValue Door::readAttr(AttrTypes_t attr, PropStream& propStream) { if(attr != ATTR_HOUSEDOORID) return Item::readAttr(attr, propStream); uint8_t doorId = 0; if(!propStream.GET_UCHAR(doorId)) return ATTR_READ_ERROR; setDoorId(doorId); return ATTR_READ_CONTINUE; }