Fixed chair exploit & beholder issue + Mini-dungeon revamp
Fixed an (quite amusing) exploit with map chairs stacking "extra healing" schedules on certain conditions. Fixed mini-dungeon not disposing players properly in some cases. Refactored the mini-dungeon structure. Fixed an issue on CASH inventory merging same items when trying to swap them. Fixed Beholder crash issue when trying to enter Cash Shop.
This commit is contained in:
@@ -32,6 +32,8 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
@@ -60,9 +62,11 @@ import server.expeditions.MapleExpeditionType;
|
||||
import server.maps.MapleHiredMerchant;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.MapleMapFactory;
|
||||
import server.maps.MapleMiniDungeon;
|
||||
import tools.MaplePacketCreator;
|
||||
import client.MapleCharacter;
|
||||
import constants.ServerConstants;
|
||||
import server.maps.MapleMiniDungeonInfo;
|
||||
|
||||
public final class Channel {
|
||||
|
||||
@@ -75,9 +79,6 @@ public final class Channel {
|
||||
private EventScriptManager eventSM;
|
||||
private Map<Integer, MapleHiredMerchant> hiredMerchants = new HashMap<>();
|
||||
private final Map<Integer, Integer> storedVars = new HashMap<>();
|
||||
private ReentrantReadWriteLock merchant_lock = new ReentrantReadWriteLock(true);
|
||||
private ReadLock merchRlock = merchant_lock.readLock();
|
||||
private WriteLock merchWlock = merchant_lock.writeLock();
|
||||
private List<MapleExpedition> expeditions = new ArrayList<>();
|
||||
private List<MapleExpeditionType> expedType = new ArrayList<>();
|
||||
private MapleEvent event;
|
||||
@@ -87,6 +88,13 @@ public final class Channel {
|
||||
private long[] dojoFinishTime;
|
||||
private ScheduledFuture<?>[] dojoTask;
|
||||
private Map<Integer, Integer> dojoParty = new HashMap<>();
|
||||
private Map<Integer, MapleMiniDungeon> dungeons = new HashMap<>();
|
||||
|
||||
private ReentrantReadWriteLock merchant_lock = new ReentrantReadWriteLock(true);
|
||||
private ReadLock merchRlock = merchant_lock.readLock();
|
||||
private WriteLock merchWlock = merchant_lock.writeLock();
|
||||
|
||||
private Lock lock = new ReentrantLock();
|
||||
|
||||
public Channel(final int world, final int channel) {
|
||||
this.world = world;
|
||||
@@ -485,4 +493,37 @@ public final class Channel {
|
||||
public long getDojoFinishTime(int dojoMapId) {
|
||||
return dojoFinishTime[getDojoSlot(dojoMapId)];
|
||||
}
|
||||
|
||||
public boolean addMiniDungeon(int dungeonid) {
|
||||
lock.lock();
|
||||
try {
|
||||
if(dungeons.containsKey(dungeonid)) return false;
|
||||
|
||||
MapleMiniDungeonInfo mmdi = MapleMiniDungeonInfo.getDungeon(dungeonid);
|
||||
MapleMiniDungeon mmd = new MapleMiniDungeon(mmdi.getBase(), 30); // all minidungeons timeouts on 30 mins
|
||||
|
||||
dungeons.put(dungeonid, mmd);
|
||||
return true;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public MapleMiniDungeon getMiniDungeon(int dungeonid) {
|
||||
lock.lock();
|
||||
try {
|
||||
return dungeons.get(dungeonid);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeMiniDungeon(int dungeonid) {
|
||||
lock.lock();
|
||||
try {
|
||||
dungeons.remove(dungeonid);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,6 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
* @author Ronan
|
||||
*/
|
||||
public final class DoorHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
|
||||
@@ -25,6 +25,7 @@ import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.Server;
|
||||
import server.maps.MapleMiniDungeonInfo;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
@@ -41,6 +42,13 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler {
|
||||
if (mc.cannotEnterCashShop()) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if(MapleMiniDungeonInfo.isDungeonMap(c.getPlayer().getMapId())) {
|
||||
c.announce(MaplePacketCreator.serverNotice(5, "Changing channels or entering Cash Shop or MTS are disabled when inside a Mini-Dungeon."));
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
if (mc.getCashShop().isOpened()) {
|
||||
@@ -50,11 +58,13 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler {
|
||||
mc.closePlayerInteractions();
|
||||
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs());
|
||||
mc.setAwayFromWorld(true);
|
||||
mc.cancelAllBuffs(true);
|
||||
mc.cancelBuffExpireTask();
|
||||
mc.cancelDiseaseExpireTask();
|
||||
mc.cancelSkillCooldownTask();
|
||||
mc.cancelExpirationTask();
|
||||
mc.stopChairTask();
|
||||
|
||||
c.announce(MaplePacketCreator.openCashShop(c, false));
|
||||
c.announce(MaplePacketCreator.showCashInventory(c));
|
||||
|
||||
@@ -36,6 +36,7 @@ import constants.ServerConstants;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.Server;
|
||||
import server.MTSItemInfo;
|
||||
import server.maps.MapleMiniDungeonInfo;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
@@ -47,6 +48,13 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
if(MapleMiniDungeonInfo.isDungeonMap(c.getPlayer().getMapId())) {
|
||||
c.announce(MaplePacketCreator.serverNotice(5, "Changing channels or entering Cash Shop or MTS are disabled when inside a Mini-Dungeon."));
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
if (!chr.isAlive()) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
@@ -59,11 +67,14 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs());
|
||||
chr.setAwayFromWorld(true);
|
||||
chr.cancelAllBuffs(true);
|
||||
chr.cancelBuffExpireTask();
|
||||
chr.cancelDiseaseExpireTask();
|
||||
chr.cancelSkillCooldownTask();
|
||||
chr.cancelExpirationTask();
|
||||
chr.stopChairTask();
|
||||
|
||||
chr.saveToDB();
|
||||
chr.getMap().removePlayer(c.getPlayer());
|
||||
try {
|
||||
|
||||
@@ -33,7 +33,7 @@ import client.inventory.MapleInventory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import server.MapleItemInformationProvider;
|
||||
|
||||
public final class ItemSortHandler extends AbstractMaplePacketHandler {
|
||||
public final class InventoryMergeHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
@@ -67,7 +67,7 @@ public final class ItemSortHandler extends AbstractMaplePacketHandler {
|
||||
MapleInventoryManipulator.move(c, inventoryType, src, dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
inventory = c.getPlayer().getInventory(inventoryType);
|
||||
@@ -183,7 +183,7 @@ class PairedQuicksort {
|
||||
}
|
||||
}
|
||||
|
||||
public final class ItemIdSortHandler extends AbstractMaplePacketHandler {
|
||||
public final class InventorySortHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
@@ -33,6 +33,9 @@ import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleJob;
|
||||
import constants.ServerConstants;
|
||||
import net.server.world.MaplePartyCharacter;
|
||||
import net.server.world.PartyOperation;
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -40,40 +43,41 @@ import constants.ServerConstants;
|
||||
* @author BubblesDev
|
||||
*/
|
||||
public class PartySearchStartHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if(!ServerConstants.USE_PARTY_SEARCH){
|
||||
return;
|
||||
}
|
||||
|
||||
int min = slea.readInt();
|
||||
int max = slea.readInt();
|
||||
slea.readInt(); // members
|
||||
int jobs = slea.readInt();
|
||||
|
||||
MapleParty party = c.getPlayer().getParty();
|
||||
if(party == null) return;
|
||||
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
MapleMap map = chr.getMap();
|
||||
World world = c.getWorldServer();
|
||||
|
||||
Collection<MapleMapObject> mapobjs = map.getPlayers();
|
||||
|
||||
for (MapleMapObject mapobj : mapobjs) {
|
||||
if (chr.getParty().getMembers().size() > 5) {
|
||||
if (party.getMembers().size() > 5) {
|
||||
break;
|
||||
}
|
||||
if (mapobj instanceof MapleCharacter) {
|
||||
MapleCharacter tchar = (MapleCharacter) mapobj;
|
||||
int charlvl = tchar.getLevel();
|
||||
if (charlvl >= min && charlvl <= max && isValidJob(tchar.getJob(), jobs)) {
|
||||
if (c.getPlayer().getParty() == null) {
|
||||
//WorldChannelInterface wci = c.getChannelServer().getWorldInterface();
|
||||
MapleParty party = c.getPlayer().getParty();
|
||||
//int partyid = party.getId();
|
||||
//party = null;//.getParty(partyid);
|
||||
if (party != null) {
|
||||
if (party.getMembers().size() < 6) {
|
||||
//MaplePartyCharacter partyplayer = tchar.getMPC();
|
||||
//wci.updateParty(party.getId(), PartyOperation.JOIN, partyplayer);
|
||||
c.getPlayer().receivePartyMemberHP();
|
||||
c.getPlayer().updatePartyMemberHP();
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.partyStatusMessage(17));
|
||||
}
|
||||
}
|
||||
if (tchar.getParty() == null) {
|
||||
MaplePartyCharacter partyplayer = new MaplePartyCharacter(tchar);
|
||||
tchar.getMap().addPartyMember(tchar);
|
||||
|
||||
world.updateParty(party.getId(), PartyOperation.JOIN, partyplayer);
|
||||
tchar.receivePartyMemberHP();
|
||||
tchar.updatePartyMemberHP();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +172,8 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
player.getMap().addPlayer(player);
|
||||
World world = server.getWorld(c.getWorld());
|
||||
world.getPlayerStorage().addPlayer(player);
|
||||
|
||||
player.setAwayFromWorld(false);
|
||||
|
||||
int buddyIds[] = player.getBuddylist().getBuddyIds();
|
||||
world.loggedOn(player.getName(), player.getId(), c.getChannel(), buddyIds);
|
||||
|
||||
Reference in New Issue
Block a user