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 client.messages.CommandType;
import constants.GameConstants;
import constants.ItemConstants;
import handling.world.WorldBroadcastService;
import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;
import org.apache.log4j.Logger;
import tools.FileoutputUtil;
import tools.MaplePacketCreator;
import tools.packet.PlayerShopPacket;
import tools.packet.TradePacket;
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;
private static final Logger log = Logger.getLogger(MapleTrade.class);
public MapleTrade(byte tradingslot, MapleCharacter chr) {
this.tradingslot = tradingslot;
this.chr = new WeakReference(chr);
}
public void CompleteTrade() {
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
if (this.exchangeItems != null) {
List<Item> itemz = new LinkedList(this.exchangeItems);
for (Item item : itemz) {
short flag = item.getFlag();
if (ItemFlag.KARMA_USE.check(flag)) {
item.setFlag((short) (flag - ItemFlag.KARMA_USE.getValue()));
}
MapleInventoryManipulator.addFromDrop(((MapleCharacter) this.chr.get()).getClient(), item, false);
FileoutputUtil.log("[交易] " + ((MapleCharacter) this.chr.get()).getName() + " 交易获得道具: " + item.getItemId() + " x " + item.getQuantity() + " - " + ii.getName(item.getItemId()));
}
this.exchangeItems.clear();
}
if (this.exchangeMeso > 0) {
((MapleCharacter) this.chr.get()).gainMeso(this.exchangeMeso - GameConstants.getTaxAmount(this.exchangeMeso), false, false);
FileoutputUtil.log("[交易] " + ((MapleCharacter) this.chr.get()).getName() + " 交易获得金币: " + this.exchangeMeso);
}
this.exchangeMeso = 0;
((MapleCharacter) this.chr.get()).getClient().getSession().write(TradePacket.TradeMessage(this.tradingslot, (byte) 8));
}
public void cancel(MapleClient c, MapleCharacter chr) {
cancel(c, chr, 0);
}
public void cancel(MapleClient c, MapleCharacter chr, int message) {
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(TradePacket.getTradeCancel(this.tradingslot, message));
}
public boolean isLocked() {
return this.locked;
}
public 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(TradePacket.getTradeMesoSet((byte) 0, this.meso));
if (this.partner != null) {
this.partner.getChr().getClient().getSession().write(TradePacket.getTradeMesoSet((byte) 1, this.meso));
}
}
}
public void addItem(Item item) {
if ((this.locked) || (this.partner == null)) {
return;
}
this.items.add(item);
((MapleCharacter) this.chr.get()).getClient().getSession().write(TradePacket.getTradeItemAdd((byte) 0, item));
if (this.partner != null) {
this.partner.getChr().getClient().getSession().write(TradePacket.getTradeItemAdd((byte) 1, item));
}
}
public void chat(String message) {
if (!CommandProcessor.processCommand(((MapleCharacter) this.chr.get()).getClient(), message, 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()) {
WorldBroadcastService.getInstance().broadcastGMMessage(MaplePacketCreator.serverMessageRedText(((MapleCharacter) this.chr.get()).getName() + " 在交易中对 " + this.partner.getChr().getName() + " 说: " + message));
} else if ((this.partner != null) && (this.partner.getChr() != null) && (this.partner.getChr().getClient().isMonitored())) {
WorldBroadcastService.getInstance().broadcastGMMessage(MaplePacketCreator.serverMessageRedText(((MapleCharacter) this.chr.get()).getName() + " 在交易中对 " + this.partner.getChr().getName() + " 说: " + message));
}
}
public void chatAuto(String message) {
((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()) {
WorldBroadcastService.getInstance().broadcastGMMessage(MaplePacketCreator.serverMessageRedText( ((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())) {
WorldBroadcastService.getInstance().broadcastGMMessage(MaplePacketCreator.serverMessageRedText(((MapleCharacter) this.chr.get()).getName() + " said in trade [Automated] with " + this.partner.getChr().getName() + " 说: " + message));
}
}
public MapleTrade getPartner() {
return this.partner;
}
public void setPartner(MapleTrade partner) {
if (this.locked) {
return;
}
this.partner = partner;
}
public MapleCharacter getChr() {
return (MapleCharacter) this.chr.get();
}
public 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 boolean setItems(MapleClient c, Item item, byte targetSlot, int quantity) {
int target = getNextTargetSlot();
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
if ((this.partner == null) || (target == -1) || (ItemConstants.isPet(item.getItemId())) || (isLocked()) || ((ItemConstants.getInventoryType(item.getItemId()) == MapleInventoryType.EQUIP) && (quantity != 1))) {
return false;
}
short flag = item.getFlag();
if (ItemFlag.封印.check(flag)) {
c.getSession().write(MaplePacketCreator.enableActions());
return false;
}
if (ItemFlag.不可交易.check(flag) && !ItemFlag.KARMA_USE.check(flag)) {
c.getSession().write(MaplePacketCreator.enableActions());
return false;
}
if ((ii.isDropRestricted(item.getItemId()) || ii.isAccountShared(item.getItemId())) && !ItemFlag.KARMA_USE.check(flag)) {
c.getSession().write(MaplePacketCreator.enableActions());
return false;
}
Item tradeItem = item.copy();
if ((ItemConstants.is飞镖道具(item.getItemId())) || (ItemConstants.is子弹道具(item.getItemId()))) {
tradeItem.setQuantity(item.getQuantity());
MapleInventoryManipulator.removeFromSlot(c, ItemConstants.getInventoryType(item.getItemId()), item.getPosition(), item.getQuantity(), true);
} else {
tradeItem.setQuantity((short) quantity);
MapleInventoryManipulator.removeFromSlot(c, ItemConstants.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((byte) targetSlot);
addItem(tradeItem);
return true;
}
private int check() {
if (((MapleCharacter) this.chr.get()).getMeso() + this.exchangeMeso < 0) {
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 (ItemConstants.getInventoryType(item.getItemId())) {
case EQUIP:
eq++;
break;
case USE:
use++;
break;
case SETUP:
setup++;
break;
case ETC:
etc++;
break;
case CASH:
cash++;
}
if ((ii.isPickupRestricted(item.getItemId())) && (((MapleCharacter) this.chr.get()).haveItem(item.getItemId(), 1, true, true))) {
return 2;
}
}
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 void completeTrade(MapleCharacter player) {
MapleTrade local = player.getTrade();
MapleTrade partner = local.getPartner();
if ((partner == null) || (local.locked)) {
return;
}
local.locked = true;
partner.getChr().getClient().getSession().write(TradePacket.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();
FileoutputUtil.log("[交易] " + local.getChr().getName() + " 和 " + partner.getChr().getName() + " 交易完成。");
} else {
partner.cancel(partner.getChr().getClient(), partner.getChr(), lz == 0 ? lz2 : lz);
local.cancel(player.getClient(), player, lz == 0 ? lz2 : lz);
}
partner.getChr().setTrade(null);
player.setTrade(null);
}
}
public static void cancelTrade(MapleTrade Localtrade, MapleClient c, MapleCharacter player) {
Localtrade.cancel(c, player);
MapleTrade partner = Localtrade.getPartner();
if ((partner != null) && (partner.getChr() != null)) {
partner.cancel(partner.getChr().getClient(), partner.getChr());
partner.getChr().setTrade(null);
}
player.setTrade(null);
}
public static void startTrade(MapleCharacter player) {
if (player.getTrade() == null) {
player.setTrade(new MapleTrade((byte) 0, player));
player.getClient().getSession().write(TradePacket.getTradeStart(player.getClient(), player.getTrade(), (byte) 0));
} else {
player.getClient().getSession().write(MaplePacketCreator.serverMessageRedText("不能同时做多件事情。"));
}
}
public static void inviteTrade(MapleCharacter player, MapleCharacter target) {
if ((player == null) || (player.getTrade() == null)) {
return;
}
if ((target != null) && (target.getTrade() == null)) {
target.setTrade(new MapleTrade((byte) 1, target));
target.getTrade().setPartner(player.getTrade());
player.getTrade().setPartner(target.getTrade());
target.getClient().getSession().write(TradePacket.getTradeInvite(player));
} else {
player.getClient().getSession().write(MaplePacketCreator.serverMessageRedText("对方正在和其他玩家进行交易中。"));
cancelTrade(player.getTrade(), player.getClient(), player);
}
}
public static void visitTrade(MapleCharacter player, MapleCharacter target) {
if ((target != null) && (player.getTrade() != null) && (player.getTrade().getPartner() == target.getTrade()) && (target.getTrade() != null) && (target.getTrade().getPartner() == player.getTrade())) {
player.getTrade().inTrade = true;
target.getClient().getSession().write(PlayerShopPacket.shopVisitorAdd(player, 1));
player.getClient().getSession().write(TradePacket.getTradeStart(player.getClient(), player.getTrade(), (byte) 1));
player.dropMessage(-2, "系统提示 : 进行金币交换请注意手续费");
target.dropMessage(-2, "系统提示 : 进行金币交换请注意手续费");
player.getClient().getSession().write(MaplePacketCreator.enableActions());
target.getClient().getSession().write(MaplePacketCreator.enableActions());
} else {
player.getClient().getSession().write(MaplePacketCreator.serverMessageRedText("对方已经取消了交易。"));
}
}
public static void declineTrade(MapleCharacter player) {
MapleTrade trade = player.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, player.getName() + " 拒绝了你的交易邀请。");
}
}
trade.cancel(player.getClient(), player);
player.setTrade(null);
}
}
}