diff --git a/src/main/java/client/Character.java b/src/main/java/client/Character.java index 1035280736..5f0b8148c2 100644 --- a/src/main/java/client/Character.java +++ b/src/main/java/client/Character.java @@ -167,7 +167,7 @@ public class Character extends AbstractCharacterObject { private Shop shop = null; private SkinColor skinColor = SkinColor.NORMAL; private Storage storage = null; - private MapleTrade trade = null; + private Trade trade = null; private MonsterBook monsterbook; private CashShop cashshop; private final Set newyears = new LinkedHashSet<>(); @@ -1676,7 +1676,7 @@ public class Character extends AbstractCharacterObject { this.unregisterChairBuff(); this.clearBanishPlayerData(); - MapleTrade.cancelTrade(this, MapleTrade.TradeResult.UNSUCCESSFUL_ANOTHER_MAP); + Trade.cancelTrade(this, Trade.TradeResult.UNSUCCESSFUL_ANOTHER_MAP); this.closePlayerInteractions(); Party e = null; @@ -5532,7 +5532,7 @@ public class Character extends AbstractCharacterObject { } public void closeTrade() { - MapleTrade.cancelTrade(this, MapleTrade.TradeResult.PARTNER_CANCEL); + Trade.cancelTrade(this, Trade.TradeResult.PARTNER_CANCEL); } public void closePlayerShop() { @@ -5887,7 +5887,7 @@ public class Character extends AbstractCharacterObject { return summons.containsValue(summon); } - public MapleTrade getTrade() { + public Trade getTrade() { return trade; } @@ -9574,7 +9574,7 @@ public class Character extends AbstractCharacterObject { slots = slotid; } - public void setTrade(MapleTrade trade) { + public void setTrade(Trade trade) { this.trade = trade; } diff --git a/src/main/java/client/processor/npc/DueyProcessor.java b/src/main/java/client/processor/npc/DueyProcessor.java index b45d225592..7d6076b81d 100644 --- a/src/main/java/client/processor/npc/DueyProcessor.java +++ b/src/main/java/client/processor/npc/DueyProcessor.java @@ -37,7 +37,7 @@ import constants.inventory.ItemConstants; import net.server.channel.Channel; import server.DueyPackage; import server.ItemInformationProvider; -import server.MapleTrade; +import server.Trade; import tools.DatabaseConnection; import tools.FilePrinter; import tools.PacketCreator; @@ -281,7 +281,7 @@ public class DueyProcessor { public static void dueySendItem(Client c, byte invTypeId, short itemPos, short amount, int sendMesos, String sendMessage, String recipient, boolean quick) { if (c.tryacquireClient()) { try { - int fee = MapleTrade.getFee(sendMesos); + int fee = Trade.getFee(sendMesos); if (!quick) { fee += 5000; } else if (!c.getPlayer().haveItem(5330000)) { diff --git a/src/main/java/net/server/channel/handlers/ChangeMapHandler.java b/src/main/java/net/server/channel/handlers/ChangeMapHandler.java index bf0a13c645..7c3dd1a30f 100644 --- a/src/main/java/net/server/channel/handlers/ChangeMapHandler.java +++ b/src/main/java/net/server/channel/handlers/ChangeMapHandler.java @@ -27,7 +27,7 @@ import client.inventory.InventoryType; import client.inventory.manipulator.InventoryManipulator; import net.AbstractPacketHandler; import net.packet.InPacket; -import server.MapleTrade; +import server.Trade; import server.maps.MapleMap; import server.maps.Portal; import tools.FilePrinter; @@ -53,7 +53,7 @@ public final class ChangeMapHandler extends AbstractPacketHandler { return; } if (chr.getTrade() != null) { - MapleTrade.cancelTrade(chr, MapleTrade.TradeResult.UNSUCCESSFUL_ANOTHER_MAP); + Trade.cancelTrade(chr, Trade.TradeResult.UNSUCCESSFUL_ANOTHER_MAP); } if (p.available() == 0) { //Cash Shop :) if (!chr.getCashShop().isOpened()) { diff --git a/src/main/java/net/server/channel/handlers/ChangeMapSpecialHandler.java b/src/main/java/net/server/channel/handlers/ChangeMapSpecialHandler.java index f64e943fe2..c2da5d16f7 100644 --- a/src/main/java/net/server/channel/handlers/ChangeMapSpecialHandler.java +++ b/src/main/java/net/server/channel/handlers/ChangeMapSpecialHandler.java @@ -24,8 +24,8 @@ package net.server.channel.handlers; import client.Client; import net.AbstractPacketHandler; import net.packet.InPacket; -import server.MapleTrade; -import server.MapleTrade.TradeResult; +import server.Trade; +import server.Trade.TradeResult; import server.maps.Portal; import tools.PacketCreator; @@ -45,7 +45,7 @@ public final class ChangeMapSpecialHandler extends AbstractPacketHandler { return; } if (c.getPlayer().getTrade() != null) { - MapleTrade.cancelTrade(c.getPlayer(), TradeResult.UNSUCCESSFUL_ANOTHER_MAP); + Trade.cancelTrade(c.getPlayer(), TradeResult.UNSUCCESSFUL_ANOTHER_MAP); } portal.enterPortal(c); } diff --git a/src/main/java/net/server/channel/handlers/PlayerInteractionHandler.java b/src/main/java/net/server/channel/handlers/PlayerInteractionHandler.java index e86bde7404..fd670a78ad 100644 --- a/src/main/java/net/server/channel/handlers/PlayerInteractionHandler.java +++ b/src/main/java/net/server/channel/handlers/PlayerInteractionHandler.java @@ -35,7 +35,7 @@ import constants.inventory.ItemConstants; import net.AbstractPacketHandler; import net.packet.InPacket; import server.ItemInformationProvider; -import server.MapleTrade; +import server.Trade; import server.maps.*; import server.maps.MiniGame.MiniGameType; import tools.FilePrinter; @@ -144,7 +144,7 @@ public final class PlayerInteractionHandler extends AbstractPacketHandler { byte createType = p.readByte(); if (createType == 3) { // trade - MapleTrade.startTrade(chr); + Trade.startTrade(chr); } else if (createType == 1) { // omok mini game int status = establishMiniroomStatus(chr, true); if (status > 0) { @@ -266,13 +266,13 @@ public final class PlayerInteractionHandler extends AbstractPacketHandler { return; } - MapleTrade.inviteTrade(chr, other); + Trade.inviteTrade(chr, other); } else if (mode == Action.DECLINE.getCode()) { - MapleTrade.declineTrade(chr); + Trade.declineTrade(chr); } else if (mode == Action.VISIT.getCode()) { if (chr.getTrade() != null && chr.getTrade().getPartner() != null) { if (!chr.getTrade().isFullTrade() && !chr.getTrade().getPartner().isFullTrade()) { - MapleTrade.visitTrade(chr, chr.getTrade().getPartner().getChr()); + Trade.visitTrade(chr, chr.getTrade().getPartner().getChr()); } else { chr.sendPacket(PacketCreator.getMiniRoomError(2)); return; @@ -332,7 +332,7 @@ public final class PlayerInteractionHandler extends AbstractPacketHandler { } } else if (mode == Action.EXIT.getCode()) { if (chr.getTrade() != null) { - MapleTrade.cancelTrade(chr, MapleTrade.TradeResult.PARTNER_CANCEL); + Trade.cancelTrade(chr, Trade.TradeResult.PARTNER_CANCEL); } else { chr.closePlayerShop(); chr.closeMiniGame(false); @@ -507,7 +507,7 @@ public final class PlayerInteractionHandler extends AbstractPacketHandler { return; } - MapleTrade trade = chr.getTrade(); + Trade trade = chr.getTrade(); if (trade != null) { if ((quantity <= item.getQuantity() && quantity >= 0) || ItemConstants.isRechargeable(item.getItemId())) { if (ii.isDropRestricted(item.getItemId())) { // ensure that undroppable items do not make it to the trade window @@ -552,7 +552,7 @@ public final class PlayerInteractionHandler extends AbstractPacketHandler { } } } else if (mode == Action.CONFIRM.getCode()) { - MapleTrade.completeTrade(chr); + Trade.completeTrade(chr); } else if (mode == Action.ADD_ITEM.getCode() || mode == Action.PUT_ITEM.getCode()) { if (isTradeOpen(chr)) return; diff --git a/src/main/java/server/MapleTrade.java b/src/main/java/server/Trade.java similarity index 90% rename from src/main/java/server/MapleTrade.java rename to src/main/java/server/Trade.java index b335c3058a..b917116c0a 100644 --- a/src/main/java/server/MapleTrade.java +++ b/src/main/java/server/Trade.java @@ -43,12 +43,11 @@ import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; /** - * * @author Matze * @author Ronan - concurrency safety + check available slots + trade results */ -public class MapleTrade { - +public class Trade { + public enum TradeResult { NO_RESPONSE(1), PARTNER_CANCEL(2), @@ -57,29 +56,29 @@ public class MapleTrade { UNSUCCESSFUL_UNIQUE_ITEM_LIMIT(9), UNSUCCESSFUL_ANOTHER_MAP(12), UNSUCCESSFUL_DAMAGED_FILES(13); - + private final int res; - private TradeResult(int res) { + TradeResult(int res) { this.res = res; } - + private byte getValue() { return (byte) res; } } - - private MapleTrade partner = null; - private List items = new ArrayList<>(); + + private Trade partner = null; + private final List items = new ArrayList<>(); private List exchangeItems; private int meso = 0; private int exchangeMeso; - private AtomicBoolean locked = new AtomicBoolean(false); - private Character chr; - private byte number; + private final AtomicBoolean locked = new AtomicBoolean(false); + private final Character chr; + private final byte number; private boolean fullTrade = false; - - public MapleTrade(byte number, Character chr) { + + public Trade(byte number, Character chr) { this.chr = chr; this.number = number; } @@ -117,38 +116,38 @@ public class MapleTrade { boolean show = YamlConfig.config.server.USE_DEBUG; items.clear(); meso = 0; - + for (Item item : exchangeItems) { KarmaManipulator.toggleKarmaFlagToUntradeable(item); InventoryManipulator.addFromDrop(chr.getClient(), item, show); } - + if (exchangeMeso > 0) { int fee = getFee(exchangeMeso); - + chr.gainMeso(exchangeMeso - fee, show, true, show); - if(fee > 0) { + if (fee > 0) { chr.dropMessage(1, "Transaction completed. You received " + GameConstants.numberWithCommas(exchangeMeso - fee) + " mesos due to trade fees."); } else { chr.dropMessage(1, "Transaction completed. You received " + GameConstants.numberWithCommas(exchangeMeso) + " mesos."); } - + result = TradeResult.NO_RESPONSE.getValue(); } else { result = TradeResult.SUCCESSFUL.getValue(); } - + exchangeMeso = 0; if (exchangeItems != null) { exchangeItems.clear(); } - + chr.sendPacket(PacketCreator.getTradeResult(number, result)); } private void cancel(byte result) { boolean show = YamlConfig.config.server.USE_DEBUG; - + for (Item item : items) { InventoryManipulator.addFromDrop(chr.getClient(), item, show); } @@ -163,7 +162,7 @@ public class MapleTrade { if (exchangeItems != null) { exchangeItems.clear(); } - + chr.sendPacket(PacketCreator.getTradeResult(number, result)); } @@ -204,10 +203,10 @@ public class MapleTrade { return false; } } - + items.add(item); } - + return true; } @@ -218,11 +217,11 @@ public class MapleTrade { } } - public MapleTrade getPartner() { + public Trade getPartner() { return partner; } - public void setPartner(MapleTrade partner) { + public void setPartner(Trade partner) { if (locked.get()) { return; } @@ -237,35 +236,35 @@ public class MapleTrade { return new LinkedList<>(items); } - public int getExchangeMesos(){ - return exchangeMeso; + public int getExchangeMesos() { + return exchangeMeso; } - + private boolean fitsMeso() { return chr.canHoldMeso(exchangeMeso - getFee(exchangeMeso)); } - + private boolean fitsInInventory() { List> tradeItems = new LinkedList<>(); for (Item item : exchangeItems) { tradeItems.add(new Pair<>(item, item.getInventoryType())); } - + return Inventory.checkSpotsAndOwnership(chr, tradeItems); } - + private boolean fitsUniquesInInventory() { List exchangeItemids = new LinkedList<>(); for (Item item : exchangeItems) { exchangeItemids.add(item.getItemId()); } - + return chr.canHoldUniques(exchangeItemids); } - + private synchronized boolean checkTradeCompleteHandshake(boolean updateSelf) { - MapleTrade self, other; - + Trade self, other; + if (updateSelf) { self = this; other = this.getPartner(); @@ -273,15 +272,15 @@ public class MapleTrade { self = this.getPartner(); other = this; } - + if (self.isLocked()) { return false; } - + self.lockTrade(); return other.isLocked(); } - + private boolean checkCompleteHandshake() { // handshake checkout thanks to Ronan if (this.getChr().getId() < this.getPartner().getChr().getId()) { return this.checkTradeCompleteHandshake(true); @@ -289,14 +288,14 @@ public class MapleTrade { return this.getPartner().checkTradeCompleteHandshake(false); } } - + public static void completeTrade(Character chr) { - MapleTrade local = chr.getTrade(); - MapleTrade partner = local.getPartner(); + Trade local = chr.getTrade(); + Trade partner = local.getPartner(); if (local.checkCompleteHandshake()) { local.fetchExchangedItems(); partner.fetchExchangedItems(); - + if (!local.fitsMeso()) { cancelTrade(local.getChr(), TradeResult.UNSUCCESSFUL); chr.message("There is not enough meso inventory space to complete the trade."); @@ -308,7 +307,7 @@ public class MapleTrade { partner.getChr().message("There is not enough meso inventory space to complete the trade."); return; } - + if (!local.fitsInInventory()) { if (local.fitsUniquesInInventory()) { cancelTrade(local.getChr(), TradeResult.UNSUCCESSFUL); @@ -330,7 +329,7 @@ public class MapleTrade { } return; } - + if (local.getChr().getLevel() < 15) { if (local.getChr().getMesosTraded() + local.exchangeMeso > 1000000) { cancelTrade(local.getChr(), TradeResult.NO_RESPONSE); @@ -348,34 +347,36 @@ public class MapleTrade { partner.getChr().addMesosTraded(partner.exchangeMeso); } } - + LogHelper.logTrade(local, partner); local.completeTrade(); partner.completeTrade(); - + partner.getChr().setTrade(null); chr.setTrade(null); } } - + private static void cancelTradeInternal(Character chr, byte selfResult, byte partnerResult) { - MapleTrade trade = chr.getTrade(); - if(trade == null) return; - + Trade trade = chr.getTrade(); + if (trade == null) { + return; + } + trade.cancel(selfResult); if (trade.getPartner() != null) { trade.getPartner().cancel(partnerResult); trade.getPartner().getChr().setTrade(null); - + InviteCoordinator.answerInvite(InviteType.TRADE, trade.getChr().getId(), trade.getPartner().getChr().getId(), false); InviteCoordinator.answerInvite(InviteType.TRADE, trade.getPartner().getChr().getId(), trade.getChr().getId(), false); } chr.setTrade(null); } - + private static byte[] tradeResultsPair(byte result) { byte selfResult, partnerResult; - + if (result == TradeResult.PARTNER_CANCEL.getValue()) { partnerResult = result; selfResult = TradeResult.NO_RESPONSE.getValue(); @@ -386,29 +387,29 @@ public class MapleTrade { partnerResult = result; selfResult = result; } - + return new byte[]{selfResult, partnerResult}; } - + private synchronized void tradeCancelHandshake(boolean updateSelf, byte result) { byte selfResult, partnerResult; - MapleTrade self; - + Trade self; + byte[] pairedResult = tradeResultsPair(result); selfResult = pairedResult[0]; partnerResult = pairedResult[1]; - + if (updateSelf) { self = this; } else { self = this.getPartner(); } - + cancelTradeInternal(self.getChr(), selfResult, partnerResult); } - + private void cancelHandshake(byte result) { // handshake checkout thanks to Ronan - MapleTrade partner = this.getPartner(); + Trade partner = this.getPartner(); if (partner == null || this.getChr().getId() < partner.getChr().getId()) { this.tradeCancelHandshake(true, result); } else { @@ -417,32 +418,32 @@ public class MapleTrade { } public static void cancelTrade(Character chr, TradeResult result) { - MapleTrade trade = chr.getTrade(); - if(trade == null) return; - + Trade trade = chr.getTrade(); + if (trade == null) { + return; + } + trade.cancelHandshake(result.getValue()); } - + public static void startTrade(Character chr) { if (chr.getTrade() == null) { - chr.setTrade(new MapleTrade((byte) 0, chr)); + chr.setTrade(new Trade((byte) 0, chr)); } } - + private static boolean hasTradeInviteBack(Character c1, Character c2) { - MapleTrade other = c2.getTrade(); + Trade other = c2.getTrade(); if (other != null) { - MapleTrade otherPartner = other.getPartner(); + Trade otherPartner = other.getPartner(); if (otherPartner != null) { - if (otherPartner.getChr().getId() == c1.getId()) { - return true; - } + return otherPartner.getChr().getId() == c1.getId(); } } - + return false; } - + public static void inviteTrade(Character c1, Character c2) { if (InviteCoordinator.hasInvite(InviteType.TRADE, c1.getId())) { if (hasTradeInviteBack(c1, c2)) { @@ -450,19 +451,19 @@ public class MapleTrade { } else { c1.message("You are already managing someone's trade invitation."); } - + return; } else if (c1.getTrade().isFullTrade()) { c1.message("You are already in a trade."); return; } - + if (InviteCoordinator.createInvite(InviteType.TRADE, c1, c1.getId(), c2.getId())) { if (c2.getTrade() == null) { - c2.setTrade(new MapleTrade((byte) 1, c2)); + c2.setTrade(new Trade((byte) 1, c2)); c2.getTrade().setPartner(c1.getTrade()); c1.getTrade().setPartner(c2.getTrade()); - + c1.sendPacket(PacketCreator.getTradeStart(c1.getClient(), c1.getTrade(), (byte) 0)); c2.sendPacket(PacketCreator.tradeInvite(c1)); } else { @@ -478,7 +479,7 @@ public class MapleTrade { public static void visitTrade(Character c1, Character c2) { MapleInviteResult inviteRes = InviteCoordinator.answerInvite(InviteType.TRADE, c1.getId(), c2.getId(), true); - + InviteResult res = inviteRes.result; if (res == InviteResult.ACCEPTED) { if (c1.getTrade() != null && c1.getTrade().getPartner() == c2.getTrade() && c2.getTrade() != null && c2.getTrade().getPartner() == c1.getTrade()) { @@ -496,28 +497,28 @@ public class MapleTrade { } public static void declineTrade(Character chr) { - MapleTrade trade = chr.getTrade(); + Trade trade = chr.getTrade(); if (trade != null) { if (trade.getPartner() != null) { Character other = trade.getPartner().getChr(); if (InviteCoordinator.answerInvite(InviteType.TRADE, chr.getId(), other.getId(), false).result == InviteResult.DENIED) { other.message(chr.getName() + " has declined your trade request."); } - + other.getTrade().cancel(TradeResult.PARTNER_CANCEL.getValue()); other.setTrade(null); - + } trade.cancel(TradeResult.NO_RESPONSE.getValue()); chr.setTrade(null); } } - public boolean isFullTrade() { - return fullTrade; - } + public boolean isFullTrade() { + return fullTrade; + } - public void setFullTrade(boolean fullTrade) { - this.fullTrade = fullTrade; - } + public void setFullTrade(boolean fullTrade) { + this.fullTrade = fullTrade; + } } \ No newline at end of file diff --git a/src/main/java/server/maps/HiredMerchant.java b/src/main/java/server/maps/HiredMerchant.java index 342ce7fb62..473bfb435f 100644 --- a/src/main/java/server/maps/HiredMerchant.java +++ b/src/main/java/server/maps/HiredMerchant.java @@ -36,7 +36,7 @@ import net.server.Server; import net.server.audit.locks.MonitoredLockType; import net.server.audit.locks.factory.MonitoredReentrantLockFactory; import server.ItemInformationProvider; -import server.MapleTrade; +import server.Trade; import tools.DatabaseConnection; import tools.PacketCreator; import tools.Pair; @@ -279,7 +279,7 @@ public class HiredMerchant extends AbstractMapObject { if (c.getPlayer().getMeso() >= price) { if (canBuy(c, newItem)) { c.getPlayer().gainMeso(-price, false); - price -= MapleTrade.getFee(price); // thanks BHB for pointing out trade fees not applying here + price -= Trade.getFee(price); // thanks BHB for pointing out trade fees not applying here synchronized (sold) { sold.add(new SoldItem(c.getPlayer().getName(), pItem.getItem().getItemId(), newItem.getQuantity(), price)); diff --git a/src/main/java/server/maps/PlayerShop.java b/src/main/java/server/maps/PlayerShop.java index 5d414d6741..dad0751db7 100644 --- a/src/main/java/server/maps/PlayerShop.java +++ b/src/main/java/server/maps/PlayerShop.java @@ -31,7 +31,7 @@ import client.inventory.manipulator.KarmaManipulator; import net.packet.Packet; import net.server.audit.locks.MonitoredLockType; import net.server.audit.locks.factory.MonitoredReentrantLockFactory; -import server.MapleTrade; +import server.Trade; import tools.PacketCreator; import tools.Pair; @@ -283,7 +283,7 @@ public class PlayerShop extends AbstractMapObject { if (canBuy(c, newItem)) { c.getPlayer().gainMeso(-price, false); - price -= MapleTrade.getFee(price); // thanks BHB for pointing out trade fees not applying here + price -= Trade.getFee(price); // thanks BHB for pointing out trade fees not applying here owner.gainMeso(price, true); SoldItem soldItem = new SoldItem(c.getPlayer().getName(), pItem.getItem().getItemId(), quantity, price); diff --git a/src/main/java/tools/LogHelper.java b/src/main/java/tools/LogHelper.java index a58990ab09..333ba92f23 100644 --- a/src/main/java/tools/LogHelper.java +++ b/src/main/java/tools/LogHelper.java @@ -5,7 +5,7 @@ import client.Client; import client.inventory.Item; import net.server.Server; import server.ItemInformationProvider; -import server.MapleTrade; +import server.Trade; import server.expeditions.Expedition; import java.text.SimpleDateFormat; @@ -14,7 +14,7 @@ import java.util.Date; public class LogHelper { - public static void logTrade(MapleTrade trade1, MapleTrade trade2) { + public static void logTrade(Trade trade1, Trade trade2) { String name1 = trade1.getChr().getName(); String name2 = trade2.getChr().getName(); String log = "TRADE BETWEEN " + name1 + " AND " + name2 + "\r\n"; diff --git a/src/main/java/tools/PacketCreator.java b/src/main/java/tools/PacketCreator.java index 9147fc1812..c0f8469d8b 100644 --- a/src/main/java/tools/PacketCreator.java +++ b/src/main/java/tools/PacketCreator.java @@ -3243,7 +3243,7 @@ public class PacketCreator { return p; } - public static Packet getTradeStart(Client c, MapleTrade trade, byte number) { + public static Packet getTradeStart(Client c, Trade trade, byte number) { final OutPacket p = OutPacket.create(SendOpcode.PLAYER_INTERACTION); p.writeByte(PlayerInteractionHandler.Action.ROOM.getCode()); p.writeByte(3);