package server;
import client.MapleCharacter;
import client.MapleClient;
import client.inventory.Item;
import client.inventory.ItemFlag;
import client.inventory.MapleInventoryType;
import client.messages.CommandProcessor;
import constants.GameConstants;
import constants.ServerConstants;
import handling.world.World;
import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;
import tools.packet.CField;
import tools.packet.CWvsContext;
import tools.packet.PlayerShopPacket;
public class MapleTrade {
private MapleTrade partner = null;
private final List<Item> items = new LinkedList();
private List<Item> exchangeItems;
private int meso = 0;
private int exchangeMeso = 0;
private boolean locked = false;
private boolean inTrade = false;
private final WeakReference<MapleCharacter> chr;
private final byte tradingslot;
public MapleTrade(byte tradingslot, MapleCharacter chr) {
this.tradingslot = tradingslot;
this.chr = new WeakReference(chr);
}
public final void CompleteTrade() {
if (this.exchangeItems != null) {
List<Item> itemz = new LinkedList(this.exchangeItems);
for (Item item : itemz) {
short flag = item.getFlag();
if (ItemFlag.KARMA_EQ.check(flag)) {
item.setFlag((short) (flag - ItemFlag.KARMA_EQ.getValue()));
} else if (ItemFlag.KARMA_USE.check(flag)) {
item.setFlag((short) (flag - ItemFlag.KARMA_USE.getValue()));
}
MapleInventoryManipulator.addFromDrop(((MapleCharacter) this.chr.get()).getClient(), item, false);
}
this.exchangeItems.clear();
}
if (this.exchangeMeso > 0) {
((MapleCharacter) this.chr.get()).gainMeso(this.exchangeMeso - GameConstants.getTaxAmount(this.exchangeMeso), false, false);
}
this.exchangeMeso = 0;
((MapleCharacter) this.chr.get()).getClient().getSession().write(CField.InteractionPacket.TradeMessage(this.tradingslot, (byte) 7));
}
public final void cancel(MapleClient c, MapleCharacter chr) {
cancel(c, chr, 0);
}
public final void cancel(MapleClient c, MapleCharacter chr, int unsuccessful) {
if (this.items != null) {
List<Item> itemz = new LinkedList(this.items);
for (Item item : itemz) {
MapleInventoryManipulator.addFromDrop(c, item, false);
}
this.items.clear();
}
if (this.meso > 0) {
chr.gainMeso(this.meso, false, false);
}
this.meso = 0;
c.getSession().write(CField.InteractionPacket.getTradeCancel(this.tradingslot, unsuccessful));
}
public final boolean isLocked() {
return this.locked;
}
public final void setMeso(int meso) {
if ((this.locked) || (this.partner == null) || (meso <= 0) || (this.meso + meso <= 0)) {
return;
}
if (((MapleCharacter) this.chr.get()).getMeso() >= meso) {
((MapleCharacter) this.chr.get()).gainMeso(-meso, false, false);
this.meso += meso;
((MapleCharacter) this.chr.get()).getClient().getSession().write(CField.InteractionPacket.getTradeMesoSet((byte) 0, this.meso));
if (this.partner != null) {
this.partner.getChr().getClient().getSession().write(CField.InteractionPacket.getTradeMesoSet((byte) 1, this.meso));
}
}
}
public final void addItem(Item item) {
if ((this.locked) || (this.partner == null)) {
return;
}
this.items.add(item);
((MapleCharacter) this.chr.get()).getClient().getSession().write(CField.InteractionPacket.getTradeItemAdd((byte) 0, item));
if (this.partner != null) {
this.partner.getChr().getClient().getSession().write(CField.InteractionPacket.getTradeItemAdd((byte) 1, item));
}
}
public final void chat(String message) throws Exception {
if (chr.get().getMap().getId() == GameConstants.JAIL) {
chr.get().dropMessage(5, "You're in jail, herp derp.");
chr.get().getClient().getSession().write(CWvsContext.enableActions());
return;
}
if (chr.get().isMuted() && !chr.get().isGM()) {
chr.get().dropMessage(5, "You are Muted, therefore you are unable to talk.");
chr.get().getClient().getSession().write(CWvsContext.enableActions());
return;
}
if (!CommandProcessor.processCommand(chr.get().getClient(), message, ServerConstants.CommandType.TRADE)) {
((MapleCharacter) this.chr.get()).dropMessage(-2, ((MapleCharacter) this.chr.get()).getName() + " : " + message);
if (this.partner != null) {
this.partner.getChr().getClient().getSession().write(PlayerShopPacket.shopChat(((MapleCharacter) this.chr.get()).getName() + " : " + message, 1));
}
}
if (((MapleCharacter) this.chr.get()).getClient().isMonitored()) {
World.Broadcast.broadcastGMMessage(CWvsContext.serverNotice(6, ((MapleCharacter) this.chr.get()).getName() + " said in trade with " + this.partner.getChr().getName() + ": " + message));
} else if ((this.partner != null) && (this.partner.getChr() != null) && (this.partner.getChr().getClient().isMonitored())) {
World.Broadcast.broadcastGMMessage(CWvsContext.serverNotice(6, ((MapleCharacter) this.chr.get()).getName() + " said in trade with " + this.partner.getChr().getName() + ": " + message));
}
}
public final void chatAuto(String message) {
if (chr.get().getMap().getId() == GameConstants.JAIL) {
chr.get().dropMessage(5, "You're in jail, herp derp.");
chr.get().getClient().getSession().write(CWvsContext.enableActions());
return;
}
if (chr.get().isMuted() && !chr.get().isGM()) {
chr.get().dropMessage(5, "You are Muted, therefore you are unable to talk. ");
chr.get().getClient().getSession().write(CWvsContext.enableActions());
return;
}
((MapleCharacter) this.chr.get()).dropMessage(-2, message);
if (this.partner != null) {
this.partner.getChr().getClient().getSession().write(PlayerShopPacket.shopChat(message, 1));
}
if (((MapleCharacter) this.chr.get()).getClient().isMonitored()) {
World.Broadcast.broadcastGMMessage(CWvsContext.serverNotice(6, ((MapleCharacter) this.chr.get()).getName() + " said in trade [Automated] with " + this.partner.getChr().getName() + ": " + message));
} else if ((this.partner != null) && (this.partner.getChr() != null) && (this.partner.getChr().getClient().isMonitored())) {
World.Broadcast.broadcastGMMessage(CWvsContext.serverNotice(6, ((MapleCharacter) this.chr.get()).getName() + " said in trade [Automated] with " + this.partner.getChr().getName() + ": " + message));
}
}
public final MapleTrade getPartner() {
return this.partner;
}
public final void setPartner(MapleTrade partner) {
if (this.locked) {
return;
}
this.partner = partner;
}
public final MapleCharacter getChr() {
return (MapleCharacter) this.chr.get();
}
public final int getNextTargetSlot() {
if (this.items.size() >= 9) {
return -1;
}
int ret = 1;
for (Item item : this.items) {
if (item.getPosition() == ret) {
ret++;
}
}
return ret;
}
public boolean inTrade() {
return this.inTrade;
}
public final boolean setItems(MapleClient c, Item item, byte targetSlot, int quantity) {
int target = getNextTargetSlot();
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
if ((this.partner == null) || (target == -1) || (GameConstants.isPet(item.getItemId())) || (isLocked()) || ((GameConstants.getInventoryType(item.getItemId()) == MapleInventoryType.EQUIP) && (quantity != 1))) {
return false;
}
short flag = item.getFlag();
if ((ItemFlag.UNTRADEABLE.check(flag)) || (ItemFlag.LOCK.check(flag))) {
c.getSession().write(CWvsContext.enableActions());
return false;
}
Item tradeItem = item.copy();
if ((GameConstants.isThrowingStar(item.getItemId())) || (GameConstants.isBullet(item.getItemId()))) {
tradeItem.setQuantity(item.getQuantity());
MapleInventoryManipulator.removeFromSlot(c, GameConstants.getInventoryType(item.getItemId()), item.getPosition(), item.getQuantity(), true);
} else {
tradeItem.setQuantity((short) quantity);
MapleInventoryManipulator.removeFromSlot(c, GameConstants.getInventoryType(item.getItemId()), item.getPosition(), (short) quantity, true);
}
if (targetSlot < 0) {
targetSlot = (byte) target;
} else {
for (Item itemz : this.items) {
if (itemz.getPosition() == targetSlot) {
targetSlot = (byte) target;
break;
}
}
}
tradeItem.setPosition((short) targetSlot);
addItem(tradeItem);
return true;
}
private final int check() {
if (((MapleCharacter) this.chr.get()).getMeso() + this.exchangeMeso < 0L) {
return 1;
}
if (this.exchangeItems != null) {
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
byte eq = 0;
byte use = 0;
byte setup = 0;
byte etc = 0;
byte cash = 0;
for (Item item : this.exchangeItems) {
switch (GameConstants.getInventoryType(item.getItemId())) {
case EQUIP:
eq = (byte) (eq + 1);
break;
case USE:
use = (byte) (use + 1);
break;
case SETUP:
setup = (byte) (setup + 1);
break;
case ETC:
etc = (byte) (etc + 1);
break;
case CASH:
cash = (byte) (cash + 1);
}
}
if ((((MapleCharacter) this.chr.get()).getInventory(MapleInventoryType.EQUIP).getNumFreeSlot() < eq) || (((MapleCharacter) this.chr.get()).getInventory(MapleInventoryType.USE).getNumFreeSlot() < use) || (((MapleCharacter) this.chr.get()).getInventory(MapleInventoryType.SETUP).getNumFreeSlot() < setup) || (((MapleCharacter) this.chr.get()).getInventory(MapleInventoryType.ETC).getNumFreeSlot() < etc) || (((MapleCharacter) this.chr.get()).getInventory(MapleInventoryType.CASH).getNumFreeSlot() < cash)) {
return 1;
}
}
return 0;
}
public static final void completeTrade(MapleCharacter c) {
MapleTrade local = c.getTrade();
MapleTrade partner = local.getPartner();
if ((partner == null) || (local.locked)) {
return;
}
local.locked = true;
partner.getChr().getClient().getSession().write(CField.InteractionPacket.getTradeConfirmation());
partner.exchangeItems = new LinkedList(local.items);
partner.exchangeMeso = local.meso;
if (partner.isLocked()) {
int lz = local.check();
int lz2 = partner.check();
if ((lz == 0) && (lz2 == 0)) {
local.CompleteTrade();
partner.CompleteTrade();
} else {
partner.cancel(partner.getChr().getClient(), partner.getChr(), lz == 0 ? lz2 : lz);
local.cancel(c.getClient(), c, lz == 0 ? lz2 : lz);
}
partner.getChr().setTrade(null);
c.setTrade(null);
}
}
public static final void cancelTrade(MapleTrade Localtrade, MapleClient c, MapleCharacter chr) {
Localtrade.cancel(c, chr);
MapleTrade partner = Localtrade.getPartner();
if ((partner != null) && (partner.getChr() != null)) {
partner.cancel(partner.getChr().getClient(), partner.getChr());
partner.getChr().setTrade(null);
}
chr.setTrade(null);
}
public static final void startTrade(MapleCharacter c) {
if (c.getTrade() == null) {
c.setTrade(new MapleTrade((byte) 0, c));
c.getClient().getSession().write(CField.InteractionPacket.getTradeStart(c.getClient(), c.getTrade(), (byte) 0));
} else {
c.getClient().getSession().write(CWvsContext.serverNotice(5, "You are already in a trade"));
}
}
public static final void inviteTrade(MapleCharacter c1, MapleCharacter c2) {
if ((c1 == null) || (c1.getTrade() == null)) {
return;
}
if ((c2 != null) && (c2.getTrade() == null)) {
c2.setTrade(new MapleTrade((byte) 1, c2));
c2.getTrade().setPartner(c1.getTrade());
c1.getTrade().setPartner(c2.getTrade());
c2.getClient().getSession().write(CField.InteractionPacket.getTradeInvite(c1));
} else {
c1.getClient().getSession().write(CWvsContext.serverNotice(5, "The other player is already trading with someone else."));
cancelTrade(c1.getTrade(), c1.getClient(), c1);
}
}
public static final void visitTrade(MapleCharacter c1, MapleCharacter c2) {
if ((c2 != null) && (c1.getTrade() != null) && (c1.getTrade().getPartner() == c2.getTrade()) && (c2.getTrade() != null) && (c2.getTrade().getPartner() == c1.getTrade())) {
c1.getTrade().inTrade = true;
c2.getClient().getSession().write(PlayerShopPacket.shopVisitorAdd(c1, 1));
c1.getClient().getSession().write(CField.InteractionPacket.getTradeStart(c1.getClient(), c1.getTrade(), (byte) 1));
c1.dropMessage(-2, "System : Use @tradehelp to see the list of trading commands");
c2.dropMessage(-2, "System : Use @tradehelp to see the list of trading commands");
} else {
c1.getClient().getSession().write(CWvsContext.serverNotice(5, "The other player has already closed the trade"));
}
}
public static final void declineTrade(MapleCharacter c) {
MapleTrade trade = c.getTrade();
if (trade != null) {
if (trade.getPartner() != null) {
MapleCharacter other = trade.getPartner().getChr();
if ((other != null) && (other.getTrade() != null)) {
other.getTrade().cancel(other.getClient(), other);
other.setTrade(null);
other.dropMessage(5, c.getName() + " has declined your trade request");
}
}
trade.cancel(c.getClient(), c);
c.setTrade(null);
}
}
}