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

	query << "SELECT * FROM `houses` WHERE `world_id` = " << g_config.getNumber(ConfigManager::WORLD_ID);
	DBResult* result;
	if(!(result = db->storeQuery(query.str())))
		return false;

	House* house = NULL;
	do
	{
		if(!(house = Houses::getInstance()->getHouse(result->getDataInt("id"))))
			continue;

		house->setRentWarnings(result->getDataInt("warnings"));
		house->setLastWarning(result->getDataInt("lastwarning"));

		house->setPaidUntil(result->getDataInt("paid"));
		if(result->getDataInt("clear") == 1)
			house->setPendingTransfer(true);

		house->setOwner(result->getDataInt("owner"));
		if(house->getOwner() && house->hasSyncFlag(House::HOUSE_SYNC_UPDATE))
			house->resetSyncFlag(House::HOUSE_SYNC_UPDATE);
	}
	while(result->next());
	result->free();

	for(HouseMap::iterator it = Houses::getInstance()->getHouseBegin(); it != Houses::getInstance()->getHouseEnd(); ++it)
	{
		if(!(house = it->second) || !house->getId() || !house->getOwner())
			continue;

		query.str("");
		query << "SELECT `listid`, `list` FROM `house_lists` WHERE `house_id` = " << house->getId();
		query << " AND `world_id` = " << g_config.getNumber(ConfigManager::WORLD_ID);
		if(!(result = db->storeQuery(query.str())))
			continue;

		do
			house->setAccessList(result->getDataInt("listid"), result->getDataString("list"));
		while(result->next());
		result->free();
	}

	return true;
}
示例#2
0
void Commands::sellHouse(Player& player, const std::string& param)
{
	Player* tradePartner = g_game.getPlayerByName(param);
	if (!tradePartner || tradePartner == &player) {
		player.sendCancel("Trade player not found.");
		return;
	}

	if (!Position::areInRange<2, 2, 0>(tradePartner->getPosition(), player.getPosition())) {
		player.sendCancel("Trade player is too far away.");
		return;
	}

	if (!tradePartner->isPremium()) {
		player.sendCancel("Trade player does not have a premium account.");
		return;
	}

	HouseTile* houseTile = dynamic_cast<HouseTile*>(player.getTile());
	if (!houseTile) {
		player.sendCancel("You must stand in your house to initiate the trade.");
		return;
	}

	House* house = houseTile->getHouse();
	if (!house || house->getOwner() != player.getGUID()) {
		player.sendCancel("You don't own this house.");
		return;
	}

	if (Houses::getInstance().getHouseByPlayerId(tradePartner->getGUID())) {
		player.sendCancel("Trade player already owns a house.");
		return;
	}

	if (IOLoginData::hasBiddedOnHouse(tradePartner->getGUID())) {
		player.sendCancel("Trade player is currently the highest bidder of an auctioned house.");
		return;
	}

	Item* transferItem = house->getTransferItem();
	if (!transferItem) {
		player.sendCancel("You can not trade this house.");
		return;
	}

	transferItem->getParent()->setParent(&player);

	if (!g_game.internalStartTrade(&player, tradePartner, transferItem)) {
		house->resetTransferItem();
	}
}
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;
}
bool IOMapSerialize::loadMapRelational(Map* map)
{
	Database* db = Database::getInstance();
	DBQuery query; //lock mutex!

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

		query.str("");
		query << "SELECT * FROM `tiles` WHERE `house_id` = " << house->getId() <<
			" AND `world_id` = " << g_config.getNumber(ConfigManager::WORLD_ID);
		if(DBResult* result = db->storeQuery(query.str()))
		{
			do
			{
				query.str("");
				query << "SELECT * FROM `tile_items` WHERE `tile_id` = " << result->getDataInt("id") << " AND `world_id` = "
					<< g_config.getNumber(ConfigManager::WORLD_ID) << " ORDER BY `sid` DESC";
				if(DBResult* itemsResult = db->storeQuery(query.str()))
				{
					if(house->hasPendingTransfer())
					{
						if(Player* player = g_game.getPlayerByGuidEx(house->getOwner()))
						{
							loadItems(itemsResult, player->getInbox(), true);
							if(player->isVirtual())
							{
								IOLoginData::getInstance()->savePlayer(player);
								delete player;
							}
						}
					}
					else
					{
						Position pos(result->getDataInt("x"), result->getDataInt("y"), result->getDataInt("z"));
						if(Tile* tile = map->getTile(pos))
							loadItems(itemsResult, tile, false);
						else
							std::clog << "[Error - IOMapSerialize::loadMapRelational] Unserialization"
								<< " of invalid tile at position "<< pos << std::endl;
					}

					itemsResult->free();
				}
			}
			while(result->next());
			result->free();
		}
		else //backward compatibility
		{
			for(HouseTileList::iterator it = house->getHouseTileBegin(); it != house->getHouseTileEnd(); ++it)
			{
				query.str("");
				query << "SELECT `id` FROM `tiles` WHERE `x` = " << (*it)->getPosition().x << " AND `y` = "
					<< (*it)->getPosition().y << " AND `z` = " << (*it)->getPosition().z << " AND `world_id` = "
					<< g_config.getNumber(ConfigManager::WORLD_ID) << " LIMIT 1";
				if(DBResult* result = db->storeQuery(query.str()))
				{
					query.str("");
					query << "SELECT * FROM `tile_items` WHERE `tile_id` = " << result->getDataInt("id") << " AND `world_id` = "
						<< g_config.getNumber(ConfigManager::WORLD_ID) << " ORDER BY `sid` DESC";
					if(DBResult* itemsResult = db->storeQuery(query.str()))
					{
						if(house->hasPendingTransfer())
						{
							if(Player* player = g_game.getPlayerByGuidEx(house->getOwner()))
							{
								loadItems(itemsResult, player->getInbox(), true);
								if(player->isVirtual())
								{
									IOLoginData::getInstance()->savePlayer(player);
									delete player;
								}
							}
						}
						else
							loadItems(itemsResult, (*it), false);

						itemsResult->free();
					}

					result->free();
				}
			}
		}
	}

	return true;
}
示例#5
0
bool Houses::payHouses() const
{
	if (rentPeriod == RENTPERIOD_NEVER) {
		return true;
	}

	time_t currentTime = time(nullptr);
	for (const auto& it : houseMap) {
		House* house = it.second;
		if (house->getOwner() == 0) {
			continue;
		}

		const uint32_t rent = house->getRent();
		if (rent == 0 || house->getPaidUntil() > currentTime) {
			continue;
		}

		const uint32_t ownerid = house->getOwner();
		Town* town = Towns::getInstance().getTown(house->getTownId());
		if (!town) {
			continue;
		}

		Player player(nullptr);
		if (!IOLoginData::loadPlayerById(&player, ownerid)) {
			//player doesnt exist, reset house owner
			house->setOwner(0);
			continue;
		}

		if (player.getBankBalance() >= rent) {
			player.setBankBalance(player.getBankBalance() - rent);

			time_t paidUntil = currentTime;
			switch (rentPeriod) {
				case RENTPERIOD_DAILY:
					paidUntil += 24 * 60 * 60;
					break;
				case RENTPERIOD_WEEKLY:
					paidUntil += 24 * 60 * 60 * 7;
					break;
				case RENTPERIOD_MONTHLY:
					paidUntil += 24 * 60 * 60 * 30;
					break;
				case RENTPERIOD_YEARLY:
					paidUntil += 24 * 60 * 60 * 365;
					break;
				default:
					break;
			}

			house->setPaidUntil(paidUntil);
		} else {
			if (house->getPayRentWarnings() < 7) {
				int32_t daysLeft = 7 - house->getPayRentWarnings();

				Item* letter = Item::CreateItem(ITEM_LETTER_STAMPED);
				std::string period;

				switch (rentPeriod) {
					case RENTPERIOD_DAILY:
						period = "daily";
						break;

					case RENTPERIOD_WEEKLY:
						period = "weekly";
						break;

					case RENTPERIOD_MONTHLY:
						period = "monthly";
						break;

					case RENTPERIOD_YEARLY:
						period = "annual";
						break;

					default:
						break;
				}

				std::ostringstream ss;
				ss << "Warning! \nThe " << period << " rent of " << house->getRent() << " gold for your house \"" << house->getName() << "\" is payable. Have it within " << daysLeft << " days or you will lose this house.";
				letter->setText(ss.str());
				g_game.internalAddItem(player.getInbox(), letter, INDEX_WHEREEVER, FLAG_NOLIMIT);
				house->setPayRentWarnings(house->getPayRentWarnings() + 1);
			} else {
				house->setOwner(0, true, &player);
			}
		}

		IOLoginData::savePlayer(&player);
	}
	return true;
}
bool IOMapSerialize::saveHouseInfo()
{
	Database& db = Database::getInstance();

	DBTransaction transaction;
	if (!transaction.begin()) {
		return false;
	}

	if (!db.executeQuery("DELETE FROM `house_lists`")) {
		return false;
	}

	std::ostringstream query;
	for (const auto& it : g_game.map.houses.getHouses()) {
		House* house = it.second;
		query << "SELECT `id` FROM `houses` WHERE `id` = " << house->getId();
		DBResult_ptr result = db.storeQuery(query.str());
		if (result) {
			query.str(std::string());
			query << "UPDATE `houses` SET `owner` = " << house->getOwner() << ", `paid` = " << house->getPaidUntil() << ", `warnings` = " << house->getPayRentWarnings() << ", `name` = " << db.escapeString(house->getName()) << ", `town_id` = " << house->getTownId() << ", `rent` = " << house->getRent() << ", `size` = " << house->getTiles().size() << ", `beds` = " << house->getBedCount() << " WHERE `id` = " << house->getId();
		} else {
			query.str(std::string());
			query << "INSERT INTO `houses` (`id`, `owner`, `paid`, `warnings`, `name`, `town_id`, `rent`, `size`, `beds`) VALUES (" << house->getId() << ',' << house->getOwner() << ',' << house->getPaidUntil() << ',' << house->getPayRentWarnings() << ',' << db.escapeString(house->getName()) << ',' << house->getTownId() << ',' << house->getRent() << ',' << house->getTiles().size() << ',' << house->getBedCount() << ')';
		}

		db.executeQuery(query.str());
		query.str(std::string());
	}

	DBInsert stmt("INSERT INTO `house_lists` (`house_id` , `listid` , `list`) VALUES ");

	for (const auto& it : g_game.map.houses.getHouses()) {
		House* house = it.second;

		std::string listText;
		if (house->getAccessList(GUEST_LIST, listText) && !listText.empty()) {
			query << house->getId() << ',' << GUEST_LIST << ',' << db.escapeString(listText);
			if (!stmt.addRow(query)) {
				return false;
			}

			listText.clear();
		}

		if (house->getAccessList(SUBOWNER_LIST, listText) && !listText.empty()) {
			query << house->getId() << ',' << SUBOWNER_LIST << ',' << db.escapeString(listText);
			if (!stmt.addRow(query)) {
				return false;
			}

			listText.clear();
		}

		for (Door* door : house->getDoors()) {
			if (door->getAccessList(listText) && !listText.empty()) {
				query << house->getId() << ',' << door->getDoorId() << ',' << db.escapeString(listText);
				if (!stmt.addRow(query)) {
					return false;
				}

				listText.clear();
			}
		}
	}

	if (!stmt.execute()) {
		return false;
	}

	return transaction.commit();
}