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:
ronancpl
2017-06-06 11:48:32 -03:00
parent 83d20e3c8b
commit dbac58e871
36 changed files with 130 additions and 62 deletions

View File

@@ -1,4 +1,4 @@
#Mon, 05 Jun 2017 18:49:35 -0300
#Tue, 06 Jun 2017 11:24:55 -0300
C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2=

BIN
dist/MapleSolaxia.jar vendored

Binary file not shown.

View File

@@ -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.

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -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":

View File

@@ -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;

View File

@@ -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.

View File

@@ -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;

View File

@@ -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++) {

View File

@@ -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);