bool IOMapSerialize::updateHouses()
{
	Database* db = Database::getInstance();
	DBQuery query;

	House* house = NULL;
	for(HouseMap::iterator it = Houses::getInstance()->getHouseBegin(); it != Houses::getInstance()->getHouseEnd(); ++it)
	{
		if(!(house = it->second))
			continue;

		query << "SELECT `price` FROM `houses` WHERE `id` = " << house->getId() << " AND `world_id` = "
			<< g_config.getNumber(ConfigManager::WORLD_ID) << " LIMIT 1";
		if(DBResult* result = db->storeQuery(query.str()))
		{
			if((uint32_t)result->getDataInt("price") != house->getPrice())
				house->setSyncFlag(House::HOUSE_SYNC_UPDATE);

			result->free();
			query.str("");

			query << "UPDATE `houses` SET ";
			if(house->hasSyncFlag(House::HOUSE_SYNC_NAME))
				query << "`name` = " << db->escapeString(house->getName()) << ", ";

			if(house->hasSyncFlag(House::HOUSE_SYNC_TOWN))
				query << "`town` = " << house->getTownId() << ", ";

			if(house->hasSyncFlag(House::HOUSE_SYNC_SIZE))
				query << "`size` = " << house->getSize() << ", ";

			if(house->hasSyncFlag(House::HOUSE_SYNC_PRICE))
				query << "`price` = " << house->getPrice() << ", ";

			if(house->hasSyncFlag(House::HOUSE_SYNC_RENT))
				query << "`rent` = " << house->getRent() << ", ";

			query << "`doors` = " << house->getDoorsCount() << ", `beds` = "
				<< house->getBedsCount() << ", `tiles` = " << house->getTilesCount();
			if(house->hasSyncFlag(House::HOUSE_SYNC_GUILD))
				query << ", `guild` = " << house->isGuild();

			query << " WHERE `id` = " << house->getId() << " AND `world_id` = "
				<< g_config.getNumber(ConfigManager::WORLD_ID) << db->getUpdateLimiter();
		}
		else
		{
			query.str("");
			query << "INSERT INTO `houses` (`id`, `world_id`, `owner`, `name`, `town`, `size`, `price`, `rent`, `doors`, `beds`, `tiles`, `guild`) VALUES ("
				<< house->getId() << ", " << g_config.getNumber(ConfigManager::WORLD_ID) << ", 0, "
				//we need owner for compatibility reasons (field doesn't have a default value)
				<< db->escapeString(house->getName()) << ", " << house->getTownId() << ", "
				<< house->getSize() << ", " << house->getPrice() << ", " << house->getRent() << ", "
				<< house->getDoorsCount() << ", " << house->getBedsCount() << ", "
				<< house->getTilesCount() << ", " << house->isGuild() << ")";
		}

		if(!db->query(query.str()))
			return false;

		query.str("");
	}

	return true;
}
Esempio n. 2
0
bool Houses::loadFromXml(std::string filename)
{
	xmlDocPtr doc = xmlParseFile(filename.c_str());
	if(!doc)
	{
		std::clog << "[Warning - Houses::loadFromXml] Cannot load houses file." << std::endl;
		std::clog << getLastXMLError() << std::endl;
		return false;
	}

	xmlNodePtr houseNode, root = xmlDocGetRootElement(doc);
	if(xmlStrcmp(root->name,(const xmlChar*)"houses"))
	{
		std::clog << "[Error - Houses::loadFromXml] Malformed houses file." << std::endl;
		xmlFreeDoc(doc);
		return false;
	}

	int32_t intValue;
	std::string strValue;

	houseNode = root->children;
	while(houseNode)
	{
		if(xmlStrcmp(houseNode->name,(const xmlChar*)"house"))
		{
			houseNode = houseNode->next;
			continue;
		}

		int32_t houseId = 0;
		if(!readXMLInteger(houseNode, "houseid", houseId))
		{
			std::clog << "[Error - Houses::loadFromXml] Could not read houseId" << std::endl;
			xmlFreeDoc(doc);
			return false;
		}

		House* house = Houses::getInstance()->getHouse(houseId);
		if(!house)
		{
			std::clog << "[Error - Houses::loadFromXml] Unknown house with id: " << houseId << std::endl;
			xmlFreeDoc(doc);
			return false;
		}

		Position entry(0, 0, 0);
		if(readXMLInteger(houseNode, "entryx", intValue))
			entry.x = intValue;

		if(readXMLInteger(houseNode, "entryy", intValue))
			entry.y = intValue;

		if(readXMLInteger(houseNode, "entryz", intValue))
			entry.z = intValue;

		if(readXMLString(houseNode, "name", strValue))
			house->setName(strValue);
		else
			house->resetSyncFlag(House::HOUSE_SYNC_NAME);

		house->setEntry(entry);
		if(!entry.x || !entry.y)
		{
			std::clog << "[Warning - Houses::loadFromXml] House entry not set for: "
				<< house->getName() << " (" << houseId << ")" << std::endl;
		}

		if(readXMLInteger(houseNode, "townid", intValue))
			house->setTownId(intValue);
		else
			house->resetSyncFlag(House::HOUSE_SYNC_TOWN);

		if(readXMLInteger(houseNode, "size", intValue))
			house->setSize(intValue);
		else
			house->resetSyncFlag(House::HOUSE_SYNC_SIZE);

		if(readXMLString(houseNode, "guildhall", strValue))
			house->setGuild(booleanString(strValue));
		else
			house->resetSyncFlag(House::HOUSE_SYNC_GUILD);

		uint32_t rent = 0;
		if(readXMLInteger(houseNode, "rent", intValue))
			rent = intValue;

		uint32_t price = (house->getSize() + house->getBedsCount()) * g_config.getNumber(ConfigManager::HOUSE_PRICE);
		// we should let players to pay only for walkable tiles + beds as single units not two items.
		if(g_config.getBool(ConfigManager::HOUSE_RENTASPRICE) && rent)
			price = rent;

		house->setPrice(price);
		if(g_config.getBool(ConfigManager::HOUSE_PRICEASRENT))
			house->setRent(price);
		else
			house->setRent(rent);

		house->setOwner(0);
		houseNode = houseNode->next;
	}

	xmlFreeDoc(doc);
	return true;
}