package server;
import client.MapleClient;
import client.inventory.Item;
import client.inventory.ItemLoader;
import client.inventory.MapleInventoryType;
import constants.GameConstants;
import constants.ItemConstants;
import database.DatabaseConnection;
import database.DatabaseException;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import tools.Pair;
import tools.packet.NPCPacket;
public class MapleStorage
implements Serializable {
private static final long serialVersionUID = 9179541993413738569L;
private final int storageId;
private final int accountId;
private final List<Item> items;
private long meso;
private byte slots;
private int storageNpcId;
private boolean changed = false;
private final Map<MapleInventoryType, List<Item>> typeItems = new EnumMap(MapleInventoryType.class);
private MapleStorage(int storageId, byte slots, long meso, int accountId) {
this.storageId = storageId;
this.slots = slots;
this.meso = meso;
this.accountId = accountId;
this.items = new LinkedList();
if (this.slots > 96) {
this.slots = 96;
this.changed = true;
}
}
public static int create(int accountId)
throws SQLException {
ResultSet rs;
try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("INSERT INTO storages (accountid, slots, meso) VALUES (?, ?, ?)", 1)) {
ps.setInt(1, accountId);
ps.setInt(2, 4);
ps.setInt(3, 0);
ps.executeUpdate();
rs = ps.getGeneratedKeys();
if (rs.next()) {
int storageid = rs.getInt(1);
ps.close();
rs.close();
return storageid;
}
ps.close();
}
rs.close();
throw new DatabaseException("Inserting char failed.");
}
public static MapleStorage loadOrCreateFromDB(int accountId) {
MapleStorage ret = null;
try {
PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM storages WHERE accountid = ?");
ps.setInt(1, accountId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
int storeId = rs.getInt("storageid");
ret = new MapleStorage(storeId, rs.getByte("slots"), rs.getLong("meso"), accountId);
rs.close();
ps.close();
for (Pair<Item, MapleInventoryType> mit : ItemLoader.仓库道具.loadItems(false, accountId).values()) {
ret.items.add(mit.getLeft());
}
} else {
int storeId = create(accountId);
ret = new MapleStorage(storeId, (byte) 4, 0, accountId);
rs.close();
ps.close();
}
} catch (SQLException ex) {
System.err.println("Error loading storage" + ex);
}
return ret;
}
public void saveToDB() {
if (!this.changed) {
return;
}
try {
try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("UPDATE storages SET slots = ?, meso = ? WHERE storageid = ?")) {
ps.setInt(1, this.slots);
ps.setLong(2, this.meso);
ps.setInt(3, this.storageId);
ps.executeUpdate();
ps.close();
}
List itemsWithType = new ArrayList();
for (Item item : this.items) {
itemsWithType.add(new Pair(item, ItemConstants.getInventoryType(item.getItemId())));
}
ItemLoader.仓库道具.saveItems(itemsWithType, this.accountId);
this.changed = false;
} catch (SQLException ex) {
System.err.println("Error saving storage" + ex);
}
}
public Item getItem(byte slot) {
if ((slot >= this.items.size()) || (slot < 0)) {
return null;
}
return (Item) this.items.get(slot);
}
public Item takeOut(byte slot) {
this.changed = true;
Item ret = (Item) this.items.remove(slot);
MapleInventoryType type = ItemConstants.getInventoryType(ret.getItemId());
this.typeItems.put(type, new ArrayList(filterItems(type)));
return ret;
}
public void store(Item item) {
this.changed = true;
this.items.add(item);
MapleInventoryType type = ItemConstants.getInventoryType(item.getItemId());
this.typeItems.put(type, new ArrayList(filterItems(type)));
}
public void arrange() {
Collections.sort(this.items, new Comparator() {
public int compare(Item o1, Item o2) {
if (o1.getItemId() < o2.getItemId()) {
return -1;
}
if (o1.getItemId() == o2.getItemId()) {
return 0;
}
return 1;
}
@Override
public int compare(Object o1, Object o2) {
throw new UnsupportedOperationException("");
}
});
for (MapleInventoryType type : MapleInventoryType.values()) {
this.typeItems.put(type, new ArrayList(this.items));
}
}
public List<Item> getItems() {
return Collections.unmodifiableList(this.items);
}
private List<Item> filterItems(MapleInventoryType type) {
List ret = new LinkedList();
for (Item item : this.items) {
if (ItemConstants.getInventoryType(item.getItemId()) == type) {
ret.add(item);
}
}
return ret;
}
public byte getSlot(MapleInventoryType type, byte slot) {
byte ret = 0;
List it = (List) this.typeItems.get(type);
if ((it == null) || (slot >= it.size()) || (slot < 0)) {
return -1;
}
for (Item item : this.items) {
if (item == it.get(slot)) {
return ret;
}
ret = (byte) (ret + 1);
}
return -1;
}
public void sendStorage(MapleClient c, int npcId) {
try {
this.storageNpcId = npcId;
// Collections.sort(this.items, new Comparator() {
// public int compare(Item o1, Item o2) {
// if (ItemConstants.getInventoryType(o1.getItemId()).getType() < ItemConstants.getInventoryType(o2.getItemId()).getType()) {
// return -1;
// }
// if (ItemConstants.getInventoryType(o1.getItemId()) == ItemConstants.getInventoryType(o2.getItemId())) {
// return 0;
// }
// return 1;
// }
//
// @Override
// public int compare(Object o1, Object o2) {
// throw new UnsupportedOperationException("");
// }
// });
Collections.sort(items, new Comparator<Item>() {
@Override
public int compare(Item o1, Item o2) {
if (GameConstants.getInventoryType(o1.getItemId()).getType() < GameConstants.getInventoryType(o2.getItemId()).getType()) {
return -1;
} else if (GameConstants.getInventoryType(o1.getItemId()) == GameConstants.getInventoryType(o2.getItemId())) {
return 0;
} else {
return 1;
}
}
});
for (MapleInventoryType type : MapleInventoryType.values()) {
this.typeItems.put(type, new ArrayList(this.items));
}
c.getSession().write(NPCPacket.getStorage(npcId, this.slots, this.items, this.meso));
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendStored(MapleClient c, MapleInventoryType type) {
c.getSession().write(NPCPacket.storeStorage(this.slots, type, (Collection) this.typeItems.get(type)));
}
public void sendTakenOut(MapleClient c, MapleInventoryType type) {
c.getSession().write(NPCPacket.takeOutStorage(this.slots, type, (Collection) this.typeItems.get(type)));
}
public long getMeso() {
return this.meso;
}
public Item findById(int itemId) {
for (Item item : this.items) {
if (item.getItemId() == itemId) {
return item;
}
}
return null;
}
public void setMeso(long meso) {
if (meso < 0) {
return;
}
this.changed = true;
this.meso = meso;
}
public void sendMeso(MapleClient c) {
c.getSession().write(NPCPacket.mesoStorage(this.slots, this.meso));
}
public boolean isFull() {
return this.items.size() >= this.slots;
}
public int getSlots() {
return this.slots;
}
public void increaseSlots(byte gain) {
this.changed = true;
this.slots = (byte) (this.slots + gain);
}
public void setSlots(byte set) {
this.changed = true;
this.slots = set;
}
public int getNpcId() {
return this.storageNpcId;
}
public void close() {
this.typeItems.clear();
}
}