Fixed minor skill exploits + EXP system
Fixed minor issues regarding exploits with some skills available on the "empowerme" command, and fixed an error with the EXP system.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#Mon, 05 Jun 2017 18:49:35 -0300
|
||||
#Tue, 06 Jun 2017 11:24:55 -0300
|
||||
|
||||
|
||||
C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2=
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
dist/MapleSolaxia.jar
vendored
BIN
dist/MapleSolaxia.jar
vendored
Binary file not shown.
@@ -294,4 +294,9 @@ V
|
||||
|
||||
05 Junho 2016,
|
||||
Novo NPC Skillbook announcer: Abdula.
|
||||
Consertada a função que retorna se uma skill pertence ou não à árvore de habilidades do jogador.
|
||||
Consertada a função que retorna se uma skill pertence ou não à árvore de habilidades do jogador.
|
||||
|
||||
06 Junho 2016,
|
||||
Corrigido command empowerme.
|
||||
Corrigidos exploits relacionados a algumas das skills do empowerme.
|
||||
Corrigido possivel loop infinito no sistema de EXP.
|
||||
@@ -11,6 +11,18 @@
|
||||
</file>
|
||||
</editor-bookmarks>
|
||||
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
|
||||
<group/>
|
||||
<group>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/command/Commands.java</file>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/MapleStatEffect.java</file>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/constants/GameConstants.java</file>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/Server.java</file>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/Skill.java</file>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/constants/ServerConstants.java</file>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/handlers/login/CharlistRequestHandler.java</file>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/client/MapleCharacter.java</file>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/AbstractDealDamageHandler.java</file>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/CloseRangeDamageHandler.java</file>
|
||||
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/MaplePacketCreator.java</file>
|
||||
</group>
|
||||
</open-files>
|
||||
</project-private>
|
||||
|
||||
@@ -2087,15 +2087,22 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
int equip = (int)Math.min((long)((gain / 10) * pendantExp), Integer.MAX_VALUE);
|
||||
|
||||
long total = gain + equip + party;
|
||||
gainExpInternal(total, equip, party, show, inChat, white);
|
||||
}
|
||||
|
||||
private void gainExpInternal(long gain, int equip, int party, boolean show, boolean inChat, boolean white) {
|
||||
long total = gain;
|
||||
if (level < getMaxLevel()) {
|
||||
if ((long) this.exp.get() + total > (long) Integer.MAX_VALUE) {
|
||||
int gainFirst = ExpTable.getExpNeededForLevel(level) - this.exp.get();
|
||||
total -= gainFirst + 1;
|
||||
this.gainExp(gainFirst + 1, party, false, inChat, white);
|
||||
long leftover = 0;
|
||||
long nextExp = exp.get() + total;
|
||||
|
||||
if (nextExp > (long)Integer.MAX_VALUE) {
|
||||
total = Integer.MAX_VALUE - exp.get();
|
||||
leftover = nextExp - Integer.MAX_VALUE;
|
||||
}
|
||||
updateSingleStat(MapleStat.EXP, this.exp.addAndGet((int)Math.min(total, Integer.MAX_VALUE)));
|
||||
updateSingleStat(MapleStat.EXP, exp.addAndGet((int)total));
|
||||
if (show && gain != 0) {
|
||||
client.announce(MaplePacketCreator.getShowExpGain(gain, equip, party, inChat, white));
|
||||
client.announce(MaplePacketCreator.getShowExpGain((int)Math.min(gain, Integer.MAX_VALUE), equip, party, inChat, white));
|
||||
}
|
||||
while (exp.get() >= ExpTable.getExpNeededForLevel(level)) {
|
||||
levelUp(true);
|
||||
@@ -2105,6 +2112,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(leftover > 0) gainExpInternal(leftover, equip, party, false, inChat, white);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -791,10 +791,10 @@ public class Commands {
|
||||
} else if (sub[0].equals("buffmap")) {
|
||||
for (MapleCharacter chr : player.getMap().getCharacters()){
|
||||
//GM Skills : Haste(Super) - Holy Symbol - Bless - Hyper Body - Echo of Hero
|
||||
SkillFactory.getSkill(4101004).getEffect(SkillFactory.getSkill(4101004).getMaxLevel()).applyTo(chr);
|
||||
SkillFactory.getSkill(2311003).getEffect(SkillFactory.getSkill(2311003).getMaxLevel()).applyTo(chr);
|
||||
SkillFactory.getSkill(1301007).getEffect(SkillFactory.getSkill(1301007).getMaxLevel()).applyTo(chr);
|
||||
SkillFactory.getSkill(2301004).getEffect(SkillFactory.getSkill(2301004).getMaxLevel()).applyTo(chr);
|
||||
SkillFactory.getSkill(9101001).getEffect(SkillFactory.getSkill(9101001).getMaxLevel()).applyTo(chr);
|
||||
SkillFactory.getSkill(9101002).getEffect(SkillFactory.getSkill(9101002).getMaxLevel()).applyTo(chr);
|
||||
SkillFactory.getSkill(9101003).getEffect(SkillFactory.getSkill(9101003).getMaxLevel()).applyTo(chr);
|
||||
SkillFactory.getSkill(9101008).getEffect(SkillFactory.getSkill(9101008).getMaxLevel()).applyTo(chr);
|
||||
SkillFactory.getSkill(1005).getEffect(SkillFactory.getSkill(1005).getMaxLevel()).applyTo(chr);
|
||||
chr.setHp(chr.getMaxHp());
|
||||
chr.updateSingleStat(MapleStat.HP, chr.getMaxHp());
|
||||
@@ -847,13 +847,14 @@ public class Commands {
|
||||
Equip eu = (Equip) equip.getItem(i);
|
||||
if(eu == null) continue;
|
||||
|
||||
short incval= (short)newStat;
|
||||
short incval = (short)newStat;
|
||||
eu.setWdef(incval);
|
||||
eu.setAcc(incval);
|
||||
eu.setAvoid(incval);
|
||||
eu.setJump(incval);
|
||||
eu.setMatk(incval);
|
||||
eu.setMdef(incval);
|
||||
eu.setHp(incval);
|
||||
eu.setMp(incval);
|
||||
eu.setSpeed(incval);
|
||||
eu.setHands(incval);
|
||||
@@ -1376,7 +1377,7 @@ public class Commands {
|
||||
}
|
||||
}
|
||||
player.yellowMessage("Skills maxed out.");
|
||||
} else if (sub[0].equals("mesos")) {
|
||||
} else if (sub[0].equals("mesos")) {
|
||||
if (sub.length >= 2) {
|
||||
player.gainMeso(Integer.parseInt(sub[1]), true);
|
||||
}
|
||||
@@ -1930,6 +1931,27 @@ public class Commands {
|
||||
} else if (sub.length > 1) {
|
||||
time *= Integer.parseInt(sub[1]);
|
||||
}
|
||||
|
||||
if(time > 1) {
|
||||
int seconds = (int) (time / 1000) % 60 ;
|
||||
int minutes = (int) ((time / (1000*60)) % 60);
|
||||
int hours = (int) ((time / (1000*60*60)) % 24);
|
||||
int days = (int) ((time / (1000*60*60*24)));
|
||||
|
||||
String strTime = "";
|
||||
if(days > 0) strTime += days + " days, ";
|
||||
if(hours > 0) strTime += hours + " hours, ";
|
||||
strTime += minutes + " minutes, ";
|
||||
strTime += seconds + " seconds";
|
||||
|
||||
for(World w : Server.getInstance().getWorlds()) {
|
||||
for(MapleCharacter chr: w.getPlayerStorage().getAllCharacters()) {
|
||||
chr.dropMessage("Server is undergoing maintenance process, and will be shutdown in " + strTime + ". Prepare yourself to quit safely in the mean time.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TimerManager.getInstance().schedule(Server.getInstance().shutdown(false), time);
|
||||
break;
|
||||
case "face":
|
||||
|
||||
@@ -94,10 +94,10 @@ public class GameConstants {
|
||||
if(!isInBranchJobTree(skillJob, jobId, 0)) {
|
||||
for(int i = 1; i <= 3; i++) {
|
||||
if(hasDivergedBranchJobTree(skillJob, jobId, i)) return false;
|
||||
if(isInBranchJobTree(skillJob, jobId, i)) return true;
|
||||
if(isInBranchJobTree(skillJob, jobId, i)) return (skillJob <= jobId);
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
return (skillJob <= jobId);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -39,6 +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_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.
|
||||
|
||||
@@ -272,24 +272,28 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
|
||||
player.checkMonsterAggro(monster);
|
||||
if (player.getBuffedValue(MapleBuffStat.PICKPOCKET) != null && (attack.skill == 0 || attack.skill == Rogue.DOUBLE_STAB || attack.skill == Bandit.SAVAGE_BLOW || attack.skill == ChiefBandit.ASSAULTER || attack.skill == ChiefBandit.BAND_OF_THIEVES || attack.skill == Shadower.ASSASSINATE || attack.skill == Shadower.TAUNT || attack.skill == Shadower.BOOMERANG_STEP)) {
|
||||
Skill pickpocket = SkillFactory.getSkill(ChiefBandit.PICKPOCKET);
|
||||
int delay = 0;
|
||||
final int maxmeso = player.getBuffedValue(MapleBuffStat.PICKPOCKET).intValue();
|
||||
for (Integer eachd : onedList) {
|
||||
eachd += Integer.MAX_VALUE;
|
||||
if (pickpocket.getEffect(player.getSkillLevel(pickpocket)).makeChanceResult()) {
|
||||
final Integer eachdf;
|
||||
if(eachd < 0)
|
||||
eachdf = eachd + Integer.MAX_VALUE;
|
||||
else
|
||||
eachdf = eachd;
|
||||
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.getMap().spawnMesoDrop(Math.min((int) Math.max(((double) eachdf / (double) 20000) * (double) maxmeso, (double) 1), maxmeso), new Point((int) (monster.getPosition().getX() + Randomizer.nextInt(100) - 50), (int) (monster.getPosition().getY())), monster, player, true, (byte) 2);
|
||||
}
|
||||
}, delay);
|
||||
delay += 100;
|
||||
int picklv = (player.getSkillLevel(pickpocket) > 0 || !ServerConstants.USE_PERMISSIVE_BUFFS) ? player.getSkillLevel(pickpocket) : pickpocket.getMaxLevel();
|
||||
if(picklv > 0) {
|
||||
int delay = 0;
|
||||
final int maxmeso = player.getBuffedValue(MapleBuffStat.PICKPOCKET).intValue();
|
||||
for (Integer eachd : onedList) {
|
||||
eachd += Integer.MAX_VALUE;
|
||||
|
||||
if (pickpocket.getEffect(picklv).makeChanceResult()) {
|
||||
final Integer eachdf;
|
||||
if(eachd < 0)
|
||||
eachdf = eachd + Integer.MAX_VALUE;
|
||||
else
|
||||
eachdf = eachd;
|
||||
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.getMap().spawnMesoDrop(Math.min((int) Math.max(((double) eachdf / (double) 20000) * (double) maxmeso, (double) 1), maxmeso), new Point((int) (monster.getPosition().getX() + Randomizer.nextInt(100) - 50), (int) (monster.getPosition().getY())), monster, player, true, (byte) 2);
|
||||
}
|
||||
}, delay);
|
||||
delay += 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (attack.skill == Marauder.ENERGY_DRAIN || attack.skill == ThunderBreaker.ENERGY_DRAIN || attack.skill == NightWalker.VAMPIRE || attack.skill == Assassin.DRAIN) {
|
||||
@@ -648,14 +652,16 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
|
||||
} else {
|
||||
// Normal Combo
|
||||
int skillLv = chr.getSkillLevel(oid);
|
||||
if(skillLv <= 0) skillLv = SkillFactory.getSkill(oid).getMaxLevel();
|
||||
if(skillLv <= 0 && ServerConstants.USE_PERMISSIVE_BUFFS) skillLv = SkillFactory.getSkill(oid).getMaxLevel();
|
||||
|
||||
MapleStatEffect ceffect = SkillFactory.getSkill(oid).getEffect(skillLv);
|
||||
calcDmgMax = (int) Math.floor(calcDmgMax * (ceffect.getDamage() + 50) / 100 + Math.floor((comboBuff - 1) * (skillLv / 6)) / 100);
|
||||
if(skillLv > 0) {
|
||||
MapleStatEffect ceffect = SkillFactory.getSkill(oid).getEffect(skillLv);
|
||||
calcDmgMax = (int) Math.floor(calcDmgMax * (ceffect.getDamage() + 50) / 100 + Math.floor((comboBuff - 1) * (skillLv / 6)) / 100);
|
||||
}
|
||||
}
|
||||
|
||||
if(GameConstants.isFinisherSkill(ret.skill)) {
|
||||
// Finisher skills do more damage based on how many orbs the player has.
|
||||
// Finisher skills do more damage based on how many orbs the player has.
|
||||
int orbs = comboBuff - 1;
|
||||
if(orbs == 2)
|
||||
calcDmgMax *= 1.2;
|
||||
|
||||
@@ -39,6 +39,7 @@ import client.MapleStat;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import constants.GameConstants;
|
||||
import constants.ServerConstants;
|
||||
import constants.skills.Crusader;
|
||||
import constants.skills.DawnWarrior;
|
||||
import constants.skills.DragonKnight;
|
||||
@@ -88,25 +89,30 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
ceffect = advcombo.getEffect(advComboSkillLevel);
|
||||
} else {
|
||||
int comboLv = player.getSkillLevel(combo);
|
||||
if(comboLv <= 0) comboLv = SkillFactory.getSkill(oid).getMaxLevel();
|
||||
ceffect = combo.getEffect(comboLv);
|
||||
}
|
||||
if (orbcount < ceffect.getX() + 1) {
|
||||
int neworbcount = orbcount + 1;
|
||||
if (advComboSkillLevel > 0 && ceffect.makeChanceResult()) {
|
||||
if (neworbcount <= ceffect.getX()) {
|
||||
neworbcount++;
|
||||
}
|
||||
}
|
||||
if(comboLv <= 0 && ServerConstants.USE_PERMISSIVE_BUFFS) comboLv = SkillFactory.getSkill(oid).getMaxLevel();
|
||||
|
||||
int olv = player.getSkillLevel(oid);
|
||||
if(olv <= 0) olv = SkillFactory.getSkill(oid).getMaxLevel();
|
||||
int duration = combo.getEffect(olv).getDuration();
|
||||
List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.COMBO, neworbcount));
|
||||
player.setBuffedValue(MapleBuffStat.COMBO, neworbcount);
|
||||
duration -= (int) (System.currentTimeMillis() - player.getBuffedStarttime(MapleBuffStat.COMBO));
|
||||
c.announce(MaplePacketCreator.giveBuff(oid, duration, stat));
|
||||
player.getMap().broadcastMessage(player, MaplePacketCreator.giveForeignBuff(player.getId(), stat), false);
|
||||
if(comboLv > 0) ceffect = combo.getEffect(comboLv);
|
||||
else ceffect = null;
|
||||
}
|
||||
if(ceffect != null) {
|
||||
if (orbcount < ceffect.getX() + 1) {
|
||||
int neworbcount = orbcount + 1;
|
||||
if (advComboSkillLevel > 0 && ceffect.makeChanceResult()) {
|
||||
if (neworbcount <= ceffect.getX()) {
|
||||
neworbcount++;
|
||||
}
|
||||
}
|
||||
|
||||
int olv = player.getSkillLevel(oid);
|
||||
if(olv <= 0) olv = SkillFactory.getSkill(oid).getMaxLevel();
|
||||
|
||||
int duration = combo.getEffect(olv).getDuration();
|
||||
List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.COMBO, neworbcount));
|
||||
player.setBuffedValue(MapleBuffStat.COMBO, neworbcount);
|
||||
duration -= (int) (System.currentTimeMillis() - player.getBuffedStarttime(MapleBuffStat.COMBO));
|
||||
c.announce(MaplePacketCreator.giveBuff(oid, duration, stat));
|
||||
player.getMap().broadcastMessage(player, MaplePacketCreator.giveForeignBuff(player.getId(), stat), false);
|
||||
}
|
||||
}
|
||||
} else if (player.getSkillLevel(player.isCygnus() ? SkillFactory.getSkill(15100004) : SkillFactory.getSkill(5110001)) > 0 && (player.getJob().isA(MapleJob.MARAUDER) || player.getJob().isA(MapleJob.THUNDERBREAKER2))) {
|
||||
for (int i = 0; i < attack.numAttacked; i++) {
|
||||
|
||||
@@ -708,9 +708,11 @@ public class MapleStatEffect {
|
||||
AutobanFactory.MPCON.addPoint(applyfrom.getAutobanManager(), "mpCon hack for skill:" + sourceid + "; Player MP: " + applyto.getMp() + " MP Needed: " + getMpCon());
|
||||
} */
|
||||
if (hpchange != 0) {
|
||||
if (hpchange < 0 && (-hpchange) >= applyto.getHp() && (!applyto.hasDisease(MapleDisease.ZOMBIFY) || hpCon == 0)) {
|
||||
applyto.getClient().announce(MaplePacketCreator.enableActions());
|
||||
return false;
|
||||
if (hpchange < 0 && (-hpchange) >= applyto.getHp() && (!applyto.hasDisease(MapleDisease.ZOMBIFY) || hpCon > 0)) {
|
||||
if(!ServerConstants.USE_PERMISSIVE_BUFFS) {
|
||||
applyto.getClient().announce(MaplePacketCreator.enableActions());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int newHp = applyto.getHp() + hpchange;
|
||||
if (newHp < 1) {
|
||||
@@ -722,8 +724,13 @@ public class MapleStatEffect {
|
||||
int newMp = applyto.getMp() + mpchange;
|
||||
if (mpchange != 0) {
|
||||
if (mpchange < 0 && -mpchange > applyto.getMp()) {
|
||||
applyto.getClient().announce(MaplePacketCreator.enableActions());
|
||||
return false;
|
||||
if(!ServerConstants.USE_PERMISSIVE_BUFFS) {
|
||||
applyto.getClient().announce(MaplePacketCreator.enableActions());
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
newMp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
applyto.setMp(newMp);
|
||||
|
||||
Reference in New Issue
Block a user