Dynamic World/Channel shutdown + Equip levels on Duey + AP/SP patch
Implemented dynamic world/channel shutdown, coupling with the dynamic deployment from last commit rendering on a fully automated world/channel management. Fixed some spawned mobs not being properly registered on events. Implemented a respawn mechanic sensitive to number of players on map. More mobs will spawn the greater the number of players is. Server flag: USE_ENABLE_FULL_RESPAWN = false. Implemented a mechanic for delayed mob loot drops, on which the delay is determined by the death animation duration. Server flag: USE_SPAWN_LOOT_ON_ANIMATION = true. Fixed EIM being disposed incorrectly when the dispose is called through scripts. Protected concurrently AP and SP distribution handlers. Slightly improved HealOvertimeHandler performance. Fixed Duey not propagating equipment level and experience when transfering items. Buyback now has a short grace period, granting the returning player time for decision making (players won't die right away, rather sticks at 1HP). Reviewed item monitor task not properly protected concurrently. Fixed some issues with ropes on some Kampung Village maps. Fixed "maxhpmp" command allowing to pass negative values.
This commit is contained in:
@@ -29,6 +29,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
@@ -39,6 +40,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
import net.server.audit.locks.MonitoredReentrantReadWriteLock;
|
||||
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
|
||||
|
||||
import net.MapleServerHandler;
|
||||
import net.mina.MapleCodecFactory;
|
||||
@@ -95,6 +97,7 @@ public final class Channel {
|
||||
private OverallScheduler channelSchedulers[] = new OverallScheduler[4];
|
||||
private Map<Integer, MapleHiredMerchant> hiredMerchants = new HashMap<>();
|
||||
private final Map<Integer, Integer> storedVars = new HashMap<>();
|
||||
private Set<Integer> playersAway = new HashSet<>();
|
||||
private List<MapleExpedition> expeditions = new ArrayList<>();
|
||||
private List<MapleExpeditionType> expedType = new ArrayList<>();
|
||||
private MapleEvent event;
|
||||
@@ -128,7 +131,7 @@ public final class Channel {
|
||||
|
||||
private MonitoredReentrantLock faceLock[] = new MonitoredReentrantLock[4];
|
||||
|
||||
private MonitoredReentrantLock lock = new MonitoredReentrantLock(MonitoredLockType.CHANNEL, true);
|
||||
private MonitoredReentrantLock lock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHANNEL, true);
|
||||
|
||||
public Channel(final int world, final int channel, long startTime) {
|
||||
this.world = world;
|
||||
@@ -165,7 +168,7 @@ public final class Channel {
|
||||
}
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
faceLock[i] = new MonitoredReentrantLock(MonitoredLockType.CHANNEL_FACEEXPRS, true);
|
||||
faceLock[i] = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHANNEL_FACEEXPRS, true);
|
||||
|
||||
mobStatusSchedulers[i] = new MobStatusScheduler();
|
||||
mobAnimationSchedulers[i] = new MobAnimationScheduler();
|
||||
@@ -208,6 +211,7 @@ public final class Channel {
|
||||
eventSM = null;
|
||||
|
||||
closeChannelSchedules();
|
||||
players = null;
|
||||
|
||||
acceptor.unbind();
|
||||
|
||||
@@ -263,10 +267,10 @@ public final class Channel {
|
||||
channelSchedulers[i] = null;
|
||||
}
|
||||
|
||||
faceLock[i].dispose();
|
||||
faceLock[i] = faceLock[i].dispose();
|
||||
}
|
||||
|
||||
lock.dispose();
|
||||
lock = lock.dispose();
|
||||
}
|
||||
|
||||
private void closeAllMerchants() {
|
||||
@@ -291,7 +295,7 @@ public final class Channel {
|
||||
public int getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
|
||||
public void addPlayer(MapleCharacter chr) {
|
||||
players.addPlayer(chr);
|
||||
chr.announce(MaplePacketCreator.serverMessage(serverMessage));
|
||||
@@ -355,6 +359,18 @@ public final class Channel {
|
||||
}
|
||||
return partym;
|
||||
}
|
||||
|
||||
public void insertPlayerAway(int chrId) { // either they in CS or MTS
|
||||
playersAway.add(chrId);
|
||||
}
|
||||
|
||||
public void removePlayerAway(int chrId) {
|
||||
playersAway.remove(chrId);
|
||||
}
|
||||
|
||||
public boolean canUninstall() {
|
||||
return players.getSize() == 0 && playersAway.isEmpty();
|
||||
}
|
||||
|
||||
public class respawnMaps implements Runnable {
|
||||
|
||||
|
||||
@@ -152,26 +152,27 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
|
||||
AutobanFactory.MPCON.addPoint(player.getAutobanManager(), "Skill: " + attack.skill + "; Player MP: " + player.getMp() + "; MP Needed: " + attackEffect.getMpCon());
|
||||
}
|
||||
|
||||
int mobCount = attackEffect.getMobCount();
|
||||
if (attack.skill != Cleric.HEAL) {
|
||||
if (player.isAlive()) {
|
||||
if(attack.skill == NightWalker.POISON_BOMB) // Poison Bomb
|
||||
if(attack.skill == NightWalker.POISON_BOMB) {// Poison Bomb
|
||||
attackEffect.applyTo(player, new Point(attack.position.x, attack.position.y));
|
||||
else if(attack.skill != Aran.BODY_PRESSURE) // prevent BP refreshing
|
||||
} else if(attack.skill != Aran.BODY_PRESSURE) {// prevent BP refreshing
|
||||
attackEffect.applyTo(player);
|
||||
|
||||
if (attack.skill == DawnWarrior.FINAL_ATTACK || attack.skill == Page.FINAL_ATTACK_BW || attack.skill == Page.FINAL_ATTACK_SWORD || attack.skill == Fighter.FINAL_ATTACK_SWORD
|
||||
|| attack.skill == Fighter.FINAL_ATTACK_AXE || attack.skill == Spearman.FINAL_ATTACK_SPEAR || attack.skill == Spearman.FINAL_ATTACK_POLEARM || attack.skill == WindArcher.FINAL_ATTACK
|
||||
|| attack.skill == DawnWarrior.FINAL_ATTACK || attack.skill == Hunter.FINAL_ATTACK || attack.skill == Crossbowman.FINAL_ATTACK) {
|
||||
|
||||
mobCount = 15;//:(
|
||||
} else if (attack.skill == Aran.HIDDEN_FULL_DOUBLE || attack.skill == Aran.HIDDEN_FULL_TRIPLE || attack.skill == Aran.HIDDEN_OVER_DOUBLE || attack.skill == Aran.HIDDEN_OVER_TRIPLE) {
|
||||
mobCount = 12;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
player.getClient().announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
}
|
||||
int mobCount = attackEffect.getMobCount();
|
||||
if (attack.skill == DawnWarrior.FINAL_ATTACK || attack.skill == Page.FINAL_ATTACK_BW || attack.skill == Page.FINAL_ATTACK_SWORD || attack.skill == Fighter.FINAL_ATTACK_SWORD
|
||||
|| attack.skill == Fighter.FINAL_ATTACK_AXE || attack.skill == Spearman.FINAL_ATTACK_SPEAR || attack.skill == Spearman.FINAL_ATTACK_POLEARM || attack.skill == WindArcher.FINAL_ATTACK
|
||||
|| attack.skill == DawnWarrior.FINAL_ATTACK || attack.skill == Hunter.FINAL_ATTACK || attack.skill == Crossbowman.FINAL_ATTACK) {
|
||||
mobCount = 15;//:(
|
||||
}
|
||||
|
||||
if (attack.skill == Aran.HIDDEN_FULL_DOUBLE || attack.skill == Aran.HIDDEN_FULL_TRIPLE || attack.skill == Aran.HIDDEN_OVER_DOUBLE || attack.skill == Aran.HIDDEN_OVER_TRIPLE) {
|
||||
mobCount = 12;
|
||||
}
|
||||
|
||||
if (attack.numAttacked > mobCount) {
|
||||
AutobanFactory.MOB_COUNT.autoban(player, "Skill: " + attack.skill + "; Count: " + attack.numAttacked + " Max: " + attackEffect.getMobCount());
|
||||
|
||||
@@ -21,22 +21,9 @@
|
||||
*/
|
||||
package net.server.channel.handlers;
|
||||
|
||||
import constants.ServerConstants;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleJob;
|
||||
import client.MapleStat;
|
||||
import client.autoban.AutobanFactory;
|
||||
import client.inventory.Equip;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.MapleInventory;
|
||||
import client.inventory.MapleInventoryType;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import client.processor.AssignAPProcessor;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/**
|
||||
@@ -45,382 +32,8 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
||||
*/
|
||||
public class AutoAssignHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
private static int getNthHighestStat(List<Short> statList, short rank) { // ranks from 0
|
||||
return(statList.size() <= rank ? 0 : statList.get(rank));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
if (chr.getRemainingAp() < 1) return;
|
||||
|
||||
int[] statGain = new int[4];
|
||||
int[] statEqpd = new int[4];
|
||||
statGain[0] = 0; statGain[1] = 0; statGain[2] = 0; statGain[3] = 0;
|
||||
|
||||
slea.skip(8);
|
||||
|
||||
if(ServerConstants.USE_SERVER_AUTOASSIGNER) {
|
||||
// --------- Ronan Lana's AUTOASSIGNER ---------
|
||||
// This method excels for assigning APs in such a way to cover all equipments AP requirements.
|
||||
byte opt = slea.readByte(); // useful for pirate autoassigning
|
||||
|
||||
int str = 0, dex = 0, luk = 0, int_ = 0;
|
||||
List<Short> eqpStrList = new ArrayList<>();
|
||||
List<Short> eqpDexList = new ArrayList<>();
|
||||
List<Short> eqpLukList = new ArrayList<>();
|
||||
|
||||
MapleInventory iv = chr.getInventory(MapleInventoryType.EQUIPPED);
|
||||
Collection<Item> equippedC = iv.list();
|
||||
Equip nEquip;
|
||||
|
||||
for (Item item : equippedC) { //selecting the biggest AP value of each stat from each equipped item.
|
||||
nEquip = (Equip)item;
|
||||
if(nEquip.getStr() > 0) eqpStrList.add(nEquip.getStr());
|
||||
str += nEquip.getStr();
|
||||
|
||||
if(nEquip.getDex() > 0) eqpDexList.add(nEquip.getDex());
|
||||
dex += nEquip.getDex();
|
||||
|
||||
if(nEquip.getLuk() > 0) eqpLukList.add(nEquip.getLuk());
|
||||
luk += nEquip.getLuk();
|
||||
|
||||
//if(nEquip.getInt() > 0) eqpIntList.add(nEquip.getInt()); //not needed...
|
||||
int_ += nEquip.getInt();
|
||||
}
|
||||
|
||||
statEqpd[0] = str;
|
||||
statEqpd[1] = dex;
|
||||
statEqpd[2] = luk;
|
||||
statEqpd[3] = int_;
|
||||
|
||||
Collections.sort(eqpStrList, Collections.reverseOrder());
|
||||
Collections.sort(eqpDexList, Collections.reverseOrder());
|
||||
Collections.sort(eqpLukList, Collections.reverseOrder());
|
||||
|
||||
//Autoassigner looks up the 1st/2nd placed equips for their stats to calculate the optimal upgrade.
|
||||
int eqpStr = getNthHighestStat(eqpStrList, (short) 0) + getNthHighestStat(eqpStrList, (short) 1);
|
||||
int eqpDex = getNthHighestStat(eqpDexList, (short) 0) + getNthHighestStat(eqpDexList, (short) 1);
|
||||
int eqpLuk = getNthHighestStat(eqpLukList, (short) 0) + getNthHighestStat(eqpLukList, (short) 1);
|
||||
|
||||
//c.getPlayer().message("----------------------------------------");
|
||||
//c.getPlayer().message("SDL: s" + eqpStr + " d" + eqpDex + " l" + eqpLuk + " BASE STATS --> STR: " + chr.getStr() + " DEX: " + chr.getDex() + " INT: " + chr.getInt() + " LUK: " + chr.getLuk());
|
||||
//c.getPlayer().message("SUM EQUIP STATS -> STR: " + str + " DEX: " + dex + " LUK: " + luk + " INT: " + int_);
|
||||
|
||||
MapleJob stance = c.getPlayer().getJobStyle(opt);
|
||||
int prStat = 0, scStat = 0, trStat = 0, temp, tempAp = chr.getRemainingAp(), CAP;
|
||||
|
||||
MapleStat primary, secondary, tertiary = MapleStat.LUK;
|
||||
switch(stance) {
|
||||
case MAGICIAN:
|
||||
CAP = 165;
|
||||
scStat = (chr.getLevel() + 3) - (chr.getLuk() + luk - eqpLuk);
|
||||
if(scStat < 0) scStat = 0;
|
||||
scStat = Math.min(scStat, tempAp);
|
||||
|
||||
if(tempAp > scStat) tempAp -= scStat;
|
||||
else tempAp = 0;
|
||||
|
||||
prStat = tempAp;
|
||||
int_ = prStat;
|
||||
luk = scStat;
|
||||
str = 0; dex = 0;
|
||||
|
||||
if(luk + chr.getLuk() > CAP) {
|
||||
temp = luk + chr.getLuk() - CAP;
|
||||
luk -= temp;
|
||||
int_ += temp;
|
||||
}
|
||||
|
||||
primary = MapleStat.INT;
|
||||
secondary = MapleStat.LUK;
|
||||
tertiary = MapleStat.DEX;
|
||||
|
||||
break;
|
||||
|
||||
case BOWMAN:
|
||||
CAP = 125;
|
||||
scStat = (chr.getLevel() + 5) - (chr.getStr() + str - eqpStr);
|
||||
if(scStat < 0) scStat = 0;
|
||||
scStat = Math.min(scStat, tempAp);
|
||||
|
||||
if(tempAp > scStat) tempAp -= scStat;
|
||||
else tempAp = 0;
|
||||
|
||||
prStat = tempAp;
|
||||
dex = prStat;
|
||||
str = scStat;
|
||||
int_ = 0; luk = 0;
|
||||
|
||||
if(str + chr.getStr() > CAP) {
|
||||
temp = str + chr.getStr() - CAP;
|
||||
str -= temp;
|
||||
dex += temp;
|
||||
}
|
||||
|
||||
primary = MapleStat.DEX;
|
||||
secondary = MapleStat.STR;
|
||||
|
||||
break;
|
||||
|
||||
case GUNSLINGER:
|
||||
case CROSSBOWMAN:
|
||||
CAP = 120;
|
||||
scStat = chr.getLevel() - (chr.getStr() + str - eqpStr);
|
||||
if(scStat < 0) scStat = 0;
|
||||
scStat = Math.min(scStat, tempAp);
|
||||
|
||||
if(tempAp > scStat) tempAp -= scStat;
|
||||
else tempAp = 0;
|
||||
|
||||
prStat = tempAp;
|
||||
dex = prStat;
|
||||
str = scStat;
|
||||
int_ = 0; luk = 0;
|
||||
|
||||
if(str + chr.getStr() > CAP) {
|
||||
temp = str + chr.getStr() - CAP;
|
||||
str -= temp;
|
||||
dex += temp;
|
||||
}
|
||||
|
||||
primary = MapleStat.DEX;
|
||||
secondary = MapleStat.STR;
|
||||
|
||||
break;
|
||||
|
||||
case THIEF:
|
||||
CAP = 160;
|
||||
|
||||
scStat = 0;
|
||||
if(chr.getDex() < 80) {
|
||||
scStat = (2 * chr.getLevel()) - (chr.getDex() + dex - eqpDex);
|
||||
if(scStat < 0) scStat = 0;
|
||||
|
||||
scStat = Math.min(80 - chr.getDex(), scStat);
|
||||
scStat = Math.min(tempAp, scStat);
|
||||
tempAp -= scStat;
|
||||
}
|
||||
|
||||
temp = (chr.getLevel() + 40) - Math.max(80, scStat + chr.getDex() + dex - eqpDex);
|
||||
if(temp < 0) temp = 0;
|
||||
temp = Math.min(tempAp, temp);
|
||||
scStat += temp;
|
||||
tempAp -= temp;
|
||||
|
||||
// thieves will upgrade STR as well only if a level-based threshold is reached.
|
||||
if(chr.getStr() >= Math.max(13, (int)(0.4 * chr.getLevel()))) {
|
||||
if(chr.getStr() < 50) {
|
||||
trStat = (chr.getLevel() - 10) - (chr.getStr() + str - eqpStr);
|
||||
if(trStat < 0) trStat = 0;
|
||||
|
||||
trStat = Math.min(50 - chr.getStr(), trStat);
|
||||
trStat = Math.min(tempAp, trStat);
|
||||
tempAp -= trStat;
|
||||
}
|
||||
|
||||
temp = (20 + (chr.getLevel() / 2)) - Math.max(50, trStat + chr.getStr() + str - eqpStr);
|
||||
if(temp < 0) temp = 0;
|
||||
temp = Math.min(tempAp, temp);
|
||||
trStat += temp;
|
||||
tempAp -= temp;
|
||||
}
|
||||
|
||||
prStat = tempAp;
|
||||
luk = prStat;
|
||||
dex = scStat;
|
||||
str = trStat;
|
||||
int_ = 0;
|
||||
|
||||
if(dex + chr.getDex() > CAP) {
|
||||
temp = dex + chr.getDex() - CAP;
|
||||
dex -= temp;
|
||||
luk += temp;
|
||||
}
|
||||
if(str + chr.getStr() > CAP) {
|
||||
temp = str + chr.getStr() - CAP;
|
||||
str -= temp;
|
||||
luk += temp;
|
||||
}
|
||||
|
||||
primary = MapleStat.LUK;
|
||||
secondary = MapleStat.DEX;
|
||||
tertiary = MapleStat.STR;
|
||||
|
||||
break;
|
||||
|
||||
case BRAWLER:
|
||||
CAP = 120;
|
||||
|
||||
scStat = chr.getLevel() - (chr.getDex() + dex - eqpDex);
|
||||
if(scStat < 0) scStat = 0;
|
||||
scStat = Math.min(scStat, tempAp);
|
||||
|
||||
if(tempAp > scStat) tempAp -= scStat;
|
||||
else tempAp = 0;
|
||||
|
||||
prStat = tempAp;
|
||||
str = prStat;
|
||||
dex = scStat;
|
||||
int_ = 0; luk = 0;
|
||||
|
||||
if(dex + chr.getDex() > CAP) {
|
||||
temp = dex + chr.getDex() - CAP;
|
||||
dex -= temp;
|
||||
str += temp;
|
||||
}
|
||||
|
||||
primary = MapleStat.STR;
|
||||
secondary = MapleStat.DEX;
|
||||
|
||||
break;
|
||||
|
||||
default: //warrior, beginner, ...
|
||||
CAP = 80;
|
||||
|
||||
scStat = ((2 * chr.getLevel()) / 3) - (chr.getDex() + dex - eqpDex);
|
||||
if(scStat < 0) scStat = 0;
|
||||
scStat = Math.min(scStat, tempAp);
|
||||
|
||||
if(tempAp > scStat) tempAp -= scStat;
|
||||
else tempAp = 0;
|
||||
|
||||
prStat = tempAp;
|
||||
str = prStat;
|
||||
dex = scStat;
|
||||
int_ = 0; luk = 0;
|
||||
|
||||
if(dex + chr.getDex() > CAP) {
|
||||
temp = dex + chr.getDex() - CAP;
|
||||
dex -= temp;
|
||||
str += temp;
|
||||
}
|
||||
|
||||
primary = MapleStat.STR;
|
||||
secondary = MapleStat.DEX;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
int extras = 0;
|
||||
|
||||
extras = gainStatByType(chr, primary, statGain, prStat + extras);
|
||||
extras = gainStatByType(chr, secondary, statGain, scStat + extras);
|
||||
extras = gainStatByType(chr, tertiary, statGain, trStat + extras);
|
||||
|
||||
if(extras > 0) { //redistribute surplus in priority order
|
||||
extras = gainStatByType(chr, primary, statGain, extras);
|
||||
extras = gainStatByType(chr, secondary, statGain, extras);
|
||||
extras = gainStatByType(chr, tertiary, statGain, extras);
|
||||
gainStatByType(chr, getQuaternaryStat(stance), statGain, extras);
|
||||
}
|
||||
|
||||
int remainingAp = (chr.getRemainingAp() - getAccumulatedStatGain(statGain));
|
||||
chr.setRemainingAp(remainingAp);
|
||||
chr.updateSingleStat(MapleStat.AVAILABLEAP, remainingAp);
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "Better AP applications detected:\r\nSTR: +" + statGain[0] + "\r\nDEX: +" + statGain[1] + "\r\nINT: +" + statGain[3] + "\r\nLUK: +" + statGain[2]));
|
||||
} else {
|
||||
if(slea.available() < 16) {
|
||||
AutobanFactory.PACKET_EDIT.alert(chr, "Didn't send full packet for Auto Assign.");
|
||||
c.disconnect(false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
MapleInventory iv = chr.getInventory(MapleInventoryType.EQUIPPED);
|
||||
Collection<Item> equippedC = iv.list();
|
||||
for (Item item : equippedC) { //selecting the biggest AP value of each stat from each equipped item.
|
||||
Equip nEquip = (Equip)item;
|
||||
|
||||
statEqpd[0] += nEquip.getStr();
|
||||
statEqpd[1] += nEquip.getDex();
|
||||
statEqpd[2] += nEquip.getLuk();
|
||||
statEqpd[3] += nEquip.getInt();
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
int extras = 0;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int type = slea.readInt();
|
||||
int tempVal = slea.readInt();
|
||||
if (tempVal < 0 || tempVal > c.getPlayer().getRemainingAp()) {
|
||||
return;
|
||||
}
|
||||
total += tempVal;
|
||||
extras += gainStatByType(chr, MapleStat.getBy5ByteEncoding(type), statGain, tempVal);
|
||||
}
|
||||
int remainingAp = (chr.getRemainingAp() - total) + extras;
|
||||
chr.setRemainingAp(remainingAp);
|
||||
chr.updateSingleStat(MapleStat.AVAILABLEAP, remainingAp);
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
}
|
||||
|
||||
private int gainStatByType(MapleCharacter chr, MapleStat type, int[] statGain, int gain) {
|
||||
if(gain <= 0) return 0;
|
||||
|
||||
int newVal = 0;
|
||||
if (type.equals(MapleStat.STR)) {
|
||||
newVal = chr.getStr() + gain;
|
||||
if (newVal > ServerConstants.MAX_AP) {
|
||||
statGain[0] += (gain - (newVal - ServerConstants.MAX_AP));
|
||||
chr.setStr(ServerConstants.MAX_AP);
|
||||
} else {
|
||||
statGain[0] += gain;
|
||||
chr.setStr(newVal);
|
||||
}
|
||||
} else if (type.equals(MapleStat.INT)) {
|
||||
newVal = chr.getInt() + gain;
|
||||
if (newVal > ServerConstants.MAX_AP) {
|
||||
statGain[3] += (gain - (newVal - ServerConstants.MAX_AP));
|
||||
chr.setInt(ServerConstants.MAX_AP);
|
||||
} else {
|
||||
statGain[3] += gain;
|
||||
chr.setInt(newVal);
|
||||
}
|
||||
} else if (type.equals(MapleStat.LUK)) {
|
||||
newVal = chr.getLuk() + gain;
|
||||
if (newVal > ServerConstants.MAX_AP) {
|
||||
statGain[2] += (gain - (newVal - ServerConstants.MAX_AP));
|
||||
chr.setLuk(ServerConstants.MAX_AP);
|
||||
} else {
|
||||
statGain[2] += gain;
|
||||
chr.setLuk(newVal);
|
||||
}
|
||||
} else if (type.equals(MapleStat.DEX)) {
|
||||
newVal = chr.getDex() + gain;
|
||||
if (newVal > ServerConstants.MAX_AP) {
|
||||
statGain[1] += (gain - (newVal - ServerConstants.MAX_AP));
|
||||
chr.setDex(ServerConstants.MAX_AP);
|
||||
} else {
|
||||
statGain[1] += gain;
|
||||
chr.setDex(newVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (newVal > ServerConstants.MAX_AP) {
|
||||
chr.updateSingleStat(type, ServerConstants.MAX_AP);
|
||||
return newVal - ServerConstants.MAX_AP;
|
||||
}
|
||||
chr.updateSingleStat(type, newVal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private MapleStat getQuaternaryStat(MapleJob stance) {
|
||||
if(stance != MapleJob.MAGICIAN) return MapleStat.INT;
|
||||
return MapleStat.STR;
|
||||
}
|
||||
|
||||
private int getAccumulatedStatGain(int[] statGain) {
|
||||
int acc = 0;
|
||||
|
||||
for(byte i = 0; i < statGain.length; i++) {
|
||||
acc += statGain[i];
|
||||
}
|
||||
|
||||
return acc;
|
||||
AssignAPProcessor.APAutoAssignAction(slea, c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,12 +37,13 @@ public final class ChangeChannelHandler extends AbstractMaplePacketHandler {
|
||||
int channel = slea.readByte() + 1;
|
||||
c.getPlayer().getAutobanManager().setTimestamp(6, slea.readInt(), 2);
|
||||
if(c.getChannel() == channel) {
|
||||
AutobanFactory.GENERAL.alert(c.getPlayer(), "CCing to same channel.");
|
||||
c.disconnect(false, false);
|
||||
return;
|
||||
AutobanFactory.GENERAL.alert(c.getPlayer(), "CCing to same channel.");
|
||||
c.disconnect(false, false);
|
||||
return;
|
||||
} else if (c.getPlayer().getCashShop().isOpened() || c.getPlayer().getMiniGame() != null || c.getPlayer().getPlayerShop() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
c.changeChannel(channel);
|
||||
}
|
||||
}
|
||||
@@ -21,319 +21,18 @@
|
||||
*/
|
||||
package net.server.channel.handlers;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleJob;
|
||||
import client.MapleStat;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import constants.ServerConstants;
|
||||
import constants.skills.BlazeWizard;
|
||||
import constants.skills.Brawler;
|
||||
import constants.skills.DawnWarrior;
|
||||
import constants.skills.Magician;
|
||||
import constants.skills.Warrior;
|
||||
import client.processor.AssignAPProcessor;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Randomizer;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
public final class DistributeAPHandler extends AbstractMaplePacketHandler {
|
||||
private static final int max = 32767;
|
||||
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
slea.readInt();
|
||||
int num = slea.readInt();
|
||||
if (c.getPlayer().getRemainingAp() > 0) {
|
||||
if (addStat(c, num, false)) {
|
||||
c.getPlayer().setRemainingAp(c.getPlayer().getRemainingAp() - 1);
|
||||
c.getPlayer().updateSingleStat(MapleStat.AVAILABLEAP, c.getPlayer().getRemainingAp());
|
||||
}
|
||||
}
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
|
||||
public static boolean addStat(MapleClient c, int apTo, boolean usedAPReset) {
|
||||
switch (apTo) {
|
||||
case 64: // Str
|
||||
if (c.getPlayer().getStr() >= max) {
|
||||
return false;
|
||||
}
|
||||
c.getPlayer().addStat(1, 1);
|
||||
break;
|
||||
case 128: // Dex
|
||||
if (c.getPlayer().getDex() >= max) {
|
||||
return false;
|
||||
}
|
||||
c.getPlayer().addStat(2, 1);
|
||||
break;
|
||||
case 256: // Int
|
||||
if (c.getPlayer().getInt() >= max) {
|
||||
return false;
|
||||
}
|
||||
c.getPlayer().addStat(3, 1);
|
||||
break;
|
||||
case 512: // Luk
|
||||
if (c.getPlayer().getLuk() >= max) {
|
||||
return false;
|
||||
}
|
||||
c.getPlayer().addStat(4, 1);
|
||||
break;
|
||||
case 2048: // HP
|
||||
addHP(c.getPlayer(), addHP(c, usedAPReset));
|
||||
break;
|
||||
case 8192: // MP
|
||||
addMP(c.getPlayer(), addMP(c, usedAPReset));
|
||||
break;
|
||||
default:
|
||||
c.announce(MaplePacketCreator.updatePlayerStats(MaplePacketCreator.EMPTY_STATUPDATE, true, c.getPlayer()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int addHP(MapleClient c, boolean usedAPReset) {
|
||||
MapleCharacter player = c.getPlayer();
|
||||
MapleJob job = player.getJob();
|
||||
int MaxHP = player.getMaxHp();
|
||||
if (player.getHpMpApUsed() > 9999 || MaxHP >= 30000) {
|
||||
return MaxHP;
|
||||
}
|
||||
|
||||
return MaxHP + calcHpChange(player, job, usedAPReset);
|
||||
}
|
||||
|
||||
private static int calcHpChange(MapleCharacter player, MapleJob job, boolean usedAPReset) {
|
||||
int MaxHP = 0;
|
||||
|
||||
if (job.isA(MapleJob.WARRIOR) || job.isA(MapleJob.DAWNWARRIOR1)) {
|
||||
if(!usedAPReset) {
|
||||
Skill increaseHP = SkillFactory.getSkill(job.isA(MapleJob.DAWNWARRIOR1) ? DawnWarrior.MAX_HP_INCREASE : Warrior.IMPROVED_MAXHP);
|
||||
int sLvl = player.getSkillLevel(increaseHP);
|
||||
|
||||
if(sLvl > 0)
|
||||
MaxHP += increaseHP.getEffect(sLvl).getY();
|
||||
}
|
||||
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if (usedAPReset) {
|
||||
MaxHP += 20;
|
||||
} else {
|
||||
MaxHP += Randomizer.rand(18, 22);
|
||||
}
|
||||
} else {
|
||||
MaxHP += 20;
|
||||
}
|
||||
} else if(job.isA(MapleJob.ARAN1)) {
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if (usedAPReset) {
|
||||
MaxHP += 20;
|
||||
} else {
|
||||
MaxHP += Randomizer.rand(26, 30);
|
||||
}
|
||||
} else {
|
||||
MaxHP += 28;
|
||||
}
|
||||
} else if (job.isA(MapleJob.MAGICIAN) || job.isA(MapleJob.BLAZEWIZARD1)) {
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if (usedAPReset) {
|
||||
MaxHP += 6;
|
||||
} else {
|
||||
MaxHP += Randomizer.rand(5, 9);
|
||||
}
|
||||
} else {
|
||||
MaxHP += 6;
|
||||
}
|
||||
} else if (job.isA(MapleJob.THIEF) || job.isA(MapleJob.NIGHTWALKER1)) {
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if (usedAPReset) {
|
||||
MaxHP += 16;
|
||||
} else {
|
||||
MaxHP += Randomizer.rand(14, 18);
|
||||
}
|
||||
} else {
|
||||
MaxHP += 16;
|
||||
}
|
||||
} else if(job.isA(MapleJob.BOWMAN) || job.isA(MapleJob.WINDARCHER1)) {
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if (usedAPReset) {
|
||||
MaxHP += 16;
|
||||
} else {
|
||||
MaxHP += Randomizer.rand(14, 18);
|
||||
}
|
||||
} else {
|
||||
MaxHP += 16;
|
||||
}
|
||||
} else if (job.isA(MapleJob.PIRATE) || job.isA(MapleJob.THUNDERBREAKER1)) {
|
||||
if(!usedAPReset) {
|
||||
Skill increaseHP = SkillFactory.getSkill(Brawler.IMPROVE_MAX_HP);
|
||||
int sLvl = player.getSkillLevel(increaseHP);
|
||||
|
||||
if(sLvl > 0)
|
||||
MaxHP += increaseHP.getEffect(sLvl).getY();
|
||||
}
|
||||
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if (usedAPReset) {
|
||||
MaxHP += 18;
|
||||
} else {
|
||||
MaxHP += Randomizer.rand(16, 20);
|
||||
}
|
||||
} else {
|
||||
MaxHP += 18;
|
||||
}
|
||||
} else if (usedAPReset) {
|
||||
MaxHP += 8;
|
||||
} else {
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
MaxHP += Randomizer.rand(8, 12);
|
||||
} else {
|
||||
MaxHP += 10;
|
||||
}
|
||||
}
|
||||
|
||||
return MaxHP;
|
||||
}
|
||||
|
||||
private static int addMP(MapleClient c, boolean usedAPReset) {
|
||||
MapleCharacter player = c.getPlayer();
|
||||
int MaxMP = player.getMaxMp();
|
||||
MapleJob job = player.getJob();
|
||||
if (player.getHpMpApUsed() > 9999 || player.getMaxMp() >= 30000) {
|
||||
return MaxMP;
|
||||
}
|
||||
|
||||
return MaxMP + calcMpChange(player, job, usedAPReset);
|
||||
}
|
||||
|
||||
private static int calcMpChange(MapleCharacter player, MapleJob job, boolean usedAPReset) {
|
||||
int MaxMP = 0;
|
||||
|
||||
if (job.isA(MapleJob.WARRIOR) || job.isA(MapleJob.DAWNWARRIOR1) || job.isA(MapleJob.ARAN1)) {
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if(!usedAPReset) {
|
||||
MaxMP += (Randomizer.rand(2, 4) + (player.getInt() / 10));
|
||||
} else {
|
||||
MaxMP += 2;
|
||||
}
|
||||
} else {
|
||||
MaxMP += 3;
|
||||
}
|
||||
} else if (job.isA(MapleJob.MAGICIAN) || job.isA(MapleJob.BLAZEWIZARD1)) {
|
||||
if(!usedAPReset) {
|
||||
Skill increaseMP = SkillFactory.getSkill(job.isA(MapleJob.BLAZEWIZARD1) ? BlazeWizard.INCREASING_MAX_MP : Magician.IMPROVED_MAX_MP_INCREASE);
|
||||
int sLvl = player.getSkillLevel(increaseMP);
|
||||
|
||||
if(sLvl > 0)
|
||||
MaxMP += increaseMP.getEffect(sLvl).getY();
|
||||
}
|
||||
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if(!usedAPReset) {
|
||||
MaxMP += (Randomizer.rand(12, 16) + (player.getInt() / 20));
|
||||
} else {
|
||||
MaxMP += 18;
|
||||
}
|
||||
} else {
|
||||
MaxMP += 18;
|
||||
}
|
||||
} else if (job.isA(MapleJob.BOWMAN) || job.isA(MapleJob.WINDARCHER1)) {
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if(!usedAPReset) {
|
||||
MaxMP += (Randomizer.rand(6, 8) + (player.getInt() / 10));
|
||||
} else {
|
||||
MaxMP += 10;
|
||||
}
|
||||
} else {
|
||||
MaxMP += 10;
|
||||
}
|
||||
} else if(job.isA(MapleJob.THIEF) || job.isA(MapleJob.NIGHTWALKER1)) {
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if(!usedAPReset) {
|
||||
MaxMP += (Randomizer.rand(6, 8) + (player.getInt() / 10));
|
||||
} else {
|
||||
MaxMP += 10;
|
||||
}
|
||||
} else {
|
||||
MaxMP += 10;
|
||||
}
|
||||
} else if (job.isA(MapleJob.PIRATE) || job.isA(MapleJob.THUNDERBREAKER1)) {
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if(!usedAPReset) {
|
||||
MaxMP += (Randomizer.rand(7, 9) + (player.getInt() / 10));
|
||||
} else {
|
||||
MaxMP += 14;
|
||||
}
|
||||
} else {
|
||||
MaxMP += 14;
|
||||
}
|
||||
} else {
|
||||
if(ServerConstants.USE_RANDOMIZE_HPMP_GAIN) {
|
||||
if(!usedAPReset) {
|
||||
MaxMP += (Randomizer.rand(4, 6) + (player.getInt() / 10));
|
||||
} else {
|
||||
MaxMP += 6;
|
||||
}
|
||||
} else {
|
||||
MaxMP += 6;
|
||||
}
|
||||
}
|
||||
|
||||
return MaxMP;
|
||||
}
|
||||
|
||||
private static void addHP(MapleCharacter player, int MaxHP) {
|
||||
MaxHP = Math.min(30000, MaxHP);
|
||||
player.setHpMpApUsed(player.getHpMpApUsed() + 1);
|
||||
player.setMaxHp(MaxHP);
|
||||
player.updateSingleStat(MapleStat.MAXHP, MaxHP);
|
||||
}
|
||||
|
||||
private static void addMP(MapleCharacter player, int MaxMP) {
|
||||
MaxMP = Math.min(30000, MaxMP);
|
||||
player.setHpMpApUsed(player.getHpMpApUsed() + 1);
|
||||
player.setMaxMp(MaxMP);
|
||||
player.updateSingleStat(MapleStat.MAXMP, MaxMP);
|
||||
}
|
||||
|
||||
public static int takeHp(MapleCharacter player, MapleJob job) {
|
||||
int MaxHP = 0;
|
||||
|
||||
if (job.isA(MapleJob.WARRIOR) || job.isA(MapleJob.DAWNWARRIOR1) || job.isA(MapleJob.ARAN1)) {
|
||||
MaxHP += 54;
|
||||
} else if (job.isA(MapleJob.MAGICIAN) || job.isA(MapleJob.BLAZEWIZARD1)) {
|
||||
MaxHP += 10;
|
||||
} else if (job.isA(MapleJob.THIEF) || job.isA(MapleJob.NIGHTWALKER1)) {
|
||||
MaxHP += 20;
|
||||
} else if(job.isA(MapleJob.BOWMAN) || job.isA(MapleJob.WINDARCHER1)) {
|
||||
MaxHP += 20;
|
||||
} else if (job.isA(MapleJob.PIRATE) || job.isA(MapleJob.THUNDERBREAKER1)) {
|
||||
MaxHP += 42;
|
||||
} else {
|
||||
MaxHP += 12;
|
||||
}
|
||||
|
||||
return MaxHP;
|
||||
}
|
||||
|
||||
public static int takeMp(MapleCharacter player, MapleJob job) {
|
||||
int MaxMP = 0;
|
||||
|
||||
if (job.isA(MapleJob.WARRIOR) || job.isA(MapleJob.DAWNWARRIOR1) || job.isA(MapleJob.ARAN1)) {
|
||||
MaxMP += 4;
|
||||
} else if (job.isA(MapleJob.MAGICIAN) || job.isA(MapleJob.BLAZEWIZARD1)) {
|
||||
MaxMP += 31;
|
||||
} else if (job.isA(MapleJob.BOWMAN) || job.isA(MapleJob.WINDARCHER1)) {
|
||||
MaxMP += 12;
|
||||
} else if(job.isA(MapleJob.THIEF) || job.isA(MapleJob.NIGHTWALKER1)) {
|
||||
MaxMP += 12;
|
||||
} else if (job.isA(MapleJob.PIRATE) || job.isA(MapleJob.THUNDERBREAKER1)) {
|
||||
MaxMP += 16;
|
||||
} else {
|
||||
MaxMP += 8;
|
||||
}
|
||||
|
||||
return MaxMP;
|
||||
}
|
||||
AssignAPProcessor.APAssignAction(c, num);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,64 +21,17 @@
|
||||
*/
|
||||
package net.server.channel.handlers;
|
||||
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.FilePrinter;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleStat;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import client.autoban.AutobanFactory;
|
||||
import constants.GameConstants;
|
||||
import constants.skills.Aran;
|
||||
import client.processor.AssignSPProcessor;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
public final class DistributeSPHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
slea.readInt();
|
||||
int skillid = slea.readInt();
|
||||
if (skillid == Aran.HIDDEN_FULL_DOUBLE || skillid == Aran.HIDDEN_FULL_TRIPLE || skillid == Aran.HIDDEN_OVER_DOUBLE || skillid == Aran.HIDDEN_OVER_TRIPLE) {
|
||||
c.getSession().write(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
MapleCharacter player = c.getPlayer();
|
||||
int remainingSp = player.getRemainingSpBySkill(GameConstants.getSkillBook(skillid/10000));
|
||||
boolean isBeginnerSkill = false;
|
||||
if ((!GameConstants.isPqSkillMap(player.getMapId()) && GameConstants.isPqSkill(skillid)) || (!player.isGM() && GameConstants.isGMSkills(skillid)) || (!GameConstants.isInJobTree(skillid, player.getJob().getId()) && !player.isGM())) {
|
||||
AutobanFactory.PACKET_EDIT.alert(player, "tried to packet edit in distributing sp.");
|
||||
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to use skill " + skillid + " without it being in their job.\r\n");
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
}
|
||||
if (skillid % 10000000 > 999 && skillid % 10000000 < 1003) {
|
||||
int total = 0;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
total += player.getSkillLevel(SkillFactory.getSkill(player.getJobType() * 10000000 + 1000 + i));
|
||||
}
|
||||
remainingSp = Math.min((player.getLevel() - 1), 6) - total;
|
||||
isBeginnerSkill = true;
|
||||
}
|
||||
Skill skill = SkillFactory.getSkill(skillid);
|
||||
int curLevel = player.getSkillLevel(skill);
|
||||
if ((remainingSp > 0 && curLevel + 1 <= (skill.isFourthJob() ? player.getMasterLevel(skill) : skill.getMaxLevel()))) {
|
||||
if (!isBeginnerSkill) {
|
||||
player.setRemainingSp(player.getRemainingSpBySkill(GameConstants.getSkillBook(skillid/10000)) - 1, GameConstants.getSkillBook(skillid/10000));
|
||||
}
|
||||
player.updateSingleStat(MapleStat.AVAILABLESP, player.getRemainingSpBySkill(GameConstants.getSkillBook(skillid/10000)));
|
||||
if (skill.getId() == Aran.FULL_SWING) {
|
||||
player.changeSkillLevel(skill, (byte) (curLevel + 1), player.getMasterLevel(skill), player.getSkillExpiration(skill));
|
||||
player.changeSkillLevel(SkillFactory.getSkill(Aran.HIDDEN_FULL_DOUBLE), (byte) player.getSkillLevel(skill), player.getMasterLevel(skill), player.getSkillExpiration(skill));
|
||||
player.changeSkillLevel(SkillFactory.getSkill(Aran.HIDDEN_FULL_TRIPLE), (byte) player.getSkillLevel(skill), player.getMasterLevel(skill), player.getSkillExpiration(skill));
|
||||
} else if (skill.getId() == Aran.OVER_SWING) {
|
||||
player.changeSkillLevel(skill, (byte) (curLevel + 1), player.getMasterLevel(skill), player.getSkillExpiration(skill));
|
||||
player.changeSkillLevel(SkillFactory.getSkill(Aran.HIDDEN_OVER_DOUBLE), (byte) player.getSkillLevel(skill), player.getMasterLevel(skill), player.getSkillExpiration(skill));
|
||||
player.changeSkillLevel(SkillFactory.getSkill(Aran.HIDDEN_OVER_TRIPLE), (byte) player.getSkillLevel(skill), player.getMasterLevel(skill), player.getSkillExpiration(skill));
|
||||
} else {
|
||||
player.changeSkillLevel(skill, (byte) (curLevel + 1), player.getMasterLevel(skill), player.getSkillExpiration(skill));
|
||||
}
|
||||
}
|
||||
AssignSPProcessor.SPAssignAction(c, skillid);
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler {
|
||||
mc.unregisterChairBuff();
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs());
|
||||
Server.getInstance().getPlayerBuffStorage().addDiseasesToStorage(mc.getId(), mc.getAllDiseases());
|
||||
mc.setAwayFromWorld(true);
|
||||
mc.setAwayFromChannelWorld();
|
||||
mc.notifyMapTransferToPartner(-1);
|
||||
mc.cancelAllBuffs(true);
|
||||
mc.cancelAllDebuffs();
|
||||
|
||||
@@ -83,7 +83,7 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
chr.unregisterChairBuff();
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs());
|
||||
Server.getInstance().getPlayerBuffStorage().addDiseasesToStorage(chr.getId(), chr.getAllDiseases());
|
||||
chr.setAwayFromWorld(true);
|
||||
chr.setAwayFromChannelWorld();
|
||||
chr.notifyMapTransferToPartner(-1);
|
||||
chr.cancelAllBuffs(true);
|
||||
chr.cancelAllDebuffs();
|
||||
@@ -96,6 +96,8 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
chr.cancelQuestExpirationTask();
|
||||
|
||||
chr.saveCharToDB();
|
||||
|
||||
c.getChannelServer().removePlayer(chr);
|
||||
chr.getMap().removePlayer(c.getPlayer());
|
||||
try {
|
||||
c.announce(MaplePacketCreator.openCashShop(c, true));
|
||||
|
||||
@@ -26,6 +26,7 @@ import client.MapleClient;
|
||||
import client.autoban.AutobanFactory;
|
||||
import client.autoban.AutobanManager;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import server.maps.MapleMapFactory;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
@@ -33,6 +34,8 @@ public final class HealOvertimeHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
if(!chr.isLoggedinWorld()) return;
|
||||
|
||||
AutobanManager abm = chr.getAutobanManager();
|
||||
int timestamp = slea.readInt();
|
||||
abm.setTimestamp(0, timestamp, 3);
|
||||
@@ -41,8 +44,7 @@ public final class HealOvertimeHandler extends AbstractMaplePacketHandler {
|
||||
if (healHP != 0) {
|
||||
if ((abm.getLastSpam(0) + 1500) > timestamp) AutobanFactory.FAST_HP_HEALING.addPoint(abm, "Fast hp healing");
|
||||
|
||||
int abHeal = 140;
|
||||
if(chr.getMapId() == 105040401 || chr.getMapId() == 105040402 || chr.getMapId() == 809000101 || chr.getMapId() == 809000201) abHeal += 40; // Sleepywood sauna and showa spa...
|
||||
int abHeal = 120 + (int)(20 * MapleMapFactory.getMapRecoveryRate(chr.getMapId())); // Sleepywood sauna and showa spa...
|
||||
if (healHP > abHeal) {
|
||||
AutobanFactory.HIGH_HP_HEALING.autoban(chr, "Healing: " + healHP + "; Max is " + abHeal + ".");
|
||||
return;
|
||||
|
||||
@@ -42,6 +42,7 @@ import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import client.BuddyList;
|
||||
import client.BuddylistEntry;
|
||||
import client.CharacterNameAndId;
|
||||
import client.MapleCharacter;
|
||||
@@ -101,7 +102,17 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
int state = c.getLoginState();
|
||||
boolean allowLogin = true;
|
||||
|
||||
Channel cserv = c.getChannelServer();
|
||||
if(cserv == null) {
|
||||
c.setChannel(1);
|
||||
cserv = c.getChannelServer();
|
||||
|
||||
if(cserv == null) { // world server is out
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* is this check really necessary?
|
||||
if (state == MapleClient.LOGIN_SERVER_TRANSITION || state == MapleClient.LOGIN_NOTLOGGEDIN) {
|
||||
@@ -126,7 +137,11 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
c.updateLoginState(MapleClient.LOGIN_LOGGEDIN);
|
||||
|
||||
World world = server.getWorld(c.getWorld());
|
||||
|
||||
cserv.addPlayer(player);
|
||||
world.addPlayer(player);
|
||||
player.setEnteredChannelWorld();
|
||||
|
||||
List<PlayerBuffValueHolder> buffs = server.getPlayerBuffStorage().getBuffsFromStorage(cid);
|
||||
if (buffs != null) {
|
||||
@@ -156,19 +171,16 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
player.getMap().addPlayer(player);
|
||||
player.visitMap(player.getMap());
|
||||
|
||||
World world = server.getWorld(c.getWorld());
|
||||
world.getPlayerStorage().addPlayer(player);
|
||||
|
||||
player.setAwayFromWorld(false);
|
||||
|
||||
int buddyIds[] = player.getBuddylist().getBuddyIds();
|
||||
BuddyList bl = player.getBuddylist();
|
||||
int buddyIds[] = bl.getBuddyIds();
|
||||
world.loggedOn(player.getName(), player.getId(), c.getChannel(), buddyIds);
|
||||
for (CharacterIdChannelPair onlineBuddy : server.getWorld(c.getWorld()).multiBuddyFind(player.getId(), buddyIds)) {
|
||||
BuddylistEntry ble = player.getBuddylist().get(onlineBuddy.getCharacterId());
|
||||
for (CharacterIdChannelPair onlineBuddy : world.multiBuddyFind(player.getId(), buddyIds)) {
|
||||
BuddylistEntry ble = bl.get(onlineBuddy.getCharacterId());
|
||||
ble.setChannel(onlineBuddy.getChannel());
|
||||
player.getBuddylist().put(ble);
|
||||
bl.put(ble);
|
||||
}
|
||||
c.announce(MaplePacketCreator.updateBuddylist(player.getBuddylist().getBuddies()));
|
||||
c.announce(MaplePacketCreator.updateBuddylist(bl.getBuddies()));
|
||||
|
||||
c.announce(MaplePacketCreator.loadFamily(player));
|
||||
if (player.getFamilyId() > 0) {
|
||||
MapleFamily f = world.getFamily(player.getFamilyId());
|
||||
|
||||
@@ -23,8 +23,6 @@ package net.server.channel.handlers;
|
||||
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import client.MapleJob;
|
||||
import client.MapleStat;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import client.creator.veteran.*;
|
||||
@@ -36,6 +34,7 @@ import client.inventory.MaplePet;
|
||||
import client.inventory.ModifyInventory;
|
||||
import client.inventory.manipulator.MapleInventoryManipulator;
|
||||
import client.inventory.manipulator.MapleKarmaManipulator;
|
||||
import client.processor.AssignAPProcessor;
|
||||
import constants.GameConstants;
|
||||
import constants.ItemConstants;
|
||||
import constants.ServerConstants;
|
||||
@@ -79,9 +78,9 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
slea.readShort();
|
||||
int itemId = slea.readInt();
|
||||
int itemType = itemId / 10000;
|
||||
Item toUse = c.getPlayer().getInventory(MapleInventoryType.CASH).getItem(c.getPlayer().getInventory(MapleInventoryType.CASH).findById(itemId).getPosition());
|
||||
Item toUse = player.getInventory(MapleInventoryType.CASH).getItem(player.getInventory(MapleInventoryType.CASH).findById(itemId).getPosition());
|
||||
String medal = "";
|
||||
Item medalItem = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -49);
|
||||
Item medalItem = player.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -49);
|
||||
if (medalItem != null) {
|
||||
medal = "<" + ii.getName(medalItem.getItemId()) + "> ";
|
||||
}
|
||||
@@ -100,7 +99,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
player.changeMap(c.getChannelServer().getMapFactory().getMap(mapId));
|
||||
} else {
|
||||
MapleInventoryManipulator.addById(c, itemId, (short) 1);
|
||||
c.getPlayer().dropMessage(1, error1);
|
||||
player.dropMessage(1, error1);
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
} else {
|
||||
@@ -149,131 +148,12 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
player.changeSkillLevel(skillSPTo, (byte) (curLevel + 1), player.getMasterLevel(skillSPTo), -1);
|
||||
}
|
||||
} else {
|
||||
List<Pair<MapleStat, Integer>> statupdate = new ArrayList<>(2);
|
||||
int APTo = slea.readInt();
|
||||
int APFrom = slea.readInt();
|
||||
switch (APFrom) {
|
||||
case 64: // str
|
||||
if (player.getStr() < 5) {
|
||||
c.getPlayer().message("You don't have the minimum STR required to swap.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
player.addStat(1, -1);
|
||||
break;
|
||||
case 128: // dex
|
||||
if (player.getDex() < 5) {
|
||||
c.getPlayer().message("You don't have the minimum DEX required to swap.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
player.addStat(2, -1);
|
||||
break;
|
||||
case 256: // int
|
||||
if (player.getInt() < 5) {
|
||||
c.getPlayer().message("You don't have the minimum INT required to swap.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
player.addStat(3, -1);
|
||||
break;
|
||||
case 512: // luk
|
||||
if (player.getLuk() < 5) {
|
||||
c.getPlayer().message("You don't have the minimum LUK required to swap.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
player.addStat(4, -1);
|
||||
break;
|
||||
case 2048: // HP
|
||||
if(ServerConstants.USE_ENFORCE_HPMP_SWAP) {
|
||||
if (APTo != 8192) {
|
||||
c.getPlayer().message("You can only swap HP ability points to MP.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (player.getHpMpApUsed() < 1) {
|
||||
c.getPlayer().message("You don't have enough HPMP stat points to spend on AP Reset.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
int hp = player.getMaxHp();
|
||||
int level_ = player.getLevel();
|
||||
|
||||
boolean canWash_ = true;
|
||||
if (hp < level_ * 14 + 148) {
|
||||
canWash_ = false;
|
||||
}
|
||||
|
||||
if (!canWash_) {
|
||||
c.getPlayer().message("You don't have the minimum HP pool required to swap.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
player.setHpMpApUsed(player.getHpMpApUsed() - 1);
|
||||
int hplose = -DistributeAPHandler.takeHp(player, player.getJob());
|
||||
int nextHp = Math.max(1, player.getHp() + hplose), nextMaxHp = Math.max(50, player.getMaxHp() + hplose);
|
||||
|
||||
player.setHp(nextHp);
|
||||
player.setMaxHp(nextMaxHp);
|
||||
statupdate.add(new Pair<>(MapleStat.HP, nextHp));
|
||||
statupdate.add(new Pair<>(MapleStat.MAXHP, nextMaxHp));
|
||||
|
||||
break;
|
||||
case 8192: // MP
|
||||
if(ServerConstants.USE_ENFORCE_HPMP_SWAP) {
|
||||
if (APTo != 2048) {
|
||||
c.getPlayer().message("You can only swap MP ability points to HP.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (player.getHpMpApUsed() < 1) {
|
||||
c.getPlayer().message("You don't have enough HPMP stat points to spend on AP Reset.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
int mp = player.getMaxMp();
|
||||
int level = player.getLevel();
|
||||
MapleJob job = player.getJob();
|
||||
|
||||
boolean canWash = true;
|
||||
if (job.isA(MapleJob.SPEARMAN) && mp < 4 * level + 156) {
|
||||
canWash = false;
|
||||
} else if (job.isA(MapleJob.FIGHTER) && mp < 4 * level + 56) {
|
||||
canWash = false;
|
||||
} else if (job.isA(MapleJob.THIEF) && job.getId() % 100 > 0 && mp < level * 14 - 4) {
|
||||
canWash = false;
|
||||
} else if (mp < level * 14 + 148) {
|
||||
canWash = false;
|
||||
}
|
||||
|
||||
if (!canWash) {
|
||||
c.getPlayer().message("You don't have the minimum MP pool required to swap.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
player.setHpMpApUsed(player.getHpMpApUsed() - 1);
|
||||
int mplose = -DistributeAPHandler.takeMp(player, job);
|
||||
int nextMp = Math.max(0, player.getMp() + mplose), nextMaxMp = Math.max(5, player.getMaxMp() + mplose);
|
||||
|
||||
player.setMp(nextMp);
|
||||
player.setMaxMp(nextMaxMp);
|
||||
statupdate.add(new Pair<>(MapleStat.MP, nextMp));
|
||||
statupdate.add(new Pair<>(MapleStat.MAXMP, nextMaxMp));
|
||||
|
||||
break;
|
||||
default:
|
||||
c.announce(MaplePacketCreator.updatePlayerStats(MaplePacketCreator.EMPTY_STATUPDATE, true, c.getPlayer()));
|
||||
return;
|
||||
|
||||
if(!AssignAPProcessor.APResetAction(c, APFrom, APTo)) {
|
||||
return;
|
||||
}
|
||||
DistributeAPHandler.addStat(c, APTo, true);
|
||||
c.announce(MaplePacketCreator.updatePlayerStats(statupdate, true, c.getPlayer()));
|
||||
}
|
||||
remove(c, itemId);
|
||||
} else if (itemType == 506) {
|
||||
@@ -287,7 +167,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
eq.setOwner(player.getName());
|
||||
} else if (itemId == 5060001 || itemId == 5061000 || itemId == 5061001 || itemId == 5061002 || itemId == 5061003) { // Sealing lock
|
||||
MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
|
||||
eq = c.getPlayer().getInventory(type).getItem((short) slea.readInt());
|
||||
eq = player.getInventory(type).getItem((short) slea.readInt());
|
||||
if (eq == null) { //Check if the type is EQUIPMENT?
|
||||
return;
|
||||
}
|
||||
@@ -317,7 +197,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
} else if (itemId == 5060002) { // Incubator
|
||||
byte inventory2 = (byte) slea.readInt();
|
||||
short slot2 = (short) slea.readInt();
|
||||
Item item2 = c.getPlayer().getInventory(MapleInventoryType.getByType(inventory2)).getItem(slot2);
|
||||
Item item2 = player.getInventory(MapleInventoryType.getByType(inventory2)).getItem(slot2);
|
||||
if (item2 == null) // hacking
|
||||
{
|
||||
return;
|
||||
@@ -388,11 +268,11 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
break;
|
||||
case 6: //item megaphone
|
||||
String msg = medal + c.getPlayer().getName() + " : " + slea.readMapleAsciiString();
|
||||
String msg = medal + player.getName() + " : " + slea.readMapleAsciiString();
|
||||
whisper = slea.readByte() == 1;
|
||||
Item item = null;
|
||||
if (slea.readByte() == 1) { //item
|
||||
item = c.getPlayer().getInventory(MapleInventoryType.getByType((byte) slea.readInt())).getItem((short) slea.readInt());
|
||||
item = player.getInventory(MapleInventoryType.getByType((byte) slea.readInt())).getItem((short) slea.readInt());
|
||||
if (item == null) //hack
|
||||
{
|
||||
return;
|
||||
@@ -412,7 +292,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
String[] msg2 = new String[lines];
|
||||
for (int i = 0; i < lines; i++) {
|
||||
msg2[i] = medal + c.getPlayer().getName() + " : " + slea.readMapleAsciiString();
|
||||
msg2[i] = medal + player.getName() + " : " + slea.readMapleAsciiString();
|
||||
}
|
||||
whisper = slea.readByte() == 1;
|
||||
Server.getInstance().broadcastMessage(c.getWorld(), MaplePacketCreator.getMultiMegaphone(msg2, c.getChannel(), whisper));
|
||||
@@ -420,10 +300,10 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
remove(c, itemId);
|
||||
} else if (itemType == 508) { // graduation banner, thanks to tmskdl12
|
||||
MapleKite kite = new MapleKite(c.getPlayer(), slea.readMapleAsciiString(), itemId);
|
||||
MapleKite kite = new MapleKite(player, slea.readMapleAsciiString(), itemId);
|
||||
|
||||
if (!GameConstants.isFreeMarketRoom(c.getPlayer().getMapId())) {
|
||||
c.getPlayer().getMap().spawnKite(kite);
|
||||
if (!GameConstants.isFreeMarketRoom(player.getMapId())) {
|
||||
player.getMap().spawnKite(kite);
|
||||
remove(c, itemId);
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.sendCannotSpawnKite());
|
||||
@@ -442,11 +322,11 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
remove(c, itemId);
|
||||
} else if (itemType == 512) {
|
||||
if (ii.getStateChangeItem(itemId) != 0) {
|
||||
for (MapleCharacter mChar : c.getPlayer().getMap().getCharacters()) {
|
||||
for (MapleCharacter mChar : player.getMap().getCharacters()) {
|
||||
ii.getItemEffect(ii.getStateChangeItem(itemId)).applyTo(mChar);
|
||||
}
|
||||
}
|
||||
player.getMap().startMapEffect(ii.getMsg(itemId).replaceFirst("%s", c.getPlayer().getName()).replaceFirst("%s", slea.readMapleAsciiString()), itemId);
|
||||
player.getMap().startMapEffect(ii.getMsg(itemId).replaceFirst("%s", player.getName()).replaceFirst("%s", slea.readMapleAsciiString()), itemId);
|
||||
remove(c, itemId);
|
||||
} else if (itemType == 517) {
|
||||
MaplePet pet = player.getPet(0);
|
||||
@@ -512,7 +392,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
|
||||
final int world = c.getWorld();
|
||||
Server.getInstance().broadcastMessage(world, MaplePacketCreator.getAvatarMega(c.getPlayer(), medal, c.getChannel(), itemId, strLines, (slea.readByte() != 0)));
|
||||
Server.getInstance().broadcastMessage(world, MaplePacketCreator.getAvatarMega(player, medal, c.getChannel(), itemId, strLines, (slea.readByte() != 0)));
|
||||
TimerManager.getInstance().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -585,20 +465,20 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
} else if (itemType == 552) {
|
||||
MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
|
||||
short slot = (short) slea.readInt();
|
||||
Item item = c.getPlayer().getInventory(type).getItem(slot);
|
||||
Item item = player.getInventory(type).getItem(slot);
|
||||
if (item == null || item.getQuantity() <= 0 || MapleKarmaManipulator.hasKarmaFlag(item) || !ii.isKarmaAble(item.getItemId())) {
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
if(MapleKarmaManipulator.hasUsedKarmaFlag(item)) {
|
||||
c.getPlayer().dropMessage(6, "Scissors of Karma was already used on this item.");
|
||||
player.dropMessage(6, "Scissors of Karma was already used on this item.");
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
}
|
||||
|
||||
MapleKarmaManipulator.setKarmaFlag(item);
|
||||
c.getPlayer().forceUpdateItem(item);
|
||||
player.forceUpdateItem(item);
|
||||
remove(c, itemId);
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
} else if (itemType == 552) { //DS EGG THING
|
||||
@@ -607,8 +487,8 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
slea.readInt();
|
||||
int itemSlot = slea.readInt();
|
||||
slea.readInt();
|
||||
final Equip equip = (Equip) c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem((short) itemSlot);
|
||||
if (equip.getVicious() == 2 || c.getPlayer().getInventory(MapleInventoryType.CASH).findById(5570000) == null) {
|
||||
final Equip equip = (Equip) player.getInventory(MapleInventoryType.EQUIP).getItem((short) itemSlot);
|
||||
if (equip.getVicious() == 2 || player.getInventory(MapleInventoryType.CASH).findById(5570000) == null) {
|
||||
return;
|
||||
}
|
||||
equip.setVicious(equip.getVicious() + 1);
|
||||
@@ -623,14 +503,14 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
|
||||
final byte eSlot = (byte) slea.readInt();
|
||||
final Item eitem = c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem(eSlot);
|
||||
final Item eitem = player.getInventory(MapleInventoryType.EQUIP).getItem(eSlot);
|
||||
|
||||
if (slea.readInt() != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
final byte uSlot = (byte) slea.readInt();
|
||||
final Item uitem = c.getPlayer().getInventory(MapleInventoryType.USE).getItem(uSlot);
|
||||
final Item uitem = player.getInventory(MapleInventoryType.USE).getItem(uSlot);
|
||||
if (eitem == null || uitem == null) {
|
||||
return;
|
||||
}
|
||||
@@ -644,12 +524,12 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
//should have a check here against PE hacks
|
||||
if(itemId / 1000000 != 5) itemId = 0;
|
||||
|
||||
c.getPlayer().toggleBlockCashShop();
|
||||
player.toggleBlockCashShop();
|
||||
|
||||
final int curlevel = toScroll.getLevel();
|
||||
c.getSession().write(MaplePacketCreator.sendVegaScroll(0x40));
|
||||
|
||||
final Equip scrolled = (Equip) ii.scrollEquipWithId(toScroll, uitem.getItemId(), false, itemId, c.getPlayer().isGM());
|
||||
final Equip scrolled = (Equip) ii.scrollEquipWithId(toScroll, uitem.getItemId(), false, itemId, player.isGM());
|
||||
c.getSession().write(MaplePacketCreator.sendVegaScroll(scrolled.getLevel() > curlevel ? 0x41 : 0x43));
|
||||
//opcodes 0x42, 0x44: "this item cannot be used"; 0x39, 0x45: crashes
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
|
||||
import net.server.Server;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
|
||||
import server.TimerManager;
|
||||
import tools.Pair;
|
||||
|
||||
@@ -42,7 +42,7 @@ import tools.Pair;
|
||||
public abstract class BaseScheduler {
|
||||
private int idleProcs = 0;
|
||||
private List<SchedulerListener> listeners = new LinkedList<>();
|
||||
private final List<Lock> externalLocks = new LinkedList<>();
|
||||
private final List<MonitoredReentrantLock> externalLocks = new LinkedList<>();
|
||||
private Map<Object, Pair<Runnable, Long>> registeredEntries = new HashMap<>();
|
||||
|
||||
private ScheduledFuture<?> schedulerTask = null;
|
||||
@@ -55,14 +55,14 @@ public abstract class BaseScheduler {
|
||||
};
|
||||
|
||||
protected BaseScheduler(MonitoredLockType lockType) {
|
||||
schedulerLock = new MonitoredReentrantLock(lockType, true);
|
||||
schedulerLock = MonitoredReentrantLockFactory.createLock(lockType, true);
|
||||
}
|
||||
|
||||
// NOTE: practice EXTREME caution when adding external locks to the scheduler system, if you don't know what you're doing DON'T USE THIS.
|
||||
protected BaseScheduler(MonitoredLockType lockType, List<Lock> extLocks) {
|
||||
schedulerLock = new MonitoredReentrantLock(lockType, true);
|
||||
protected BaseScheduler(MonitoredLockType lockType, List<MonitoredReentrantLock> extLocks) {
|
||||
schedulerLock = MonitoredReentrantLockFactory.createLock(lockType, true);
|
||||
|
||||
for(Lock lock : extLocks) {
|
||||
for(MonitoredReentrantLock lock : extLocks) {
|
||||
externalLocks.add(lock);
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public abstract class BaseScheduler {
|
||||
|
||||
private void lockScheduler() {
|
||||
if(!externalLocks.isEmpty()) {
|
||||
for(Lock l : externalLocks) {
|
||||
for(MonitoredReentrantLock l : externalLocks) {
|
||||
l.lock();
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ public abstract class BaseScheduler {
|
||||
|
||||
private void unlockScheduler() {
|
||||
if(!externalLocks.isEmpty()) {
|
||||
for(Lock l : externalLocks) {
|
||||
for(MonitoredReentrantLock l : externalLocks) {
|
||||
l.unlock();
|
||||
}
|
||||
}
|
||||
@@ -190,12 +190,12 @@ public abstract class BaseScheduler {
|
||||
}
|
||||
|
||||
listeners.clear();
|
||||
externalLocks.clear();
|
||||
registeredEntries.clear();
|
||||
} finally {
|
||||
unlockScheduler();
|
||||
externalLocks.clear();
|
||||
}
|
||||
|
||||
schedulerLock.dispose();
|
||||
schedulerLock = schedulerLock.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
package net.server.channel.worker;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan
|
||||
*/
|
||||
public class FaceExpressionScheduler extends BaseScheduler {
|
||||
public FaceExpressionScheduler(final Lock channelFaceLock) {
|
||||
public FaceExpressionScheduler(final MonitoredReentrantLock channelFaceLock) {
|
||||
super(MonitoredLockType.CHANNEL_FACESCHDL, Collections.singletonList(channelFaceLock));
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -32,7 +33,7 @@ import net.server.audit.locks.MonitoredReentrantLock;
|
||||
*/
|
||||
public class MobAnimationScheduler extends BaseScheduler {
|
||||
Set<Integer> onAnimationMobs = new HashSet<>(1000);
|
||||
private MonitoredReentrantLock animationLock = new MonitoredReentrantLock(MonitoredLockType.CHANNEL_MOBANIMAT, true);
|
||||
private MonitoredReentrantLock animationLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHANNEL_MOBANIMAT, true);
|
||||
|
||||
private static Runnable r = new Runnable() {
|
||||
@Override
|
||||
@@ -75,7 +76,7 @@ public class MobAnimationScheduler extends BaseScheduler {
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
animationLock.dispose();
|
||||
animationLock = animationLock.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.server.audit.locks.MonitoredLockType;
|
||||
import net.server.audit.locks.MonitoredReentrantLock;
|
||||
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -34,7 +35,7 @@ import net.server.audit.locks.MonitoredReentrantLock;
|
||||
*/
|
||||
public class MobStatusScheduler extends BaseScheduler {
|
||||
private Map<MonsterStatusEffect, MobStatusOvertimeEntry> registeredMobStatusOvertime = new HashMap<>();
|
||||
private MonitoredReentrantLock overtimeStatusLock = new MonitoredReentrantLock(MonitoredLockType.CHANNEL_OVTSTATUS, true);
|
||||
private MonitoredReentrantLock overtimeStatusLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHANNEL_OVTSTATUS, true);
|
||||
|
||||
private class MobStatusOvertimeEntry {
|
||||
private int procCount;
|
||||
@@ -110,7 +111,7 @@ public class MobStatusScheduler extends BaseScheduler {
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
overtimeStatusLock.dispose();
|
||||
overtimeStatusLock = overtimeStatusLock.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user