Meso patch + Swift Dmg Reflect buff + GPQ Rewards + Starting Q. items

Fixed several RNG pool issues within several handler classes.
Fixed an overflow issue with mesos, that would cause players to lose all amount on inventory.
Changed the code coupon SQL structure. Now nxcode_items.quantity is to be specified for both nx values and item quantities alike, instead of the use of "quantity" only when items are being provided.
Bob Snail now appears each 4 hours, instead of any time.
Removed duplicate command Warpto. Warpto merged with Reach command.
Fixed solo expeditions being disposed for "lack of personnel" after changing maps (normal limitations should not apply when USE_ENABLE_SOLO_EXPEDITIONS is enabled).
Fixed mobskills "Weapon/Magic Reflect" taking too long to show the active status over the mob's head.
Fixed a case with clean slate scroll not working as expected.
Improved reward contents for the GPQ.
Fixed loot manager not acting properly when verifying one-of-a-kind contents.
Implemented quest item requirement checkups to start quests. Items required to start a quest now should appear if the player did not start it yet, e.g.: SOS letter.
Fixed an issue with server message/boss HPbar switch interaction that would not work the moment after a player changed channels/entered Cash Shop.
Improved Victoria Island worldmap design, at the Kerning subway area.
This commit is contained in:
ronancpl
2018-12-05 02:52:14 -02:00
parent 0910dc2428
commit a17c233693
53 changed files with 625 additions and 343 deletions

View File

@@ -569,7 +569,7 @@ public class Server {
}
public List<Integer> getActiveCoupons() {
synchronized(activeCoupons) {
synchronized (activeCoupons) {
return activeCoupons;
}
}
@@ -586,7 +586,7 @@ public class Server {
public void toggleCoupon(Integer couponId) {
if(ItemConstants.isRateCoupon(couponId)) {
synchronized(activeCoupons) {
synchronized (activeCoupons) {
if(activeCoupons.contains(couponId)) {
activeCoupons.remove(couponId);
}
@@ -600,7 +600,7 @@ public class Server {
}
public void updateActiveCoupons() throws SQLException {
synchronized(activeCoupons) {
synchronized (activeCoupons) {
activeCoupons.clear();
Calendar c = Calendar.getInstance();
@@ -1669,9 +1669,10 @@ public class Server {
}
private void disconnectIdlesOnLoginState() {
List<MapleClient> toDisconnect = new LinkedList<>();
srvLock.lock();
try {
List<MapleClient> toDisconnect = new LinkedList<>();
long timeNow = System.currentTimeMillis();
for(Entry<MapleClient, Long> mc : inLoginState.entrySet()) {
@@ -1681,17 +1682,19 @@ public class Server {
}
for(MapleClient c : toDisconnect) {
if(c.isLoggedIn()) {
c.disconnect(false, false);
} else {
c.getSession().close(true);
}
inLoginState.remove(c);
}
} finally {
srvLock.unlock();
}
for (MapleClient c : toDisconnect) { // thanks Lei for pointing a deadlock issue with srvLock
if(c.isLoggedIn()) {
c.disconnect(false, false);
} else {
c.getSession().close(true);
}
}
}
private void disconnectIdlesOnLoginTask() {
@@ -1707,75 +1710,73 @@ public class Server {
return new Runnable() {
@Override
public void run() {
srvLock.lock();
try {
System.out.println((restart ? "Restarting" : "Shutting down") + " the server!\r\n");
if (getWorlds() == null) return;//already shutdown
for (World w : getWorlds()) {
w.shutdown();
}
/*for (World w : getWorlds()) {
while (w.getPlayerStorage().getAllCharacters().size() > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
System.err.println("FUCK MY LIFE");
}
}
}
for (Channel ch : getAllChannels()) {
while (ch.getConnectedClients() > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
System.err.println("FUCK MY LIFE");
}
}
}*/
List<Channel> allChannels = getAllChannels();
if(ServerConstants.USE_THREAD_TRACKER) ThreadTracker.getInstance().cancelThreadTrackerTask();
for (Channel ch : allChannels) {
while (!ch.finishedShutdown()) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
System.err.println("FUCK MY LIFE");
}
}
}
resetServerWorlds();
ThreadManager.getInstance().stop();
TimerManager.getInstance().purge();
TimerManager.getInstance().stop();
System.out.println("Worlds + Channels are offline.");
acceptor.unbind();
acceptor = null;
if (!restart) {
System.exit(0);
} else {
System.out.println("\r\nRestarting the server....\r\n");
try {
instance.finalize();//FUU I CAN AND IT'S FREE
} catch (Throwable ex) {
ex.printStackTrace();
}
instance = null;
System.gc();
getInstance().init();//DID I DO EVERYTHING?! D:
}
} finally {
srvLock.unlock();
}
shutdownInternal(restart);
}
};
}
private synchronized void shutdownInternal(boolean restart) {
System.out.println((restart ? "Restarting" : "Shutting down") + " the server!\r\n");
if (getWorlds() == null) return;//already shutdown
for (World w : getWorlds()) {
w.shutdown();
}
/*for (World w : getWorlds()) {
while (w.getPlayerStorage().getAllCharacters().size() > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
System.err.println("FUCK MY LIFE");
}
}
}
for (Channel ch : getAllChannels()) {
while (ch.getConnectedClients() > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
System.err.println("FUCK MY LIFE");
}
}
}*/
List<Channel> allChannels = getAllChannels();
if(ServerConstants.USE_THREAD_TRACKER) ThreadTracker.getInstance().cancelThreadTrackerTask();
for (Channel ch : allChannels) {
while (!ch.finishedShutdown()) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
System.err.println("FUCK MY LIFE");
}
}
}
resetServerWorlds();
ThreadManager.getInstance().stop();
TimerManager.getInstance().purge();
TimerManager.getInstance().stop();
System.out.println("Worlds + Channels are offline.");
acceptor.unbind();
acceptor = null;
if (!restart) {
System.exit(0);
} else {
System.out.println("\r\nRestarting the server....\r\n");
try {
instance.finalize();//FUU I CAN AND IT'S FREE
} catch (Throwable ex) {
ex.printStackTrace();
}
instance = null;
System.gc();
getInstance().init();//DID I DO EVERYTHING?! D:
}
}
}

View File

@@ -55,7 +55,7 @@ public final class AdminCommandHandler extends AbstractMaplePacketHandler {
int[][] toSpawn = MapleItemInformationProvider.getInstance().getSummonMobs(slea.readInt());
for (int z = 0; z < toSpawn.length; z++) {
int[] toSpawnChild = toSpawn[z];
if (Randomizer.nextInt(101) <= toSpawnChild[1]) {
if (Randomizer.nextInt(100) < toSpawnChild[1]) {
c.getPlayer().getMap().spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(toSpawnChild[0]), c.getPlayer().getPosition());
}
}

View File

@@ -62,17 +62,17 @@ public final class CouponCodeHandler extends AbstractMaplePacketHandler {
ResultSet rs = ps.executeQuery();
while (rs.next()) {
int type = rs.getInt("type"), item = rs.getInt("item");
int type = rs.getInt("type"), quantity = rs.getInt("quantity");
if (type < 5) {
Integer i = couponPoints.get(type);
if (i != null) {
couponPoints.put(type, i + item);
couponPoints.put(type, i + quantity);
} else {
couponPoints.put(type, item);
couponPoints.put(type, quantity);
}
} else {
int quantity = rs.getInt("quantity");
int item = rs.getInt("item");
Integer i = couponItems.get(item);
if (i != null) {
@@ -108,7 +108,7 @@ public final class CouponCodeHandler extends AbstractMaplePacketHandler {
if (!couponPoints.isEmpty()) {
for (Entry<Integer, Integer> e : couponPoints.entrySet()) {
ret.add(new Pair<>(e.getKey(), new Pair<>(e.getValue(), 777)));
ret.add(new Pair<>(e.getKey(), new Pair<>(777, e.getValue())));
}
}
@@ -199,27 +199,37 @@ public final class CouponCodeHandler extends AbstractMaplePacketHandler {
for (Pair<Integer, Pair<Integer, Integer>> p : codeRes.getRight()) {
type = p.getLeft();
int item = p.getRight().getLeft();
int quantity = p.getRight().getRight();
CashShop cs = c.getPlayer().getCashShop();
switch (type) {
case 0:
case 4:
cs.gainCash(1, item); //nxCredit
cs.gainCash(1, quantity); //nxCredit
break;
case 1:
cs.gainCash(2, item); //maplePoint
cs.gainCash(2, quantity); //maplePoint
break;
case 2:
cs.gainCash(4, item); //nxPrepaid
cs.gainCash(4, quantity); //nxPrepaid
break;
case 3:
cs.gainCash(1, item);
cs.gainCash(4, (item / 5000));
cs.gainCash(1, quantity);
cs.gainCash(4, (quantity / 5000));
break;
default:
short qty = p.getRight().getRight().shortValue();
int item = p.getRight().getLeft();
short qty;
if (quantity > Short.MAX_VALUE) {
qty = Short.MAX_VALUE;
} else if (quantity < Short.MIN_VALUE) {
qty = Short.MIN_VALUE;
} else {
qty = (short) quantity;
}
if (MapleItemInformationProvider.getInstance().isCash(item)) {
Item it = CashShop.generateCouponItem(item, qty);

View File

@@ -86,6 +86,8 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
return;
}
chr.closePlayerInteractions();
chr.unregisterChairBuff();
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs());
Server.getInstance().getPlayerBuffStorage().addDiseasesToStorage(chr.getId(), chr.getAllDiseases());

View File

@@ -43,7 +43,7 @@ public final class HealOvertimeHandler extends AbstractMaplePacketHandler {
short healHP = slea.readShort();
if (healHP != 0) {
abm.setTimestamp(8, timestamp, 4); // thanks Vcoc for pointing out d/c happening here
abm.setTimestamp(8, timestamp, 28); // thanks Vcoc & Thora for pointing out d/c happening here
if ((abm.getLastSpam(0) + 1500) > timestamp) AutobanFactory.FAST_HP_HEALING.addPoint(abm, "Fast hp healing");
int abHeal = 120 + (int)(20 * MapleMapFactory.getMapRecoveryRate(chr.getMapId())); // Sleepywood sauna and showa spa...
@@ -58,7 +58,7 @@ public final class HealOvertimeHandler extends AbstractMaplePacketHandler {
}
short healMP = slea.readShort();
if (healMP != 0 && healMP < 1000) {
abm.setTimestamp(9, timestamp, 4);
abm.setTimestamp(9, timestamp, 28);
if ((abm.getLastSpam(1) + 1500) > timestamp) AutobanFactory.FAST_MP_HEALING.addPoint(abm, "Fast mp healing");
chr.addMP(healMP);
abm.spam(1, timestamp);

View File

@@ -37,7 +37,9 @@ import tools.data.input.SeekableLittleEndianAccessor;
/**
*
* @author Ronan - header layout courtesy of Eric
* @author Ronan
*
* Header layout thanks to Eric
*/
public final class NewYearCardHandler extends AbstractMaplePacketHandler {

View File

@@ -52,7 +52,7 @@ public final class PetCommandHandler extends AbstractMaplePacketHandler {
return;
}
if (Randomizer.nextInt(101) <= petCommand.getProbability()) {
if (Randomizer.nextInt(100) < petCommand.getProbability()) {
pet.gainClosenessFullness(chr, petCommand.getIncrease(), 0, command);
chr.getMap().broadcastMessage(MaplePacketCreator.commandResponse(chr.getId(), petIndex, false, command, false));
} else {

View File

@@ -36,7 +36,7 @@ import tools.data.input.SeekableLittleEndianAccessor;
*/
public final class QuestActionHandler extends AbstractMaplePacketHandler {
// isNpcNearby credits to gabriel.sin
// isNpcNearby credits to GabrielSin
private static boolean isNpcNearby(SeekableLittleEndianAccessor slea, MapleCharacter player, MapleQuest quest, int npcId) {
Point playerP = null;

View File

@@ -74,7 +74,7 @@ public final class ScrollHandler extends AbstractMaplePacketHandler {
Item wscroll = null;
if (ItemConstants.isCleanSlate(scroll.getItemId())) {
Map<String, Integer> eqStats = ii.getEquipStats(scroll.getItemId());
Map<String, Integer> eqStats = ii.getEquipStats(toScroll.getItemId()); // clean slate issue found thanks to Masterrulax
if (eqStats == null || eqStats.get("tuc") == 0) {
c.announce(MaplePacketCreator.getInventoryFull());
return;

View File

@@ -106,7 +106,7 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
for (loseItem loseItem : loseItems) {
type = ItemConstants.getInventoryType(loseItem.getId());
for (byte b = 0; b < loseItem.getX(); b++) {//LOL?
if (Randomizer.nextInt(101) >= loseItem.getChance()) {
if (Randomizer.nextInt(100) < loseItem.getChance()) {
if (chr.haveItem(loseItem.getId())) {
pos.x = (int) (playerpos + ((d % 2 == 0) ? (25 * (d + 1) / 2) : -(25 * (d / 2))));
MapleInventoryManipulator.removeById(c, type, loseItem.getId(), 1, false, false);

View File

@@ -0,0 +1,14 @@
package net.server.channel.handlers;
import client.MapleClient;
import net.AbstractMaplePacketHandler;
import tools.data.input.SeekableLittleEndianAccessor;
import tools.MaplePacketCreator;
public final class UseItemCanvasHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
c.announce(MaplePacketCreator.enableActions());
}
}

View File

@@ -54,7 +54,7 @@ public final class UseSummonBagHandler extends AbstractMaplePacketHandler {
int[][] toSpawn = MapleItemInformationProvider.getInstance().getSummonMobs(itemId);
for (int z = 0; z < toSpawn.length; z++) {
int[] toSpawnChild = toSpawn[z];
if (Randomizer.nextInt(101) <= toSpawnChild[1]) {
if (Randomizer.nextInt(100) < toSpawnChild[1]) {
c.getPlayer().getMap().spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(toSpawnChild[0]), c.getPlayer().getPosition());
}
}