/* OrpheusMS: MapleStory Private Server based on OdinMS Copyright (C) 2012 Aaron Weiss <aaron@deviant-core.net> Patrick Huy <patrick.huy@frz.cc> Matthias Butz <matze@odinms.de> Jan Christian Meyer <vimes@odinms.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package server; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import client.IItem; import client.Item; import client.MapleClient; import client.MapleInventoryType; import client.MaplePet; import constants.ItemConstants; import tools.DatabaseConnection; import tools.MaplePacketCreator; import tools.Output; /** * * @author Matze */ public class MapleShop { private static final Set<Integer> rechargeableItems = new LinkedHashSet<Integer>(); private int id; private int npcId; private List<MapleShopItem> items; private int tokenvalue = 1000000000; private int token = 4000313; static { for (int i = 2070000; i < 2070017; i++) { rechargeableItems.add(i); } rechargeableItems.add(2331000);// Blaze Capsule rechargeableItems.add(2332000);// Glaze Capsule rechargeableItems.add(2070018); rechargeableItems.remove(2070014); // doesn't exist for (int i = 2330000; i <= 2330005; i++) { rechargeableItems.add(i); } } private MapleShop(int id, int npcId) { this.id = id; this.npcId = npcId; items = new ArrayList<MapleShopItem>(); } private void addItem(MapleShopItem item) { items.add(item); } public void sendShop(MapleClient c) { c.getPlayer().setShop(this); c.getSession().write(MaplePacketCreator.getNPCShop(c, getNpcId(), items)); } public void buy(MapleClient c, short slot, int itemId, short quantity) { MapleShopItem item = findBySlot(slot); if (item != null) { if (item.getItemId() != itemId) { Output.print("Wrong slot number in shop " + id); return; } } else return; MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); if (item != null && item.getPrice() > 0) { if (c.getPlayer().getMeso() >= (long) item.getPrice() * quantity) { if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) { if (!ItemConstants.isRechargable(itemId)) { // Pets can't be // bought from // shops MapleInventoryManipulator.addById(c, itemId, quantity); c.getPlayer().gainMeso(-(item.getPrice() * quantity), false); } else { short slotMax = ii.getSlotMax(c, item.getItemId()); quantity = slotMax; MapleInventoryManipulator.addById(c, itemId, quantity); c.getPlayer().gainMeso(-item.getPrice(), false); } c.getSession().write(MaplePacketCreator.shopTransaction((byte) 0)); } else c.getSession().write(MaplePacketCreator.shopTransaction((byte) 3)); } else c.getSession().write(MaplePacketCreator.shopTransaction((byte) 2)); } else if (item != null && item.getPitch() > 0) { if (c.getPlayer().getInventory(MapleInventoryType.ETC).countById(4310000) >= (long) item.getPitch() * quantity) { if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) { if (!ItemConstants.isRechargable(itemId)) { MapleInventoryManipulator.addById(c, itemId, quantity); MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, item.getPitch() * quantity, false, false); } else { short slotMax = ii.getSlotMax(c, item.getItemId()); quantity = slotMax; MapleInventoryManipulator.addById(c, itemId, quantity); MapleInventoryManipulator.removeById(c, MapleInventoryType.ETC, 4310000, item.getPitch() * quantity, false, false); } c.getSession().write(MaplePacketCreator.shopTransaction((byte) 0)); } else c.getSession().write(MaplePacketCreator.shopTransaction((byte) 3)); } } else if (c.getPlayer().getInventory(MapleInventoryType.CASH).countById(token) != 0) { int amount = c.getPlayer().getInventory(MapleInventoryType.CASH).countById(token); int value = amount * tokenvalue; int cost = item.getPrice() * quantity; if (c.getPlayer().getMeso() + value >= cost) { int cardreduce = value - cost; int diff = cardreduce + c.getPlayer().getMeso(); if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) { if (itemId >= 5000000 && itemId <= 5000100) { int petid = MaplePet.createPet(itemId); MapleInventoryManipulator.addById(c, itemId, quantity, null, petid, -1); } else { MapleInventoryManipulator.addById(c, itemId, quantity); } c.getPlayer().gainMeso(diff, false); } else { c.getSession().write(MaplePacketCreator.shopTransaction((byte) 3)); } c.getSession().write(MaplePacketCreator.shopTransaction((byte) 0)); } else c.getSession().write(MaplePacketCreator.shopTransaction((byte) 2)); } } public void sell(MapleClient c, MapleInventoryType type, short slot, short quantity) { if (quantity == 0xFFFF || quantity == 0) { quantity = 1; } MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); IItem item = c.getPlayer().getInventory(type).getItem((byte) slot); if (ItemConstants.isRechargable(item.getItemId())) { quantity = item.getQuantity(); } if (quantity < 0) { return; } short iQuant = item.getQuantity(); if (iQuant == 0xFFFF) { iQuant = 1; } if (quantity <= iQuant && iQuant > 0) { MapleInventoryManipulator.removeFromSlot(c, type, (byte) slot, quantity, false); double price; if (ItemConstants.isRechargable(item.getItemId())) { price = ii.getWholePrice(item.getItemId()) / (double) ii.getSlotMax(c, item.getItemId()); } else { price = ii.getPrice(item.getItemId()); } int recvMesos = (int) Math.max(Math.ceil(price * quantity), 0); if (price != -1 && recvMesos > 0) { c.getPlayer().gainMeso(recvMesos, false); } c.getSession().write(MaplePacketCreator.shopTransaction((byte) 0x8)); } } public void recharge(MapleClient c, byte slot) { MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); IItem item = c.getPlayer().getInventory(MapleInventoryType.USE).getItem(slot); if (item == null || !ItemConstants.isRechargable(item.getItemId())) { return; } short slotMax = ii.getSlotMax(c, item.getItemId()); if (item.getQuantity() < 0) { return; } if (item.getQuantity() < slotMax) { int price = (int) Math.round(ii.getPrice(item.getItemId()) * (slotMax - item.getQuantity())); if (c.getPlayer().getMeso() >= price) { item.setQuantity(slotMax); c.getSession().write(MaplePacketCreator.updateInventorySlot(MapleInventoryType.USE, (Item) item)); c.getPlayer().gainMeso(-price, false, true, false); c.getSession().write(MaplePacketCreator.shopTransaction((byte) 0x8)); } else { c.getSession().write(MaplePacketCreator.serverNotice(1, "You do not have enough mesos.")); c.getSession().write(MaplePacketCreator.enableActions()); } } } private MapleShopItem findBySlot(short slot) { return items.get(slot); } public static MapleShop createFromDB(int id, boolean isShopId) { MapleShop ret = null; int shopId; try { Connection con = DatabaseConnection.getConnection(); PreparedStatement ps; if (isShopId) { ps = con.prepareStatement("SELECT * FROM shops WHERE shopid = ?"); } else { ps = con.prepareStatement("SELECT * FROM shops WHERE npcid = ?"); } ps.setInt(1, id); ResultSet rs = ps.executeQuery(); if (rs.next()) { shopId = rs.getInt("shopid"); ret = new MapleShop(shopId, rs.getInt("npcid")); rs.close(); ps.close(); } else { rs.close(); ps.close(); return null; } ps = con.prepareStatement("SELECT * FROM shopitems WHERE shopid = ? ORDER BY position ASC"); ps.setInt(1, shopId); rs = ps.executeQuery(); List<Integer> recharges = new ArrayList<Integer>(rechargeableItems); while (rs.next()) { if (ItemConstants.isRechargable(rs.getInt("itemid"))) { MapleShopItem starItem = new MapleShopItem((short) 1, rs.getInt("itemid"), rs.getInt("price"), rs.getInt("pitch")); ret.addItem(starItem); if (rechargeableItems.contains(starItem.getItemId())) { recharges.remove(Integer.valueOf(starItem.getItemId())); } } else { ret.addItem(new MapleShopItem((short) 1000, rs.getInt("itemid"), rs.getInt("price"), rs.getInt("pitch"))); } } for (Integer recharge : recharges) { ret.addItem(new MapleShopItem((short) 1000, recharge.intValue(), 0, 0)); } rs.close(); ps.close(); } catch (SQLException e) { e.printStackTrace(); } return ret; } public int getNpcId() { return npcId; } public int getId() { return id; } }