Support for auction house discount vouchers.
Contributed by ren.
This commit is contained in:
		@@ -5,5 +5,6 @@ CREATE TABLE IF NOT EXISTS `commission_items` (
 | 
			
		||||
	`price_per_unit` BIGINT NOT NULL,
 | 
			
		||||
	`start_time` TIMESTAMP NOT NULL,
 | 
			
		||||
	`duration_in_days` TINYINT NOT NULL,
 | 
			
		||||
	`discount_in_percentage` TINYINT NOT NULL,
 | 
			
		||||
	PRIMARY KEY (`commission_id`)
 | 
			
		||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
 | 
			
		||||
@@ -56,8 +56,9 @@ import org.l2jmobius.gameserver.network.serverpackets.commission.ExResponseCommi
 | 
			
		||||
import org.l2jmobius.gameserver.network.serverpackets.commission.ExResponseCommissionRegister;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author NosBit
 | 
			
		||||
 * @author NosBit, Ren
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class CommissionManager
 | 
			
		||||
{
 | 
			
		||||
	private static final Logger LOGGER = Logger.getLogger(CommissionManager.class.getName());
 | 
			
		||||
@@ -66,12 +67,21 @@ public class CommissionManager
 | 
			
		||||
	private static final int ITEMS_LIMIT_PER_REQUEST = 999;
 | 
			
		||||
	private static final int MAX_ITEMS_REGISTRED_PER_PLAYER = 10;
 | 
			
		||||
	private static final long MIN_REGISTRATION_AND_SALE_FEE = 1000;
 | 
			
		||||
	private static final double REGISTRATION_FEE_PER_DAY = 0.001;
 | 
			
		||||
	private static final double REGISTRATION_FEE_PER_DAY = 0.0001;
 | 
			
		||||
	private static final double SALE_FEE_PER_DAY = 0.005;
 | 
			
		||||
	private static final int DURATION[] =
 | 
			
		||||
	{
 | 
			
		||||
		1,
 | 
			
		||||
		3,
 | 
			
		||||
		5,
 | 
			
		||||
		7,
 | 
			
		||||
		15,
 | 
			
		||||
		30
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	private static final String SELECT_ALL_ITEMS = "SELECT * FROM `items` WHERE `loc` = ?";
 | 
			
		||||
	private static final String SELECT_ALL_COMMISSION_ITEMS = "SELECT * FROM `commission_items`";
 | 
			
		||||
	private static final String INSERT_COMMISSION_ITEM = "INSERT INTO `commission_items`(`item_object_id`, `price_per_unit`, `start_time`, `duration_in_days`) VALUES (?, ?, ?, ?)";
 | 
			
		||||
	private static final String INSERT_COMMISSION_ITEM = "INSERT INTO `commission_items`(`item_object_id`, `price_per_unit`, `start_time`, `duration_in_days`, `discount_in_percentage`) VALUES (?, ?, ?, ?, ?)";
 | 
			
		||||
	private static final String DELETE_COMMISSION_ITEM = "DELETE FROM `commission_items` WHERE `commission_id` = ?";
 | 
			
		||||
	
 | 
			
		||||
	private final Map<Long, CommissionItem> _commissionItems = new ConcurrentSkipListMap<>();
 | 
			
		||||
@@ -106,7 +116,7 @@ public class CommissionManager
 | 
			
		||||
						LOGGER.warning(getClass().getSimpleName() + ": Failed loading commission item with commission id " + commissionId + " because item instance does not exist or failed to load.");
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					final CommissionItem commissionItem = new CommissionItem(commissionId, itemInstance, rs.getLong("price_per_unit"), rs.getTimestamp("start_time").toInstant(), rs.getByte("duration_in_days"));
 | 
			
		||||
					final CommissionItem commissionItem = new CommissionItem(commissionId, itemInstance, rs.getLong("price_per_unit"), rs.getTimestamp("start_time").toInstant(), rs.getByte("duration_in_days"), rs.getByte("discount_in_percentage"));
 | 
			
		||||
					_commissionItems.put(commissionItem.getCommissionId(), commissionItem);
 | 
			
		||||
					if (commissionItem.getEndTime().isBefore(Instant.now()))
 | 
			
		||||
					{
 | 
			
		||||
@@ -186,9 +196,10 @@ public class CommissionManager
 | 
			
		||||
	 * @param itemObjectId the item object id
 | 
			
		||||
	 * @param itemCount the item count
 | 
			
		||||
	 * @param pricePerUnit the price per unit
 | 
			
		||||
	 * @param durationInDays the duration in days
 | 
			
		||||
	 * @param durationType the duration type
 | 
			
		||||
	 * @param discountInPercentage the discount type
 | 
			
		||||
	 */
 | 
			
		||||
	public void registerItem(PlayerInstance player, int itemObjectId, long itemCount, long pricePerUnit, byte durationInDays)
 | 
			
		||||
	public void registerItem(PlayerInstance player, int itemObjectId, long itemCount, long pricePerUnit, int durationType, byte discountInPercentage)
 | 
			
		||||
	{
 | 
			
		||||
		if (itemCount < 1)
 | 
			
		||||
		{
 | 
			
		||||
@@ -213,6 +224,8 @@ public class CommissionManager
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		final byte durationInDays = (byte) DURATION[durationType];
 | 
			
		||||
		
 | 
			
		||||
		synchronized (this)
 | 
			
		||||
		{
 | 
			
		||||
			//@formatter:off
 | 
			
		||||
@@ -223,12 +236,12 @@ public class CommissionManager
 | 
			
		||||
			
 | 
			
		||||
			if (playerRegisteredItems >= MAX_ITEMS_REGISTRED_PER_PLAYER)
 | 
			
		||||
			{
 | 
			
		||||
				player.sendPacket(SystemMessageId.THE_ITEM_HAS_FAILED_TO_BE_REGISTERED);
 | 
			
		||||
				player.sendPacket(SystemMessageId.THE_MAXIMUM_NUMBER_OF_AUCTION_HOUSE_ITEMS_FOR_REGISTRATION_IS_10);
 | 
			
		||||
				player.sendPacket(ExResponseCommissionRegister.FAILED);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			final long registrationFee = (long) Math.max(MIN_REGISTRATION_AND_SALE_FEE, (totalPrice * REGISTRATION_FEE_PER_DAY) * durationInDays);
 | 
			
		||||
			final long registrationFee = (long) Math.max(MIN_REGISTRATION_AND_SALE_FEE, (totalPrice * REGISTRATION_FEE_PER_DAY) * Math.min(durationInDays, 7));
 | 
			
		||||
			if (!player.getInventory().reduceAdena("Commission Registration Fee", registrationFee, player, null))
 | 
			
		||||
			{
 | 
			
		||||
				player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA_TO_REGISTER_THE_ITEM);
 | 
			
		||||
@@ -245,6 +258,30 @@ public class CommissionManager
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			switch (Math.max(durationType, discountInPercentage))
 | 
			
		||||
			{
 | 
			
		||||
				case 4:
 | 
			
		||||
				{
 | 
			
		||||
					player.destroyItemByItemId("Consume", 22353, 1, player, true); // 15 days
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 5:
 | 
			
		||||
				{
 | 
			
		||||
					player.destroyItemByItemId("Consume", 22354, 1, player, true); // 30 days
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 30:
 | 
			
		||||
				{
 | 
			
		||||
					player.destroyItemByItemId("Consume", 22351, 1, player, true); // 30% discount
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				case 100:
 | 
			
		||||
				{
 | 
			
		||||
					player.destroyItemByItemId("Consume", 22352, 1, player, true); // 100% discount
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			try (Connection con = DatabaseFactory.getConnection();
 | 
			
		||||
				PreparedStatement ps = con.prepareStatement(INSERT_COMMISSION_ITEM, Statement.RETURN_GENERATED_KEYS))
 | 
			
		||||
			{
 | 
			
		||||
@@ -253,18 +290,20 @@ public class CommissionManager
 | 
			
		||||
				ps.setLong(2, pricePerUnit);
 | 
			
		||||
				ps.setTimestamp(3, Timestamp.from(startTime));
 | 
			
		||||
				ps.setByte(4, durationInDays);
 | 
			
		||||
				ps.setByte(5, discountInPercentage);
 | 
			
		||||
				ps.executeUpdate();
 | 
			
		||||
				try (ResultSet rs = ps.getGeneratedKeys())
 | 
			
		||||
				{
 | 
			
		||||
					if (rs.next())
 | 
			
		||||
					{
 | 
			
		||||
						final CommissionItem commissionItem = new CommissionItem(rs.getLong(1), itemInstance, pricePerUnit, startTime, durationInDays);
 | 
			
		||||
						final CommissionItem commissionItem = new CommissionItem(rs.getLong(1), itemInstance, pricePerUnit, startTime, durationInDays, discountInPercentage);
 | 
			
		||||
						final ScheduledFuture<?> saleEndTask = ThreadPool.schedule(() -> expireSale(commissionItem), Duration.between(Instant.now(), commissionItem.getEndTime()).toMillis());
 | 
			
		||||
						commissionItem.setSaleEndTask(saleEndTask);
 | 
			
		||||
						_commissionItems.put(commissionItem.getCommissionId(), commissionItem);
 | 
			
		||||
						player.getLastCommissionInfos().put(itemInstance.getId(), new ExResponseCommissionInfo(itemInstance.getId(), pricePerUnit, itemCount, (byte) ((durationInDays - 1) / 2)));
 | 
			
		||||
						player.sendPacket(SystemMessageId.THE_ITEM_HAS_BEEN_SUCCESSFULLY_REGISTERED);
 | 
			
		||||
						player.sendPacket(ExResponseCommissionRegister.SUCCEED);
 | 
			
		||||
						
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
@@ -374,10 +413,13 @@ public class CommissionManager
 | 
			
		||||
		
 | 
			
		||||
		if (deleteItemFromDB(commissionId))
 | 
			
		||||
		{
 | 
			
		||||
			final long saleFee = (long) Math.max(MIN_REGISTRATION_AND_SALE_FEE, (totalPrice * SALE_FEE_PER_DAY) * commissionItem.getDurationInDays());
 | 
			
		||||
			final float discountFee = (float) commissionItem.getDiscountInPercentage() / 100;
 | 
			
		||||
			
 | 
			
		||||
			final long saleFee = (long) Math.max(MIN_REGISTRATION_AND_SALE_FEE, (totalPrice * SALE_FEE_PER_DAY) * Math.min(commissionItem.getDurationInDays(), 7));
 | 
			
		||||
			final long addDiscount = (long) (saleFee * discountFee);
 | 
			
		||||
			final Message mail = new Message(itemInstance.getOwnerId(), itemInstance, MailType.COMMISSION_ITEM_SOLD);
 | 
			
		||||
			final Mail attachement = mail.createAttachments();
 | 
			
		||||
			attachement.addItem("Commission Item Sold", Inventory.ADENA_ID, totalPrice - saleFee, player, null);
 | 
			
		||||
			attachement.addItem("Commission Item Sold", Inventory.ADENA_ID, (totalPrice - saleFee) + addDiscount, player, null);
 | 
			
		||||
			MailManager.getInstance().sendMessage(mail);
 | 
			
		||||
			
 | 
			
		||||
			player.sendPacket(new ExResponseCommissionBuyItem(commissionItem));
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ import org.l2jmobius.gameserver.model.ItemInfo;
 | 
			
		||||
import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author NosBit
 | 
			
		||||
 * @author NosBit, Ren
 | 
			
		||||
 */
 | 
			
		||||
public class CommissionItem
 | 
			
		||||
{
 | 
			
		||||
@@ -34,9 +34,10 @@ public class CommissionItem
 | 
			
		||||
	private final long _pricePerUnit;
 | 
			
		||||
	private final Instant _startTime;
 | 
			
		||||
	private final byte _durationInDays;
 | 
			
		||||
	private final byte _discountInPercentage;
 | 
			
		||||
	private ScheduledFuture<?> _saleEndTask;
 | 
			
		||||
	
 | 
			
		||||
	public CommissionItem(long commissionId, ItemInstance itemInstance, long pricePerUnit, Instant startTime, byte durationInDays)
 | 
			
		||||
	public CommissionItem(long commissionId, ItemInstance itemInstance, long pricePerUnit, Instant startTime, byte durationInDays, byte discountInPercentage)
 | 
			
		||||
	{
 | 
			
		||||
		_commissionId = commissionId;
 | 
			
		||||
		_itemInstance = itemInstance;
 | 
			
		||||
@@ -44,6 +45,7 @@ public class CommissionItem
 | 
			
		||||
		_pricePerUnit = pricePerUnit;
 | 
			
		||||
		_startTime = startTime;
 | 
			
		||||
		_durationInDays = durationInDays;
 | 
			
		||||
		_discountInPercentage = discountInPercentage;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
@@ -100,6 +102,15 @@ public class CommissionItem
 | 
			
		||||
		return _durationInDays;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Gets the discount in percentage
 | 
			
		||||
	 * @return the _discountInPercentage
 | 
			
		||||
	 */
 | 
			
		||||
	public byte getDiscountInPercentage()
 | 
			
		||||
	{
 | 
			
		||||
		return _discountInPercentage;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Gets the end time.
 | 
			
		||||
	 * @return the end time
 | 
			
		||||
 
 | 
			
		||||
@@ -24,14 +24,15 @@ import org.l2jmobius.gameserver.network.clientpackets.IClientIncomingPacket;
 | 
			
		||||
import org.l2jmobius.gameserver.network.serverpackets.commission.ExCloseCommission;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author NosBit
 | 
			
		||||
 * @author NosBit, Ren
 | 
			
		||||
 */
 | 
			
		||||
public class RequestCommissionRegister implements IClientIncomingPacket
 | 
			
		||||
{
 | 
			
		||||
	private int _itemObjectId;
 | 
			
		||||
	private long _pricePerUnit;
 | 
			
		||||
	private long _itemCount;
 | 
			
		||||
	private int _durationType; // -1 = None, 0 = 1 Day, 1 = 3 Days, 2 = 5 Days, 3 = 7 Days
 | 
			
		||||
	private int _durationType; // -1 = None, 0 = 1 Day, 1 = 3 Days, 2 = 5 Days, 3 = 7 Days, 4 = 15 Days, 5 = 30 Days;
 | 
			
		||||
	private int _feeDiscountType; // 0 = none, 1 = 30% discount, 2 = 100% discount;
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean read(GameClient client, PacketReader packet)
 | 
			
		||||
@@ -41,6 +42,8 @@ public class RequestCommissionRegister implements IClientIncomingPacket
 | 
			
		||||
		_pricePerUnit = packet.readQ();
 | 
			
		||||
		_itemCount = packet.readQ();
 | 
			
		||||
		_durationType = packet.readD();
 | 
			
		||||
		_feeDiscountType = packet.readH();
 | 
			
		||||
		// packet.readH(); // Unknown IDS;
 | 
			
		||||
		// packet.readD(); // Unknown
 | 
			
		||||
		// packet.readD(); // Unknown
 | 
			
		||||
		return true;
 | 
			
		||||
@@ -55,18 +58,48 @@ public class RequestCommissionRegister implements IClientIncomingPacket
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if ((_durationType < 0) || (_durationType > 3))
 | 
			
		||||
		if ((_feeDiscountType < 0) || (_feeDiscountType > 2))
 | 
			
		||||
		{
 | 
			
		||||
			LOGGER.warning("Player " + player + " sent incorrect commission discount type: " + _feeDiscountType + ".");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if ((_feeDiscountType == 1) && (player.getInventory().getItemByItemId(22351) == null))
 | 
			
		||||
		{
 | 
			
		||||
			LOGGER.warning("Player " + player + ": Auction House Fee 30% Voucher no found in her inventory.");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		else if ((_feeDiscountType == 2) && (player.getInventory().getItemByItemId(22352) == null))
 | 
			
		||||
		{
 | 
			
		||||
			LOGGER.warning("Player " + player + ": Auction House Fee 100% Voucher no found in her inventory.");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if ((_durationType < 0) || (_durationType > 5))
 | 
			
		||||
		{
 | 
			
		||||
			LOGGER.warning("Player " + player + " sent incorrect commission duration type: " + _durationType + ".");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if ((_durationType == 4) && (player.getInventory().getItemByItemId(22353) == null))
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
			LOGGER.warning("Player " + player + ": Auction House (15-day) ExtensiΓ³n no found in her inventory.");
 | 
			
		||||
			return;
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
		else if ((_durationType == 5) && (player.getInventory().getItemByItemId(22354) == null))
 | 
			
		||||
		{
 | 
			
		||||
			LOGGER.warning("Player " + player + ": Auction House (30-day) ExtensiΓ³n no found in her inventory.");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (!CommissionManager.isPlayerAllowedToInteract(player))
 | 
			
		||||
		{
 | 
			
		||||
			client.sendPacket(ExCloseCommission.STATIC_PACKET);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		CommissionManager.getInstance().registerItem(player, _itemObjectId, _itemCount, _pricePerUnit, (byte) ((_durationType * 2) + 1));
 | 
			
		||||
		CommissionManager.getInstance().registerItem(player, _itemObjectId, _itemCount, _pricePerUnit, _durationType, (byte) Math.min((_feeDiscountType * 30) * _feeDiscountType, 100));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user