From fddbe953ff401be676d2f2d0435516c6cf3ef47b Mon Sep 17 00:00:00 2001 From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com> Date: Mon, 18 Jan 2021 14:59:04 +0000 Subject: [PATCH] Support for auction house discount vouchers. Contributed by ren. --- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- .../sql/game/commission_items.sql | 1 + .../instancemanager/CommissionManager.java | 64 +++++++++++++++---- .../model/commission/CommissionItem.java | 15 ++++- .../commission/RequestCommissionRegister.java | 41 ++++++++++-- 68 files changed, 1768 insertions(+), 289 deletions(-) diff --git a/L2J_Mobius_1.0_Ertheia/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_1.0_Ertheia/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_1.0_Ertheia/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_1.0_Ertheia/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_2.5_Underground/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_2.5_Underground/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_2.5_Underground/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_2.5_Underground/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_2.5_Underground/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_3.0_Helios/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_3.0_Helios/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_3.0_Helios/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_3.0_Helios/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_3.0_Helios/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_4.0_GrandCrusade/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_4.0_GrandCrusade/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_5.0_Salvation/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_5.0_Salvation/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_5.0_Salvation/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_5.0_Salvation/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_5.0_Salvation/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_5.5_EtinasFate/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_5.5_EtinasFate/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_5.5_EtinasFate/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_5.5_EtinasFate/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 6d66cbcafe..1d4c23989c 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_5.5_EtinasFate/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_6.0_Fafurion/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_6.0_Fafurion/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_6.0_Fafurion/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_6.0_Fafurion/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 6d66cbcafe..1d4c23989c 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_6.0_Fafurion/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_7.0_PreludeOfWar/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_7.0_PreludeOfWar/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 6d66cbcafe..1d4c23989c 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_7.0_PreludeOfWar/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_8.0_Homunculus/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_8.0_Homunculus/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_8.0_Homunculus/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_8.0_Homunculus/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 6d66cbcafe..1d4c23989c 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_8.0_Homunculus/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_Classic_2.0_Saviors/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_Classic_2.1_Zaken/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_Classic_2.1_Zaken/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_Classic_2.2_Antharas/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_Classic_2.2_Antharas/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_Classic_2.3_SevenSigns/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_Classic_2.4_SecretOfEmpire/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_Classic_3.0_TheKamael/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_Classic_3.0_TheKamael/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_Classic_3.0_TheKamael/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_Classic_3.0_TheKamael/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_Classic_Interlude/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_Classic_Interlude/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_Classic_Interlude/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_Classic_Interlude/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..8af56b3328 100644 --- a/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_Classic_Interlude/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } } diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/db_installer/sql/game/commission_items.sql b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/db_installer/sql/game/commission_items.sql index 6a489609eb..79601a9a4e 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/db_installer/sql/game/commission_items.sql +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/dist/db_installer/sql/game/commission_items.sql @@ -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; \ No newline at end of file diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java index 781c07913c..fecb438b84 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/instancemanager/CommissionManager.java @@ -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 _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)); diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java index 1c35b450d4..78f69964ea 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/model/commission/CommissionItem.java @@ -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 diff --git a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java index d2cc5627e2..d941ee5049 100644 --- a/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java +++ b/L2J_Mobius_Essence_4.0_DwellingOfSpirits/java/org/l2jmobius/gameserver/network/clientpackets/commission/RequestCommissionRegister.java @@ -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)); } }