Package l2p.gameserver.clientpackets

Source Code of l2p.gameserver.clientpackets.RequestBuyItem

package l2p.gameserver.clientpackets;

import java.util.logging.Logger;

import l2p.Config;
import l2p.gameserver.TradeController;
import l2p.gameserver.TradeController.NpcTradeList;
import l2p.gameserver.cache.Msg;
import l2p.gameserver.model.L2Character;
import l2p.gameserver.model.L2Player;
import l2p.gameserver.model.TradeItem;
import l2p.gameserver.model.entity.residence.Castle;
import l2p.gameserver.model.instances.L2CastleChamberlainInstance;
import l2p.gameserver.model.instances.L2ClanHallManagerInstance;
import l2p.gameserver.model.instances.L2MercManagerInstance;
import l2p.gameserver.model.instances.L2MerchantInstance;
import l2p.gameserver.model.instances.L2NpcFriendInstance;
import l2p.gameserver.model.instances.L2NpcInstance;
import l2p.gameserver.model.items.L2ItemInstance;
import l2p.gameserver.serverpackets.ExBuySellList;
import l2p.gameserver.tables.ItemTable;
import l2p.util.GArray;
import l2p.util.Log;
import l2p.util.SafeMath;
import l2p.util.Util;

public class RequestBuyItem extends L2GameClientPacket
{
  private static Logger _log = Logger.getLogger(RequestBuyItem.class.getName());
  private int _listId;
  private int _count;
  private long[] _items; // count*2

  @Override
  public void readImpl()
  {
    _listId = readD();
    _count = readD();
    if(_count * 12 > _buf.remaining() || _count > Short.MAX_VALUE || _count <= 0)
    {
      _items = null;
      return;
    }
    _items = new long[_count * 2];
    for(int i = 0; i < _count; i++)
    {
      _items[i * 2 + 0] = readD();
      _items[i * 2 + 1] = readQ();
      if(_items[i * 2 + 0] < 1 || _items[i * 2 + 1] < 1)
      {
        _items = null;
        break;
      }
    }
  }

  @Override
  public void runImpl()
  {
    L2Player activeChar = getClient().getActiveChar();
    if(activeChar == null)
    {
      return;
    }
    if(_items == null || _count == 0)
    {
      return;
    }
    if(activeChar.isOutOfControl())
    {
      activeChar.sendActionFailed();
      return;
    }
    if(!Config.ALT_GAME_KARMA_PLAYER_CAN_SHOP && activeChar.getKarma() > 0 && !activeChar.isGM())
    {
      activeChar.sendActionFailed();
      return;
    }
    // Проверяем, не подменили ли id
    if(activeChar.getBuyListId() != _listId)
    {
      Util.handleIllegalPlayerAction(activeChar, "RequestBuyItem[100]", "Tried to buy from buylist: " + _listId, 1);
      return;
    }
    L2NpcInstance npc = activeChar.getLastNpc();
    boolean isValidMerchant = npc instanceof L2ClanHallManagerInstance || npc instanceof L2MerchantInstance || npc instanceof L2MercManagerInstance || npc instanceof L2CastleChamberlainInstance || npc instanceof L2NpcFriendInstance;
    if(!activeChar.isGM() && (npc == null || !isValidMerchant || !activeChar.isInRange(npc.getLoc(), L2Character.INTERACTION_DISTANCE)))
    {
      activeChar.sendActionFailed();
      return;
    }
    L2NpcInstance merchant = null;
    if(npc != null && (npc instanceof L2MerchantInstance || npc instanceof L2ClanHallManagerInstance)) //TODO расширить список?
    {
      merchant = npc;
    }
    GArray<L2ItemInstance> items = new GArray<L2ItemInstance>(_count);
    for(int i = 0; i < _count; i++)
    {
      int itemId = (int) _items[i * 2 + 0];
      long cnt = _items[i * 2 + 1];
      if(cnt <= 0)
      {
        activeChar.sendActionFailed();
        return;
      }
      L2ItemInstance inst = ItemTable.getInstance().createItem(itemId);
      if(inst == null)
      {
        activeChar.sendActionFailed();
        return;
      }
      if(!inst.isStackable() && cnt != 1)
      {
        activeChar.sendActionFailed();
        return;
      }
      inst.setCount(cnt);
      items.add(inst);
    }
    long finalLoad = 0;
    int finalCount = activeChar.getInventory().getSize();
    int needsSpace;
    int weight;
    long currentMoney = activeChar.getAdena();
    int itemId;
    long cnt, price, tax = 0, totalCost = 0, subTotal = 0;
    double taxRate = 0;
    Castle castle = null;
    if(merchant != null)
    {
      castle = merchant.getCastle(activeChar);
      if(castle != null)
      {
        taxRate = castle.getTaxRate();
      }
    }
    for(int i = 0; i < items.size(); i++)
    {
      itemId = items.get(i).getItemId();
      cnt = items.get(i).getCount();
      needsSpace = 2;
      if(items.get(i).getItem().isStackable())
      {
        needsSpace = 1;
        if(activeChar.getInventory().getItemByItemId(itemId) != null)
        {
          needsSpace = 0;
        }
      }
      NpcTradeList list = TradeController.getInstance().getBuyList(_listId);
      if(list == null)
      {
        Log.add("tried to buy from non-exist list " + _listId, "errors", activeChar);
        activeChar.sendActionFailed();
        return;
      }
      TradeItem ti = getItemByItemId(itemId, list);
      price = ti == null ? 0 : ti.getOwnersPrice();
      if(itemId >= 3960 && itemId <= 4921)
      {
        price *= Config.RATE_SIEGE_GUARDS_PRICE;
      }
      if(price == 0 && !activeChar.getPlayerAccess().UseGMShop)
      {
        Util.handleIllegalPlayerAction(activeChar, "RequestBuyItem[191]", "Tried to buy zero price item, list " + _listId + " item " + itemId, 0);
        for(L2ItemInstance item : items)
        {
          item.deleteMe();
        }
        activeChar.sendMessage("Error: zero-price item! Please notify GM.");
        activeChar.sendActionFailed();
        return;
      }
      weight = items.get(i).getItem().getWeight();
      if(price < 0)
      {
        _log.warning("ERROR, no price found. Wrong buylist?");
        for(L2ItemInstance item : items)
        {
          item.deleteMe();
        }
        activeChar.sendActionFailed();
        return;
      }
      try
      {
        if(cnt < 0)
        {
          throw new ArithmeticException("cnt < 0");
        }
        subTotal = SafeMath.safeAddLong(subTotal, SafeMath.safeMulLong(cnt, price)); // Before tax
        tax = SafeMath.safeMulLong(subTotal, taxRate);
        totalCost = SafeMath.safeAddLong(subTotal, tax);
        if(totalCost < 0)
        {
          throw new ArithmeticException("213: Tried to purchase negative " + totalCost + " adena worth of goods.");
        }
        finalLoad = SafeMath.safeAddLong(finalLoad, SafeMath.safeMulLong(cnt, weight));
        if(finalLoad < 0)
        {
          throw new ArithmeticException("254: Tried to purchase negative " + finalLoad + " adena worth of goods.");
        }
      }
      catch(ArithmeticException e)
      {
        Util.handleIllegalPlayerAction(activeChar, "RequestBuyItem[157]", "merchant: " + merchant + ": " + e.getMessage(), 1);
        for(L2ItemInstance item : items)
        {
          item.deleteMe();
        }
        sendPacket(Msg.YOU_HAVE_EXCEEDED_THE_QUANTITY_THAT_CAN_BE_INPUTTED, Msg.ActionFail);
        return;
      }
      if(needsSpace == 2)
      {
        finalCount += cnt;
      }
      else if(needsSpace == 1)
      {
        finalCount += 1;
      }
    }
    if(totalCost > currentMoney || subTotal < 0 || currentMoney <= 0)
    {
      for(L2ItemInstance item : items)
      {
        item.deleteMe();
      }
      sendPacket(Msg.YOU_DO_NOT_HAVE_ENOUGH_ADENA, Msg.ActionFail);
      return;
    }
    if(!activeChar.getInventory().validateWeight(finalLoad))
    {
      for(L2ItemInstance item : items)
      {
        item.deleteMe();
      }
      sendPacket(Msg.YOU_HAVE_EXCEEDED_THE_WEIGHT_LIMIT, Msg.ActionFail);
      return;
    }
    if(!activeChar.getInventory().validateCapacity(finalCount))
    {
      for(L2ItemInstance item : items)
      {
        item.deleteMe();
      }
      sendPacket(Msg.YOUR_INVENTORY_IS_FULL, Msg.ActionFail);
      return;
    }
    // Для магазинов с ограниченным количеством товара число продаваемых предметов уменьшаем после всех проверок
    NpcTradeList list = TradeController.getInstance().getBuyList(_listId);
    for(int i = 0; i < items.size(); i++)
    {
      itemId = items.get(i).getItemId();
      cnt = items.get(i).getCount();
      TradeItem ic = getItemByItemId(itemId, list);
      if(ic != null && ic.isCountLimited())
      {
        if(cnt > ic.getCurrentValue())
        {
          int t = (int) (System.currentTimeMillis() / 60000);
          if(ic.getLastRechargeTime() + ic.getRechargeTime() <= t)
          {
            ic.setLastRechargeTime(t);
            ic.setCurrentValue(ic.getCount());
          }
          else
          {
            continue;
          }
        }
        else
        {
          ic.setCurrentValue(ic.getCurrentValue() - cnt);
        }
      }
    }
    activeChar.reduceAdena(totalCost, true);
    for(L2ItemInstance item : items)
    {
      Log.LogItem(activeChar, merchant, Log.BuyItem, item);
      activeChar.getInventory().addItem(item);
    }
    // Add tax to castle treasury if not owned by npc clan
    if(castle != null && castle.getOwnerId() > 0 && activeChar.getReflection().getId() == 0)
    {
      castle.addToTreasury(tax, true, false);
      Log.add(castle.getName() + "|" + tax + "|BuyItem", "treasury");
    }
    sendPacket(new ExBuySellList(list, activeChar, taxRate).done());
    activeChar.updateStats();
  }

  private static final TradeItem getItemByItemId(int itemId, NpcTradeList list)
  {
    for(TradeItem ti : list.getItems())
    {
      if(ti.getItemId() == itemId)
      {
        return ti;
      }
    }
    return null;
  }
}
TOP

Related Classes of l2p.gameserver.clientpackets.RequestBuyItem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.