diff --git a/build/built-jar.properties b/build/built-jar.properties index a0f912d872..5be08aa22e 100644 --- a/build/built-jar.properties +++ b/build/built-jar.properties @@ -1,4 +1,4 @@ -#Sun, 18 Jun 2017 02:53:19 -0300 +#Mon, 19 Jun 2017 14:48:35 -0300 C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2= diff --git a/build/classes/client/MapleBuffStat.class b/build/classes/client/MapleBuffStat.class index 5e650b4824..9b51cfe62c 100644 Binary files a/build/classes/client/MapleBuffStat.class and b/build/classes/client/MapleBuffStat.class differ diff --git a/build/classes/client/MapleCharacter$1.class b/build/classes/client/MapleCharacter$1.class index 8c915665a3..cda0181234 100644 Binary files a/build/classes/client/MapleCharacter$1.class and b/build/classes/client/MapleCharacter$1.class differ diff --git a/build/classes/client/MapleCharacter$10.class b/build/classes/client/MapleCharacter$10.class index 5db70657ff..6f7911f686 100644 Binary files a/build/classes/client/MapleCharacter$10.class and b/build/classes/client/MapleCharacter$10.class differ diff --git a/build/classes/client/MapleCharacter$11.class b/build/classes/client/MapleCharacter$11.class index fd894efb84..08ca1311e8 100644 Binary files a/build/classes/client/MapleCharacter$11.class and b/build/classes/client/MapleCharacter$11.class differ diff --git a/build/classes/client/MapleCharacter$12.class b/build/classes/client/MapleCharacter$12.class index 9e5dca18cf..3e4cb04be2 100644 Binary files a/build/classes/client/MapleCharacter$12.class and b/build/classes/client/MapleCharacter$12.class differ diff --git a/build/classes/client/MapleCharacter$13.class b/build/classes/client/MapleCharacter$13.class index 9201666403..415f1f76a2 100644 Binary files a/build/classes/client/MapleCharacter$13.class and b/build/classes/client/MapleCharacter$13.class differ diff --git a/build/classes/client/MapleCharacter$14.class b/build/classes/client/MapleCharacter$14.class index da427c2bdd..21c363f261 100644 Binary files a/build/classes/client/MapleCharacter$14.class and b/build/classes/client/MapleCharacter$14.class differ diff --git a/build/classes/client/MapleCharacter$15.class b/build/classes/client/MapleCharacter$15.class index 6749638e94..0d2deb02ac 100644 Binary files a/build/classes/client/MapleCharacter$15.class and b/build/classes/client/MapleCharacter$15.class differ diff --git a/build/classes/client/MapleCharacter$16.class b/build/classes/client/MapleCharacter$16.class index 80d6537289..8d78cf8a4d 100644 Binary files a/build/classes/client/MapleCharacter$16.class and b/build/classes/client/MapleCharacter$16.class differ diff --git a/build/classes/client/MapleCharacter$17.class b/build/classes/client/MapleCharacter$17.class index e832dbcf96..e349edd109 100644 Binary files a/build/classes/client/MapleCharacter$17.class and b/build/classes/client/MapleCharacter$17.class differ diff --git a/build/classes/client/MapleCharacter$18.class b/build/classes/client/MapleCharacter$18.class index f86ec6adca..c5a3194125 100644 Binary files a/build/classes/client/MapleCharacter$18.class and b/build/classes/client/MapleCharacter$18.class differ diff --git a/build/classes/client/MapleCharacter$2.class b/build/classes/client/MapleCharacter$2.class index a2ea5df276..99b73046d8 100644 Binary files a/build/classes/client/MapleCharacter$2.class and b/build/classes/client/MapleCharacter$2.class differ diff --git a/build/classes/client/MapleCharacter$3.class b/build/classes/client/MapleCharacter$3.class index 1887522ea6..dfd55c3466 100644 Binary files a/build/classes/client/MapleCharacter$3.class and b/build/classes/client/MapleCharacter$3.class differ diff --git a/build/classes/client/MapleCharacter$4.class b/build/classes/client/MapleCharacter$4.class index 4712a8fea3..6e56939012 100644 Binary files a/build/classes/client/MapleCharacter$4.class and b/build/classes/client/MapleCharacter$4.class differ diff --git a/build/classes/client/MapleCharacter$5.class b/build/classes/client/MapleCharacter$5.class index 2f97916868..763d1a145e 100644 Binary files a/build/classes/client/MapleCharacter$5.class and b/build/classes/client/MapleCharacter$5.class differ diff --git a/build/classes/client/MapleCharacter$6.class b/build/classes/client/MapleCharacter$6.class index 002cc78e4f..a6e9ae54ba 100644 Binary files a/build/classes/client/MapleCharacter$6.class and b/build/classes/client/MapleCharacter$6.class differ diff --git a/build/classes/client/MapleCharacter$7.class b/build/classes/client/MapleCharacter$7.class index 9520854af1..c8afc399d3 100644 Binary files a/build/classes/client/MapleCharacter$7.class and b/build/classes/client/MapleCharacter$7.class differ diff --git a/build/classes/client/MapleCharacter$8.class b/build/classes/client/MapleCharacter$8.class index fc4c5544fb..d555c6d3e8 100644 Binary files a/build/classes/client/MapleCharacter$8.class and b/build/classes/client/MapleCharacter$8.class differ diff --git a/build/classes/client/MapleCharacter$9.class b/build/classes/client/MapleCharacter$9.class index 66829ca473..658217c610 100644 Binary files a/build/classes/client/MapleCharacter$9.class and b/build/classes/client/MapleCharacter$9.class differ diff --git a/build/classes/client/MapleCharacter$CancelCooldownAction.class b/build/classes/client/MapleCharacter$CancelCooldownAction.class index a1c51341c8..a4d5ced0f9 100644 Binary files a/build/classes/client/MapleCharacter$CancelCooldownAction.class and b/build/classes/client/MapleCharacter$CancelCooldownAction.class differ diff --git a/build/classes/client/MapleCharacter$FameStatus.class b/build/classes/client/MapleCharacter$FameStatus.class index df59fb778a..e38d5f8ac8 100644 Binary files a/build/classes/client/MapleCharacter$FameStatus.class and b/build/classes/client/MapleCharacter$FameStatus.class differ diff --git a/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class b/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class index dc55187e1a..f7bf159ade 100644 Binary files a/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class and b/build/classes/client/MapleCharacter$MapleBuffStatValueHolder.class differ diff --git a/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class b/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class index 7682ba19da..9d4c134c82 100644 Binary files a/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class and b/build/classes/client/MapleCharacter$MapleCoolDownValueHolder.class differ diff --git a/build/classes/client/MapleCharacter$SkillEntry.class b/build/classes/client/MapleCharacter$SkillEntry.class index ddc0380acf..56019cf7c1 100644 Binary files a/build/classes/client/MapleCharacter$SkillEntry.class and b/build/classes/client/MapleCharacter$SkillEntry.class differ diff --git a/build/classes/client/MapleCharacter.class b/build/classes/client/MapleCharacter.class index 84bc4e3401..bc39a3a957 100644 Binary files a/build/classes/client/MapleCharacter.class and b/build/classes/client/MapleCharacter.class differ diff --git a/build/classes/client/command/Commands$1.class b/build/classes/client/command/Commands$1.class index f788196e57..93fe0780fc 100644 Binary files a/build/classes/client/command/Commands$1.class and b/build/classes/client/command/Commands$1.class differ diff --git a/build/classes/client/command/Commands.class b/build/classes/client/command/Commands.class index e0068cdf88..c38c18fdcd 100644 Binary files a/build/classes/client/command/Commands.class and b/build/classes/client/command/Commands.class differ diff --git a/build/classes/client/inventory/MapleInventory.class b/build/classes/client/inventory/MapleInventory.class index eb321ded05..a1ed69522f 100644 Binary files a/build/classes/client/inventory/MapleInventory.class and b/build/classes/client/inventory/MapleInventory.class differ diff --git a/build/classes/constants/ServerConstants.class b/build/classes/constants/ServerConstants.class index 8f48ebf359..f5707d1ae2 100644 Binary files a/build/classes/constants/ServerConstants.class and b/build/classes/constants/ServerConstants.class differ diff --git a/build/classes/net/server/CouponWorker.class b/build/classes/net/server/CouponWorker.class index d97420ae14..79498e6aa7 100644 Binary files a/build/classes/net/server/CouponWorker.class and b/build/classes/net/server/CouponWorker.class differ diff --git a/build/classes/net/server/Server$1.class b/build/classes/net/server/Server$1.class index e3bb2746e5..f933d5ed48 100644 Binary files a/build/classes/net/server/Server$1.class and b/build/classes/net/server/Server$1.class differ diff --git a/build/classes/net/server/Server.class b/build/classes/net/server/Server.class index 69a961adad..b9e2c777da 100644 Binary files a/build/classes/net/server/Server.class and b/build/classes/net/server/Server.class differ diff --git a/build/classes/net/server/channel/handlers/AbstractDealDamageHandler.class b/build/classes/net/server/channel/handlers/AbstractDealDamageHandler.class index 9eaefb7b1f..5fd62f795c 100644 Binary files a/build/classes/net/server/channel/handlers/AbstractDealDamageHandler.class and b/build/classes/net/server/channel/handlers/AbstractDealDamageHandler.class differ diff --git a/build/classes/net/server/channel/handlers/CloseRangeDamageHandler.class b/build/classes/net/server/channel/handlers/CloseRangeDamageHandler.class index 330f125371..161a7721ba 100644 Binary files a/build/classes/net/server/channel/handlers/CloseRangeDamageHandler.class and b/build/classes/net/server/channel/handlers/CloseRangeDamageHandler.class differ diff --git a/build/classes/net/server/channel/handlers/PlayerLoggedinHandler.class b/build/classes/net/server/channel/handlers/PlayerLoggedinHandler.class index 4bf4f5bd26..d13119fa5c 100644 Binary files a/build/classes/net/server/channel/handlers/PlayerLoggedinHandler.class and b/build/classes/net/server/channel/handlers/PlayerLoggedinHandler.class differ diff --git a/build/classes/net/server/world/World$1.class b/build/classes/net/server/world/World$1.class index baa56660b3..26812bbc32 100644 Binary files a/build/classes/net/server/world/World$1.class and b/build/classes/net/server/world/World$1.class differ diff --git a/build/classes/net/server/world/World.class b/build/classes/net/server/world/World.class index eff849d181..673bb0e52a 100644 Binary files a/build/classes/net/server/world/World.class and b/build/classes/net/server/world/World.class differ diff --git a/build/classes/server/MapleStatEffect$CancelEffectAction.class b/build/classes/server/MapleStatEffect$CancelEffectAction.class index 92b195c8da..4aef3c90a2 100644 Binary files a/build/classes/server/MapleStatEffect$CancelEffectAction.class and b/build/classes/server/MapleStatEffect$CancelEffectAction.class differ diff --git a/build/classes/server/MapleStatEffect.class b/build/classes/server/MapleStatEffect.class index 085aa0cea3..c64a0118d2 100644 Binary files a/build/classes/server/MapleStatEffect.class and b/build/classes/server/MapleStatEffect.class differ diff --git a/dist/MapleSolaxia.jar b/dist/MapleSolaxia.jar index b0407b9669..e390a4315e 100644 Binary files a/dist/MapleSolaxia.jar and b/dist/MapleSolaxia.jar differ diff --git a/mychanges_ptbr.txt b/mychanges_ptbr.txt index ac28d947fe..e64525620d 100644 --- a/mychanges_ptbr.txt +++ b/mychanges_ptbr.txt @@ -320,4 +320,13 @@ Corre 15 - 17 Junho 2017, Correção de bug na função de atribuição de EXP, que não permitia receber valores negativos de EXP. -Implementação da GPQ. \ No newline at end of file +Implementação da GPQ. + +18 Junho 2017, +Correção de problema de concorrência referente às alterações nos rates do server. +Consertado bugs referentes ao comando "level", não reatribuindo rates apropriadamente. + +19 Junho 2017, +Consertado cupons não aparecendo apropriadamente na região de buffs. +Consertado alguns problemas de concorrência com cupons. +Consertado alguns problemas de concorrência com character buffs. \ No newline at end of file diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml index a0f2f44b10..225a2093d8 100644 --- a/nbproject/private/private.xml +++ b/nbproject/private/private.xml @@ -12,15 +12,18 @@ - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/event/GuildQuest.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/9040009.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/ChangeMapHandler.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/9040006.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/reactor/2006001.js - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/reactor/9208009.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/TimerManager.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/PlayerLoggedinHandler.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/command/Commands.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/MapleStatEffect.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/Server.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/CouponWorker.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleBuffStat.java file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/constants/ServerConstants.java file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleCharacter.java - file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/scripts/npc/9040001.js + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/MapleItemInformationProvider.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/inventory/MapleInventory.java + file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/MaplePacketCreator.java diff --git a/scripts/npc/22000.js b/scripts/npc/22000.js index a135c3b54e..d5571633fa 100644 --- a/scripts/npc/22000.js +++ b/scripts/npc/22000.js @@ -62,8 +62,11 @@ function action(mode, type, selection) { cm.dispose(); } } else if (status == 3) { - if (cm.haveItem(4031801)) + if (cm.haveItem(4031801)) { cm.gainItem(4031801, -1); + } else { + cm.gainMeso(-150); + } cm.warp(104000000); cm.dispose(); } diff --git a/scripts/npc/9040005.js b/scripts/npc/9040005.js index d01b2983cb..7dae431267 100644 --- a/scripts/npc/9040005.js +++ b/scripts/npc/9040005.js @@ -25,7 +25,7 @@ function start() { function action(mode, type, selection) { if(mode == 1) { - cm.warp(990001100); + cm.warp(101030104); } cm.dispose(); } diff --git a/src/client/MapleBuffStat.java b/src/client/MapleBuffStat.java index a7467e5552..206a2c9e2b 100644 --- a/src/client/MapleBuffStat.java +++ b/src/client/MapleBuffStat.java @@ -22,42 +22,48 @@ package client; public enum MapleBuffStat { - //SLOW(0x1), - MORPH(0x2), - RECOVERY(0x4), - MAPLE_WARRIOR(0x8), - STANCE(0x10), - SHARP_EYES(0x20), - MANA_REFLECTION(0x40), - //ALWAYS_RIGHT(0X80), + //SLOW(0x1L), + MORPH(0x2L), + RECOVERY(0x4L), + MAPLE_WARRIOR(0x8L), + STANCE(0x10L), + SHARP_EYES(0x20L), + MANA_REFLECTION(0x40L), + //ALWAYS_RIGHT(0X80L), //------ bgn EDITED SLOT (was unused before) -------- MAP_PROTECTION(0x100000000000000L), //------ end EDITED SLOT ---------------------------- - SHADOW_CLAW(0x100), - INFINITY(0x200), - HOLY_SHIELD(0x400), - HAMSTRING(0x800), - BLIND(0x1000), - CONCENTRATE(0x2000), - //4000 - ECHO_OF_HERO(0x8000), - //10000 - GHOST_MORPH(0x20000), - AURA(0x40000), - CONFUSE(0x80000), - //100000 - //200000 - //400000 - //800000 - //1000000 - //2000000 - //4000000 - BERSERK_FURY(0x8000000), - DIVINE_BODY(0x10000000), + SHADOW_CLAW(0x100L), + INFINITY(0x200L), + HOLY_SHIELD(0x400L), + HAMSTRING(0x800L), + BLIND(0x1000L), + CONCENTRATE(0x2000L), + //4000L + ECHO_OF_HERO(0x8000L), + //10000L + GHOST_MORPH(0x20000L), + AURA(0x40000L), + CONFUSE(0x80000L), + + // ---- COUPON feature (was unused anyway) ---- + + COUPON_EXP1(0x100000L), + COUPON_EXP2(0x200000L), + COUPON_EXP3(0x400000L), + COUPON_EXP4(0x800000L), + COUPON_DRP1(0x1000000L), + COUPON_DRP2(0x2000000L), + COUPON_DRP3(0x4000000L), + + // ---- end COUPON feature ---- + + BERSERK_FURY(0x8000000L), + DIVINE_BODY(0x10000000L), SPARK(0x20000000L), - //40000000 + //40000000L FINALATTACK(0x80000000L), BATTLESHIP(0xA00000040L), // weird one WATK(0x100000000L), diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java index 3e5e1f5048..71526e444f 100644 --- a/src/client/MapleCharacter.java +++ b/src/client/MapleCharacter.java @@ -46,6 +46,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; //import java.util.TimeZone; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.Lock; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; @@ -257,6 +259,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { private ScheduledFuture expiretask; private ScheduledFuture recoveryTask; private List> timers = new ArrayList<>(); + private Lock couponLock = new ReentrantLock(); private NumberFormat nf = new DecimalFormat("#,###,###,###"); private ArrayList excluded = new ArrayList<>(); private MonsterBook monsterbook; @@ -700,9 +703,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } } - public void cancelBuffStats(MapleBuffStat stat) { + public synchronized void cancelBuffStats(MapleBuffStat stat) { List buffStatList = Arrays.asList(stat); - deregisterBuffStats(buffStatList); + dropBuffStats(deregisterBuffStats(buffStatList)); cancelPlayerBuffs(buffStatList); } @@ -789,7 +792,15 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { cancelEffect(MapleItemInformationProvider.getInstance().getItemEffect(itemId), false, -1); } - public void cancelEffect(MapleStatEffect effect, boolean overwrite, long startTime) { + public synchronized void cancelEffect(MapleStatEffect effect, boolean overwrite, long startTime) { + cancelEffect(effect, overwrite, startTime, true); + } + + private void cancelEffect(MapleStatEffect effect, boolean overwrite, long startTime, boolean firstCancel) { + dropBuffStats(cancelEffectInternal(effect, overwrite, startTime)); + } + + private List cancelEffectInternal(MapleStatEffect effect, boolean overwrite, long startTime) { List buffstats; if (!overwrite) { buffstats = getBuffStats(effect, startTime); @@ -800,7 +811,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { buffstats.add(statup.getLeft()); } } - deregisterBuffStats(buffstats); + List toCancel = deregisterBuffStats(buffstats); if (effect.isMagicDoor()) { if (!getDoors().isEmpty()) { MapleDoor door = getDoors().iterator().next(); @@ -842,6 +853,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { if (!overwrite) { cancelPlayerBuffs(buffstats); } + + return toCancel; } public void cancelEffectFromBuffStat(MapleBuffStat stat) { @@ -1745,60 +1758,63 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } } - private void deregisterBuffStats(List stats) { - synchronized (stats) { - List effectsToCancel = new ArrayList<>(stats.size()); - for (MapleBuffStat stat : stats) { - MapleBuffStatValueHolder mbsvh = effects.get(stat); - if (mbsvh != null) { - effects.remove(stat); - boolean addMbsvh = true; - for (MapleBuffStatValueHolder contained : effectsToCancel) { - if (mbsvh.startTime == contained.startTime && contained.effect == mbsvh.effect) { - addMbsvh = false; - } - } - if (addMbsvh) { - effectsToCancel.add(mbsvh); - } - if (stat == MapleBuffStat.RECOVERY) { - if (recoveryTask != null) { - recoveryTask.cancel(false); - recoveryTask = null; - } - } else if (stat == MapleBuffStat.SUMMON || stat == MapleBuffStat.PUPPET) { - int summonId = mbsvh.effect.getSourceId(); - - MapleSummon summon = summons.get(summonId); - if (summon != null) { - getMap().broadcastMessage(MaplePacketCreator.removeSummon(summon, true), summon.getPosition()); - getMap().removeMapObject(summon); - removeVisibleMapObject(summon); - summons.remove(summonId); - } - if (summon.getSkill() == DarkKnight.BEHOLDER) { - if (beholderHealingSchedule != null) { - beholderHealingSchedule.cancel(false); - beholderHealingSchedule = null; - } - if (beholderBuffSchedule != null) { - beholderBuffSchedule.cancel(false); - beholderBuffSchedule = null; - } - } - } else if (stat == MapleBuffStat.DRAGONBLOOD) { - dragonBloodSchedule.cancel(false); - dragonBloodSchedule = null; + private void dropBuffStats(List effectsToCancel) { + for (MapleBuffStatValueHolder cancelEffectCancelTasks : effectsToCancel) { + if (cancelEffectCancelTasks.schedule != null) { + cancelEffectCancelTasks.schedule.cancel(false); + this.cancelEffect(cancelEffectCancelTasks.effect, false, -1, false); + } + } + } + + private List deregisterBuffStats(List stats) { + List effectsToCancel = new ArrayList<>(stats.size()); + for (MapleBuffStat stat : stats) { + MapleBuffStatValueHolder mbsvh = effects.get(stat); + if (mbsvh != null) { + effects.remove(stat); + boolean addMbsvh = true; + for (MapleBuffStatValueHolder contained : effectsToCancel) { + if (mbsvh.startTime == contained.startTime && contained.effect == mbsvh.effect) { + addMbsvh = false; } } - } - for (MapleBuffStatValueHolder cancelEffectCancelTasks : effectsToCancel) { - if (cancelEffectCancelTasks.schedule != null) { - cancelEffectCancelTasks.schedule.cancel(false); - this.cancelEffect(cancelEffectCancelTasks.effect, false, -1); + if (addMbsvh) { + effectsToCancel.add(mbsvh); + } + if (stat == MapleBuffStat.RECOVERY) { + if (recoveryTask != null) { + recoveryTask.cancel(false); + recoveryTask = null; + } + } else if (stat == MapleBuffStat.SUMMON || stat == MapleBuffStat.PUPPET) { + int summonId = mbsvh.effect.getSourceId(); + + MapleSummon summon = summons.get(summonId); + if (summon != null) { + getMap().broadcastMessage(MaplePacketCreator.removeSummon(summon, true), summon.getPosition()); + getMap().removeMapObject(summon); + removeVisibleMapObject(summon); + summons.remove(summonId); + } + if (summon.getSkill() == DarkKnight.BEHOLDER) { + if (beholderHealingSchedule != null) { + beholderHealingSchedule.cancel(false); + beholderHealingSchedule = null; + } + if (beholderBuffSchedule != null) { + beholderBuffSchedule.cancel(false); + beholderBuffSchedule = null; + } + } + } else if (stat == MapleBuffStat.DRAGONBLOOD) { + dragonBloodSchedule.cancel(false); + dragonBloodSchedule = null; } } } + + return effectsToCancel; } public void disableDoor() { @@ -2015,6 +2031,9 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { expiretask = TimerManager.getInstance().register(new Runnable() { @Override public void run() { + MapleItemInformationProvider miip = MapleItemInformationProvider.getInstance(); + boolean deletedCoupon = false; + long expiration, currenttime = System.currentTimeMillis(); Set keys = getSkills().keySet(); for (Iterator i = keys.iterator(); i.hasNext();) { @@ -2038,12 +2057,19 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } else if (expiration != -1 && expiration < currenttime) { client.announce(MaplePacketCreator.itemExpired(item.getItemId())); toberemove.add(item); + if(miip.isRateCoupon(item.getItemId())) { + deletedCoupon = true; + } } } for (Item item : toberemove) { MapleInventoryManipulator.removeFromSlot(client, inv.getType(), item.getPosition(), item.getQuantity(), true); } toberemove.clear(); + + if(deletedCoupon) { + updateCouponRates(); + } } } }, 60000); @@ -2378,10 +2404,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { return new ArrayList<>(doors); } - public int getDropRate() { - return dropRate; - } - public int getEnergyBar() { return energybar; } @@ -2405,6 +2427,38 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { public int getExpRate() { return expRate; } + + public int getCouponExpRate() { + return expCoupon; + } + + public int getRawExpRate() { + return expRate / (expCoupon * client.getWorldServer().getExpRate()); + } + + public int getDropRate() { + return dropRate; + } + + public int getCouponDropRate() { + return dropCoupon; + } + + public int getRawDropRate() { + return dropRate / (dropCoupon * client.getWorldServer().getDropRate()); + } + + public int getMesoRate() { + return mesoRate; + } + + public int getCouponMesoRate() { + return mesoCoupon; + } + + public int getRawMesoRate() { + return mesoRate / (mesoCoupon * client.getWorldServer().getMesoRate()); + } public int getFace() { return face; @@ -2675,10 +2729,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { return merchantmeso; } - public int getMesoRate() { - return mesoRate; - } - public int getMesosTraded() { return mesosTraded; } @@ -3511,12 +3561,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { for (byte i = 1; i < 5; i++) { gainSlots(i, 4, true); } - } - - this.yellowMessage("We see you reached level " + level + ". Congratulations! As a token of your success, your inventory has been expanded a little bit."); + + this.yellowMessage("You reached level " + level + ". Congratulations! As a token of your success, your inventory has been expanded a little bit."); + } } if (level % 20 == 0 && ServerConstants.USE_ADD_RATES_BY_LEVEL == true) { //For the drop & meso rate - revertPlayerRates(); + revertLastPlayerRates(); setPlayerRates(); this.yellowMessage("You managed to get level " + level + "! Getting experience and items seems a little easier now, huh?"); } @@ -3626,24 +3676,22 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { } } - public void setPlayerRates() { + public void setPlayerRates() { this.expRate *= GameConstants.getPlayerBonusExpRate(this.level / 20); this.mesoRate *= GameConstants.getPlayerBonusMesoRate(this.level / 20); this.dropRate *= GameConstants.getPlayerBonusDropRate(this.level / 20); } - public void revertPlayerRates() { + public void revertLastPlayerRates() { this.expRate /= GameConstants.getPlayerBonusExpRate((this.level - 1) / 20); this.mesoRate /= GameConstants.getPlayerBonusMesoRate((this.level - 1) / 20); this.dropRate /= GameConstants.getPlayerBonusDropRate((this.level - 1) / 20); } - public void revertWorldRates() { - World worldz = Server.getInstance().getWorld(world); - - this.expRate /= worldz.getExpRate(); - this.mesoRate /= worldz.getMesoRate(); - this.dropRate /= worldz.getDropRate(); + public void revertPlayerRates() { + this.expRate /= GameConstants.getPlayerBonusExpRate(this.level / 20); + this.mesoRate /= GameConstants.getPlayerBonusMesoRate(this.level / 20); + this.dropRate /= GameConstants.getPlayerBonusDropRate(this.level / 20); } public void setWorldRates() { @@ -3653,13 +3701,30 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { this.dropRate *= worldz.getDropRate(); } - public void revertCouponRates() { + public void revertWorldRates() { + World worldz = Server.getInstance().getWorld(world); + this.expRate /= worldz.getExpRate(); + this.mesoRate /= worldz.getMesoRate(); + this.dropRate /= worldz.getDropRate(); + } + + private void setCouponRates() { + setActiveCoupons(); + activateCouponsEffects(); + } + + private void revertCouponRates() { revertCouponsEffects(); } - public void setCouponRates() { - setActiveCoupons(); - activateCouponsEffects(); + public void updateCouponRates() { + try { + couponLock.lock(); + revertCouponRates(); + setCouponRates(); + } finally { + couponLock.unlock(); + } } public void resetPlayerRates() { @@ -4508,6 +4573,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { }, buffInterval, buffInterval); } } else if (effect.isRecovery()) { + int healInterval = (ServerConstants.USE_ULTRA_RECOVERY) ? 2500 : 5000; + final byte heal = (byte) effect.getX(); recoveryTask = TimerManager.getInstance().register(new Runnable() { @Override @@ -4516,12 +4583,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject { client.announce(MaplePacketCreator.showOwnRecovery(heal)); getMap().broadcastMessage(MapleCharacter.this, MaplePacketCreator.showRecovery(id, heal), false); } - }, 5000, 5000); + }, healInterval, healInterval); } //is it possible to maintain a list of statup effects of the same type concurrently? Pair for (Pair statup : effect.getStatups()) { - effects.put(statup.getLeft(), new MapleBuffStatValueHolder(effect, starttime, schedule, statup.getRight().intValue())); + effects.put(statup.getLeft(), new MapleBuffStatValueHolder(effect, starttime, schedule, statup.getRight())); } recalcLocalStats(); } diff --git a/src/client/command/Commands.java b/src/client/command/Commands.java index 6e8d9c4606..63c9ecff57 100644 --- a/src/client/command/Commands.java +++ b/src/client/command/Commands.java @@ -522,19 +522,22 @@ public class Commands { player.yellowMessage("DROP RATE"); player.message(">>Base DROP Rate: " + c.getWorldServer().getDropRate() + "x"); - player.message(">>Your DROP Rate: " + player.getDropRate() / c.getWorldServer().getDropRate() + "x"); + player.message(">>Your DROP Rate: " + player.getRawDropRate() + "x"); + if(player.getCouponDropRate() != 1) player.message(">>Your Coupon DROP Rate: " + player.getCouponDropRate() + "x"); player.message(">>------------------------------------------------"); player.message(">>Total DROP Rate: " + player.getDropRate() + "x"); player.yellowMessage("MESO RATE"); player.message(">>Base MESO Rate: " + c.getWorldServer().getMesoRate() + "x"); - player.message(">>Your MESO Rate: " + player.getMesoRate() / c.getWorldServer().getMesoRate() + "x"); + player.message(">>Your MESO Rate: " + player.getRawMesoRate() + "x"); + if(player.getCouponMesoRate() != 1) player.message(">>Your Coupon MESO Rate: " + player.getCouponMesoRate() + "x"); player.message(">>------------------------------------------------"); player.message(">>Total MESO Rate: " + player.getMesoRate() + "x"); player.yellowMessage("EXP RATE"); player.message(">>Base EXP Rate: " + c.getWorldServer().getExpRate() + "x"); - player.message(">>Your EXP Rate: " + player.getExpRate() / c.getWorldServer().getExpRate() + "x"); + player.message(">>Your EXP Rate: " + player.getRawExpRate() + "x"); + if(player.getCouponExpRate() != 1) player.message(">>Your Coupon EXP Rate: " + player.getCouponExpRate() + "x"); player.message(">>------------------------------------------------"); player.message(">>Total EXP Rate: " + player.getExpRate() + "x"); /*if(c.getWorldServer().getExpRate() > ServerConstants.EXP_RATE) { @@ -1386,8 +1389,12 @@ public class Commands { return true; } - player.setLevel(Integer.parseInt(sub[1]) - 1); - player.loseExp(player.getExp(), false, false); + player.loseExp(player.getExp(), false, false); + + player.revertPlayerRates(); + player.setLevel(Math.min(Integer.parseInt(sub[1]), player.getMaxLevel()) - 1); + player.setPlayerRates(); + player.levelUp(false); } else if (sub[0].equals("levelpro")) { if (sub.length < 2){ @@ -1402,7 +1409,9 @@ public class Commands { final String[] s = {"setall", String.valueOf(Short.MAX_VALUE)}; executeGMCommand(c, s, heading); player.loseExp(player.getExp(), false, false); + player.revertPlayerRates(); player.setLevel(255); + player.setPlayerRates(); player.setFame(13337); player.setMaxHp(30000); player.setMaxMp(30000); @@ -1410,8 +1419,6 @@ public class Commands { player.updateSingleStat(MapleStat.FAME, 13337); player.updateSingleStat(MapleStat.MAXHP, 30000); player.updateSingleStat(MapleStat.MAXMP, 30000); - player.revertPlayerRates(); - player.setPlayerRates(); player.yellowMessage("Stats maxed out."); } else if (sub[0].equals("maxskills")) { for (MapleData skill_ : MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/" + "String.wz")).getData("Skill.img").getChildren()) { diff --git a/src/client/inventory/MapleInventory.java b/src/client/inventory/MapleInventory.java index bad9b2e329..73c1e8028c 100644 --- a/src/client/inventory/MapleInventory.java +++ b/src/client/inventory/MapleInventory.java @@ -199,8 +199,7 @@ public class MapleInventory implements Iterable { inventory.put(slot, item); if(MapleItemInformationProvider.getInstance().isRateCoupon(item.getItemId())) { - owner.revertCouponRates(); - owner.setCouponRates(); + owner.updateCouponRates(); } } @@ -208,8 +207,7 @@ public class MapleInventory implements Iterable { Item item = inventory.remove(slot); if(item != null && MapleItemInformationProvider.getInstance().isRateCoupon(item.getItemId())) { - owner.revertCouponRates(); - owner.setCouponRates(); + owner.updateCouponRates(); } } diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java index d1c2b01976..226d0b1e73 100644 --- a/src/constants/ServerConstants.java +++ b/src/constants/ServerConstants.java @@ -39,7 +39,7 @@ public class ServerConstants { public static final boolean USE_DEBUG_SHOW_INFO_EQPEXP = false; //Prints on the cmd all equip exp gain info. public static final boolean USE_MTS = false; public static final boolean USE_FAMILY_SYSTEM = false; - public static final boolean USE_PERMISSIVE_BUFFS = true; //WARNING: Allows players that does not have increased certain buff-type skills to use it's effect. Used mainly on buff-cast commands, however making this active may generate a source for possible client-edited exploits. + public static final boolean USE_PERMISSIVE_BUFFS = false; //WARNING: Allows players that does not have increased certain buff-type skills to use it's effect. Used mainly on buff-cast commands, however making this active may generate a source for possible client-edited exploits. public static final boolean USE_DUEY = true; public static final boolean USE_ITEM_SORT = true; public static final boolean USE_ITEM_SORT_BY_NAME = false; //Item sorting based on name rather than id. diff --git a/src/net/server/CouponWorker.java b/src/net/server/CouponWorker.java index 5e0a41c97b..cc1f1c7921 100644 --- a/src/net/server/CouponWorker.java +++ b/src/net/server/CouponWorker.java @@ -19,21 +19,11 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ + package net.server; -import java.util.Calendar; -import java.util.LinkedList; -import java.util.List; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; - -import constants.ServerConstants; -import tools.DatabaseConnection; - -import net.server.world.World; -import client.MapleCharacter; +import tools.FilePrinter; /** * @author Ronan @@ -46,7 +36,7 @@ public class CouponWorker implements Runnable { Server.getInstance().updateActiveCoupons(); Server.getInstance().commitActiveCoupons(); } catch(SQLException sqle) { - sqle.printStackTrace(); + FilePrinter.printError(FilePrinter.EXCEPTION_CAUGHT, "Unexpected SQL error: " + sqle.getMessage() + "\n\n"); } } } diff --git a/src/net/server/Server.java b/src/net/server/Server.java index b0fa5880f2..7bb5624a84 100644 --- a/src/net/server/Server.java +++ b/src/net/server/Server.java @@ -167,8 +167,7 @@ public class Server implements Runnable { for(MapleCharacter chr: world.getPlayerStorage().getAllCharacters()) { if(!chr.isLoggedin()) continue; - chr.revertCouponRates(); - chr.setCouponRates(); + chr.updateCouponRates(); } } } diff --git a/src/net/server/channel/handlers/MesoDropHandler.java b/src/net/server/channel/handlers/MesoDropHandler.java index 1e4a7d4052..ce7e900d48 100644 --- a/src/net/server/channel/handlers/MesoDropHandler.java +++ b/src/net/server/channel/handlers/MesoDropHandler.java @@ -32,21 +32,21 @@ import client.MapleClient; * @author Matze */ public final class MesoDropHandler extends AbstractMaplePacketHandler {//FIX - public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { - MapleCharacter player = c.getPlayer(); - if (!player.isAlive()) { - c.announce(MaplePacketCreator.enableActions()); - return; + public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { + MapleCharacter player = c.getPlayer(); + if (!player.isAlive()) { + c.announce(MaplePacketCreator.enableActions()); + return; + } + if (!player.canDropMeso()){ + player.announce(MaplePacketCreator.serverNotice(5, "Fast meso drop has been patched, cut that out. ;)")); + return; + } + slea.skip(4); + int meso = slea.readInt(); + if (meso <= player.getMeso() && meso > 9 && meso < 50001) { + player.gainMeso(-meso, false, true, false); + player.getMap().spawnMesoDrop(meso, player.getPosition(), player, player, true, (byte) 2); + } } - if (!player.canDropMeso()){ - player.announce(MaplePacketCreator.serverNotice(5, "Fast meso drop has been patched, cut that out. ;)")); - return; - } - slea.skip(4); - int meso = slea.readInt(); - if (meso <= player.getMeso() && meso > 9 && meso < 50001) { - player.gainMeso(-meso, false, true, false); - player.getMap().spawnMesoDrop(meso, player.getPosition(), player, player, true, (byte) 2); - } - } } \ No newline at end of file diff --git a/src/net/server/channel/handlers/PlayerLoggedinHandler.java b/src/net/server/channel/handlers/PlayerLoggedinHandler.java index cd265431bd..94a2cb8718 100644 --- a/src/net/server/channel/handlers/PlayerLoggedinHandler.java +++ b/src/net/server/channel/handlers/PlayerLoggedinHandler.java @@ -269,11 +269,10 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler { if (player.getMap().getHPDec() > 0) player.resetHpDecreaseTask(); - player.dispelBuffCoupons(); player.resetPlayerRates(); if(ServerConstants.USE_ADD_RATES_BY_LEVEL == true) player.setPlayerRates(); player.setWorldRates(); - player.setCouponRates(); + player.updateCouponRates(); } } diff --git a/src/net/server/world/World.java b/src/net/server/world/World.java index 79800b3a3b..f9416881d5 100644 --- a/src/net/server/world/World.java +++ b/src/net/server/world/World.java @@ -32,9 +32,10 @@ import constants.ServerConstants; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.Set; @@ -114,12 +115,15 @@ public class World { } public void setExpRate(int exp) { - //System.out.println("Setting server EXP Rate to " + exp * ServerConstants.EXP_RATE + "x."); - for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) { + List list = new LinkedList<>(getPlayerStorage().getAllCharacters()); + + for(MapleCharacter chr : list) { + if(!chr.isLoggedin()) continue; chr.revertWorldRates(); } this.exprate = exp; - for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) { + for(MapleCharacter chr : list) { + if(!chr.isLoggedin()) continue; chr.setWorldRates(); } } @@ -129,11 +133,15 @@ public class World { } public void setDropRate(int drop) { - for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) { + List list = new LinkedList<>(getPlayerStorage().getAllCharacters()); + + for(MapleCharacter chr : list) { + if(!chr.isLoggedin()) continue; chr.revertWorldRates(); } this.droprate = drop; - for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) { + for(MapleCharacter chr : list) { + if(!chr.isLoggedin()) continue; chr.setWorldRates(); } } @@ -143,11 +151,15 @@ public class World { } public void setMesoRate(int meso) { - for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) { + List list = new LinkedList<>(getPlayerStorage().getAllCharacters()); + + for(MapleCharacter chr : list) { + if(!chr.isLoggedin()) continue; chr.revertWorldRates(); } this.mesorate = meso; - for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) { + for(MapleCharacter chr : list) { + if(!chr.isLoggedin()) continue; chr.setWorldRates(); } } @@ -157,13 +169,7 @@ public class World { } public void setBossDropRate(int bossdrop) { - for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) { - chr.revertWorldRates(); - } this.bossdroprate = bossdrop; - for(MapleCharacter chr : getPlayerStorage().getAllCharacters()) { - chr.setWorldRates(); - } } public PlayerStorage getPlayerStorage() { diff --git a/src/server/MapleStatEffect.java b/src/server/MapleStatEffect.java index 0313730582..d9c2fb77e8 100644 --- a/src/server/MapleStatEffect.java +++ b/src/server/MapleStatEffect.java @@ -223,6 +223,40 @@ public class MapleStatEffect { addBuffStatPairToListIfNotZero(statups, MapleBuffStat.JUMP, Integer.valueOf(ret.jump)); addBuffStatPairToListIfNotZero(statups, MapleBuffStat.PYRAMID_PQ, Integer.valueOf(ret.berserk)); addBuffStatPairToListIfNotZero(statups, MapleBuffStat.BOOSTER, Integer.valueOf(ret.booster)); + + if(MapleItemInformationProvider.getInstance().isRateCoupon(sourceid)) { + switch(MapleDataTool.getInt("expR", source, 0)) { + case 1: + addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_EXP1, 1); + break; + + case 2: + addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_EXP2, 1); + break; + + case 3: + addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_EXP3, 1); + break; + + case 4: + addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_EXP4, 1); + break; + } + + switch(MapleDataTool.getInt("drpR", source, 0)) { + case 1: + addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_DRP1, 1); + break; + + case 2: + addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_DRP2, 1); + break; + + case 3: + addBuffStatPairToListIfNotZero(statups, MapleBuffStat.COUPON_DRP3, 1); + break; + } + } } MapleData ltd = source.getChildByPath("lt"); if (ltd != null) { @@ -928,7 +962,7 @@ public class MapleStatEffect { } private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary) { - if (!isMonsterRiding()) { + if (!isMonsterRiding() && !isCouponBuff()) { applyto.cancelEffect(this, true, -1); } @@ -1253,6 +1287,10 @@ public class MapleStatEffect { return skill && sourceid == ChiefBandit.CHAKRA; } + private boolean isCouponBuff() { + return MapleItemInformationProvider.getInstance().isRateCoupon(sourceid); + } + public boolean isMonsterRiding() { return skill && (sourceid % 10000000 == 1004 || sourceid == Corsair.BATTLE_SHIP || sourceid == Beginner.SPACESHIP || sourceid == Noblesse.SPACESHIP || sourceid == Beginner.YETI_MOUNT1 || sourceid == Beginner.YETI_MOUNT2 || sourceid == Beginner.WITCH_BROOMSTICK || sourceid == Beginner.BALROG_MOUNT diff --git a/wz/Item.wz/Cash/0521.img.xml b/wz/Item.wz/Cash/0521.img.xml index 7f1104f3b2..704708b144 100644 --- a/wz/Item.wz/Cash/0521.img.xml +++ b/wz/Item.wz/Cash/0521.img.xml @@ -22,8 +22,8 @@ - + @@ -46,8 +46,8 @@ - + @@ -70,8 +70,8 @@ - + @@ -94,8 +94,8 @@ - + @@ -118,8 +118,8 @@ - + @@ -142,8 +142,8 @@ - + @@ -163,8 +163,8 @@ - + @@ -184,8 +184,8 @@ - + @@ -205,8 +205,8 @@ - + @@ -226,8 +226,8 @@ - + @@ -247,8 +247,8 @@ - + @@ -273,8 +273,8 @@ - + @@ -299,8 +299,8 @@ - + @@ -325,8 +325,8 @@ - + @@ -351,8 +351,8 @@ - + @@ -377,8 +377,8 @@ - + @@ -401,8 +401,8 @@ - + @@ -422,8 +422,8 @@ - + @@ -448,8 +448,8 @@ - + @@ -472,8 +472,8 @@ - + @@ -493,8 +493,8 @@ - + @@ -519,8 +519,8 @@ - + @@ -543,8 +543,8 @@ - + @@ -564,8 +564,8 @@ - + @@ -590,8 +590,8 @@ - + @@ -616,8 +616,8 @@ - + @@ -642,8 +642,8 @@ - + @@ -668,8 +668,8 @@ - + @@ -695,8 +695,8 @@ - + @@ -722,8 +722,8 @@ - + diff --git a/wz/Item.wz/Cash/0536.img.xml b/wz/Item.wz/Cash/0536.img.xml index 025b4de0d6..fc50cd2174 100644 --- a/wz/Item.wz/Cash/0536.img.xml +++ b/wz/Item.wz/Cash/0536.img.xml @@ -22,8 +22,8 @@ - + @@ -48,8 +48,8 @@ - + @@ -74,8 +74,8 @@ - + @@ -100,8 +100,8 @@ - + @@ -126,8 +126,8 @@ - + @@ -152,8 +152,8 @@ - + @@ -178,8 +178,8 @@ - + @@ -204,8 +204,8 @@ - + @@ -230,8 +230,8 @@ - + @@ -256,8 +256,8 @@ - +