/* 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 client.IEquip; import client.IItem; import client.Item; import client.ItemFactory; import client.ItemInventoryEntry; import client.MapleInventoryType; import client.MaplePet; import constants.ItemConstants; import java.io.File; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import provider.MapleData; import provider.MapleDataProvider; import provider.MapleDataProviderFactory; import provider.MapleDataTool; import tools.DatabaseConnection; /* * @author Flav */ public class CashShop { public static class CashItem { private int sn, itemId, price; private long period; private short count; private boolean onSale; private CashItem(int sn, int itemId, int price, long period, short count, boolean onSale) { this.sn = sn; this.itemId = itemId; this.price = price; this.period = (period == 0 ? 90 : period); this.count = count; this.onSale = onSale; } public int getSN() { return sn; } public int getItemId() { return itemId; } public int getPrice() { return price; } public short getCount() { return count; } public boolean isOnSale() { return onSale; } public IItem toItem() { MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); IItem item; int petid = -1; if (ItemConstants.isPet(itemId)) petid = MaplePet.createPet(itemId); if (ii.getInventoryType(itemId).equals(MapleInventoryType.EQUIP)) { item = ii.getEquipById(itemId); } else { item = new Item(itemId, (byte) 0, count, petid); } if (ItemConstants.EXPIRING_ITEMS) item.setExpiration(period == 1 ? System.currentTimeMillis() + (1000 * 60 * 60 * 4 * period) : System.currentTimeMillis() + (1000 * 60 * 60 * 24 * period)); item.setSN(sn); return item; } } public static class SpecialCashItem { private int sn, modifier; private byte info; // ? public SpecialCashItem(int sn, int modifier, byte info) { this.sn = sn; this.modifier = modifier; this.info = info; } public int getSN() { return sn; } public int getModifier() { return modifier; } public byte getInfo() { return info; } } public static class CashItemFactory { private static final Map<Integer, CashItem> items = new HashMap<Integer, CashItem>(); private static final Map<Integer, List<Integer>> packages = new HashMap<Integer, List<Integer>>(); private static final List<SpecialCashItem> specialcashitems = new ArrayList<SpecialCashItem>(); static { MapleDataProvider etc = MapleDataProviderFactory.getDataProvider(new File("wz/Etc.wz")); for (MapleData item : etc.getData("Commodity.img").getChildren()) { int sn = MapleDataTool.getIntConvert("SN", item); int itemId = MapleDataTool.getIntConvert("ItemId", item); int price = MapleDataTool.getIntConvert("Price", item, 0); long period = MapleDataTool.getIntConvert("Period", item, 1); short count = (short) MapleDataTool.getIntConvert("Count", item, 1); boolean onSale = MapleDataTool.getIntConvert("OnSale", item, 0) == 1; items.put(sn, new CashItem(sn, itemId, price, period, count, onSale)); } for (MapleData cashPackage : etc.getData("CashPackage.img").getChildren()) { List<Integer> cPackage = new ArrayList<Integer>(); for (MapleData item : cashPackage.getChildByPath("SN").getChildren()) { cPackage.add(Integer.parseInt(item.getData().toString())); } packages.put(Integer.parseInt(cashPackage.getName()), cPackage); } PreparedStatement ps = null; ResultSet rs = null; try { ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM specialcashitems"); rs = ps.executeQuery(); while (rs.next()) { specialcashitems.add(new SpecialCashItem(rs.getInt("sn"), rs.getInt("modifier"), rs.getByte("info"))); } } catch (SQLException ex) { ex.printStackTrace(); } finally { try { if (rs != null) rs.close(); if (ps != null) ps.close(); } catch (SQLException ex) { } } } public static CashItem getItem(int sn) { return items.get(sn); } public static List<IItem> getPackage(int itemId) { List<IItem> cashPackage = new ArrayList<IItem>(); for (int sn : packages.get(itemId)) { cashPackage.add(getItem(sn).toItem()); } return cashPackage; } public static boolean isPackage(int itemId) { return packages.containsKey(itemId); } public static List<SpecialCashItem> getSpecialCashItems() { return specialcashitems; } public static void reloadSpecialCashItems() {// Yay? specialcashitems.clear(); PreparedStatement ps = null; ResultSet rs = null; try { ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM specialcashitems"); rs = ps.executeQuery(); while (rs.next()) { specialcashitems.add(new SpecialCashItem(rs.getInt("sn"), rs.getInt("modifier"), rs.getByte("info"))); } } catch (SQLException ex) { ex.printStackTrace(); } finally { try { if (rs != null) rs.close(); if (ps != null) ps.close(); } catch (SQLException ex) { } } } } private int accountId, characterId, nxCredit, maplePoint, nxPrepaid; private boolean opened; private ItemFactory factory; private List<IItem> inventory = new ArrayList<IItem>(); private List<Integer> wishList = new ArrayList<Integer>(); private int notes = 0; public CashShop(int accountId, int characterId, int jobType) throws SQLException { this.accountId = accountId; this.characterId = characterId; if (jobType == 0) { factory = ItemFactory.CASH_EXPLORER; } else if (jobType == 1) { factory = ItemFactory.CASH_CYGNUS; } else if (jobType == 2) { factory = ItemFactory.CASH_ARAN; } Connection con = DatabaseConnection.getConnection(); PreparedStatement ps = null; ResultSet rs = null; try { ps = con.prepareStatement("SELECT `nxCredit`, `maplePoint`, `nxPrepaid` FROM `accounts` WHERE `id` = ?"); ps.setInt(1, accountId); rs = ps.executeQuery(); if (rs.next()) { this.nxCredit = rs.getInt("nxCredit"); this.maplePoint = rs.getInt("maplePoint"); this.nxPrepaid = rs.getInt("nxPrepaid"); } rs.close(); ps.close(); for (ItemInventoryEntry entry : factory.loadItems(accountId, false)) { inventory.add(entry.item); } ps = con.prepareStatement("SELECT `sn` FROM `wishlists` WHERE `charid` = ?"); ps.setInt(1, characterId); rs = ps.executeQuery(); while (rs.next()) { wishList.add(rs.getInt("sn")); } rs.close(); ps.close(); } finally { if (ps != null) ps.close(); if (rs != null) rs.close(); } } public int getCash(int type) { switch (type) { case 1: return nxCredit; case 2: return maplePoint; case 4: return nxPrepaid; } return 0; } public void gainCash(int type, int cash) { switch (type) { case 1: nxCredit += cash; break; case 2: maplePoint += cash; break; case 4: nxPrepaid += cash; break; } } public boolean isOpened() { return opened; } public void open(boolean b) { opened = b; } public List<IItem> getInventory() { return inventory; } public IItem findByCashId(int cashId) { boolean isRing = false; IEquip equip = null; for (IItem item : inventory) { if (item.getType() == IItem.EQUIP) { equip = (IEquip) item; isRing = equip.getRingId() > -1; } if ((item.getPetId() > -1 ? item.getPetId() : isRing ? equip.getRingId() : item.getCashId()) == cashId) { return item; } } return null; } public void addToInventory(IItem item) { inventory.add(item); } public void removeFromInventory(IItem item) { inventory.remove(item); } public List<Integer> getWishList() { return wishList; } public void clearWishList() { wishList.clear(); } public void addToWishList(int sn) { wishList.add(sn); } public void gift(int recipient, String from, String message, int sn) { gift(recipient, from, message, sn, -1); } public void gift(int recipient, String from, String message, int sn, int ringid) { PreparedStatement ps = null; try { ps = DatabaseConnection.getConnection().prepareStatement("INSERT INTO `gifts` VALUES (DEFAULT, ?, ?, ?, ?, ?)"); ps.setInt(1, recipient); ps.setString(2, from); ps.setString(3, message); ps.setInt(4, sn); ps.setInt(5, ringid); ps.executeUpdate(); } catch (SQLException sqle) { sqle.printStackTrace(); } finally { try { if (ps != null) ps.close(); } catch (SQLException ex) { } } } public List<GiftEntry> loadGifts() { List<GiftEntry> gifts = new ArrayList<GiftEntry>(); Connection con = DatabaseConnection.getConnection(); try { PreparedStatement ps = con.prepareStatement("SELECT * FROM `gifts` WHERE `to` = ?"); ps.setInt(1, characterId); ResultSet rs = ps.executeQuery(); while (rs.next()) { notes++; CashItem cItem = CashItemFactory.getItem(rs.getInt("sn")); IItem item = cItem.toItem(); IEquip equip = null; item.setGiftFrom(rs.getString("from")); if (item.getType() == MapleInventoryType.EQUIP.getType()) { equip = (IEquip) item; equip.setRingId(rs.getInt("ringid")); gifts.add(new GiftEntry(equip, rs.getString("message"))); } else gifts.add(new GiftEntry(item, rs.getString("message"))); if (CashItemFactory.isPackage(cItem.getItemId())) { // Packages // never // contains // a ring for (IItem packageItem : CashItemFactory.getPackage(cItem.getItemId())) { packageItem.setGiftFrom(rs.getString("from")); addToInventory(packageItem); } } else { addToInventory(equip == null ? item : equip); } } rs.close(); ps.close(); ps = con.prepareStatement("DELETE FROM `gifts` WHERE `to` = ?"); ps.setInt(1, characterId); ps.executeUpdate(); ps.close(); } catch (SQLException sqle) { sqle.printStackTrace(); } return gifts; } public int getAvailableNotes() { return notes; } public void decreaseNotes() { notes--; } public void save() throws SQLException { Connection con = DatabaseConnection.getConnection(); PreparedStatement ps = con.prepareStatement("UPDATE `accounts` SET `nxCredit` = ?, `maplePoint` = ?, `nxPrepaid` = ? WHERE `id` = ?"); ps.setInt(1, nxCredit); ps.setInt(2, maplePoint); ps.setInt(3, nxPrepaid); ps.setInt(4, accountId); ps.executeUpdate(); ps.close(); List<ItemInventoryEntry> itemsWithType = new ArrayList<ItemInventoryEntry>(); for (IItem item : inventory) { itemsWithType.add(new ItemInventoryEntry(item, MapleItemInformationProvider.getInstance().getInventoryType(item.getItemId()))); } factory.saveItems(itemsWithType, accountId); ps = con.prepareStatement("DELETE FROM `wishlists` WHERE `charid` = ?"); ps.setInt(1, characterId); ps.executeUpdate(); ps = con.prepareStatement("INSERT INTO `wishlists` VALUES (DEFAULT, ?, ?)"); ps.setInt(1, characterId); for (int sn : wishList) { ps.setInt(2, sn); ps.executeUpdate(); } ps.close(); } }