Maker & Storage fetch Wz + Buff system & PS / HM patch + Pet Evolution
Storage now fetches transaction fees from the WZ. Maker now pulls info about catalyzers from the WZ. Fixed the enhanced buff system disappearing with some statsup when using multiple-statups items. Fixed hired merchant now removing owner and visitors at expiration time. Fixed some concurrent issues with player shops and hired merchants. Fixed pet evolutions, now not only handing out not-expired pets but also refreshing the expire time as well. Added item replace behaviour on the item expire system.
This commit is contained in:
@@ -69,6 +69,7 @@ import java.sql.Connection;
|
||||
import server.MakerItemFactory.MakerItemCreateEntry;
|
||||
import server.life.MapleMonsterInformationProvider;
|
||||
import server.life.MapleLifeFactory;
|
||||
import tools.StringUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -81,6 +82,7 @@ public class MapleItemInformationProvider {
|
||||
protected MapleDataProvider itemData;
|
||||
protected MapleDataProvider equipData;
|
||||
protected MapleDataProvider stringData;
|
||||
protected MapleDataProvider etcData;
|
||||
protected MapleData cashStringData;
|
||||
protected MapleData consumeStringData;
|
||||
protected MapleData eqpStringData;
|
||||
@@ -112,17 +114,20 @@ public class MapleItemInformationProvider {
|
||||
protected Map<Integer, Boolean> consumeOnPickupCache = new HashMap<>();
|
||||
protected Map<Integer, Boolean> isQuestItemCache = new HashMap<>();
|
||||
protected Map<Integer, Boolean> isPartyQuestItemCache = new HashMap<>();
|
||||
protected Map<Integer, Pair<Integer, String>> replaceOnExpireCache = new HashMap<>();
|
||||
protected Map<Integer, String> equipmentSlotCache = new HashMap<>();
|
||||
protected Map<Integer, Boolean> noCancelMouseCache = new HashMap<>();
|
||||
protected Map<Integer, Integer> mobCrystalMakerCache = new HashMap<>();
|
||||
protected Map<Integer, Pair<String, Integer>> statUpgradeMakerCache = new HashMap<>();
|
||||
protected Map<Integer, MakerItemFactory.MakerItemCreateEntry> makerItemCache = new HashMap<>();
|
||||
protected Map<Integer, Integer> makerCatalystCache = new HashMap<>();
|
||||
|
||||
private MapleItemInformationProvider() {
|
||||
loadCardIdData();
|
||||
itemData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Item.wz"));
|
||||
equipData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Character.wz"));
|
||||
stringData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/String.wz"));
|
||||
etcData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Etc.wz"));
|
||||
cashStringData = stringData.getData("Cash.img");
|
||||
consumeStringData = stringData.getData("Consume.img");
|
||||
eqpStringData = stringData.getData("Eqp.img");
|
||||
@@ -515,6 +520,20 @@ public class MapleItemInformationProvider {
|
||||
return retPrice;
|
||||
}
|
||||
|
||||
public Pair<Integer, String> getReplaceOnExpire(int itemId) { // thanks to GabrielSin
|
||||
if (replaceOnExpireCache.containsKey(itemId)) {
|
||||
return replaceOnExpireCache.get(itemId);
|
||||
}
|
||||
|
||||
int itemReplacement = MapleDataTool.getInt("info/replace/itemid", getItemData(itemId), 0);
|
||||
String msg = MapleDataTool.getString("info/replace/msg", getItemData(itemId));
|
||||
|
||||
Pair<Integer, String> ret = new Pair<>(itemReplacement, msg);
|
||||
replaceOnExpireCache.put(itemId, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected String getEquipmentSlot(int itemId) {
|
||||
if (equipmentSlotCache.containsKey(itemId)) {
|
||||
return equipmentSlotCache.get(itemId);
|
||||
@@ -1869,6 +1888,26 @@ public class MapleItemInformationProvider {
|
||||
return fee;
|
||||
}
|
||||
|
||||
public int getMakerStimulant(int itemId) { // thanks to Arnah
|
||||
Integer itemid = makerCatalystCache.get(itemId);
|
||||
if(itemid != null) {
|
||||
return itemid;
|
||||
}
|
||||
|
||||
itemid = -1;
|
||||
for(MapleData md : etcData.getData("ItemMake.img").getChildren()) {
|
||||
MapleData me = md.getChildByPath(StringUtil.getLeftPaddedStr(Integer.toString(itemId), '0', 8));
|
||||
|
||||
if(me != null) {
|
||||
itemid = MapleDataTool.getInt(me.getChildByPath("catalyst"), -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
makerCatalystCache.put(itemId, itemid);
|
||||
return itemid;
|
||||
}
|
||||
|
||||
public Set<String> getWhoDrops(Integer itemId) {
|
||||
Set<String> list = new HashSet<>();
|
||||
Connection con = null;
|
||||
|
||||
@@ -22,6 +22,7 @@ import client.MapleClient;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.ItemFactory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@@ -34,6 +35,10 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import provider.MapleData;
|
||||
import provider.MapleDataProvider;
|
||||
import provider.MapleDataProviderFactory;
|
||||
import provider.MapleDataTool;
|
||||
import tools.locks.MonitoredReentrantLock;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
@@ -45,8 +50,11 @@ import tools.locks.MonitoredLockType;
|
||||
* @author Matze
|
||||
*/
|
||||
public class MapleStorage {
|
||||
|
||||
private static Map<Integer, Integer> trunkGetCache = new HashMap<>();
|
||||
private static Map<Integer, Integer> trunkPutCache = new HashMap<>();
|
||||
|
||||
private int id;
|
||||
private int currentNpcid;
|
||||
private int meso;
|
||||
private byte slots;
|
||||
private Map<MapleInventoryType, List<Item>> typeItems = new HashMap<>();
|
||||
@@ -247,6 +255,8 @@ public class MapleStorage {
|
||||
for (MapleInventoryType type : MapleInventoryType.values()) {
|
||||
typeItems.put(type, new ArrayList<>(storageItems));
|
||||
}
|
||||
|
||||
currentNpcid = npcId;
|
||||
c.announce(MaplePacketCreator.getStorage(npcId, slots, storageItems, meso));
|
||||
} finally {
|
||||
lock.unlock();
|
||||
@@ -302,6 +312,42 @@ public class MapleStorage {
|
||||
public void sendMeso(MapleClient c) {
|
||||
c.announce(MaplePacketCreator.mesoStorage(slots, meso));
|
||||
}
|
||||
|
||||
public int getStoreFee() { // thanks to GabrielSin
|
||||
int npcId = currentNpcid;
|
||||
Integer fee = trunkPutCache.get(npcId);
|
||||
if(fee == null) {
|
||||
fee = 100;
|
||||
|
||||
MapleDataProvider npc = MapleDataProviderFactory.getDataProvider(new File("wz/Npc.wz"));
|
||||
MapleData npcData = npc.getData(npcId + ".img");
|
||||
if(npcData != null) {
|
||||
fee = MapleDataTool.getIntConvert("info/trunkPut", npcData, 100);
|
||||
}
|
||||
|
||||
trunkPutCache.put(npcId, fee);
|
||||
}
|
||||
|
||||
return fee;
|
||||
}
|
||||
|
||||
public int getTakeOutFee() {
|
||||
int npcId = currentNpcid;
|
||||
Integer fee = trunkGetCache.get(npcId);
|
||||
if(fee == null) {
|
||||
fee = 0;
|
||||
|
||||
MapleDataProvider npc = MapleDataProviderFactory.getDataProvider(new File("wz/Npc.wz"));
|
||||
MapleData npcData = npc.getData(npcId + ".img");
|
||||
if(npcData != null) {
|
||||
fee = MapleDataTool.getIntConvert("info/trunkGet", npcData, 0);
|
||||
}
|
||||
|
||||
trunkGetCache.put(npcId, fee);
|
||||
}
|
||||
|
||||
return fee;
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
lock.lock();
|
||||
|
||||
@@ -147,7 +147,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
|
||||
return -1; //Actually 0 because of the +1's.
|
||||
}
|
||||
|
||||
public void removeAllVisitors() {
|
||||
private void removeAllVisitors() {
|
||||
visitorLock.lock();
|
||||
try {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
@@ -271,6 +271,24 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
|
||||
}
|
||||
|
||||
public void forceClose() {
|
||||
//Server.getInstance().getChannel(world, channel).removeHiredMerchant(ownerId);
|
||||
map.broadcastMessage(MaplePacketCreator.destroyHiredMerchant(getOwnerId()));
|
||||
map.removeMapObject(this);
|
||||
|
||||
MapleCharacter owner = Server.getInstance().getWorld(world).getPlayerStorage().getCharacterById(ownerId);
|
||||
|
||||
visitorLock.lock();
|
||||
try {
|
||||
setOpen(false);
|
||||
removeAllVisitors();
|
||||
|
||||
if(owner != null && owner.isLoggedinWorld() && this == owner.getHiredMerchant()) {
|
||||
closeOwnerMerchant(owner);
|
||||
}
|
||||
} finally {
|
||||
visitorLock.unlock();
|
||||
}
|
||||
|
||||
Server.getInstance().getWorld(world).unregisterHiredMerchant(this);
|
||||
|
||||
try {
|
||||
@@ -281,11 +299,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
//Server.getInstance().getChannel(world, channel).removeHiredMerchant(ownerId);
|
||||
map.broadcastMessage(MaplePacketCreator.destroyHiredMerchant(getOwnerId()));
|
||||
|
||||
map.removeMapObject(this);
|
||||
|
||||
|
||||
MapleCharacter player = Server.getInstance().getWorld(world).getPlayerStorage().getCharacterById(ownerId);
|
||||
if(player != null) {
|
||||
player.setHasMerchant(false);
|
||||
@@ -306,55 +320,87 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
|
||||
map = null;
|
||||
}
|
||||
|
||||
public void closeShop(MapleClient c, boolean timeout) {
|
||||
map.removeMapObject(this);
|
||||
map.broadcastMessage(MaplePacketCreator.destroyHiredMerchant(ownerId));
|
||||
c.getChannelServer().removeHiredMerchant(ownerId);
|
||||
|
||||
try {
|
||||
MapleCharacter player = c.getWorldServer().getPlayerStorage().getCharacterById(ownerId);
|
||||
if(player != null) {
|
||||
player.setHasMerchant(false);
|
||||
} else {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET HasMerchant = 0 WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) {
|
||||
ps.setInt(1, ownerId);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
con.close();
|
||||
}
|
||||
public void closeOwnerMerchant(MapleCharacter chr) {
|
||||
if(this.isOwner(chr)) {
|
||||
chr.announce(MaplePacketCreator.hiredMerchantOwnerLeave());
|
||||
chr.announce(MaplePacketCreator.leaveHiredMerchant(0x00, 0x03));
|
||||
this.closeShop(chr.getClient(), false);
|
||||
chr.setHasMerchant(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void closeShop(MapleClient c, boolean timeout) {
|
||||
map.removeMapObject(this);
|
||||
map.broadcastMessage(MaplePacketCreator.destroyHiredMerchant(ownerId));
|
||||
c.getChannelServer().removeHiredMerchant(ownerId);
|
||||
|
||||
List<MaplePlayerShopItem> copyItems = getItems();
|
||||
if (check(c.getPlayer(), copyItems) && !timeout) {
|
||||
for (MaplePlayerShopItem mpsi : copyItems) {
|
||||
if(mpsi.isExist()) {
|
||||
if (mpsi.getItem().getInventoryType().equals(MapleInventoryType.EQUIP)) {
|
||||
MapleInventoryManipulator.addFromDrop(c, mpsi.getItem(), false);
|
||||
} else {
|
||||
MapleInventoryManipulator.addById(c, mpsi.getItem().getItemId(), (short) (mpsi.getBundles() * mpsi.getItem().getQuantity()), null, -1, mpsi.getItem().getFlag(), mpsi.getItem().getExpiration());
|
||||
}
|
||||
try {
|
||||
MapleCharacter player = c.getWorldServer().getPlayerStorage().getCharacterById(ownerId);
|
||||
if(player != null) {
|
||||
player.setHasMerchant(false);
|
||||
} else {
|
||||
Connection con = DatabaseConnection.getConnection();
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET HasMerchant = 0 WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) {
|
||||
ps.setInt(1, ownerId);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
con.close();
|
||||
}
|
||||
|
||||
List<MaplePlayerShopItem> copyItems = getItems();
|
||||
if (check(c.getPlayer(), copyItems) && !timeout) {
|
||||
for (MaplePlayerShopItem mpsi : copyItems) {
|
||||
if(mpsi.isExist()) {
|
||||
if (mpsi.getItem().getInventoryType().equals(MapleInventoryType.EQUIP)) {
|
||||
MapleInventoryManipulator.addFromDrop(c, mpsi.getItem(), false);
|
||||
} else {
|
||||
MapleInventoryManipulator.addById(c, mpsi.getItem().getItemId(), (short) (mpsi.getBundles() * mpsi.getItem().getQuantity()), null, -1, mpsi.getItem().getFlag(), mpsi.getItem().getExpiration());
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (items) {
|
||||
items.clear();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
this.saveItems(timeout);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
synchronized (items) {
|
||||
items.clear();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
this.saveItems(timeout);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Server.getInstance().getWorld(world).unregisterHiredMerchant(this);
|
||||
|
||||
synchronized (items) {
|
||||
items.clear();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Server.getInstance().getWorld(world).unregisterHiredMerchant(this);
|
||||
}
|
||||
|
||||
public synchronized void visitShop(MapleCharacter chr) {
|
||||
visitorLock.lock();
|
||||
try {
|
||||
if (this.isOwner(chr)) {
|
||||
this.setOpen(false);
|
||||
this.removeAllVisitors();
|
||||
|
||||
chr.announce(MaplePacketCreator.getHiredMerchant(chr, this, false));
|
||||
} else if (!this.isOpen()) {
|
||||
chr.announce(MaplePacketCreator.getMiniRoomError(18));
|
||||
return;
|
||||
} else if (!this.addVisitor(chr)) {
|
||||
chr.announce(MaplePacketCreator.getMiniRoomError(2));
|
||||
return;
|
||||
} else {
|
||||
chr.announce(MaplePacketCreator.getHiredMerchant(chr, this, false));
|
||||
}
|
||||
chr.setHiredMerchant(this);
|
||||
} finally {
|
||||
visitorLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
|
||||
@@ -1732,7 +1732,7 @@ public class MapleMap {
|
||||
}
|
||||
|
||||
public Point getGroundBelow(Point pos) {
|
||||
Point spos = new Point(pos.x, pos.y - 7); // Using -7 fixes spawning pets causing a lot of issues.
|
||||
Point spos = new Point(pos.x, pos.y - 14); // Using -14 fixes spawning pets causing a lot of issues.
|
||||
spos = calcPointBelow(spos);
|
||||
spos.y--;//shouldn't be null!
|
||||
return spos;
|
||||
|
||||
@@ -99,20 +99,15 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
|
||||
}
|
||||
|
||||
private void addVisitor(MapleCharacter visitor) {
|
||||
visitorLock.lock();
|
||||
try {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (visitors[i] == null) {
|
||||
visitors[i] = visitor;
|
||||
visitor.setSlot(i);
|
||||
this.broadcast(MaplePacketCreator.getPlayerShopNewVisitor(visitor, i + 1));
|
||||
|
||||
if(i == 2) visitor.getMap().broadcastMessage(MaplePacketCreator.addCharBox(owner, 1));
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (visitors[i] == null) {
|
||||
visitors[i] = visitor;
|
||||
visitor.setSlot(i);
|
||||
this.broadcast(MaplePacketCreator.getPlayerShopNewVisitor(visitor, i + 1));
|
||||
|
||||
if(i == 2) visitor.getMap().broadcastMessage(MaplePacketCreator.addCharBox(owner, 1));
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
visitorLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,11 +485,6 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
|
||||
}
|
||||
|
||||
public synchronized boolean visitShop(MapleCharacter chr) {
|
||||
if(!open.get()) {
|
||||
chr.dropMessage(1, "This store is not yet open.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.isBanned(chr.getName())) {
|
||||
chr.dropMessage(1, "You have been banned from this store.");
|
||||
return false;
|
||||
@@ -502,6 +492,11 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
|
||||
|
||||
visitorLock.lock();
|
||||
try {
|
||||
if(!open.get()) {
|
||||
chr.dropMessage(1, "This store is not yet open.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.hasFreeSlot() && !this.isVisitor(chr)) {
|
||||
this.addVisitor(chr);
|
||||
chr.setPlayerShop(this);
|
||||
|
||||
Reference in New Issue
Block a user