Autosave feature + Pet Ignore fix
Added experimental autosaver feature. Fixed pet ignore feature not saving/loading data in some cases. Added concurrency protection for inventory classes and monster book.
This commit is contained in:
@@ -4529,26 +4529,31 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
PreparedStatement ps2;
|
||||
ResultSet rs2;
|
||||
for(byte i = 0; i < 3; i++) {
|
||||
MaplePet pet = ret.getPet(i);
|
||||
if(pet == null) continue;
|
||||
|
||||
int petId = pet.getUniqueId();
|
||||
ps2 = con.prepareStatement("SELECT itemid FROM petignores WHERE petid = ?"); // Get pet details..
|
||||
PreparedStatement ps2, ps3;
|
||||
ResultSet rs2, rs3;
|
||||
|
||||
ps3 = con.prepareStatement("SELECT petid FROM inventoryitems WHERE characterid = ? AND petid > -1");
|
||||
ps3.setInt(1, charid);
|
||||
rs3 = ps3.executeQuery();
|
||||
while(rs3.next()) {
|
||||
int petId = rs3.getInt("petid");
|
||||
|
||||
ps2 = con.prepareStatement("SELECT itemid FROM petignores WHERE petid = ?");
|
||||
ps2.setInt(1, petId);
|
||||
|
||||
|
||||
ret.resetExcluded(petId);
|
||||
|
||||
rs2 = ps2.executeQuery();
|
||||
while(rs2.next()) {
|
||||
ret.addExcluded(petId, rs2.getInt("itemid"));
|
||||
}
|
||||
|
||||
|
||||
ps2.close();
|
||||
rs2.close();
|
||||
}
|
||||
ps3.close();
|
||||
rs3.close();
|
||||
|
||||
ret.commitExcludedItems();
|
||||
|
||||
if (channelserver) {
|
||||
@@ -5525,10 +5530,28 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
// synchronize this call instead of trying to give access all at once (?)
|
||||
public synchronized void saveToDB() {
|
||||
public void saveToDB() {
|
||||
if(ServerConstants.USE_AUTOSAVE) {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
saveToDB(true);
|
||||
}
|
||||
};
|
||||
|
||||
Thread t = new Thread(r); //spawns a new thread to deal with this
|
||||
t.start();
|
||||
} else {
|
||||
saveToDB(true);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void saveToDB(boolean notAutosave) {
|
||||
Calendar c = Calendar.getInstance();
|
||||
FilePrinter.print(FilePrinter.SAVING_CHARACTER, "Attempting to save " + name + " at " + c.getTime().toString());
|
||||
|
||||
if(notAutosave) FilePrinter.print(FilePrinter.SAVING_CHARACTER, "Attempting to save " + name + " at " + c.getTime().toString());
|
||||
else FilePrinter.print(FilePrinter.AUTOSAVING_CHARACTER, "Attempting to autosave " + name + " at " + c.getTime().toString());
|
||||
|
||||
Connection con = null;
|
||||
try {
|
||||
con = DatabaseConnection.getConnection();
|
||||
@@ -5577,7 +5600,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
ps.setInt(22, meso.get());
|
||||
ps.setInt(23, hpMpApUsed);
|
||||
if (map == null || map.getId() == 610020000 || map.getId() == 610020001) {
|
||||
if (map == null || map.getId() == 610020000 || map.getId() == 610020001) { // reset to first spawnpoint on those maps
|
||||
ps.setInt(24, 0);
|
||||
} else {
|
||||
MaplePortal closest = map.findClosestPlayerSpawnpoint(getPosition());
|
||||
@@ -5648,7 +5671,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
petLock.unlock();
|
||||
}
|
||||
|
||||
for(Entry<Integer, Set<Integer>> es: getExcluded().entrySet()) {
|
||||
for(Entry<Integer, Set<Integer>> es: getExcluded().entrySet()) { // this set is already protected
|
||||
try (PreparedStatement ps2 = con.prepareStatement("DELETE FROM petignores WHERE petid=?")) {
|
||||
ps2.setInt(1, es.getKey());
|
||||
ps2.executeUpdate();
|
||||
@@ -5667,8 +5690,10 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
deleteWhereCharacterId(con, "DELETE FROM keymap WHERE characterid = ?");
|
||||
ps = con.prepareStatement("INSERT INTO keymap (characterid, `key`, `type`, `action`) VALUES (?, ?, ?, ?)");
|
||||
ps.setInt(1, id);
|
||||
for (Entry<Integer, MapleKeyBinding> keybinding : keymap.entrySet()) {
|
||||
ps.setInt(2, keybinding.getKey().intValue());
|
||||
|
||||
Set<Entry<Integer, MapleKeyBinding>> keybindingItems = Collections.unmodifiableSet(keymap.entrySet());
|
||||
for (Entry<Integer, MapleKeyBinding> keybinding : keybindingItems) {
|
||||
ps.setInt(2, keybinding.getKey());
|
||||
ps.setInt(3, keybinding.getValue().getType());
|
||||
ps.setInt(4, keybinding.getValue().getAction());
|
||||
ps.addBatch();
|
||||
@@ -5691,14 +5716,13 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
ps.executeBatch();
|
||||
|
||||
List<Pair<Item, MapleInventoryType>> itemsWithType = new ArrayList<>();
|
||||
|
||||
for (MapleInventory iv : inventory) {
|
||||
for (Item item : iv.list()) {
|
||||
itemsWithType.add(new Pair<>(item, iv.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
ItemFactory.INVENTORY.saveItems(itemsWithType, id, con);
|
||||
|
||||
deleteWhereCharacterId(con, "DELETE FROM skills WHERE characterid = ?");
|
||||
@@ -6283,7 +6307,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
if (slots <= 96) {
|
||||
inventory[type].setSlotLimit(slots);
|
||||
|
||||
saveToDB();
|
||||
this.saveToDB();
|
||||
if (update) {
|
||||
client.announce(MaplePacketCreator.updateInventorySlotLimit(type, slots));
|
||||
}
|
||||
@@ -6552,6 +6576,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
getMap().broadcastMessage(this, MaplePacketCreator.showPet(this, pet, true, hunger), true);
|
||||
|
||||
removePet(pet, shift_left);
|
||||
commitExcludedItems();
|
||||
|
||||
client.announce(MaplePacketCreator.petStatUpdate(this));
|
||||
client.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
|
||||
@@ -25,9 +25,13 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
@@ -36,85 +40,140 @@ public final class MonsterBook {
|
||||
private int normalCard = 0;
|
||||
private int bookLevel = 1;
|
||||
private Map<Integer, Integer> cards = new LinkedHashMap<>();
|
||||
private Lock lock = new ReentrantLock();
|
||||
|
||||
private Set<Entry<Integer, Integer>> getCardSet() {
|
||||
lock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableSet(cards.entrySet());
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void addCard(final MapleClient c, final int cardid) {
|
||||
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.showForeignCardEffect(c.getPlayer().getId()), false);
|
||||
for (Entry<Integer, Integer> all : cards.entrySet()) {
|
||||
if (all.getKey() == cardid) {
|
||||
if (all.getValue() > 4) {
|
||||
c.announce(MaplePacketCreator.addCard(true, cardid, all.getValue()));
|
||||
} else {
|
||||
all.setValue(all.getValue() + 1);
|
||||
c.announce(MaplePacketCreator.addCard(false, cardid, all.getValue()));
|
||||
c.announce(MaplePacketCreator.showGainCard());
|
||||
calculateLevel();
|
||||
|
||||
Integer qty;
|
||||
lock.lock();
|
||||
try {
|
||||
qty = cards.get(cardid);
|
||||
|
||||
if(qty != null) {
|
||||
if(qty < 5) {
|
||||
cards.put(cardid, qty + 1);
|
||||
}
|
||||
} else {
|
||||
cards.put(cardid, 1);
|
||||
qty = 0;
|
||||
|
||||
if (cardid / 1000 >= 2388) {
|
||||
specialCard++;
|
||||
} else {
|
||||
normalCard++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
cards.put(cardid, 1);
|
||||
c.announce(MaplePacketCreator.addCard(false, cardid, 1));
|
||||
c.announce(MaplePacketCreator.showGainCard());
|
||||
calculateLevel();
|
||||
|
||||
if (cardid / 1000 >= 2388) {
|
||||
specialCard++;
|
||||
if(qty < 5) {
|
||||
calculateLevel(); // current leveling system only accounts unique cards...
|
||||
|
||||
c.announce(MaplePacketCreator.addCard(false, cardid, qty + 1));
|
||||
c.announce(MaplePacketCreator.showGainCard());
|
||||
} else {
|
||||
normalCard++;
|
||||
c.announce(MaplePacketCreator.addCard(true, cardid, 5));
|
||||
}
|
||||
|
||||
//c.getPlayer().saveToDB(); //is it REALLY needed to save to DB every new entry?
|
||||
}
|
||||
|
||||
private void calculateLevel() {
|
||||
bookLevel = (int) Math.max(1, Math.sqrt((normalCard + specialCard) / 5));
|
||||
lock.lock();
|
||||
try {
|
||||
bookLevel = (int) Math.max(1, Math.sqrt((normalCard + specialCard) / 5));
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getBookLevel() {
|
||||
return bookLevel;
|
||||
lock.lock();
|
||||
try {
|
||||
return bookLevel;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getCards() {
|
||||
return cards;
|
||||
lock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableMap(cards);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalCards() {
|
||||
return specialCard + normalCard;
|
||||
lock.lock();
|
||||
try {
|
||||
return specialCard + normalCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getNormalCard() {
|
||||
return normalCard;
|
||||
lock.lock();
|
||||
try {
|
||||
return normalCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getSpecialCard() {
|
||||
return specialCard;
|
||||
lock.lock();
|
||||
try {
|
||||
return specialCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadCards(final int charid) throws SQLException {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT cardid, level FROM monsterbook WHERE charid = ? ORDER BY cardid ASC")) {
|
||||
ps.setInt(1, charid);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
int cardid, level;
|
||||
while (rs.next()) {
|
||||
cardid = rs.getInt("cardid");
|
||||
level = rs.getInt("level");
|
||||
if (cardid / 1000 >= 2388) {
|
||||
specialCard++;
|
||||
} else {
|
||||
normalCard++;
|
||||
lock.lock();
|
||||
try {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT cardid, level FROM monsterbook WHERE charid = ? ORDER BY cardid ASC")) {
|
||||
ps.setInt(1, charid);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
int cardid, level;
|
||||
while (rs.next()) {
|
||||
cardid = rs.getInt("cardid");
|
||||
level = rs.getInt("level");
|
||||
if (cardid / 1000 >= 2388) {
|
||||
specialCard++;
|
||||
} else {
|
||||
normalCard++;
|
||||
}
|
||||
cards.put(cardid, level);
|
||||
}
|
||||
cards.put(cardid, level);
|
||||
}
|
||||
}
|
||||
|
||||
con.close();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
con.close();
|
||||
calculateLevel();
|
||||
}
|
||||
|
||||
public void saveCards(final int charid) {
|
||||
if (cards.isEmpty()) {
|
||||
Set<Entry<Integer, Integer>> cardSet = getCardSet();
|
||||
|
||||
if (cardSet.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -125,7 +184,7 @@ public final class MonsterBook {
|
||||
ps.close();
|
||||
boolean first = true;
|
||||
StringBuilder query = new StringBuilder();
|
||||
for (Entry<Integer, Integer> all : cards.entrySet()) {
|
||||
for (Entry<Integer, Integer> all : cardSet) {
|
||||
if (first) {
|
||||
query.append("INSERT INTO monsterbook VALUES (");
|
||||
first = false;
|
||||
|
||||
@@ -141,7 +141,6 @@ public enum ItemFactory {
|
||||
ResultSet rs = null;
|
||||
|
||||
lock.lock();
|
||||
|
||||
try {
|
||||
StringBuilder query = new StringBuilder();
|
||||
query.append("DELETE `inventoryitems`, `inventoryequipment` FROM `inventoryitems` LEFT JOIN `inventoryequipment` USING(`inventoryitemid`) WHERE `type` = ? AND `");
|
||||
|
||||
@@ -29,6 +29,8 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import tools.Pair;
|
||||
import client.MapleCharacter;
|
||||
@@ -36,6 +38,7 @@ import client.MapleClient;
|
||||
import constants.ItemConstants;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MapleInventoryManipulator;
|
||||
import tools.FilePrinter;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -47,6 +50,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
private byte slotLimit;
|
||||
private MapleInventoryType type;
|
||||
private boolean checked = false;
|
||||
private Lock lock = new ReentrantLock();
|
||||
|
||||
public MapleInventory(MapleCharacter mc, MapleInventoryType type, byte slotLimit) {
|
||||
this.owner = mc;
|
||||
@@ -64,15 +68,34 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public byte getSlotLimit() {
|
||||
return slotLimit;
|
||||
lock.lock();
|
||||
try {
|
||||
return slotLimit;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setSlotLimit(int newLimit) {
|
||||
slotLimit = (byte) newLimit;
|
||||
lock.lock();
|
||||
try {
|
||||
slotLimit = (byte) newLimit;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<Item> list() {
|
||||
lock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableCollection(inventory.values());
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Item findById(int itemId) {
|
||||
for (Item item : inventory.values()) {
|
||||
for (Item item : list()) {
|
||||
if (item.getItemId() == itemId) {
|
||||
return item;
|
||||
}
|
||||
@@ -81,10 +104,10 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public Item findByName(String name) {
|
||||
for (Item item : inventory.values()) {
|
||||
for (Item item : list()) {
|
||||
String itemName = MapleItemInformationProvider.getInstance().getName(item.getItemId());
|
||||
if(itemName == null) {
|
||||
System.out.println("[CRITICAL] Item " + item.getItemId() + " has no name.");
|
||||
FilePrinter.printError(FilePrinter.EXCEPTION, "[CRITICAL] Item " + item.getItemId() + " has no name.");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -97,7 +120,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
|
||||
public int countById(int itemId) {
|
||||
int qty = 0;
|
||||
for (Item item : inventory.values()) {
|
||||
for (Item item : list()) {
|
||||
if (item.getItemId() == itemId) {
|
||||
qty += item.getQuantity();
|
||||
}
|
||||
@@ -138,7 +161,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
|
||||
public List<Item> listById(int itemId) {
|
||||
List<Item> ret = new ArrayList<>();
|
||||
for (Item item : inventory.values()) {
|
||||
for (Item item : list()) {
|
||||
if (item.getItemId() == itemId) {
|
||||
ret.add(item);
|
||||
}
|
||||
@@ -149,10 +172,6 @@ public class MapleInventory implements Iterable<Item> {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Collection<Item> list() {
|
||||
return inventory.values();
|
||||
}
|
||||
|
||||
public short addItem(Item item) {
|
||||
short slotId = getNextFreeSlot();
|
||||
if (slotId < 0 || item == null) {
|
||||
@@ -171,29 +190,34 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public void move(short sSlot, short dSlot, short slotMax) {
|
||||
Item source = (Item) inventory.get(sSlot);
|
||||
Item target = (Item) inventory.get(dSlot);
|
||||
if (source == null) {
|
||||
return;
|
||||
}
|
||||
if (target == null) {
|
||||
source.setPosition(dSlot);
|
||||
inventory.put(dSlot, source);
|
||||
inventory.remove(sSlot);
|
||||
} else if (target.getItemId() == source.getItemId() && !ItemConstants.isRechargable(source.getItemId())) {
|
||||
if (type.getType() == MapleInventoryType.EQUIP.getType()) {
|
||||
lock.lock();
|
||||
try {
|
||||
Item source = (Item) inventory.get(sSlot);
|
||||
Item target = (Item) inventory.get(dSlot);
|
||||
if (source == null) {
|
||||
return;
|
||||
}
|
||||
if (target == null) {
|
||||
source.setPosition(dSlot);
|
||||
inventory.put(dSlot, source);
|
||||
inventory.remove(sSlot);
|
||||
} else if (target.getItemId() == source.getItemId() && !ItemConstants.isRechargable(source.getItemId())) {
|
||||
if (type.getType() == MapleInventoryType.EQUIP.getType()) {
|
||||
swap(target, source);
|
||||
}
|
||||
if (source.getQuantity() + target.getQuantity() > slotMax) {
|
||||
short rest = (short) ((source.getQuantity() + target.getQuantity()) - slotMax);
|
||||
source.setQuantity(rest);
|
||||
target.setQuantity(slotMax);
|
||||
} else {
|
||||
target.setQuantity((short) (source.getQuantity() + target.getQuantity()));
|
||||
inventory.remove(sSlot);
|
||||
}
|
||||
} else {
|
||||
swap(target, source);
|
||||
}
|
||||
if (source.getQuantity() + target.getQuantity() > slotMax) {
|
||||
short rest = (short) ((source.getQuantity() + target.getQuantity()) - slotMax);
|
||||
source.setQuantity(rest);
|
||||
target.setQuantity(slotMax);
|
||||
} else {
|
||||
target.setQuantity((short) (source.getQuantity() + target.getQuantity()));
|
||||
inventory.remove(sSlot);
|
||||
}
|
||||
} else {
|
||||
swap(target, source);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +232,12 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public Item getItem(short slot) {
|
||||
return inventory.get(slot);
|
||||
lock.lock();
|
||||
try {
|
||||
return inventory.get(slot);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeItem(short slot) {
|
||||
@@ -216,7 +245,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public void removeItem(short slot, short quantity, boolean allowZero) {
|
||||
Item item = inventory.get(slot);
|
||||
Item item = getItem(slot);
|
||||
if (item == null) {// TODO is it ok not to throw an exception here?
|
||||
return;
|
||||
}
|
||||
@@ -230,7 +259,12 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public void addSlot(short slot, Item item) {
|
||||
inventory.put(slot, item);
|
||||
lock.lock();
|
||||
try {
|
||||
inventory.put(slot, item);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
if(ItemConstants.isRateCoupon(item.getItemId())) {
|
||||
owner.updateCouponRates();
|
||||
@@ -238,7 +272,13 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public void removeSlot(short slot) {
|
||||
Item item = inventory.remove(slot);
|
||||
Item item;
|
||||
lock.lock();
|
||||
try {
|
||||
item = inventory.remove(slot);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
if(item != null && ItemConstants.isRateCoupon(item.getItemId())) {
|
||||
owner.updateCouponRates();
|
||||
@@ -246,40 +286,67 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
return inventory.size() >= slotLimit;
|
||||
lock.lock();
|
||||
try {
|
||||
return inventory.size() >= slotLimit;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFull(int margin) {
|
||||
return inventory.size() + margin >= slotLimit;
|
||||
lock.lock();
|
||||
try {
|
||||
return inventory.size() + margin >= slotLimit;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFullAfterSomeItems(int margin, int used) {
|
||||
return inventory.size() + margin >= slotLimit - used;
|
||||
lock.lock();
|
||||
try {
|
||||
return inventory.size() + margin >= slotLimit - used;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public short getNextFreeSlot() {
|
||||
if (isFull()) {
|
||||
return -1;
|
||||
}
|
||||
for (short i = 1; i <= slotLimit; i++) {
|
||||
if (!inventory.keySet().contains(i)) {
|
||||
return i;
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
for (short i = 1; i <= slotLimit; i++) {
|
||||
if (!inventory.containsKey(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public short getNumFreeSlot() {
|
||||
if (isFull()) {
|
||||
return 0;
|
||||
}
|
||||
short free = 0;
|
||||
for (short i = 1; i <= slotLimit; i++) {
|
||||
if (!inventory.keySet().contains(i)) {
|
||||
free++;
|
||||
}
|
||||
}
|
||||
return free;
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
short free = 0;
|
||||
for (short i = 1; i <= slotLimit; i++) {
|
||||
if (!inventory.containsKey(i)) {
|
||||
free++;
|
||||
}
|
||||
}
|
||||
return free;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean checkSpot(MapleCharacter chr, Item item) {
|
||||
@@ -394,7 +461,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
|
||||
@Override
|
||||
public Iterator<Item> iterator() {
|
||||
return Collections.unmodifiableCollection(inventory.values()).iterator();
|
||||
return Collections.unmodifiableCollection(list()).iterator();
|
||||
}
|
||||
|
||||
public Collection<MapleInventory> allInventories() {
|
||||
@@ -404,7 +471,7 @@ public class MapleInventory implements Iterable<Item> {
|
||||
public Item findByCashId(int cashId) {
|
||||
boolean isRing = false;
|
||||
Equip equip = null;
|
||||
for (Item item : inventory.values()) {
|
||||
for (Item item : list()) {
|
||||
if (item.getType() == MapleInventoryType.EQUIP.getType()) {
|
||||
equip = (Equip) item;
|
||||
isRing = equip.getRingId() > -1;
|
||||
@@ -417,10 +484,20 @@ public class MapleInventory implements Iterable<Item> {
|
||||
}
|
||||
|
||||
public boolean checked() {
|
||||
return checked;
|
||||
lock.lock();
|
||||
try {
|
||||
return checked;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void checked(boolean yes) {
|
||||
checked = yes;
|
||||
lock.lock();
|
||||
try {
|
||||
checked = yes;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user