Reformat and clean up "net" package

This commit is contained in:
P0nk
2021-09-09 23:26:02 +02:00
parent 69f4580637
commit 6be6ea9927
235 changed files with 3556 additions and 3398 deletions
+1 -4
View File
@@ -60,10 +60,7 @@ public final class PacketProcessor {
return null; return null;
} }
PacketHandler handler = handlers[packetId]; PacketHandler handler = handlers[packetId];
if (handler != null) { return handler;
return handler;
}
return null;
} }
public void registerHandler(RecvOpcode code, PacketHandler handler) { public void registerHandler(RecvOpcode code, PacketHandler handler) {
@@ -36,15 +36,15 @@ import java.security.NoSuchAlgorithmException;
public class MapleAESOFB { public class MapleAESOFB {
private static final Logger log = LoggerFactory.getLogger(MapleAESOFB.class); private static final Logger log = LoggerFactory.getLogger(MapleAESOFB.class);
private final static SecretKeySpec skey = new SecretKeySpec( private final static SecretKeySpec skey = new SecretKeySpec(
new byte[]{ new byte[]{
0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
(byte) 0xB4, 0x00, 0x00, 0x00, (byte) 0xB4, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x33, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
0x52, 0x00, 0x00, 0x00}, "AES"); 0x52, 0x00, 0x00, 0x00}, "AES");
private static final byte[] funnyBytes = new byte[]{ private static final byte[] funnyBytes = new byte[]{
(byte) 0xEC, (byte) 0x3F, (byte) 0x77, (byte) 0xA4, (byte) 0x45, (byte) 0xD0, (byte) 0x71, (byte) 0xBF, (byte) 0xEC, (byte) 0x3F, (byte) 0x77, (byte) 0xA4, (byte) 0x45, (byte) 0xD0, (byte) 0x71, (byte) 0xBF,
+1 -1
View File
@@ -206,7 +206,7 @@ public enum RecvOpcode {
private int code = -2; private int code = -2;
private RecvOpcode(int code) { RecvOpcode(int code) {
this.code = code; this.code = code;
} }
+1 -1
View File
@@ -356,7 +356,7 @@ public enum SendOpcode {
VEGA_SCROLL(0x166); VEGA_SCROLL(0x166);
private int code = -2; private int code = -2;
private SendOpcode(int code) { SendOpcode(int code) {
this.code = code; this.code = code;
} }
@@ -33,15 +33,14 @@ import java.util.Map;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
/** /**
*
* @author Danny//changed to map :3 * @author Danny//changed to map :3
* @author Ronan//debuffs to storage as well * @author Ronan//debuffs to storage as well
*/ */
public class PlayerBuffStorage { public class PlayerBuffStorage {
private int id = (int) (Math.random() * 100); private final int id = (int) (Math.random() * 100);
private final Lock lock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.BUFF_STORAGE, true); private final Lock lock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.BUFF_STORAGE, true);
private Map<Integer, List<PlayerBuffValueHolder>> buffs = new HashMap<>(); private final Map<Integer, List<PlayerBuffValueHolder>> buffs = new HashMap<>();
private Map<Integer, Map<Disease, Pair<Long, MobSkill>>> diseases = new HashMap<>(); private final Map<Integer, Map<Disease, Pair<Long, MobSkill>>> diseases = new HashMap<>();
public void addBuffsToStorage(int chrid, List<PlayerBuffValueHolder> toStore) { public void addBuffsToStorage(int chrid, List<PlayerBuffValueHolder> toStore) {
lock.lock(); lock.lock();
@@ -99,9 +98,6 @@ public class PlayerBuffStorage {
return false; return false;
} }
final PlayerBuffStorage other = (PlayerBuffStorage) obj; final PlayerBuffStorage other = (PlayerBuffStorage) obj;
if (id != other.id) { return id == other.id;
return false;
}
return true;
} }
} }
@@ -24,7 +24,6 @@ package net.server;
import server.StatEffect; import server.StatEffect;
/** /**
*
* @author Danny * @author Danny
*/ */
public class PlayerBuffValueHolder { public class PlayerBuffValueHolder {
@@ -22,7 +22,6 @@
package net.server; package net.server;
/** /**
*
* @author Danny * @author Danny
*/ */
public class PlayerCoolDownValueHolder { public class PlayerCoolDownValueHolder {
@@ -29,8 +29,8 @@ public class PlayerDiseaseValueHolder {//Thanks Celino
public Disease disease; public Disease disease;
public PlayerDiseaseValueHolder(final Disease disease, final long startTime, final long length) { public PlayerDiseaseValueHolder(final Disease disease, final long startTime, final long length) {
this.disease = disease; this.disease = disease;
this.startTime = startTime; this.startTime = startTime;
this.length = length; this.length = length;
} }
} }
+18 -16
View File
@@ -36,8 +36,8 @@ public class PlayerStorage {
private final MonitoredReentrantReadWriteLock locks = new MonitoredReentrantReadWriteLock(MonitoredLockType.PLAYER_STORAGE, true); private final MonitoredReentrantReadWriteLock locks = new MonitoredReentrantReadWriteLock(MonitoredLockType.PLAYER_STORAGE, true);
private final Map<Integer, Character> storage = new LinkedHashMap<>(); private final Map<Integer, Character> storage = new LinkedHashMap<>();
private final Map<String, Character> nameStorage = new LinkedHashMap<>(); private final Map<String, Character> nameStorage = new LinkedHashMap<>();
private MonitoredReadLock rlock = MonitoredReadLockFactory.createLock(locks); private final MonitoredReadLock rlock = MonitoredReadLockFactory.createLock(locks);
private MonitoredWriteLock wlock = MonitoredWriteLockFactory.createLock(locks); private final MonitoredWriteLock wlock = MonitoredWriteLockFactory.createLock(locks);
public void addPlayer(Character chr) { public void addPlayer(Character chr) {
wlock.lock(); wlock.lock();
@@ -45,15 +45,17 @@ public class PlayerStorage {
storage.put(chr.getId(), chr); storage.put(chr.getId(), chr);
nameStorage.put(chr.getName().toLowerCase(), chr); nameStorage.put(chr.getName().toLowerCase(), chr);
} finally { } finally {
wlock.unlock(); wlock.unlock();
} }
} }
public Character removePlayer(int chr) { public Character removePlayer(int chr) {
wlock.lock(); wlock.lock();
try { try {
Character mc = storage.remove(chr); Character mc = storage.remove(chr);
if(mc != null) nameStorage.remove(mc.getName().toLowerCase()); if (mc != null) {
nameStorage.remove(mc.getName().toLowerCase());
}
return mc; return mc;
} finally { } finally {
@@ -90,26 +92,26 @@ public class PlayerStorage {
public final void disconnectAll() { public final void disconnectAll() {
List<Character> chrList; List<Character> chrList;
rlock.lock(); rlock.lock();
try { try {
chrList = new ArrayList<>(storage.values()); chrList = new ArrayList<>(storage.values());
} finally { } finally {
rlock.unlock(); rlock.unlock();
} }
for(Character mc : chrList) { for (Character mc : chrList) {
Client client = mc.getClient(); Client client = mc.getClient();
if(client != null) { if (client != null) {
client.forceDisconnect(); client.forceDisconnect();
} }
} }
wlock.lock(); wlock.lock();
try { try {
storage.clear(); storage.clear();
} finally { } finally {
wlock.unlock(); wlock.unlock();
} }
} }
public int getSize() { public int getSize() {
+4 -4
View File
@@ -96,14 +96,14 @@ public class Server {
private static final List<Integer> activeCoupons = new LinkedList<>(); private static final List<Integer> activeCoupons = new LinkedList<>();
private LoginServer loginServer; private LoginServer loginServer;
private List<Map<Integer, String>> channels = new LinkedList<>(); private final List<Map<Integer, String>> channels = new LinkedList<>();
private List<World> worlds = new ArrayList<>(); private final List<World> worlds = new ArrayList<>();
private final Properties subnetInfo = new Properties(); private final Properties subnetInfo = new Properties();
private final Map<Integer, Set<Integer>> accountChars = new HashMap<>(); private final Map<Integer, Set<Integer>> accountChars = new HashMap<>();
private final Map<Integer, Short> accountCharacterCount = new HashMap<>(); private final Map<Integer, Short> accountCharacterCount = new HashMap<>();
private final Map<Integer, Integer> worldChars = new HashMap<>(); private final Map<Integer, Integer> worldChars = new HashMap<>();
private final Map<String, Integer> transitioningChars = new HashMap<>(); private final Map<String, Integer> transitioningChars = new HashMap<>();
private List<Pair<Integer, String>> worldRecommendedList = new LinkedList<>(); private final List<Pair<Integer, String>> worldRecommendedList = new LinkedList<>();
private final Map<Integer, Guild> guilds = new HashMap<>(100); private final Map<Integer, Guild> guilds = new HashMap<>(100);
private final Map<Client, Long> inLoginState = new HashMap<>(100); private final Map<Client, Long> inLoginState = new HashMap<>(100);
@@ -1613,7 +1613,7 @@ public class Server {
String reason = Character.checkWorldTransferEligibility(con, characterId, oldWorld, newWorld); //check if character is still eligible String reason = Character.checkWorldTransferEligibility(con, characterId, oldWorld, newWorld); //check if character is still eligible
if (reason != null) { if (reason != null) {
removedTransfers.add(nameChangeId); removedTransfers.add(nameChangeId);
FilePrinter.print(FilePrinter.WORLD_TRANSFER, "World transfer cancelled : Character ID " + characterId + " at " + Calendar.getInstance().getTime().toString() + ", Reason : " + reason); FilePrinter.print(FilePrinter.WORLD_TRANSFER, "World transfer cancelled : Character ID " + characterId + " at " + Calendar.getInstance().getTime() + ", Reason : " + reason);
try (PreparedStatement delPs = con.prepareStatement("DELETE FROM worldtransfers WHERE id = ?")) { try (PreparedStatement delPs = con.prepareStatement("DELETE FROM worldtransfers WHERE id = ?")) {
delPs.setInt(1, nameChangeId); delPs.setInt(1, nameChangeId);
delPs.executeUpdate(); delPs.executeUpdate();
@@ -20,15 +20,14 @@
package net.server.audit; package net.server.audit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
/** /**
*
* @author Ronan * @author Ronan
*/ */
public class LockCollector { public class LockCollector {
@@ -39,7 +38,7 @@ public class LockCollector {
return instance; return instance;
} }
private Map<Runnable, Integer> disposableLocks = new HashMap<>(200); private final Map<Runnable, Integer> disposableLocks = new HashMap<>(200);
private final Lock lock = new ReentrantLock(true); private final Lock lock = new ReentrantLock(true);
public void registerDisposeAction(Runnable r) { public void registerDisposeAction(Runnable r) {
@@ -56,9 +55,9 @@ public class LockCollector {
lock.lock(); lock.lock();
try { try {
for(Entry<Runnable, Integer> e : disposableLocks.entrySet()) { for (Entry<Runnable, Integer> e : disposableLocks.entrySet()) {
Integer eVal = e.getValue(); Integer eVal = e.getValue();
if(eVal > 5) { // updates each 2min if (eVal > 5) { // updates each 2min
toDispose.add(e.getKey()); toDispose.add(e.getKey());
} else { } else {
disposableLocks.put(e.getKey(), ++eVal); disposableLocks.put(e.getKey(), ++eVal);
@@ -68,7 +67,7 @@ public class LockCollector {
lock.unlock(); lock.unlock();
} }
for(Runnable r : toDispose) { for (Runnable r : toDispose) {
r.run(); r.run();
} }
} }
@@ -33,9 +33,8 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
/** /**
*
* @author RonanLana * @author RonanLana
* * <p>
* This tool has the main purpose of auditing deadlocks throughout the server and must be used only for debugging. The flag is USE_THREAD_TRACKER. * This tool has the main purpose of auditing deadlocks throughout the server and must be used only for debugging. The flag is USE_THREAD_TRACKER.
*/ */
public class ThreadTracker { public class ThreadTracker {
@@ -67,14 +66,14 @@ public class ThreadTracker {
Map<MonitoredLockType, List<Integer>> lockValues = new HashMap<>(); Map<MonitoredLockType, List<Integer>> lockValues = new HashMap<>();
Set<Long> executingThreads = new HashSet<>(); Set<Long> executingThreads = new HashSet<>();
for(Map.Entry<Long, AtomicInteger> lc : lockCount.entrySet()) { for (Map.Entry<Long, AtomicInteger> lc : lockCount.entrySet()) {
if(lc.getValue().get() != 0) { if (lc.getValue().get() != 0) {
executingThreads.add(lockThreads.get(lc.getKey())); executingThreads.add(lockThreads.get(lc.getKey()));
MonitoredLockType lockId = lockIds.get(lc.getKey()); MonitoredLockType lockId = lockIds.get(lc.getKey());
List<Integer> list = lockValues.get(lockId); List<Integer> list = lockValues.get(lockId);
if(list == null) { if (list == null) {
list = new ArrayList<>(); list = new ArrayList<>();
lockValues.put(lockId, list); lockValues.put(lockId, list);
} }
@@ -86,18 +85,18 @@ public class ThreadTracker {
String s = "----------------------------\r\n" + dateFormat + "\r\n "; String s = "----------------------------\r\n" + dateFormat + "\r\n ";
s += "Lock-thread usage count:"; s += "Lock-thread usage count:";
for(Map.Entry<MonitoredLockType, List<Integer>> lock : lockValues.entrySet()) { for (Map.Entry<MonitoredLockType, List<Integer>> lock : lockValues.entrySet()) {
s += ("\r\n " + lock.getKey().name() + ": "); s += ("\r\n " + lock.getKey().name() + ": ");
for(Integer i : lock.getValue()) { for (Integer i : lock.getValue()) {
s += (i + " "); s += (i + " ");
} }
} }
s += "\r\n\r\nThread opened lock path:"; s += "\r\n\r\nThread opened lock path:";
for(Long tid : executingThreads) { for (Long tid : executingThreads) {
s += "\r\n"; s += "\r\n";
for(MonitoredLockType lockid : threadTracker.get(tid)) { for (MonitoredLockType lockid : threadTracker.get(tid)) {
s += (lockid.name() + " "); s += (lockid.name() + " ");
} }
s += "|"; s += "|";
@@ -110,7 +109,7 @@ public class ThreadTracker {
private static String printThreadLog(List<MonitoredLockType> stillLockedPath, String dateFormat) { private static String printThreadLog(List<MonitoredLockType> stillLockedPath, String dateFormat) {
String s = "----------------------------\r\n" + dateFormat + "\r\n "; String s = "----------------------------\r\n" + dateFormat + "\r\n ";
for(MonitoredLockType lock : stillLockedPath) { for (MonitoredLockType lock : stillLockedPath) {
s += (lock.name() + " "); s += (lock.name() + " ");
} }
s += "\r\n\r\n"; s += "\r\n\r\n";
@@ -130,20 +129,20 @@ public class ThreadTracker {
public void accessThreadTracker(boolean update, boolean lock, MonitoredLockType lockId, long lockOid) { public void accessThreadTracker(boolean update, boolean lock, MonitoredLockType lockId, long lockOid) {
ttLock.lock(); ttLock.lock();
try { try {
if(update) { if (update) {
if(!lock) { // update tracker if (!lock) { // update tracker
List<Long> toRemove = new ArrayList<>(); List<Long> toRemove = new ArrayList<>();
for(Long l : threadUpdate.keySet()) { for (Long l : threadUpdate.keySet()) {
int next = threadUpdate.get(l) + 1; int next = threadUpdate.get(l) + 1;
if(next == 4) { if (next == 4) {
List<MonitoredLockType> tt = threadTracker.get(l); List<MonitoredLockType> tt = threadTracker.get(l);
if(tt.isEmpty()) { if (tt.isEmpty()) {
toRemove.add(l); toRemove.add(l);
} else { } else {
StackTraceElement[] ste = threads.get(l).getStackTrace(); StackTraceElement[] ste = threads.get(l).getStackTrace();
if(ste.length > 0) { if (ste.length > 0) {
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getDefault()); dateFormat.setTimeZone(TimeZone.getDefault());
String df = dateFormat.format(new Date()); String df = dateFormat.format(new Date());
@@ -157,29 +156,29 @@ public class ThreadTracker {
threadUpdate.put(l, next); threadUpdate.put(l, next);
} }
for(Long l : toRemove) { for (Long l : toRemove) {
threadTracker.remove(l); threadTracker.remove(l);
threadUpdate.remove(l); threadUpdate.remove(l);
threads.remove(l); threads.remove(l);
for(Map<Long, Integer> threadLock : locks.values()) { for (Map<Long, Integer> threadLock : locks.values()) {
threadLock.remove(l); threadLock.remove(l);
} }
} }
toRemove.clear(); toRemove.clear();
for(Entry<Long, Integer> it : lockUpdate.entrySet()) { for (Entry<Long, Integer> it : lockUpdate.entrySet()) {
int val = it.getValue() + 1; int val = it.getValue() + 1;
if(val < 60) { if (val < 60) {
lockUpdate.put(it.getKey(), val); lockUpdate.put(it.getKey(), val);
} else { } else {
toRemove.add(it.getKey()); // free the structure after 60 silent updates toRemove.add(it.getKey()); // free the structure after 60 silent updates
} }
} }
for(Long l : toRemove) { for (Long l : toRemove) {
lockCount.remove(l); lockCount.remove(l);
lockIds.remove(l); lockIds.remove(l);
lockThreads.remove(l); lockThreads.remove(l);
@@ -195,9 +194,9 @@ public class ThreadTracker {
} else { } else {
long tid = Thread.currentThread().getId(); long tid = Thread.currentThread().getId();
if(lock) { if (lock) {
AtomicInteger c = lockCount.get(lockOid); AtomicInteger c = lockCount.get(lockOid);
if(c == null) { if (c == null) {
c = new AtomicInteger(0); c = new AtomicInteger(0);
lockCount.put(lockOid, c); lockCount.put(lockOid, c);
lockIds.put(lockOid, lockId); lockIds.put(lockOid, lockId);
@@ -207,30 +206,29 @@ public class ThreadTracker {
c.incrementAndGet(); c.incrementAndGet();
List<MonitoredLockType> list = threadTracker.get(tid); List<MonitoredLockType> list = threadTracker.get(tid);
if(list == null) { if (list == null) {
list = new ArrayList<>(5); list = new ArrayList<>(5);
threadTracker.put(tid, list); threadTracker.put(tid, list);
threadUpdate.put(tid, 0); threadUpdate.put(tid, 0);
threads.put(tid, Thread.currentThread()); threads.put(tid, Thread.currentThread());
} else if(list.isEmpty()) { } else if (list.isEmpty()) {
threadUpdate.put(tid, 0); threadUpdate.put(tid, 0);
} }
list.add(lockId); list.add(lockId);
Map<Long, Integer> threadLock = locks.get(lockId); Map<Long, Integer> threadLock = locks.get(lockId);
if(threadLock == null) { if (threadLock == null) {
threadLock = new HashMap<>(5); threadLock = new HashMap<>(5);
locks.put(lockId, threadLock); locks.put(lockId, threadLock);
} }
Integer lc = threadLock.get(tid); Integer lc = threadLock.get(tid);
if(lc != null) { if (lc != null) {
threadLock.put(tid, lc + 1); threadLock.put(tid, lc + 1);
} else { } else {
threadLock.put(tid, 1); threadLock.put(tid, 1);
} }
} } else {
else {
AtomicInteger c = lockCount.get(lockOid); AtomicInteger c = lockCount.get(lockOid);
if (c != null) { // thanks BHB for detecting an NPE here if (c != null) { // thanks BHB for detecting an NPE here
c.decrementAndGet(); c.decrementAndGet();
@@ -239,8 +237,8 @@ public class ThreadTracker {
lockUpdate.put(lockOid, 0); lockUpdate.put(lockOid, 0);
List<MonitoredLockType> list = threadTracker.get(tid); List<MonitoredLockType> list = threadTracker.get(tid);
for(int i = list.size() - 1; i >= 0; i--) { for (int i = list.size() - 1; i >= 0; i--) {
if(lockId.equals(list.get(i))) { if (lockId.equals(list.get(i))) {
list.remove(i); list.remove(i);
break; break;
} }
@@ -258,8 +256,8 @@ public class ThreadTracker {
private String printLockStatus(MonitoredLockType lockId) { private String printLockStatus(MonitoredLockType lockId) {
String s = ""; String s = "";
for(Long threadid : locks.get(lockId).keySet()) { for (Long threadid : locks.get(lockId).keySet()) {
for(MonitoredLockType lockid : threadTracker.get(threadid)) { for (MonitoredLockType lockid : threadTracker.get(threadid)) {
s += (" " + lockid.name()); s += (" " + lockid.name());
} }
@@ -20,7 +20,6 @@
package net.server.audit.locks; package net.server.audit.locks;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
@@ -20,7 +20,6 @@
package net.server.audit.locks; package net.server.audit.locks;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public interface MonitoredReadLock { public interface MonitoredReadLock {
@@ -20,7 +20,6 @@
package net.server.audit.locks; package net.server.audit.locks;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public interface MonitoredReentrantLock { public interface MonitoredReentrantLock {
@@ -22,7 +22,6 @@ package net.server.audit.locks;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class MonitoredReentrantReadWriteLock extends ReentrantReadWriteLock { public class MonitoredReentrantReadWriteLock extends ReentrantReadWriteLock {
@@ -20,7 +20,6 @@
package net.server.audit.locks; package net.server.audit.locks;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public interface MonitoredWriteLock { public interface MonitoredWriteLock {
@@ -37,7 +37,6 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class TrackerReadLock extends ReentrantReadWriteLock.ReadLock implements MonitoredReadLock { public class TrackerReadLock extends ReentrantReadWriteLock.ReadLock implements MonitoredReadLock {
@@ -56,8 +55,8 @@ public class TrackerReadLock extends ReentrantReadWriteLock.ReadLock implements
@Override @Override
public void lock() { public void lock() {
if(YamlConfig.config.server.USE_THREAD_TRACKER) { if (YamlConfig.config.server.USE_THREAD_TRACKER) {
if(deadlockedState != null) { if (deadlockedState != null) {
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getDefault()); dateFormat.setTimeZone(TimeZone.getDefault());
@@ -74,7 +73,7 @@ public class TrackerReadLock extends ReentrantReadWriteLock.ReadLock implements
@Override @Override
public void unlock() { public void unlock() {
if(YamlConfig.config.server.USE_THREAD_TRACKER) { if (YamlConfig.config.server.USE_THREAD_TRACKER) {
unregisterLocking(); unregisterLocking();
} }
@@ -83,9 +82,9 @@ public class TrackerReadLock extends ReentrantReadWriteLock.ReadLock implements
@Override @Override
public boolean tryLock() { public boolean tryLock() {
if(super.tryLock()) { if (super.tryLock()) {
if(YamlConfig.config.server.USE_THREAD_TRACKER) { if (YamlConfig.config.server.USE_THREAD_TRACKER) {
if(deadlockedState != null) { if (deadlockedState != null) {
//FilePrinter.printError(FilePrinter.DEADLOCK_ERROR, "Deadlock occurred when trying to use the '" + id.name() + "' lock resources:\r\n" + printStackTrace(deadlockedState)); //FilePrinter.printError(FilePrinter.DEADLOCK_ERROR, "Deadlock occurred when trying to use the '" + id.name() + "' lock resources:\r\n" + printStackTrace(deadlockedState));
ThreadTracker.getInstance().accessThreadTracker(true, true, id, hashcode); ThreadTracker.getInstance().accessThreadTracker(true, true, id, hashcode);
deadlockedState = null; deadlockedState = null;
@@ -104,7 +103,7 @@ public class TrackerReadLock extends ReentrantReadWriteLock.ReadLock implements
try { try {
ThreadTracker.getInstance().accessThreadTracker(false, true, id, hashcode); ThreadTracker.getInstance().accessThreadTracker(false, true, id, hashcode);
if(reentrantCount.incrementAndGet() == 1) { if (reentrantCount.incrementAndGet() == 1) {
final Thread t = Thread.currentThread(); final Thread t = Thread.currentThread();
timeoutSchedule = TimerManager.getInstance().schedule(() -> issueDeadlock(t), YamlConfig.config.server.LOCK_MONITOR_TIME); timeoutSchedule = TimerManager.getInstance().schedule(() -> issueDeadlock(t), YamlConfig.config.server.LOCK_MONITOR_TIME);
} }
@@ -116,8 +115,8 @@ public class TrackerReadLock extends ReentrantReadWriteLock.ReadLock implements
private void unregisterLocking() { private void unregisterLocking() {
state.lock(); state.lock();
try { try {
if(reentrantCount.decrementAndGet() == 0) { if (reentrantCount.decrementAndGet() == 0) {
if(timeoutSchedule != null) { if (timeoutSchedule != null) {
timeoutSchedule.cancel(false); timeoutSchedule.cancel(false);
timeoutSchedule = null; timeoutSchedule = null;
} }
@@ -147,7 +146,7 @@ public class TrackerReadLock extends ReentrantReadWriteLock.ReadLock implements
public MonitoredReadLock dispose() { public MonitoredReadLock dispose() {
state.lock(); state.lock();
try { try {
if(timeoutSchedule != null) { if (timeoutSchedule != null) {
timeoutSchedule.cancel(false); timeoutSchedule.cancel(false);
timeoutSchedule = null; timeoutSchedule = null;
} }
@@ -35,7 +35,6 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class TrackerReentrantLock extends ReentrantLock implements MonitoredReentrantLock { public class TrackerReentrantLock extends ReentrantLock implements MonitoredReentrantLock {
@@ -60,8 +59,8 @@ public class TrackerReentrantLock extends ReentrantLock implements MonitoredReen
@Override @Override
public void lock() { public void lock() {
if(YamlConfig.config.server.USE_THREAD_TRACKER) { if (YamlConfig.config.server.USE_THREAD_TRACKER) {
if(deadlockedState != null) { if (deadlockedState != null) {
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getDefault()); dateFormat.setTimeZone(TimeZone.getDefault());
@@ -78,7 +77,7 @@ public class TrackerReentrantLock extends ReentrantLock implements MonitoredReen
@Override @Override
public void unlock() { public void unlock() {
if(YamlConfig.config.server.USE_THREAD_TRACKER) { if (YamlConfig.config.server.USE_THREAD_TRACKER) {
unregisterLocking(); unregisterLocking();
} }
@@ -87,9 +86,9 @@ public class TrackerReentrantLock extends ReentrantLock implements MonitoredReen
@Override @Override
public boolean tryLock() { public boolean tryLock() {
if(super.tryLock()) { if (super.tryLock()) {
if(YamlConfig.config.server.USE_THREAD_TRACKER) { if (YamlConfig.config.server.USE_THREAD_TRACKER) {
if(deadlockedState != null) { if (deadlockedState != null) {
//FilePrinter.printError(FilePrinter.DEADLOCK_ERROR, "Deadlock occurred when trying to use the '" + id.name() + "' lock resources:\r\n" + printStackTrace(deadlockedState)); //FilePrinter.printError(FilePrinter.DEADLOCK_ERROR, "Deadlock occurred when trying to use the '" + id.name() + "' lock resources:\r\n" + printStackTrace(deadlockedState));
ThreadTracker.getInstance().accessThreadTracker(true, true, id, hashcode); ThreadTracker.getInstance().accessThreadTracker(true, true, id, hashcode);
deadlockedState = null; deadlockedState = null;
@@ -108,7 +107,7 @@ public class TrackerReentrantLock extends ReentrantLock implements MonitoredReen
try { try {
ThreadTracker.getInstance().accessThreadTracker(false, true, id, hashcode); ThreadTracker.getInstance().accessThreadTracker(false, true, id, hashcode);
if(reentrantCount.incrementAndGet() == 1) { if (reentrantCount.incrementAndGet() == 1) {
final Thread t = Thread.currentThread(); final Thread t = Thread.currentThread();
timeoutSchedule = TimerManager.getInstance().schedule(() -> issueDeadlock(t), YamlConfig.config.server.LOCK_MONITOR_TIME); timeoutSchedule = TimerManager.getInstance().schedule(() -> issueDeadlock(t), YamlConfig.config.server.LOCK_MONITOR_TIME);
} }
@@ -120,8 +119,8 @@ public class TrackerReentrantLock extends ReentrantLock implements MonitoredReen
private void unregisterLocking() { private void unregisterLocking() {
state.lock(); state.lock();
try { try {
if(reentrantCount.decrementAndGet() == 0) { if (reentrantCount.decrementAndGet() == 0) {
if(timeoutSchedule != null) { if (timeoutSchedule != null) {
timeoutSchedule.cancel(false); timeoutSchedule.cancel(false);
timeoutSchedule = null; timeoutSchedule = null;
} }
@@ -151,7 +150,7 @@ public class TrackerReentrantLock extends ReentrantLock implements MonitoredReen
public MonitoredReentrantLock dispose() { public MonitoredReentrantLock dispose() {
state.lock(); state.lock();
try { try {
if(timeoutSchedule != null) { if (timeoutSchedule != null) {
timeoutSchedule.cancel(false); timeoutSchedule.cancel(false);
timeoutSchedule = null; timeoutSchedule = null;
} }
@@ -37,7 +37,6 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class TrackerWriteLock extends ReentrantReadWriteLock.WriteLock implements MonitoredWriteLock { public class TrackerWriteLock extends ReentrantReadWriteLock.WriteLock implements MonitoredWriteLock {
@@ -56,8 +55,8 @@ public class TrackerWriteLock extends ReentrantReadWriteLock.WriteLock implement
@Override @Override
public void lock() { public void lock() {
if(YamlConfig.config.server.USE_THREAD_TRACKER) { if (YamlConfig.config.server.USE_THREAD_TRACKER) {
if(deadlockedState != null) { if (deadlockedState != null) {
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getDefault()); dateFormat.setTimeZone(TimeZone.getDefault());
@@ -74,7 +73,7 @@ public class TrackerWriteLock extends ReentrantReadWriteLock.WriteLock implement
@Override @Override
public void unlock() { public void unlock() {
if(YamlConfig.config.server.USE_THREAD_TRACKER) { if (YamlConfig.config.server.USE_THREAD_TRACKER) {
unregisterLocking(); unregisterLocking();
} }
@@ -83,9 +82,9 @@ public class TrackerWriteLock extends ReentrantReadWriteLock.WriteLock implement
@Override @Override
public boolean tryLock() { public boolean tryLock() {
if(super.tryLock()) { if (super.tryLock()) {
if(YamlConfig.config.server.USE_THREAD_TRACKER) { if (YamlConfig.config.server.USE_THREAD_TRACKER) {
if(deadlockedState != null) { if (deadlockedState != null) {
//FilePrinter.printError(FilePrinter.DEADLOCK_ERROR, "Deadlock occurred when trying to use the '" + id.name() + "' lock resources:\r\n" + printStackTrace(deadlockedState)); //FilePrinter.printError(FilePrinter.DEADLOCK_ERROR, "Deadlock occurred when trying to use the '" + id.name() + "' lock resources:\r\n" + printStackTrace(deadlockedState));
ThreadTracker.getInstance().accessThreadTracker(true, true, id, hashcode); ThreadTracker.getInstance().accessThreadTracker(true, true, id, hashcode);
deadlockedState = null; deadlockedState = null;
@@ -104,7 +103,7 @@ public class TrackerWriteLock extends ReentrantReadWriteLock.WriteLock implement
try { try {
ThreadTracker.getInstance().accessThreadTracker(false, true, id, hashcode); ThreadTracker.getInstance().accessThreadTracker(false, true, id, hashcode);
if(reentrantCount.incrementAndGet() == 1) { if (reentrantCount.incrementAndGet() == 1) {
final Thread t = Thread.currentThread(); final Thread t = Thread.currentThread();
timeoutSchedule = TimerManager.getInstance().schedule(() -> issueDeadlock(t), YamlConfig.config.server.LOCK_MONITOR_TIME); timeoutSchedule = TimerManager.getInstance().schedule(() -> issueDeadlock(t), YamlConfig.config.server.LOCK_MONITOR_TIME);
} }
@@ -116,8 +115,8 @@ public class TrackerWriteLock extends ReentrantReadWriteLock.WriteLock implement
private void unregisterLocking() { private void unregisterLocking() {
state.lock(); state.lock();
try { try {
if(reentrantCount.decrementAndGet() == 0) { if (reentrantCount.decrementAndGet() == 0) {
if(timeoutSchedule != null) { if (timeoutSchedule != null) {
timeoutSchedule.cancel(false); timeoutSchedule.cancel(false);
timeoutSchedule = null; timeoutSchedule = null;
} }
@@ -147,7 +146,7 @@ public class TrackerWriteLock extends ReentrantReadWriteLock.WriteLock implement
public MonitoredWriteLock dispose() { public MonitoredWriteLock dispose() {
state.lock(); state.lock();
try { try {
if(timeoutSchedule != null) { if (timeoutSchedule != null) {
timeoutSchedule.cancel(false); timeoutSchedule.cancel(false);
timeoutSchedule = null; timeoutSchedule = null;
} }
@@ -24,7 +24,6 @@ import net.server.audit.locks.MonitoredReadLock;
import tools.FilePrinter; import tools.FilePrinter;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class EmptyReadLock extends AbstractEmptyLock implements MonitoredReadLock { public class EmptyReadLock extends AbstractEmptyLock implements MonitoredReadLock {
@@ -24,7 +24,6 @@ import net.server.audit.locks.MonitoredReentrantLock;
import tools.FilePrinter; import tools.FilePrinter;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class EmptyReentrantLock extends AbstractEmptyLock implements MonitoredReentrantLock { public class EmptyReentrantLock extends AbstractEmptyLock implements MonitoredReentrantLock {
@@ -24,7 +24,6 @@ import net.server.audit.locks.MonitoredWriteLock;
import tools.FilePrinter; import tools.FilePrinter;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class EmptyWriteLock extends AbstractEmptyLock implements MonitoredWriteLock { public class EmptyWriteLock extends AbstractEmptyLock implements MonitoredWriteLock {
@@ -23,7 +23,6 @@ import net.server.audit.locks.MonitoredReentrantReadWriteLock;
import net.server.audit.locks.active.TrackerReadLock; import net.server.audit.locks.active.TrackerReadLock;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class MonitoredReadLockFactory { public class MonitoredReadLockFactory {
@@ -23,7 +23,6 @@ import net.server.audit.locks.MonitoredLockType;
import net.server.audit.locks.active.TrackerReentrantLock; import net.server.audit.locks.active.TrackerReentrantLock;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class MonitoredReentrantLockFactory { public class MonitoredReentrantLockFactory {
@@ -23,7 +23,6 @@ import net.server.audit.locks.MonitoredReentrantReadWriteLock;
import net.server.audit.locks.active.TrackerWriteLock; import net.server.audit.locks.active.TrackerWriteLock;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class MonitoredWriteLockFactory { public class MonitoredWriteLockFactory {
+122 -89
View File
@@ -70,25 +70,25 @@ public final class Channel {
private MapManager mapManager; private MapManager mapManager;
private EventScriptManager eventSM; private EventScriptManager eventSM;
private ServicesManager services; private ServicesManager services;
private Map<Integer, HiredMerchant> hiredMerchants = new HashMap<>(); private final Map<Integer, HiredMerchant> hiredMerchants = new HashMap<>();
private final Map<Integer, Integer> storedVars = new HashMap<>(); private final Map<Integer, Integer> storedVars = new HashMap<>();
private Set<Integer> playersAway = new HashSet<>(); private final Set<Integer> playersAway = new HashSet<>();
private Map<ExpeditionType, Expedition> expeditions = new HashMap<>(); private final Map<ExpeditionType, Expedition> expeditions = new HashMap<>();
private Map<Integer, MiniDungeon> dungeons = new HashMap<>(); private final Map<Integer, MiniDungeon> dungeons = new HashMap<>();
private List<ExpeditionType> expedType = new ArrayList<>(); private final List<ExpeditionType> expedType = new ArrayList<>();
private Set<MapleMap> ownedMaps = Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>())); private final Set<MapleMap> ownedMaps = Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>()));
private Event event; private Event event;
private boolean finishedShutdown = false; private boolean finishedShutdown = false;
private Set<Integer> usedMC = new HashSet<>(); private final Set<Integer> usedMC = new HashSet<>();
private int usedDojo = 0; private int usedDojo = 0;
private int[] dojoStage; private int[] dojoStage;
private long[] dojoFinishTime; private long[] dojoFinishTime;
private ScheduledFuture<?>[] dojoTask; private ScheduledFuture<?>[] dojoTask;
private Map<Integer, Integer> dojoParty = new HashMap<>(); private final Map<Integer, Integer> dojoParty = new HashMap<>();
private List<Integer> chapelReservationQueue = new LinkedList<>(); private final List<Integer> chapelReservationQueue = new LinkedList<>();
private List<Integer> cathedralReservationQueue = new LinkedList<>(); private final List<Integer> cathedralReservationQueue = new LinkedList<>();
private ScheduledFuture<?> chapelReservationTask; private ScheduledFuture<?> chapelReservationTask;
private ScheduledFuture<?> cathedralReservationTask; private ScheduledFuture<?> cathedralReservationTask;
@@ -100,11 +100,11 @@ public final class Channel {
private Set<Integer> ongoingCathedralGuests = null; private Set<Integer> ongoingCathedralGuests = null;
private long ongoingStartTime; private long ongoingStartTime;
private MonitoredReentrantReadWriteLock merchantLock = new MonitoredReentrantReadWriteLock(MonitoredLockType.MERCHANT, true); private final MonitoredReentrantReadWriteLock merchantLock = new MonitoredReentrantReadWriteLock(MonitoredLockType.MERCHANT, true);
private MonitoredReadLock merchRlock = MonitoredReadLockFactory.createLock(merchantLock); private final MonitoredReadLock merchRlock = MonitoredReadLockFactory.createLock(merchantLock);
private MonitoredWriteLock merchWlock = MonitoredWriteLockFactory.createLock(merchantLock); private final MonitoredWriteLock merchWlock = MonitoredWriteLockFactory.createLock(merchantLock);
private MonitoredReentrantLock[] faceLock = new MonitoredReentrantLock[YamlConfig.config.server.CHANNEL_LOCKS]; private final MonitoredReentrantLock[] faceLock = new MonitoredReentrantLock[YamlConfig.config.server.CHANNEL_LOCKS];
private MonitoredReentrantLock lock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHANNEL, true); private MonitoredReentrantLock lock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHANNEL, true);
@@ -132,7 +132,7 @@ public final class Channel {
dojoStage = new int[20]; dojoStage = new int[20];
dojoFinishTime = new long[20]; dojoFinishTime = new long[20];
dojoTask = new ScheduledFuture<?>[20]; dojoTask = new ScheduledFuture<?>[20];
for(int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
dojoStage[i] = 0; dojoStage[i] = 0;
dojoFinishTime[i] = 0; dojoFinishTime[i] = 0;
dojoTask[i] = null; dojoTask[i] = null;
@@ -152,14 +152,14 @@ public final class Channel {
return channelServer; return channelServer;
} }
public synchronized void reloadEventScriptManager(){ public synchronized void reloadEventScriptManager() {
if (finishedShutdown) { if (finishedShutdown) {
return; return;
} }
eventSM.cancel(); eventSM.cancel();
eventSM = null; eventSM = null;
eventSM = new EventScriptManager(this, getEvents()); eventSM = new EventScriptManager(this, getEvents());
} }
public final synchronized void shutdown() { public final synchronized void shutdown() {
@@ -200,8 +200,8 @@ public final class Channel {
private void closeChannelSchedules() { private void closeChannelSchedules() {
lock.lock(); lock.lock();
try { try {
for(int i = 0; i < dojoTask.length; i++) { for (int i = 0; i < dojoTask.length; i++) {
if(dojoTask[i] != null) { if (dojoTask[i] != null) {
dojoTask[i].cancel(false); dojoTask[i].cancel(false);
dojoTask[i] = null; dojoTask[i] = null;
} }
@@ -219,7 +219,7 @@ public final class Channel {
} }
private void emptyLocks() { private void emptyLocks() {
for(int i = 0; i < YamlConfig.config.server.CHANNEL_LOCKS; i++) { for (int i = 0; i < YamlConfig.config.server.CHANNEL_LOCKS; i++) {
faceLock[i] = faceLock[i].dispose(); faceLock[i] = faceLock[i].dispose();
} }
@@ -280,7 +280,7 @@ public final class Channel {
} }
public int getChannelCapacity() { public int getChannelCapacity() {
return (int)(Math.ceil(((float) players.getAllCharacters().size() / YamlConfig.config.server.CHANNEL_LOAD) * 800)); return (int) (Math.ceil(((float) players.getAllCharacters().size() / YamlConfig.config.server.CHANNEL_LOAD) * 800));
} }
public void broadcastPacket(Packet packet) { public void broadcastPacket(Packet packet) {
@@ -445,16 +445,16 @@ public final class Channel {
getWorldServer().resetDisabledServerMessages(); getWorldServer().resetDisabledServerMessages();
} }
private static String [] getEvents(){ private static String[] getEvents() {
List<String> events = new ArrayList<>(); List<String> events = new ArrayList<>();
for (File file : new File("scripts/event").listFiles()){ for (File file : new File("scripts/event").listFiles()) {
events.add(file.getName().substring(0, file.getName().length() - 3)); events.add(file.getName().substring(0, file.getName().length() - 3));
} }
return events.toArray(new String[0]); return events.toArray(new String[0]);
} }
public int getStoredVar(int key) { public int getStoredVar(int key) {
if(storedVars.containsKey(key)) { if (storedVars.containsKey(key)) {
return storedVars.get(key); return storedVars.get(key);
} }
@@ -466,7 +466,9 @@ public final class Channel {
} }
public int lookupPartyDojo(Party party) { public int lookupPartyDojo(Party party) {
if(party == null) return -1; if (party == null) {
return -1;
}
Integer i = dojoParty.get(party.hashCode()); Integer i = dojoParty.get(party.hashCode());
return (i != null) ? i : -1; return (i != null) ? i : -1;
@@ -482,24 +484,26 @@ public final class Channel {
int dojoList = this.usedDojo; int dojoList = this.usedDojo;
int range, slot = 0; int range, slot = 0;
if(!isPartyDojo) { if (!isPartyDojo) {
dojoList = dojoList >> 5; dojoList = dojoList >> 5;
range = 15; range = 15;
} else { } else {
range = 5; range = 5;
} }
while((dojoList & 1) != 0) { while ((dojoList & 1) != 0) {
dojoList = (dojoList >> 1); dojoList = (dojoList >> 1);
slot++; slot++;
} }
if(slot < range) { if (slot < range) {
int slotMapid = (isPartyDojo ? 925030000 : 925020000) + (100 * (fromStage + 1)) + slot; int slotMapid = (isPartyDojo ? 925030000 : 925020000) + (100 * (fromStage + 1)) + slot;
int dojoSlot = getDojoSlot(slotMapid); int dojoSlot = getDojoSlot(slotMapid);
if(party != null) { if (party != null) {
if(dojoParty.containsKey(party.hashCode())) return -2; if (dojoParty.containsKey(party.hashCode())) {
return -2;
}
dojoParty.put(party.hashCode(), dojoSlot); dojoParty.put(party.hashCode(), dojoSlot);
} }
@@ -527,15 +531,17 @@ public final class Channel {
lock.unlock(); lock.unlock();
} }
if(party != null) { if (party != null) {
if(dojoParty.remove(party.hashCode()) != null) return; if (dojoParty.remove(party.hashCode()) != null) {
return;
}
} }
if(dojoParty.containsValue(slot)) { // strange case, no party there! if (dojoParty.containsValue(slot)) { // strange case, no party there!
Set<Entry<Integer, Integer>> es = new HashSet<>(dojoParty.entrySet()); Set<Entry<Integer, Integer>> es = new HashSet<>(dojoParty.entrySet());
for(Entry<Integer, Integer> e: es) { for (Entry<Integer, Integer> e : es) {
if(e.getValue() == slot) { if (e.getValue() == slot) {
dojoParty.remove(e.getKey()); dojoParty.remove(e.getKey());
break; break;
} }
@@ -548,7 +554,7 @@ public final class Channel {
} }
public void resetDojoMap(int fromMapId) { public void resetDojoMap(int fromMapId) {
for(int i = 0; i < (((fromMapId / 100) % 100 <= 36) ? 5 : 2); i++) { for (int i = 0; i < (((fromMapId / 100) % 100 <= 36) ? 5 : 2); i++) {
this.getMapFactory().getMap(fromMapId + (100 * i)).resetMapObjects(); this.getMapFactory().getMap(fromMapId + (100 * i)).resetMapObjects();
} }
} }
@@ -563,26 +569,30 @@ public final class Channel {
} }
public void freeDojoSectionIfEmpty(int dojoMapId) { public void freeDojoSectionIfEmpty(int dojoMapId) {
final int slot = getDojoSlot(dojoMapId); final int slot = getDojoSlot(dojoMapId);
final int delta = (dojoMapId) % 100; final int delta = (dojoMapId) % 100;
final int stage = (dojoMapId / 100) % 100; final int stage = (dojoMapId / 100) % 100;
final int dojoBaseMap = (dojoMapId >= 925030000) ? 925030000 : 925020000; final int dojoBaseMap = (dojoMapId >= 925030000) ? 925030000 : 925020000;
for (int i = 0; i < 5; i++) { //only 32 stages, but 38 maps for (int i = 0; i < 5; i++) { //only 32 stages, but 38 maps
if (stage + i > 38) { if (stage + i > 38) {
break; break;
}
MapleMap dojoMap = getMapFactory().getMap(dojoBaseMap + (100 * (stage + i)) + delta);
if(!dojoMap.getAllPlayers().isEmpty()) return;
} }
MapleMap dojoMap = getMapFactory().getMap(dojoBaseMap + (100 * (stage + i)) + delta);
if (!dojoMap.getAllPlayers().isEmpty()) {
return;
}
}
freeDojoSlot(slot, null); freeDojoSlot(slot, null);
} }
private void startDojoSchedule(final int dojoMapId) { private void startDojoSchedule(final int dojoMapId) {
final int slot = getDojoSlot(dojoMapId); final int slot = getDojoSlot(dojoMapId);
final int stage = (dojoMapId / 100) % 100; final int stage = (dojoMapId / 100) % 100;
if(stage <= dojoStage[slot]) return; if (stage <= dojoStage[slot]) {
return;
}
long clockTime = (stage > 36 ? 15 : (stage / 6) + 5) * 60000; long clockTime = (stage > 36 ? 15 : (stage / 6) + 5) * 60000;
@@ -602,8 +612,8 @@ public final class Channel {
} }
MapleMap dojoExit = getMapFactory().getMap(925020002); MapleMap dojoExit = getMapFactory().getMap(925020002);
for(Character chr: getMapFactory().getMap(dojoBaseMap + (100 * (stage + i)) + delta).getAllPlayers()) { for (Character chr : getMapFactory().getMap(dojoBaseMap + (100 * (stage + i)) + delta).getAllPlayers()) {
if(GameConstants.isDojo(chr.getMap().getId())) { if (GameConstants.isDojo(chr.getMap().getId())) {
chr.changeMap(dojoExit); chr.changeMap(dojoExit);
} }
party = chr.getParty(); party = chr.getParty();
@@ -622,11 +632,13 @@ public final class Channel {
public void dismissDojoSchedule(int dojoMapId, Party party) { public void dismissDojoSchedule(int dojoMapId, Party party) {
int slot = getDojoSlot(dojoMapId); int slot = getDojoSlot(dojoMapId);
int stage = (dojoMapId / 100) % 100; int stage = (dojoMapId / 100) % 100;
if(stage <= dojoStage[slot]) return; if (stage <= dojoStage[slot]) {
return;
}
lock.lock(); lock.lock();
try { try {
if(this.dojoTask[slot] != null) { if (this.dojoTask[slot] != null) {
this.dojoTask[slot].cancel(false); this.dojoTask[slot].cancel(false);
this.dojoTask[slot] = null; this.dojoTask[slot] = null;
} }
@@ -641,7 +653,7 @@ public final class Channel {
int slot = getDojoSlot(dojoMapId); int slot = getDojoSlot(dojoMapId);
int dojoStg = (dojoMapId / 100) % 100; int dojoStg = (dojoMapId / 100) % 100;
if(this.dojoStage[slot] < dojoStg) { if (this.dojoStage[slot] < dojoStg) {
this.dojoStage[slot] = dojoStg; this.dojoStage[slot] = dojoStg;
return true; return true;
} else { } else {
@@ -656,7 +668,9 @@ public final class Channel {
public boolean addMiniDungeon(int dungeonid) { public boolean addMiniDungeon(int dungeonid) {
lock.lock(); lock.lock();
try { try {
if(dungeons.containsKey(dungeonid)) return false; if (dungeons.containsKey(dungeonid)) {
return false;
}
MiniDungeonInfo mmdi = MiniDungeonInfo.getDungeon(dungeonid); MiniDungeonInfo mmdi = MiniDungeonInfo.getDungeon(dungeonid);
MiniDungeon mmd = new MiniDungeon(mmdi.getBase(), this.getMapFactory().getMap(mmdi.getDungeonId()).getTimeLimit()); // thanks Conrad for noticing hardcoded time limit for minidungeons MiniDungeon mmd = new MiniDungeon(mmdi.getBase(), this.getMapFactory().getMap(mmdi.getDungeonId()).getTimeLimit()); // thanks Conrad for noticing hardcoded time limit for minidungeons
@@ -692,10 +706,14 @@ public final class Channel {
lock.lock(); lock.lock();
try { try {
List<Integer> weddingReservationQueue = (cathedral ? cathedralReservationQueue : chapelReservationQueue); List<Integer> weddingReservationQueue = (cathedral ? cathedralReservationQueue : chapelReservationQueue);
if(weddingReservationQueue.isEmpty()) return null; if (weddingReservationQueue.isEmpty()) {
return null;
}
ret = weddingReservationQueue.remove(0); ret = weddingReservationQueue.remove(0);
if(ret == null) return null; if (ret == null) {
return null;
}
} finally { } finally {
lock.unlock(); lock.unlock();
} }
@@ -723,23 +741,29 @@ public final class Channel {
} }
public int getWeddingReservationStatus(Integer weddingId, boolean cathedral) { public int getWeddingReservationStatus(Integer weddingId, boolean cathedral) {
if(weddingId == null) return -1; if (weddingId == null) {
return -1;
}
lock.lock(); lock.lock();
try { try {
if(cathedral) { if (cathedral) {
if(weddingId.equals(ongoingCathedral)) return 0; if (weddingId.equals(ongoingCathedral)) {
return 0;
}
for(int i = 0; i < cathedralReservationQueue.size(); i++) { for (int i = 0; i < cathedralReservationQueue.size(); i++) {
if(weddingId.equals(cathedralReservationQueue.get(i))) { if (weddingId.equals(cathedralReservationQueue.get(i))) {
return i + 1; return i + 1;
} }
} }
} else { } else {
if(weddingId.equals(ongoingChapel)) return 0; if (weddingId.equals(ongoingChapel)) {
return 0;
}
for(int i = 0; i < chapelReservationQueue.size(); i++) { for (int i = 0; i < chapelReservationQueue.size(); i++) {
if(weddingId.equals(chapelReservationQueue.get(i))) { if (weddingId.equals(chapelReservationQueue.get(i))) {
return i + 1; return i + 1;
} }
} }
@@ -752,7 +776,9 @@ public final class Channel {
} }
public int pushWeddingReservation(Integer weddingId, boolean cathedral, boolean premium, Integer groomId, Integer brideId) { public int pushWeddingReservation(Integer weddingId, boolean cathedral, boolean premium, Integer groomId, Integer brideId) {
if(weddingId == null || isWeddingReserved(weddingId)) return -1; if (weddingId == null || isWeddingReserved(weddingId)) {
return -1;
}
World wserv = getWorldServer(); World wserv = getWorldServer();
wserv.putMarriageQueued(weddingId, cathedral, premium, groomId, brideId); wserv.putMarriageQueued(weddingId, cathedral, premium, groomId, brideId);
@@ -762,7 +788,7 @@ public final class Channel {
List<Integer> weddingReservationQueue = (cathedral ? cathedralReservationQueue : chapelReservationQueue); List<Integer> weddingReservationQueue = (cathedral ? cathedralReservationQueue : chapelReservationQueue);
int delay = YamlConfig.config.server.WEDDING_RESERVATION_DELAY - 1 - weddingReservationQueue.size(); int delay = YamlConfig.config.server.WEDDING_RESERVATION_DELAY - 1 - weddingReservationQueue.size();
for(int i = 0; i < delay; i++) { for (int i = 0; i < delay; i++) {
weddingReservationQueue.add(null); // push empty slots to fill the waiting time weddingReservationQueue.add(null); // push empty slots to fill the waiting time
} }
@@ -776,7 +802,7 @@ public final class Channel {
public boolean isOngoingWeddingGuest(boolean cathedral, int playerId) { public boolean isOngoingWeddingGuest(boolean cathedral, int playerId) {
lock.lock(); lock.lock();
try { try {
if(cathedral) { if (cathedral) {
return ongoingCathedralGuests != null && ongoingCathedralGuests.contains(playerId); return ongoingCathedralGuests != null && ongoingCathedralGuests.contains(playerId);
} else { } else {
return ongoingChapelGuests != null && ongoingChapelGuests.contains(playerId); return ongoingChapelGuests != null && ongoingChapelGuests.contains(playerId);
@@ -807,7 +833,7 @@ public final class Channel {
public void closeOngoingWedding(boolean cathedral) { public void closeOngoingWedding(boolean cathedral) {
lock.lock(); lock.lock();
try { try {
if(cathedral) { if (cathedral) {
ongoingCathedral = null; ongoingCathedral = null;
ongoingCathedralType = null; ongoingCathedralType = null;
ongoingCathedralGuests = null; ongoingCathedralGuests = null;
@@ -824,7 +850,7 @@ public final class Channel {
public void setOngoingWedding(final boolean cathedral, Boolean premium, Integer weddingId, Set<Integer> guests) { public void setOngoingWedding(final boolean cathedral, Boolean premium, Integer weddingId, Set<Integer> guests) {
lock.lock(); lock.lock();
try { try {
if(cathedral) { if (cathedral) {
ongoingCathedral = weddingId; ongoingCathedral = weddingId;
ongoingCathedralType = premium; ongoingCathedralType = premium;
ongoingCathedralGuests = guests; ongoingCathedralGuests = guests;
@@ -838,10 +864,10 @@ public final class Channel {
} }
ongoingStartTime = System.currentTimeMillis(); ongoingStartTime = System.currentTimeMillis();
if(weddingId != null) { if (weddingId != null) {
ScheduledFuture<?> weddingTask = TimerManager.getInstance().schedule(() -> closeOngoingWedding(cathedral), YamlConfig.config.server.WEDDING_RESERVATION_TIMEOUT * 60 * 1000); ScheduledFuture<?> weddingTask = TimerManager.getInstance().schedule(() -> closeOngoingWedding(cathedral), YamlConfig.config.server.WEDDING_RESERVATION_TIMEOUT * 60 * 1000);
if(cathedral) { if (cathedral) {
cathedralReservationTask = weddingTask; cathedralReservationTask = weddingTask;
} else { } else {
chapelReservationTask = weddingTask; chapelReservationTask = weddingTask;
@@ -850,13 +876,17 @@ public final class Channel {
} }
public synchronized boolean acceptOngoingWedding(final boolean cathedral) { // couple succeeded to show up and started the ceremony public synchronized boolean acceptOngoingWedding(final boolean cathedral) { // couple succeeded to show up and started the ceremony
if(cathedral) { if (cathedral) {
if(cathedralReservationTask == null) return false; if (cathedralReservationTask == null) {
return false;
}
cathedralReservationTask.cancel(false); cathedralReservationTask.cancel(false);
cathedralReservationTask = null; cathedralReservationTask = null;
} else { } else {
if(chapelReservationTask == null) return false; if (chapelReservationTask == null) {
return false;
}
chapelReservationTask.cancel(false); chapelReservationTask.cancel(false);
chapelReservationTask = null; chapelReservationTask = null;
@@ -869,29 +899,30 @@ public final class Channel {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
long leftTime = futureTime - System.currentTimeMillis(); long leftTime = futureTime - System.currentTimeMillis();
if(leftTime < 0) { if (leftTime < 0) {
return null; return null;
} }
byte mode = 0; byte mode = 0;
if(leftTime / (60*1000) > 0) { if (leftTime / (60 * 1000) > 0) {
mode++; //counts minutes mode++; //counts minutes
if(leftTime / (60*60*1000) > 0) if (leftTime / (60 * 60 * 1000) > 0) {
mode++; //counts hours mode++; //counts hours
}
} }
switch(mode) { switch (mode) {
case 2: case 2:
int hours = (int) ((leftTime / (1000*60*60))); int hours = (int) ((leftTime / (1000 * 60 * 60)));
str.append(hours + " hours, "); str.append(hours + " hours, ");
case 1: case 1:
int minutes = (int) ((leftTime / (1000*60)) % 60); int minutes = (int) ((leftTime / (1000 * 60)) % 60);
str.append(minutes + " minutes, "); str.append(minutes + " minutes, ");
default: default:
int seconds = (int) (leftTime / 1000) % 60 ; int seconds = (int) (leftTime / 1000) % 60;
str.append(seconds + " seconds"); str.append(seconds + " seconds");
} }
@@ -907,7 +938,9 @@ public final class Channel {
} }
public String getWeddingReservationTimeLeft(Integer weddingId) { public String getWeddingReservationTimeLeft(Integer weddingId) {
if(weddingId == null) return null; if (weddingId == null) {
return null;
}
lock.lock(); lock.lock();
try { try {
@@ -915,17 +948,17 @@ public final class Channel {
int resStatus; int resStatus;
resStatus = getWeddingReservationStatus(weddingId, true); resStatus = getWeddingReservationStatus(weddingId, true);
if(resStatus < 0) { if (resStatus < 0) {
cathedral = false; cathedral = false;
resStatus = getWeddingReservationStatus(weddingId, false); resStatus = getWeddingReservationStatus(weddingId, false);
if(resStatus < 0) { if (resStatus < 0) {
return null; return null;
} }
} }
String venue = (cathedral ? "Cathedral" : "Chapel"); String venue = (cathedral ? "Cathedral" : "Chapel");
if(resStatus == 0) { if (resStatus == 0) {
return venue + " - RIGHT NOW"; return venue + " - RIGHT NOW";
} }
@@ -22,7 +22,6 @@
package net.server.channel; package net.server.channel;
/** /**
*
* @author Frz * @author Frz
*/ */
public class CharacterIdChannelPair { public class CharacterIdChannelPair {
@@ -65,7 +65,9 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
} }
int skillLevel = chr.getSkillLevel(mySkill); int skillLevel = chr.getSkillLevel(mySkill);
if(skillLevel == 0 && GameConstants.isPqSkillMap(chr.getMapId()) && GameConstants.isPqSkill(mySkill.getId())) skillLevel = 1; if (skillLevel == 0 && GameConstants.isPqSkillMap(chr.getMapId()) && GameConstants.isPqSkill(mySkill.getId())) {
skillLevel = 1;
}
if (skillLevel == 0) { if (skillLevel == 0) {
return null; return null;
@@ -108,12 +110,12 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
int mobCount = attackEffect.getMobCount(); int mobCount = attackEffect.getMobCount();
if (attack.skill != Cleric.HEAL) { if (attack.skill != Cleric.HEAL) {
if (player.isAlive()) { if (player.isAlive()) {
if(attack.skill == Aran.BODY_PRESSURE || attack.skill == Marauder.ENERGY_CHARGE || attack.skill == ThunderBreaker.ENERGY_CHARGE) { // thanks IxianMace for noticing Energy Charge skills refreshing on touch if (attack.skill == Aran.BODY_PRESSURE || attack.skill == Marauder.ENERGY_CHARGE || attack.skill == ThunderBreaker.ENERGY_CHARGE) { // thanks IxianMace for noticing Energy Charge skills refreshing on touch
// prevent touch dmg skills refreshing // prevent touch dmg skills refreshing
} else if(attack.skill == DawnWarrior.FINAL_ATTACK || attack.skill == WindArcher.FINAL_ATTACK) { } else if (attack.skill == DawnWarrior.FINAL_ATTACK || attack.skill == WindArcher.FINAL_ATTACK) {
// prevent cygnus FA refreshing // prevent cygnus FA refreshing
mobCount = 15; mobCount = 15;
} else if(attack.skill == NightWalker.POISON_BOMB) {// Poison Bomb } else if (attack.skill == NightWalker.POISON_BOMB) {// Poison Bomb
attackEffect.applyTo(player, new Point(attack.position.x, attack.position.y)); attackEffect.applyTo(player, new Point(attack.position.x, attack.position.y));
} else { } else {
attackEffect.applyTo(player); attackEffect.applyTo(player);
@@ -154,30 +156,30 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
MapObject mapobject = map.getMapObject(oned); MapObject mapobject = map.getMapObject(oned);
if (mapobject != null && mapobject.getType() == MapObjectType.ITEM) { if (mapobject != null && mapobject.getType() == MapObjectType.ITEM) {
final MapItem mapitem = (MapItem) mapobject; final MapItem mapitem = (MapItem) mapobject;
if (mapitem.getMeso() == 0) { //Maybe it is possible some how? if (mapitem.getMeso() == 0) { //Maybe it is possible some how?
return;
}
mapitem.lockItem();
try {
if (mapitem.isPickedUp()) {
return; return;
} }
TimerManager.getInstance().schedule(() -> {
mapitem.lockItem(); mapitem.lockItem();
try { try {
if (mapitem.isPickedUp()) { if (mapitem.isPickedUp()) {
return; return;
}
TimerManager.getInstance().schedule(() -> {
mapitem.lockItem();
try {
if (mapitem.isPickedUp()) {
return;
}
map.pickItemDrop(PacketCreator.removeItemFromMap(mapitem.getObjectId(), 4, 0), mapitem);
} finally {
mapitem.unlockItem();
} }
}, delay); map.pickItemDrop(PacketCreator.removeItemFromMap(mapitem.getObjectId(), 4, 0), mapitem);
delay += 100; } finally {
} finally { mapitem.unlockItem();
mapitem.unlockItem(); }
} }, delay);
delay += 100;
} finally {
mapitem.unlockItem();
}
} else if (mapobject != null && mapobject.getType() != MapObjectType.MONSTER) { } else if (mapobject != null && mapobject.getType() != MapObjectType.MONSTER) {
return; return;
} }
@@ -189,29 +191,29 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
double distance = player.getPosition().distanceSq(monster.getPosition()); double distance = player.getPosition().distanceSq(monster.getPosition());
double distanceToDetect = 200000.0; double distanceToDetect = 200000.0;
if(attack.ranged) if (attack.ranged) {
distanceToDetect += 400000; distanceToDetect += 400000;
}
if(attack.magic) if (attack.magic) {
distanceToDetect += 200000; distanceToDetect += 200000;
}
if(player.getJob().isA(Job.ARAN1)) if (player.getJob().isA(Job.ARAN1)) {
distanceToDetect += 200000; // Arans have extra range over normal warriors. distanceToDetect += 200000; // Arans have extra range over normal warriors.
}
if(attack.skill == Aran.COMBO_SMASH || attack.skill == Aran.BODY_PRESSURE) if (attack.skill == Aran.COMBO_SMASH || attack.skill == Aran.BODY_PRESSURE) {
distanceToDetect += 40000; distanceToDetect += 40000;
} else if (attack.skill == Bishop.GENESIS || attack.skill == ILArchMage.BLIZZARD || attack.skill == FPArchMage.METEOR_SHOWER) {
else if(attack.skill == Bishop.GENESIS || attack.skill == ILArchMage.BLIZZARD || attack.skill == FPArchMage.METEOR_SHOWER)
distanceToDetect += 275000; distanceToDetect += 275000;
} else if (attack.skill == Hero.BRANDISH || attack.skill == DragonKnight.SPEAR_CRUSHER || attack.skill == DragonKnight.POLE_ARM_CRUSHER) {
else if(attack.skill == Hero.BRANDISH || attack.skill == DragonKnight.SPEAR_CRUSHER || attack.skill == DragonKnight.POLE_ARM_CRUSHER)
distanceToDetect += 40000; distanceToDetect += 40000;
} else if (attack.skill == DragonKnight.DRAGON_ROAR || attack.skill == SuperGM.SUPER_DRAGON_ROAR) {
else if(attack.skill == DragonKnight.DRAGON_ROAR || attack.skill == SuperGM.SUPER_DRAGON_ROAR)
distanceToDetect += 250000; distanceToDetect += 250000;
} else if (attack.skill == Shadower.BOOMERANG_STEP) {
else if(attack.skill == Shadower.BOOMERANG_STEP)
distanceToDetect += 60000; distanceToDetect += 60000;
}
if (distance > distanceToDetect) { if (distance > distanceToDetect) {
AutobanFactory.DISTANCE_HACK.alert(player, "Distance Sq to monster: " + distance + " SID: " + attack.skill + " MID: " + monster.getId()); AutobanFactory.DISTANCE_HACK.alert(player, "Distance Sq to monster: " + distance + " SID: " + attack.skill + " MID: " + monster.getId());
@@ -244,7 +246,9 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
} }
for (Integer eachd : onedList) { for (Integer eachd : onedList) {
if(eachd < 0) eachd += Integer.MAX_VALUE; if (eachd < 0) {
eachd += Integer.MAX_VALUE;
}
totDamageToOneMonster += eachd; totDamageToOneMonster += eachd;
} }
totDamage += totDamageToOneMonster; totDamage += totDamageToOneMonster;
@@ -252,7 +256,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
if (player.getBuffedValue(BuffStat.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)) { if (player.getBuffedValue(BuffStat.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); Skill pickpocket = SkillFactory.getSkill(ChiefBandit.PICKPOCKET);
int picklv = (player.isGM()) ? pickpocket.getMaxLevel() : player.getSkillLevel(pickpocket); int picklv = (player.isGM()) ? pickpocket.getMaxLevel() : player.getSkillLevel(pickpocket);
if(picklv > 0) { if (picklv > 0) {
int delay = 0; int delay = 0;
final int maxmeso = player.getBuffedValue(BuffStat.PICKPOCKET); final int maxmeso = player.getBuffedValue(BuffStat.PICKPOCKET);
for (Integer eachd : onedList) { for (Integer eachd : onedList) {
@@ -260,10 +264,11 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
if (pickpocket.getEffect(picklv).makeChanceResult()) { if (pickpocket.getEffect(picklv).makeChanceResult()) {
final int eachdf; final int eachdf;
if(eachd < 0) if (eachd < 0) {
eachdf = eachd + Integer.MAX_VALUE; eachdf = eachd + Integer.MAX_VALUE;
else } else {
eachdf = eachd; eachdf = eachd;
}
TimerManager.getInstance().schedule(() -> map.spawnMesoDrop(Math.min((int) Math.max(((double) eachdf / (double) 20000) * (double) maxmeso, 1), maxmeso), new Point((int) (monster.getPosition().getX() + Randomizer.nextInt(100) - 50), (int) (monster.getPosition().getY())), monster, player, true, (byte) 2), delay); TimerManager.getInstance().schedule(() -> map.spawnMesoDrop(Math.min((int) Math.max(((double) eachdf / (double) 20000) * (double) maxmeso, 1), maxmeso), new Point((int) (monster.getPosition().getX() + Randomizer.nextInt(100) - 50), (int) (monster.getPosition().getY())), monster, player, true, (byte) 2), delay);
delay += 100; delay += 100;
@@ -280,11 +285,13 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
MonsterInformationProvider mi = MonsterInformationProvider.getInstance(); MonsterInformationProvider mi = MonsterInformationProvider.getInstance();
List<Integer> dropPool = mi.retrieveDropPool(monster.getId()); List<Integer> dropPool = mi.retrieveDropPool(monster.getId());
if(!dropPool.isEmpty()) { if (!dropPool.isEmpty()) {
int rndPool = (int) Math.floor(Math.random() * dropPool.get(dropPool.size() - 1)); int rndPool = (int) Math.floor(Math.random() * dropPool.get(dropPool.size() - 1));
int i = 0; int i = 0;
while(rndPool >= dropPool.get(i)) i++; while (rndPool >= dropPool.get(i)) {
i++;
}
List<MonsterDropEntry> toSteal = new ArrayList<>(); List<MonsterDropEntry> toSteal = new ArrayList<>();
toSteal.add(mi.retrieveDrop(monster.getId()).get(i)); toSteal.add(mi.retrieveDrop(monster.getId()).get(i));
@@ -313,13 +320,13 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
} }
if (player.isAran()) { if (player.isAran()) {
if (player.getBuffedValue(BuffStat.WK_CHARGE) != null) { if (player.getBuffedValue(BuffStat.WK_CHARGE) != null) {
Skill snowCharge = SkillFactory.getSkill(Aran.SNOW_CHARGE); Skill snowCharge = SkillFactory.getSkill(Aran.SNOW_CHARGE);
if (totDamageToOneMonster > 0) { if (totDamageToOneMonster > 0) {
MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.SPEED, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getX()), snowCharge, null, false); MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(Collections.singletonMap(MonsterStatus.SPEED, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getX()), snowCharge, null, false);
monster.applyStatus(player, monsterStatusEffect, false, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getY() * 1000); monster.applyStatus(player, monsterStatusEffect, false, snowCharge.getEffect(player.getSkillLevel(snowCharge)).getY() * 1000);
} }
} }
} }
if (player.getBuffedValue(BuffStat.HAMSTRING) != null) { if (player.getBuffedValue(BuffStat.HAMSTRING) != null) {
Skill hamstring = SkillFactory.getSkill(Bowmaster.HAMSTRING); Skill hamstring = SkillFactory.getSkill(Bowmaster.HAMSTRING);
@@ -390,7 +397,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
} }
} }
} else if (job >= 311 && job <= 322) { } else if (job >= 311 && job <= 322) {
if (!monster.isBoss()) { if (!monster.isBoss()) {
Skill mortalBlow; Skill mortalBlow;
if (job == 311 || job == 312) { if (job == 311 || job == 312) {
mortalBlow = SkillFactory.getSkill(Ranger.MORTAL_BLOW); mortalBlow = SkillFactory.getSkill(Ranger.MORTAL_BLOW);
@@ -407,7 +414,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
} }
} }
} }
} }
} }
if (attack.skill != 0) { if (attack.skill != 0) {
if (attackEffect.getFixDamage() != -1) { if (attackEffect.getFixDamage() != -1) {
@@ -416,15 +423,15 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
} }
int threeSnailsId = player.getJobType() * 10000000 + 1000; int threeSnailsId = player.getJobType() * 10000000 + 1000;
if(attack.skill == threeSnailsId) { if (attack.skill == threeSnailsId) {
if(YamlConfig.config.server.USE_ULTRA_THREE_SNAILS) { if (YamlConfig.config.server.USE_ULTRA_THREE_SNAILS) {
int skillLv = player.getSkillLevel(threeSnailsId); int skillLv = player.getSkillLevel(threeSnailsId);
if(skillLv > 0) { if (skillLv > 0) {
AbstractPlayerInteraction api = player.getAbstractPlayerInteraction(); AbstractPlayerInteraction api = player.getAbstractPlayerInteraction();
int shellId; int shellId;
switch(skillLv) { switch (skillLv) {
case 1: case 1:
shellId = 4000019; shellId = 4000019;
break; break;
@@ -437,7 +444,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
shellId = 4000016; shellId = 4000016;
} }
if(api.haveItem(shellId, 1)) { if (api.haveItem(shellId, 1)) {
api.gainItem(shellId, (short) -1, false); api.gainItem(shellId, (short) -1, false);
totDamageToOneMonster *= player.getLevel(); totDamageToOneMonster *= player.getLevel();
} else { } else {
@@ -452,28 +459,28 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
} }
if (totDamageToOneMonster > 0 && attackEffect != null) { if (totDamageToOneMonster > 0 && attackEffect != null) {
Map<MonsterStatus, Integer> attackEffectStati = attackEffect.getMonsterStati(); Map<MonsterStatus, Integer> attackEffectStati = attackEffect.getMonsterStati();
if(!attackEffectStati.isEmpty()) { if (!attackEffectStati.isEmpty()) {
if (attackEffect.makeChanceResult()) { if (attackEffect.makeChanceResult()) {
monster.applyStatus(player, new MonsterStatusEffect(attackEffectStati, theSkill, null, false), attackEffect.isPoison(), attackEffect.getDuration()); monster.applyStatus(player, new MonsterStatusEffect(attackEffectStati, theSkill, null, false), attackEffect.isPoison(), attackEffect.getDuration());
} }
} }
} }
if (attack.skill == Paladin.HEAVENS_HAMMER) { if (attack.skill == Paladin.HEAVENS_HAMMER) {
if(!monster.isBoss()) { if (!monster.isBoss()) {
damageMonsterWithSkill(player, map, monster, monster.getHp() - 1, attack.skill, 1777); damageMonsterWithSkill(player, map, monster, monster.getHp() - 1, attack.skill, 1777);
} else { } else {
int HHDmg = (player.calculateMaxBaseDamage(player.getTotalWatk()) * (SkillFactory.getSkill(Paladin.HEAVENS_HAMMER).getEffect(player.getSkillLevel(SkillFactory.getSkill(Paladin.HEAVENS_HAMMER))).getDamage() / 100)); int HHDmg = (player.calculateMaxBaseDamage(player.getTotalWatk()) * (SkillFactory.getSkill(Paladin.HEAVENS_HAMMER).getEffect(player.getSkillLevel(SkillFactory.getSkill(Paladin.HEAVENS_HAMMER))).getDamage() / 100));
damageMonsterWithSkill(player, map, monster, (int) (Math.floor(Math.random() * (HHDmg / 5) + HHDmg * .8)), attack.skill, 1777); damageMonsterWithSkill(player, map, monster, (int) (Math.floor(Math.random() * (HHDmg / 5) + HHDmg * .8)), attack.skill, 1777);
} }
} else if (attack.skill == Aran.COMBO_TEMPEST) { } else if (attack.skill == Aran.COMBO_TEMPEST) {
if(!monster.isBoss()) { if (!monster.isBoss()) {
damageMonsterWithSkill(player, map, monster, monster.getHp(), attack.skill, 0); damageMonsterWithSkill(player, map, monster, monster.getHp(), attack.skill, 0);
} else { } else {
int TmpDmg = (player.calculateMaxBaseDamage(player.getTotalWatk()) * (SkillFactory.getSkill(Aran.COMBO_TEMPEST).getEffect(player.getSkillLevel(SkillFactory.getSkill(Aran.COMBO_TEMPEST))).getDamage() / 100)); int TmpDmg = (player.calculateMaxBaseDamage(player.getTotalWatk()) * (SkillFactory.getSkill(Aran.COMBO_TEMPEST).getEffect(player.getSkillLevel(SkillFactory.getSkill(Aran.COMBO_TEMPEST))).getDamage() / 100));
damageMonsterWithSkill(player, map, monster, (int) (Math.floor(Math.random() * (TmpDmg / 5) + TmpDmg * .8)), attack.skill, 0); damageMonsterWithSkill(player, map, monster, (int) (Math.floor(Math.random() * (TmpDmg / 5) + TmpDmg * .8)), attack.skill, 0);
} }
} else { } else {
if(attack.skill == Aran.BODY_PRESSURE) { if (attack.skill == Aran.BODY_PRESSURE) {
map.broadcastMessage(PacketCreator.damageMonster(monster.getObjectId(), totDamageToOneMonster)); map.broadcastMessage(PacketCreator.damageMonster(monster.getObjectId(), totDamageToOneMonster));
} }
@@ -511,10 +518,13 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
private static void damageMonsterWithSkill(final Character attacker, final MapleMap map, final Monster monster, final int damage, int skillid, int fixedTime) { private static void damageMonsterWithSkill(final Character attacker, final MapleMap map, final Monster monster, final int damage, int skillid, int fixedTime) {
int animationTime; int animationTime;
if(fixedTime == 0) animationTime = SkillFactory.getSkill(skillid).getAnimationTime(); if (fixedTime == 0) {
else animationTime = fixedTime; animationTime = SkillFactory.getSkill(skillid).getAnimationTime();
} else {
animationTime = fixedTime;
}
if(animationTime > 0) { // be sure to only use LIMITED ATTACKS with animation time here if (animationTime > 0) { // be sure to only use LIMITED ATTACKS with animation time here
TimerManager.getInstance().schedule(() -> { TimerManager.getInstance().schedule(() -> {
map.broadcastMessage(PacketCreator.damageMonster(monster.getObjectId(), damage), monster.getPosition()); map.broadcastMessage(PacketCreator.damageMonster(monster.getObjectId(), damage), monster.getPosition());
map.damageMonster(attacker, monster, damage); map.damageMonster(attacker, monster, damage);
@@ -526,7 +536,7 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
} }
protected AttackInfo parseDamage(InPacket p, Character chr, boolean ranged, boolean magic) { protected AttackInfo parseDamage(InPacket p, Character chr, boolean ranged, boolean magic) {
//2C 00 00 01 91 A1 12 00 A5 57 62 FC E2 75 99 10 00 47 80 01 04 01 C6 CC 02 DD FF 5F 00 //2C 00 00 01 91 A1 12 00 A5 57 62 FC E2 75 99 10 00 47 80 01 04 01 C6 CC 02 DD FF 5F 00
AttackInfo ret = new AttackInfo(); AttackInfo ret = new AttackInfo();
p.readByte(); p.readByte();
ret.numAttackedAndDamage = p.readByte(); ret.numAttackedAndDamage = p.readByte();
@@ -539,7 +549,9 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
if (ret.skill > 0) { if (ret.skill > 0) {
ret.skilllevel = chr.getSkillLevel(ret.skill); ret.skilllevel = chr.getSkillLevel(ret.skill);
if(ret.skilllevel == 0 && GameConstants.isPqSkillMap(chr.getMapId()) && GameConstants.isPqSkill(ret.skill)) ret.skilllevel = 1; if (ret.skilllevel == 0 && GameConstants.isPqSkillMap(chr.getMapId()) && GameConstants.isPqSkill(ret.skill)) {
ret.skilllevel = 1;
}
} }
if (ret.skill == Evan.ICE_BREATH || ret.skill == Evan.FIRE_BREATH || ret.skill == FPArchMage.BIG_BANG || ret.skill == ILArchMage.BIG_BANG || ret.skill == Bishop.BIG_BANG || ret.skill == Gunslinger.GRENADE || ret.skill == Brawler.CORKSCREW_BLOW || ret.skill == ThunderBreaker.CORKSCREW_BLOW || ret.skill == NightWalker.POISON_BOMB) { if (ret.skill == Evan.ICE_BREATH || ret.skill == Evan.FIRE_BREATH || ret.skill == FPArchMage.BIG_BANG || ret.skill == ILArchMage.BIG_BANG || ret.skill == Bishop.BIG_BANG || ret.skill == Gunslinger.GRENADE || ret.skill == Brawler.CORKSCREW_BLOW || ret.skill == ThunderBreaker.CORKSCREW_BLOW || ret.skill == NightWalker.POISON_BOMB) {
@@ -607,51 +619,55 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
// Several skills have their own formula in this section. // Several skills have their own formula in this section.
long calcDmgMax; long calcDmgMax;
if(magic && ret.skill != 0) { // thanks onechord for noticing a few false positives stemming from maxdmg as 0 if (magic && ret.skill != 0) { // thanks onechord for noticing a few false positives stemming from maxdmg as 0
calcDmgMax = (long) (Math.ceil((chr.getTotalMagic() * Math.ceil(chr.getTotalMagic() / 1000.0) + chr.getTotalMagic()) / 30.0) + Math.ceil(chr.getTotalInt() / 200.0)); calcDmgMax = (long) (Math.ceil((chr.getTotalMagic() * Math.ceil(chr.getTotalMagic() / 1000.0) + chr.getTotalMagic()) / 30.0) + Math.ceil(chr.getTotalInt() / 200.0));
} else if(ret.skill == 4001344 || ret.skill == NightWalker.LUCKY_SEVEN || ret.skill == NightLord.TRIPLE_THROW) { } else if (ret.skill == 4001344 || ret.skill == NightWalker.LUCKY_SEVEN || ret.skill == NightLord.TRIPLE_THROW) {
calcDmgMax = (long) ((chr.getTotalLuk() * 5) * Math.ceil(chr.getTotalWatk() / 100.0)); calcDmgMax = (long) ((chr.getTotalLuk() * 5) * Math.ceil(chr.getTotalWatk() / 100.0));
} else if(ret.skill == DragonKnight.DRAGON_ROAR) { } else if (ret.skill == DragonKnight.DRAGON_ROAR) {
calcDmgMax = (long) ((chr.getTotalStr() * 4 + chr.getTotalDex()) * Math.ceil(chr.getTotalWatk() / 100.0)); calcDmgMax = (long) ((chr.getTotalStr() * 4 + chr.getTotalDex()) * Math.ceil(chr.getTotalWatk() / 100.0));
} else if(ret.skill == NightLord.VENOMOUS_STAR || ret.skill == Shadower.VENOMOUS_STAB) { } else if (ret.skill == NightLord.VENOMOUS_STAR || ret.skill == Shadower.VENOMOUS_STAB) {
calcDmgMax = (long) (Math.ceil((18.5 * (chr.getTotalStr() + chr.getTotalLuk()) + chr.getTotalDex() * 2) / 100.0) * chr.calculateMaxBaseDamage(chr.getTotalWatk())); calcDmgMax = (long) (Math.ceil((18.5 * (chr.getTotalStr() + chr.getTotalLuk()) + chr.getTotalDex() * 2) / 100.0) * chr.calculateMaxBaseDamage(chr.getTotalWatk()));
} else { } else {
calcDmgMax = chr.calculateMaxBaseDamage(chr.getTotalWatk()); calcDmgMax = chr.calculateMaxBaseDamage(chr.getTotalWatk());
} }
if(ret.skill != 0) { if (ret.skill != 0) {
Skill skill = SkillFactory.getSkill(ret.skill); Skill skill = SkillFactory.getSkill(ret.skill);
StatEffect effect = skill.getEffect(ret.skilllevel); StatEffect effect = skill.getEffect(ret.skilllevel);
if (magic) { if (magic) {
// Since the skill is magic based, use the magic formula // Since the skill is magic based, use the magic formula
if(chr.getJob() == Job.IL_ARCHMAGE || chr.getJob() == Job.IL_MAGE) { if (chr.getJob() == Job.IL_ARCHMAGE || chr.getJob() == Job.IL_MAGE) {
int skillLvl = chr.getSkillLevel(ILMage.ELEMENT_AMPLIFICATION); int skillLvl = chr.getSkillLevel(ILMage.ELEMENT_AMPLIFICATION);
if(skillLvl > 0) if (skillLvl > 0) {
calcDmgMax = calcDmgMax * SkillFactory.getSkill(ILMage.ELEMENT_AMPLIFICATION).getEffect(skillLvl).getY() / 100; calcDmgMax = calcDmgMax * SkillFactory.getSkill(ILMage.ELEMENT_AMPLIFICATION).getEffect(skillLvl).getY() / 100;
} else if(chr.getJob() == Job.FP_ARCHMAGE || chr.getJob() == Job.FP_MAGE) { }
} else if (chr.getJob() == Job.FP_ARCHMAGE || chr.getJob() == Job.FP_MAGE) {
int skillLvl = chr.getSkillLevel(FPMage.ELEMENT_AMPLIFICATION); int skillLvl = chr.getSkillLevel(FPMage.ELEMENT_AMPLIFICATION);
if(skillLvl > 0) if (skillLvl > 0) {
calcDmgMax = calcDmgMax * SkillFactory.getSkill(FPMage.ELEMENT_AMPLIFICATION).getEffect(skillLvl).getY() / 100; calcDmgMax = calcDmgMax * SkillFactory.getSkill(FPMage.ELEMENT_AMPLIFICATION).getEffect(skillLvl).getY() / 100;
} else if(chr.getJob() == Job.BLAZEWIZARD3 || chr.getJob() == Job.BLAZEWIZARD4) { }
} else if (chr.getJob() == Job.BLAZEWIZARD3 || chr.getJob() == Job.BLAZEWIZARD4) {
int skillLvl = chr.getSkillLevel(BlazeWizard.ELEMENT_AMPLIFICATION); int skillLvl = chr.getSkillLevel(BlazeWizard.ELEMENT_AMPLIFICATION);
if(skillLvl > 0) if (skillLvl > 0) {
calcDmgMax = calcDmgMax * SkillFactory.getSkill(BlazeWizard.ELEMENT_AMPLIFICATION).getEffect(skillLvl).getY() / 100; calcDmgMax = calcDmgMax * SkillFactory.getSkill(BlazeWizard.ELEMENT_AMPLIFICATION).getEffect(skillLvl).getY() / 100;
} else if(chr.getJob() == Job.EVAN7 || chr.getJob() == Job.EVAN8 || chr.getJob() == Job.EVAN9 || chr.getJob() == Job.EVAN10) { }
} else if (chr.getJob() == Job.EVAN7 || chr.getJob() == Job.EVAN8 || chr.getJob() == Job.EVAN9 || chr.getJob() == Job.EVAN10) {
int skillLvl = chr.getSkillLevel(Evan.MAGIC_AMPLIFICATION); int skillLvl = chr.getSkillLevel(Evan.MAGIC_AMPLIFICATION);
if(skillLvl > 0) if (skillLvl > 0) {
calcDmgMax = calcDmgMax * SkillFactory.getSkill(Evan.MAGIC_AMPLIFICATION).getEffect(skillLvl).getY() / 100; calcDmgMax = calcDmgMax * SkillFactory.getSkill(Evan.MAGIC_AMPLIFICATION).getEffect(skillLvl).getY() / 100;
}
} }
calcDmgMax *= effect.getMatk(); calcDmgMax *= effect.getMatk();
if(ret.skill == Cleric.HEAL) { if (ret.skill == Cleric.HEAL) {
// This formula is still a bit wonky, but it is fairly accurate. // This formula is still a bit wonky, but it is fairly accurate.
calcDmgMax = (int) Math.round((chr.getTotalInt() * 4.8 + chr.getTotalLuk() * 4) * chr.getTotalMagic() / 1000); calcDmgMax = (int) Math.round((chr.getTotalInt() * 4.8 + chr.getTotalLuk() * 4) * chr.getTotalMagic() / 1000);
calcDmgMax = calcDmgMax * effect.getHp() / 100; calcDmgMax = calcDmgMax * effect.getHp() / 100;
ret.speed = 7; ret.speed = 7;
} }
} else if(ret.skill == Hermit.SHADOW_MESO) { } else if (ret.skill == Hermit.SHADOW_MESO) {
// Shadow Meso also has its own formula // Shadow Meso also has its own formula
calcDmgMax = effect.getMoneyCon() * 10; calcDmgMax = effect.getMoneyCon() * 10;
calcDmgMax = (int) Math.floor(calcDmgMax * 1.5); calcDmgMax = (int) Math.floor(calcDmgMax * 1.5);
@@ -662,40 +678,43 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
} }
Integer comboBuff = chr.getBuffedValue(BuffStat.COMBO); Integer comboBuff = chr.getBuffedValue(BuffStat.COMBO);
if(comboBuff != null && comboBuff > 0) { if (comboBuff != null && comboBuff > 0) {
int oid = chr.isCygnus() ? DawnWarrior.COMBO : Crusader.COMBO; int oid = chr.isCygnus() ? DawnWarrior.COMBO : Crusader.COMBO;
int advcomboid = chr.isCygnus() ? DawnWarrior.ADVANCED_COMBO : Hero.ADVANCED_COMBO; int advcomboid = chr.isCygnus() ? DawnWarrior.ADVANCED_COMBO : Hero.ADVANCED_COMBO;
if(comboBuff > 6) { if (comboBuff > 6) {
// Advanced Combo // Advanced Combo
StatEffect ceffect = SkillFactory.getSkill(advcomboid).getEffect(chr.getSkillLevel(advcomboid)); StatEffect ceffect = SkillFactory.getSkill(advcomboid).getEffect(chr.getSkillLevel(advcomboid));
calcDmgMax = (long) Math.floor(calcDmgMax * (ceffect.getDamage() + 50) / 100 + 0.20 + (comboBuff - 5) * 0.04); calcDmgMax = (long) Math.floor(calcDmgMax * (ceffect.getDamage() + 50) / 100 + 0.20 + (comboBuff - 5) * 0.04);
} else { } else {
// Normal Combo // Normal Combo
int skillLv = chr.getSkillLevel(oid); int skillLv = chr.getSkillLevel(oid);
if(skillLv <= 0 || chr.isGM()) skillLv = SkillFactory.getSkill(oid).getMaxLevel(); if (skillLv <= 0 || chr.isGM()) {
skillLv = SkillFactory.getSkill(oid).getMaxLevel();
}
if(skillLv > 0) { if (skillLv > 0) {
StatEffect ceffect = SkillFactory.getSkill(oid).getEffect(skillLv); StatEffect ceffect = SkillFactory.getSkill(oid).getEffect(skillLv);
calcDmgMax = (long) Math.floor(calcDmgMax * (ceffect.getDamage() + 50) / 100 + Math.floor((comboBuff - 1) * (skillLv / 6)) / 100); calcDmgMax = (long) Math.floor(calcDmgMax * (ceffect.getDamage() + 50) / 100 + Math.floor((comboBuff - 1) * (skillLv / 6)) / 100);
} }
} }
if(GameConstants.isFinisherSkill(ret.skill)) { 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; int orbs = comboBuff - 1;
if(orbs == 2) if (orbs == 2) {
calcDmgMax *= 1.2; calcDmgMax *= 1.2;
else if(orbs == 3) } else if (orbs == 3) {
calcDmgMax *= 1.54; calcDmgMax *= 1.54;
else if(orbs == 4) } else if (orbs == 4) {
calcDmgMax *= 2; calcDmgMax *= 2;
else if(orbs >= 5) } else if (orbs >= 5) {
calcDmgMax *= 2.5; calcDmgMax *= 2.5;
}
} }
} }
if(chr.getEnergyBar() == 15000) { if (chr.getEnergyBar() == 15000) {
int energycharge = chr.isCygnus() ? ThunderBreaker.ENERGY_CHARGE : Marauder.ENERGY_CHARGE; int energycharge = chr.isCygnus() ? ThunderBreaker.ENERGY_CHARGE : Marauder.ENERGY_CHARGE;
StatEffect ceffect = SkillFactory.getSkill(energycharge).getEffect(chr.getSkillLevel(energycharge)); StatEffect ceffect = SkillFactory.getSkill(energycharge).getEffect(chr.getSkillLevel(energycharge));
calcDmgMax *= (100 + ceffect.getDamage()) / 100; calcDmgMax *= (100 + ceffect.getDamage()) / 100;
@@ -712,16 +731,13 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
calcDmgMax = (long) Math.ceil(calcDmgMax * dmgBuff); calcDmgMax = (long) Math.ceil(calcDmgMax * dmgBuff);
} }
if(chr.getMapId() >= 914000000 && chr.getMapId() <= 914000500) { if (chr.getMapId() >= 914000000 && chr.getMapId() <= 914000500) {
calcDmgMax += 80000; // Aran Tutorial. calcDmgMax += 80000; // Aran Tutorial.
} }
boolean canCrit = false; boolean canCrit = chr.getJob().isA((Job.BOWMAN)) || chr.getJob().isA(Job.THIEF) || chr.getJob().isA(Job.NIGHTWALKER1) || chr.getJob().isA(Job.WINDARCHER1) || chr.getJob() == Job.ARAN3 || chr.getJob() == Job.ARAN4 || chr.getJob() == Job.MARAUDER || chr.getJob() == Job.BUCCANEER;
if(chr.getJob().isA((Job.BOWMAN)) || chr.getJob().isA(Job.THIEF) || chr.getJob().isA(Job.NIGHTWALKER1) || chr.getJob().isA(Job.WINDARCHER1) || chr.getJob() == Job.ARAN3 || chr.getJob() == Job.ARAN4 || chr.getJob() == Job.MARAUDER || chr.getJob() == Job.BUCCANEER) {
canCrit = true;
}
if(chr.getBuffEffect(BuffStat.SHARP_EYES) != null) { if (chr.getBuffEffect(BuffStat.SHARP_EYES) != null) {
// Any class that has sharp eyes can crit. Also, since it stacks with normal crit go ahead // Any class that has sharp eyes can crit. Also, since it stacks with normal crit go ahead
// and calc it in. // and calc it in.
@@ -729,15 +745,13 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
calcDmgMax *= 1.4; calcDmgMax *= 1.4;
} }
boolean shadowPartner = false; boolean shadowPartner = chr.getBuffEffect(BuffStat.SHADOWPARTNER) != null;
if(chr.getBuffEffect(BuffStat.SHADOWPARTNER) != null) {
shadowPartner = true;
}
if(ret.skill != 0) { if (ret.skill != 0) {
int fixed = ret.getAttackEffect(chr, SkillFactory.getSkill(ret.skill)).getFixDamage(); int fixed = ret.getAttackEffect(chr, SkillFactory.getSkill(ret.skill)).getFixDamage();
if(fixed > 0) if (fixed > 0) {
calcDmgMax = fixed; calcDmgMax = fixed;
}
} }
for (int i = 0; i < ret.numAttacked; i++) { for (int i = 0; i < ret.numAttacked; i++) {
int oid = p.readInt(); int oid = p.readInt();
@@ -745,25 +759,25 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
List<Integer> allDamageNumbers = new ArrayList<>(); List<Integer> allDamageNumbers = new ArrayList<>();
Monster monster = chr.getMap().getMonsterByOid(oid); Monster monster = chr.getMap().getMonsterByOid(oid);
if(chr.getBuffEffect(BuffStat.WK_CHARGE) != null) { if (chr.getBuffEffect(BuffStat.WK_CHARGE) != null) {
// Charge, so now we need to check elemental effectiveness // Charge, so now we need to check elemental effectiveness
int sourceID = chr.getBuffSource(BuffStat.WK_CHARGE); int sourceID = chr.getBuffSource(BuffStat.WK_CHARGE);
int level = chr.getBuffedValue(BuffStat.WK_CHARGE); int level = chr.getBuffedValue(BuffStat.WK_CHARGE);
if(monster != null) { if (monster != null) {
if(sourceID == WhiteKnight.BW_FIRE_CHARGE || sourceID == WhiteKnight.SWORD_FIRE_CHARGE) { if (sourceID == WhiteKnight.BW_FIRE_CHARGE || sourceID == WhiteKnight.SWORD_FIRE_CHARGE) {
if(monster.getStats().getEffectiveness(Element.FIRE) == ElementalEffectiveness.WEAK) { if (monster.getStats().getEffectiveness(Element.FIRE) == ElementalEffectiveness.WEAK) {
calcDmgMax *= 1.05 + level * 0.015; calcDmgMax *= 1.05 + level * 0.015;
} }
} else if(sourceID == WhiteKnight.BW_ICE_CHARGE || sourceID == WhiteKnight.SWORD_ICE_CHARGE) { } else if (sourceID == WhiteKnight.BW_ICE_CHARGE || sourceID == WhiteKnight.SWORD_ICE_CHARGE) {
if(monster.getStats().getEffectiveness(Element.ICE) == ElementalEffectiveness.WEAK) { if (monster.getStats().getEffectiveness(Element.ICE) == ElementalEffectiveness.WEAK) {
calcDmgMax *= 1.05 + level * 0.015; calcDmgMax *= 1.05 + level * 0.015;
} }
} else if(sourceID == WhiteKnight.BW_LIT_CHARGE || sourceID == WhiteKnight.SWORD_LIT_CHARGE) { } else if (sourceID == WhiteKnight.BW_LIT_CHARGE || sourceID == WhiteKnight.SWORD_LIT_CHARGE) {
if(monster.getStats().getEffectiveness(Element.LIGHTING) == ElementalEffectiveness.WEAK) { if (monster.getStats().getEffectiveness(Element.LIGHTING) == ElementalEffectiveness.WEAK) {
calcDmgMax *= 1.05 + level * 0.015; calcDmgMax *= 1.05 + level * 0.015;
} }
} else if(sourceID == Paladin.BW_HOLY_CHARGE || sourceID == Paladin.SWORD_HOLY_CHARGE) { } else if (sourceID == Paladin.BW_HOLY_CHARGE || sourceID == Paladin.SWORD_HOLY_CHARGE) {
if(monster.getStats().getEffectiveness(Element.HOLY) == ElementalEffectiveness.WEAK) { if (monster.getStats().getEffectiveness(Element.HOLY) == ElementalEffectiveness.WEAK) {
calcDmgMax *= 1.2 + level * 0.015; calcDmgMax *= 1.2 + level * 0.015;
} }
} }
@@ -774,91 +788,94 @@ public abstract class AbstractDealDamageHandler extends AbstractPacketHandler {
} }
} }
if(ret.skill != 0) { if (ret.skill != 0) {
Skill skill = SkillFactory.getSkill(ret.skill); Skill skill = SkillFactory.getSkill(ret.skill);
if(skill.getElement() != Element.NEUTRAL && chr.getBuffedValue(BuffStat.ELEMENTAL_RESET) == null) { if (skill.getElement() != Element.NEUTRAL && chr.getBuffedValue(BuffStat.ELEMENTAL_RESET) == null) {
// The skill has an element effect, so we need to factor that in. // The skill has an element effect, so we need to factor that in.
if(monster != null) { if (monster != null) {
ElementalEffectiveness eff = monster.getElementalEffectiveness(skill.getElement()); ElementalEffectiveness eff = monster.getElementalEffectiveness(skill.getElement());
if(eff == ElementalEffectiveness.WEAK) { if (eff == ElementalEffectiveness.WEAK) {
calcDmgMax *= 1.5;
} else if(eff == ElementalEffectiveness.STRONG) {
//calcDmgMax *= 0.5;
}
} else {
// Since we already know the skill has an elemental attribute, but we dont know if the monster is weak or not, lets
// take the safe approach and just assume they are weak.
calcDmgMax *= 1.5; calcDmgMax *= 1.5;
} else if (eff == ElementalEffectiveness.STRONG) {
//calcDmgMax *= 0.5;
}
} else {
// Since we already know the skill has an elemental attribute, but we dont know if the monster is weak or not, lets
// take the safe approach and just assume they are weak.
calcDmgMax *= 1.5;
}
}
if (ret.skill == FPWizard.POISON_BREATH || ret.skill == FPMage.POISON_MIST || ret.skill == FPArchMage.FIRE_DEMON || ret.skill == ILArchMage.ICE_DEMON) {
if (monster != null) {
// Turns out poison is completely server side, so I don't know why I added this. >.<
//calcDmgMax = monster.getHp() / (70 - chr.getSkillLevel(skill));
}
} else if (ret.skill == Hermit.SHADOW_WEB) {
if (monster != null) {
calcDmgMax = monster.getHp() / (50 - chr.getSkillLevel(skill));
}
} else if (ret.skill == Hermit.SHADOW_MESO) {
if (monster != null) {
monster.debuffMob(Hermit.SHADOW_MESO);
}
} else if (ret.skill == Aran.BODY_PRESSURE) {
if (monster != null) {
int bodyPressureDmg = (int) Math.ceil(monster.getMaxHp() * SkillFactory.getSkill(Aran.BODY_PRESSURE).getEffect(ret.skilllevel).getDamage() / 100.0);
if (bodyPressureDmg > calcDmgMax) {
calcDmgMax = bodyPressureDmg;
} }
} }
if(ret.skill == FPWizard.POISON_BREATH || ret.skill == FPMage.POISON_MIST || ret.skill == FPArchMage.FIRE_DEMON || ret.skill == ILArchMage.ICE_DEMON) { }
if(monster != null) {
// Turns out poison is completely server side, so I don't know why I added this. >.<
//calcDmgMax = monster.getHp() / (70 - chr.getSkillLevel(skill));
}
} else if(ret.skill == Hermit.SHADOW_WEB) {
if(monster != null) {
calcDmgMax = monster.getHp() / (50 - chr.getSkillLevel(skill));
}
} else if(ret.skill == Hermit.SHADOW_MESO) {
if(monster != null) {
monster.debuffMob(Hermit.SHADOW_MESO);
}
} else if (ret.skill == Aran.BODY_PRESSURE) {
if (monster != null) {
int bodyPressureDmg = (int) Math.ceil(monster.getMaxHp() * SkillFactory.getSkill(Aran.BODY_PRESSURE).getEffect(ret.skilllevel).getDamage() / 100.0);
if (bodyPressureDmg > calcDmgMax) {
calcDmgMax = bodyPressureDmg;
}
}
}
} }
for (int j = 0; j < ret.numDamage; j++) { for (int j = 0; j < ret.numDamage; j++) {
int damage = p.readInt(); int damage = p.readInt();
long hitDmgMax = calcDmgMax; long hitDmgMax = calcDmgMax;
if(ret.skill == Buccaneer.BARRAGE || ret.skill == ThunderBreaker.BARRAGE) { if (ret.skill == Buccaneer.BARRAGE || ret.skill == ThunderBreaker.BARRAGE) {
if(j > 3) if (j > 3) {
hitDmgMax *= Math.pow(2, (j - 3)); hitDmgMax *= Math.pow(2, (j - 3));
} }
if(shadowPartner) { }
// For shadow partner, the second half of the hits only do 50% damage. So calc that if (shadowPartner) {
// in for the crit effects. // For shadow partner, the second half of the hits only do 50% damage. So calc that
if(j >= ret.numDamage / 2) { // in for the crit effects.
hitDmgMax *= 0.5; if (j >= ret.numDamage / 2) {
} hitDmgMax *= 0.5;
} }
}
if(ret.skill == Marksman.SNIPE) { if (ret.skill == Marksman.SNIPE) {
damage = 195000 + Randomizer.nextInt(5000); damage = 195000 + Randomizer.nextInt(5000);
hitDmgMax = 200000; hitDmgMax = 200000;
} else if (ret.skill == Beginner.BAMBOO_RAIN || ret.skill == Noblesse.BAMBOO_RAIN || ret.skill == Evan.BAMBOO_THRUST || ret.skill == Legend.BAMBOO_THRUST) { } else if (ret.skill == Beginner.BAMBOO_RAIN || ret.skill == Noblesse.BAMBOO_RAIN || ret.skill == Evan.BAMBOO_THRUST || ret.skill == Legend.BAMBOO_THRUST) {
hitDmgMax = 82569000; // 30% of Max HP of strongest Dojo boss hitDmgMax = 82569000; // 30% of Max HP of strongest Dojo boss
} }
long maxWithCrit = hitDmgMax; long maxWithCrit = hitDmgMax;
if(canCrit) // They can crit, so up the max. if (canCrit) // They can crit, so up the max.
maxWithCrit *= 2; {
maxWithCrit *= 2;
}
// Warn if the damage is over 1.5x what we calculated above. // Warn if the damage is over 1.5x what we calculated above.
if(damage > maxWithCrit * 1.5) { if (damage > maxWithCrit * 1.5) {
AutobanFactory.DAMAGE_HACK.alert(chr, "DMG: " + damage + " MaxDMG: " + maxWithCrit + " SID: " + ret.skill + " MobID: " + (monster != null ? monster.getId() : "null") + " Map: " + chr.getMap().getMapName() + " (" + chr.getMapId() + ")"); AutobanFactory.DAMAGE_HACK.alert(chr, "DMG: " + damage + " MaxDMG: " + maxWithCrit + " SID: " + ret.skill + " MobID: " + (monster != null ? monster.getId() : "null") + " Map: " + chr.getMap().getMapName() + " (" + chr.getMapId() + ")");
} }
// Add a ab point if its over 5x what we calculated. // Add a ab point if its over 5x what we calculated.
if(damage > maxWithCrit * 5) { if (damage > maxWithCrit * 5) {
AutobanFactory.DAMAGE_HACK.addPoint(chr.getAutobanManager(), "DMG: " + damage + " MaxDMG: " + maxWithCrit + " SID: " + ret.skill + " MobID: " + (monster != null ? monster.getId() : "null") + " Map: " + chr.getMap().getMapName() + " (" + chr.getMapId() + ")"); AutobanFactory.DAMAGE_HACK.addPoint(chr.getAutobanManager(), "DMG: " + damage + " MaxDMG: " + maxWithCrit + " SID: " + ret.skill + " MobID: " + (monster != null ? monster.getId() : "null") + " Map: " + chr.getMap().getMapName() + " (" + chr.getMapId() + ")");
} }
if (ret.skill == Marksman.SNIPE || (canCrit && damage > hitDmgMax)) { if (ret.skill == Marksman.SNIPE || (canCrit && damage > hitDmgMax)) {
// If the skill is a crit, inverse the damage to make it show up on clients. // If the skill is a crit, inverse the damage to make it show up on clients.
damage = -Integer.MAX_VALUE + damage - 1; damage = -Integer.MAX_VALUE + damage - 1;
} }
allDamageNumbers.add(damage); allDamageNumbers.add(damage);
} }
if (ret.skill != Corsair.RAPID_FIRE || ret.skill != Aran.HIDDEN_FULL_DOUBLE || ret.skill != Aran.HIDDEN_FULL_TRIPLE || ret.skill != Aran.HIDDEN_OVER_DOUBLE || ret.skill != Aran.HIDDEN_OVER_TRIPLE) { if (ret.skill != Corsair.RAPID_FIRE || ret.skill != Aran.HIDDEN_FULL_DOUBLE || ret.skill != Aran.HIDDEN_FULL_TRIPLE || ret.skill != Aran.HIDDEN_OVER_DOUBLE || ret.skill != Aran.HIDDEN_OVER_TRIPLE) {
p.skip(4); p.skip(4);
} }
ret.allDamage.put(oid, allDamageNumbers); ret.allDamage.put(oid, allDamageNumbers);
} }
@@ -36,7 +36,9 @@ public abstract class AbstractMovementPacketHandler extends AbstractPacketHandle
protected List<LifeMovementFragment> parseMovement(InPacket p) throws EmptyMovementException { protected List<LifeMovementFragment> parseMovement(InPacket p) throws EmptyMovementException {
List<LifeMovementFragment> res = new ArrayList<>(); List<LifeMovementFragment> res = new ArrayList<>();
byte numCommands = p.readByte(); byte numCommands = p.readByte();
if (numCommands < 1) throw new EmptyMovementException(p); if (numCommands < 1) {
throw new EmptyMovementException(p);
}
for (byte i = 0; i < numCommands; i++) { for (byte i = 0; i < numCommands; i++) {
byte command = p.readByte(); byte command = p.readByte();
switch (command) { switch (command) {
@@ -148,14 +150,16 @@ public abstract class AbstractMovementPacketHandler extends AbstractPacketHandle
protected void updatePosition(InPacket p, AnimatedMapObject target, int yOffset) throws EmptyMovementException { protected void updatePosition(InPacket p, AnimatedMapObject target, int yOffset) throws EmptyMovementException {
byte numCommands = p.readByte(); byte numCommands = p.readByte();
if (numCommands < 1) throw new EmptyMovementException(p); if (numCommands < 1) {
throw new EmptyMovementException(p);
}
for (byte i = 0; i < numCommands; i++) { for (byte i = 0; i < numCommands; i++) {
byte command = p.readByte(); byte command = p.readByte();
switch (command) { switch (command) {
case 0: // normal move case 0: // normal move
case 5: case 5:
case 17: { // Float case 17: { // Float
//Absolute movement - only this is important for the server, other movement can be passed to the client //Absolute movement - only this is important for the server, other movement can be passed to the client
short xpos = p.readShort(); //is signed fine here? short xpos = p.readShort(); //is signed fine here?
short ypos = p.readShort(); short ypos = p.readShort();
target.setPosition(new Point(xpos, ypos + yOffset)); target.setPosition(new Point(xpos, ypos + yOffset));
@@ -175,8 +179,8 @@ public abstract class AbstractMovementPacketHandler extends AbstractPacketHandle
case 19: // Springs on maps case 19: // Springs on maps
case 20: // Aran Combat Step case 20: // Aran Combat Step
case 22: { case 22: {
//Relative movement - server only cares about stance //Relative movement - server only cares about stance
p.skip(4); //xpos = lea.readShort(); ypos = lea.readShort(); p.skip(4); //xpos = lea.readShort(); ypos = lea.readShort();
byte newstate = p.readByte(); byte newstate = p.readByte();
target.setStance(newstate); target.setStance(newstate);
p.readShort(); //duration p.readShort(); //duration
@@ -190,8 +194,8 @@ public abstract class AbstractMovementPacketHandler extends AbstractPacketHandle
case 11: //chair case 11: //chair
{ {
// case 14: { // case 14: {
//Teleport movement - same as above //Teleport movement - same as above
p.skip(8); //xpos = lea.readShort(); ypos = lea.readShort(); xwobble = lea.readShort(); ywobble = lea.readShort(); p.skip(8); //xpos = lea.readShort(); ypos = lea.readShort(); xwobble = lea.readShort(); ywobble = lea.readShort();
byte newstate = p.readByte(); byte newstate = p.readByte();
target.setStance(newstate); target.setStance(newstate);
break; break;
@@ -215,8 +219,8 @@ public abstract class AbstractMovementPacketHandler extends AbstractPacketHandle
break; break;
}*/ }*/
case 15: { case 15: {
//Jump down movement - stance only //Jump down movement - stance only
p.skip(12); //short xpos = lea.readShort(); ypos = lea.readShort(); xwobble = lea.readShort(); ywobble = lea.readShort(); fh = lea.readShort(); ofh = lea.readShort(); p.skip(12); //short xpos = lea.readShort(); ypos = lea.readShort(); xwobble = lea.readShort(); ywobble = lea.readShort(); fh = lea.readShort(); ofh = lea.readShort();
byte newstate = p.readByte(); byte newstate = p.readByte();
target.setStance(newstate); target.setStance(newstate);
p.readShort(); // duration p.readShort(); // duration
@@ -41,7 +41,6 @@ import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
/** /**
*
* @author Jay Estrella * @author Jay Estrella
* @author Ubaware * @author Ubaware
*/ */
@@ -49,7 +48,7 @@ public final class AcceptFamilyHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
if(!YamlConfig.config.server.USE_FAMILY_SYSTEM) { if (!YamlConfig.config.server.USE_FAMILY_SYSTEM) {
return; return;
} }
Character chr = c.getPlayer(); Character chr = c.getPlayer();
@@ -58,15 +57,17 @@ public final class AcceptFamilyHandler extends AbstractPacketHandler {
boolean accept = p.readByte() != 0; boolean accept = p.readByte() != 0;
// String inviterName = slea.readMapleAsciiString(); // String inviterName = slea.readMapleAsciiString();
Character inviter = c.getWorldServer().getPlayerStorage().getCharacterById(inviterId); Character inviter = c.getWorldServer().getPlayerStorage().getCharacterById(inviterId);
if(inviter != null) { if (inviter != null) {
InviteResult inviteResult = InviteCoordinator.answerInvite(InviteType.FAMILY, c.getPlayer().getId(), c.getPlayer(), accept); InviteResult inviteResult = InviteCoordinator.answerInvite(InviteType.FAMILY, c.getPlayer().getId(), c.getPlayer(), accept);
if(inviteResult.result == InviteResultType.NOT_FOUND) return; //was never invited. (or expired on server only somehow?) if (inviteResult.result == InviteResultType.NOT_FOUND) {
if(accept) { return; //was never invited. (or expired on server only somehow?)
if(inviter.getFamily() != null) { }
if(chr.getFamily() == null) { if (accept) {
if (inviter.getFamily() != null) {
if (chr.getFamily() == null) {
FamilyEntry newEntry = new FamilyEntry(inviter.getFamily(), chr.getId(), chr.getName(), chr.getLevel(), chr.getJob()); FamilyEntry newEntry = new FamilyEntry(inviter.getFamily(), chr.getId(), chr.getName(), chr.getLevel(), chr.getJob());
newEntry.setCharacter(chr); newEntry.setCharacter(chr);
if(!newEntry.setSenior(inviter.getFamilyEntry(), true)) { if (!newEntry.setSenior(inviter.getFamilyEntry(), true)) {
inviter.sendPacket(PacketCreator.sendFamilyMessage(1, 0)); inviter.sendPacket(PacketCreator.sendFamilyMessage(1, 0));
return; return;
} else { } else {
@@ -77,8 +78,10 @@ public final class AcceptFamilyHandler extends AbstractPacketHandler {
} else { //absorb target family } else { //absorb target family
FamilyEntry targetEntry = chr.getFamilyEntry(); FamilyEntry targetEntry = chr.getFamilyEntry();
Family targetFamily = targetEntry.getFamily(); Family targetFamily = targetEntry.getFamily();
if(targetFamily.getLeader() != targetEntry) return; if (targetFamily.getLeader() != targetEntry) {
if(inviter.getFamily().getTotalGenerations() + targetFamily.getTotalGenerations() <= YamlConfig.config.server.FAMILY_MAX_GENERATIONS) { return;
}
if (inviter.getFamily().getTotalGenerations() + targetFamily.getTotalGenerations() <= YamlConfig.config.server.FAMILY_MAX_GENERATIONS) {
targetEntry.join(inviter.getFamilyEntry()); targetEntry.join(inviter.getFamilyEntry());
} else { } else {
inviter.sendPacket(PacketCreator.sendFamilyMessage(76, 0)); inviter.sendPacket(PacketCreator.sendFamilyMessage(76, 0));
@@ -87,7 +90,7 @@ public final class AcceptFamilyHandler extends AbstractPacketHandler {
} }
} }
} else { // create new family } else { // create new family
if(chr.getFamily() != null && inviter.getFamily() != null && chr.getFamily().getTotalGenerations() + inviter.getFamily().getTotalGenerations() >= YamlConfig.config.server.FAMILY_MAX_GENERATIONS) { if (chr.getFamily() != null && inviter.getFamily() != null && chr.getFamily().getTotalGenerations() + inviter.getFamily().getTotalGenerations() >= YamlConfig.config.server.FAMILY_MAX_GENERATIONS) {
inviter.sendPacket(PacketCreator.sendFamilyMessage(76, 0)); inviter.sendPacket(PacketCreator.sendFamilyMessage(76, 0));
chr.sendPacket(PacketCreator.sendFamilyMessage(76, 0)); chr.sendPacket(PacketCreator.sendFamilyMessage(76, 0));
return; return;
@@ -98,7 +101,7 @@ public final class AcceptFamilyHandler extends AbstractPacketHandler {
inviterEntry.setCharacter(inviter); inviterEntry.setCharacter(inviter);
newFamily.setLeader(inviter.getFamilyEntry()); newFamily.setLeader(inviter.getFamilyEntry());
newFamily.addEntry(inviterEntry); newFamily.addEntry(inviterEntry);
if(chr.getFamily() == null) { //completely new family if (chr.getFamily() == null) { //completely new family
FamilyEntry newEntry = new FamilyEntry(newFamily, chr.getId(), chr.getName(), chr.getLevel(), chr.getJob()); FamilyEntry newEntry = new FamilyEntry(newFamily, chr.getId(), chr.getName(), chr.getLevel(), chr.getJob());
newEntry.setCharacter(chr); newEntry.setCharacter(chr);
newEntry.setSenior(inviterEntry, true); newEntry.setSenior(inviterEntry, true);
@@ -107,7 +110,7 @@ public final class AcceptFamilyHandler extends AbstractPacketHandler {
insertNewFamilyRecord(chr.getId(), newFamily.getID(), inviter.getId(), false); // char was already saved from setSenior() above insertNewFamilyRecord(chr.getId(), newFamily.getID(), inviter.getId(), false); // char was already saved from setSenior() above
newFamily.setMessage("", true); newFamily.setMessage("", true);
} else { //new family for inviter, absorb invitee family } else { //new family for inviter, absorb invitee family
insertNewFamilyRecord(inviter.getId(), newFamily.getID(), 0 , true); insertNewFamilyRecord(inviter.getId(), newFamily.getID(), 0, true);
newFamily.setMessage("", true); newFamily.setMessage("", true);
chr.getFamilyEntry().join(inviterEntry); chr.getFamilyEntry().join(inviterEntry);
} }
@@ -124,27 +127,27 @@ public final class AcceptFamilyHandler extends AbstractPacketHandler {
} }
private static void insertNewFamilyRecord(int characterID, int familyID, int seniorID, boolean updateChar) { private static void insertNewFamilyRecord(int characterID, int familyID, int seniorID, boolean updateChar) {
try(Connection con = DatabaseConnection.getConnection()) { try (Connection con = DatabaseConnection.getConnection()) {
try(PreparedStatement ps = con.prepareStatement("INSERT INTO family_character (cid, familyid, seniorid) VALUES (?, ?, ?)")) { try (PreparedStatement ps = con.prepareStatement("INSERT INTO family_character (cid, familyid, seniorid) VALUES (?, ?, ?)")) {
ps.setInt(1, characterID); ps.setInt(1, characterID);
ps.setInt(2, familyID); ps.setInt(2, familyID);
ps.setInt(3, seniorID); ps.setInt(3, seniorID);
ps.executeUpdate(); ps.executeUpdate();
} catch(SQLException e) { } catch (SQLException e) {
FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not save new family record for char id " + characterID + "."); FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not save new family record for char id " + characterID + ".");
e.printStackTrace(); e.printStackTrace();
} }
if(updateChar) { if (updateChar) {
try(PreparedStatement ps = con.prepareStatement("UPDATE characters SET familyid = ? WHERE id = ?")) { try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET familyid = ? WHERE id = ?")) {
ps.setInt(1, familyID); ps.setInt(1, familyID);
ps.setInt(2, characterID); ps.setInt(2, characterID);
ps.executeUpdate(); ps.executeUpdate();
} catch(SQLException e) { } catch (SQLException e) {
FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not update 'characters' 'familyid' record for char id " + characterID + "."); FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not update 'characters' 'familyid' record for char id " + characterID + ".");
e.printStackTrace(); e.printStackTrace();
} }
} }
} catch(SQLException e) { } catch (SQLException e) {
FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not get connection to DB."); FilePrinter.printError(FilePrinter.FAMILY_ERROR, e, "Could not get connection to DB.");
e.printStackTrace(); e.printStackTrace();
} }
@@ -9,7 +9,6 @@ import tools.LogHelper;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author kevintjuh93 * @author kevintjuh93
*/ */
public class AdminChatHandler extends AbstractPacketHandler { public class AdminChatHandler extends AbstractPacketHandler {
@@ -75,10 +75,10 @@ public final class AdminCommandHandler extends AbstractPacketHandler {
c.getPlayer().setExp(p.readInt()); c.getPlayer().setExp(p.readInt());
break; break;
case 0x03: // /ban <name> case 0x03: // /ban <name>
c.getPlayer().yellowMessage("Please use !ban <IGN> <Reason>"); c.getPlayer().yellowMessage("Please use !ban <IGN> <Reason>");
break; break;
case 0x04: // /block <name> <duration (in days)> <HACK/BOT/AD/HARASS/CURSE/SCAM/MISCONDUCT/SELL/ICASH/TEMP/GM/IPROGRAM/MEGAPHONE> case 0x04: // /block <name> <duration (in days)> <HACK/BOT/AD/HARASS/CURSE/SCAM/MISCONDUCT/SELL/ICASH/TEMP/GM/IPROGRAM/MEGAPHONE>
victim = p.readString(); victim = p.readString();
int type = p.readByte(); //reason int type = p.readByte(); //reason
int duration = p.readInt(); int duration = p.readInt();
String description = p.readString(); String description = p.readString();
@@ -176,7 +176,7 @@ public final class AdminCommandHandler extends AbstractPacketHandler {
} }
break; break;
default: default:
System.out.println("New GM packet encountered (MODE : " + mode + ": " + p.toString()); System.out.println("New GM packet encountered (MODE : " + mode + ": " + p);
break; break;
} }
} }
@@ -33,7 +33,6 @@ import net.server.guild.GuildPackets;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author XoticStory, Ronan * @author XoticStory, Ronan
*/ */
public final class AllianceOperationHandler extends AbstractPacketHandler { public final class AllianceOperationHandler extends AbstractPacketHandler {
@@ -215,7 +214,9 @@ public final class AllianceOperationHandler extends AbstractPacketHandler {
private void changePlayerAllianceRank(Alliance alliance, Character chr, boolean raise) { private void changePlayerAllianceRank(Alliance alliance, Character chr, boolean raise) {
int newRank = chr.getAllianceRank() + (raise ? -1 : 1); int newRank = chr.getAllianceRank() + (raise ? -1 : 1);
if(newRank < 3 || newRank > 5) return; if (newRank < 3 || newRank > 5) {
return;
}
chr.getMGC().setAllianceRank(newRank); chr.getMGC().setAllianceRank(newRank);
chr.saveGuildStatus(); chr.saveGuildStatus();
@@ -53,7 +53,9 @@ public class AranComboHandler extends AbstractPacketHandler {
case 80: case 80:
case 90: case 90:
case 100: case 100:
if (player.getJob().getId() != 2000 && (combo / 10) > skillLevel) break; if (player.getJob().getId() != 2000 && (combo / 10) > skillLevel) {
break;
}
SkillFactory.getSkill(Aran.COMBO_ABILITY).getEffect(combo / 10).applyComboBuff(player, combo); SkillFactory.getSkill(Aran.COMBO_ABILITY).getEffect(combo / 10).applyComboBuff(player, combo);
break; break;
} }
@@ -33,7 +33,9 @@ public final class AutoAggroHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
Character player = c.getPlayer(); Character player = c.getPlayer();
if (player.isHidden()) return; // Don't auto aggro GM's in hide... if (player.isHidden()) {
return; // Don't auto aggro GM's in hide...
}
MapleMap map = player.getMap(); MapleMap map = player.getMap();
int oid = p.readInt(); int oid = p.readInt();
@@ -27,7 +27,6 @@ import net.AbstractPacketHandler;
import net.packet.InPacket; import net.packet.InPacket;
/** /**
*
* @author Generic, Ronan * @author Generic, Ronan
*/ */
public class AutoAssignHandler extends AbstractPacketHandler { public class AutoAssignHandler extends AbstractPacketHandler {
@@ -30,7 +30,6 @@ import server.maps.Summon;
import java.util.Collection; import java.util.Collection;
/** /**
*
* @author BubblesDev * @author BubblesDev
*/ */
public final class BeholderHandler extends AbstractPacketHandler {//Summon Skills noobs public final class BeholderHandler extends AbstractPacketHandler {//Summon Skills noobs
@@ -40,7 +40,7 @@ import static client.BuddyList.BuddyOperation.ADDED;
public class BuddylistModifyHandler extends AbstractPacketHandler { public class BuddylistModifyHandler extends AbstractPacketHandler {
private static class CharacterIdNameBuddyCapacity extends CharacterNameAndId { private static class CharacterIdNameBuddyCapacity extends CharacterNameAndId {
private int buddyCapacity; private final int buddyCapacity;
public CharacterIdNameBuddyCapacity(int id, String name, int buddyCapacity) { public CharacterIdNameBuddyCapacity(int id, String name, int buddyCapacity) {
super(id, name); super(id, name);
@@ -108,7 +108,7 @@ public class BuddylistModifyHandler extends AbstractPacketHandler {
if (charWithId != null) { if (charWithId != null) {
BuddyAddResult buddyAddResult = null; BuddyAddResult buddyAddResult = null;
if (channel != -1) { if (channel != -1) {
buddyAddResult = world.requestBuddyAdd(addName, c.getChannel(), player.getId(), player.getName()); buddyAddResult = world.requestBuddyAdd(addName, c.getChannel(), player.getId(), player.getName());
} else { } else {
try (Connection con = DatabaseConnection.getConnection()) { try (Connection con = DatabaseConnection.getConnection()) {
try (PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) as buddyCount FROM buddies WHERE characterid = ? AND pending = 0")) { try (PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) as buddyCount FROM buddies WHERE characterid = ? AND pending = 0")) {
@@ -129,7 +129,9 @@ public final class CashOperationHandler extends AbstractPacketHandler {
ex.printStackTrace(); ex.printStackTrace();
} }
Character receiver = c.getChannelServer().getPlayerStorage().getCharacterByName(recipient.get("name")); Character receiver = c.getChannelServer().getPlayerStorage().getCharacterByName(recipient.get("name"));
if (receiver != null) receiver.showNote(); if (receiver != null) {
receiver.showNote();
}
} else if (action == 0x05) { // Modify wish list } else if (action == 0x05) { // Modify wish list
cs.clearWishList(); cs.clearWishList();
for (byte i = 0; i < 10; i++) { for (byte i = 0; i < 10; i++) {
@@ -262,9 +264,9 @@ public final class CashOperationHandler extends AbstractPacketHandler {
cs.removeFromInventory(item); cs.removeFromInventory(item);
c.sendPacket(PacketCreator.takeFromCashInventory(item)); c.sendPacket(PacketCreator.takeFromCashInventory(item));
if(item instanceof Equip) { if (item instanceof Equip) {
Equip equip = (Equip) item; Equip equip = (Equip) item;
if(equip.getRingId() >= 0) { if (equip.getRingId() >= 0) {
Ring ring = Ring.loadFromDb(equip.getRingId()); Ring ring = Ring.loadFromDb(equip.getRingId());
chr.addPlayerRing(ring); chr.addPlayerRing(ring);
} }
@@ -316,7 +318,7 @@ public final class CashOperationHandler extends AbstractPacketHandler {
return; return;
}*/ //Gotta let them faggots marry too, hence why this is commented out <3 }*/ //Gotta let them faggots marry too, hence why this is commented out <3
if(itemRing.toItem() instanceof Equip) { if (itemRing.toItem() instanceof Equip) {
Equip eqp = (Equip) itemRing.toItem(); Equip eqp = (Equip) itemRing.toItem();
Pair<Integer, Integer> rings = Ring.createRing(itemRing.getItemId(), chr, partner); Pair<Integer, Integer> rings = Ring.createRing(itemRing.getItemId(), chr, partner);
eqp.setRingId(rings.getLeft()); eqp.setRingId(rings.getLeft());
@@ -377,10 +379,10 @@ public final class CashOperationHandler extends AbstractPacketHandler {
String text = p.readString(); String text = p.readString();
Character partner = c.getChannelServer().getPlayerStorage().getCharacterByName(sentTo); Character partner = c.getChannelServer().getPlayerStorage().getCharacterByName(sentTo);
if (partner == null) { if (partner == null) {
c.sendPacket(PacketCreator.showCashShopMessage((byte)0xBE)); c.sendPacket(PacketCreator.showCashShopMessage((byte) 0xBE));
} else { } else {
// Need to check to make sure its actually an equip and the right SN... // Need to check to make sure its actually an equip and the right SN...
if(itemRing.toItem() instanceof Equip) { if (itemRing.toItem() instanceof Equip) {
Equip eqp = (Equip) itemRing.toItem(); Equip eqp = (Equip) itemRing.toItem();
Pair<Integer, Integer> rings = Ring.createRing(itemRing.getItemId(), chr, partner); Pair<Integer, Integer> rings = Ring.createRing(itemRing.getItemId(), chr, partner);
eqp.setRingId(rings.getLeft()); eqp.setRingId(rings.getLeft());
@@ -405,59 +407,59 @@ public final class CashOperationHandler extends AbstractPacketHandler {
} else if (action == 0x2E) { //name change } else if (action == 0x2E) { //name change
CashItem cItem = CashItemFactory.getItem(p.readInt()); CashItem cItem = CashItemFactory.getItem(p.readInt());
if (cItem == null || !canBuy(chr, cItem, cs.getCash(4))) { if (cItem == null || !canBuy(chr, cItem, cs.getCash(4))) {
c.sendPacket(PacketCreator.showCashShopMessage((byte)0)); c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
c.enableCSActions(); c.enableCSActions();
return; return;
} }
if(cItem.getSN() == 50600000 && YamlConfig.config.server.ALLOW_CASHSHOP_NAME_CHANGE) { if (cItem.getSN() == 50600000 && YamlConfig.config.server.ALLOW_CASHSHOP_NAME_CHANGE) {
p.readString(); //old name p.readString(); //old name
String newName = p.readString(); String newName = p.readString();
if(!Character.canCreateChar(newName) || chr.getLevel() < 10) { //(longest ban duration isn't tracked currently) if (!Character.canCreateChar(newName) || chr.getLevel() < 10) { //(longest ban duration isn't tracked currently)
c.sendPacket(PacketCreator.showCashShopMessage((byte)0)); c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
c.enableCSActions(); c.enableCSActions();
return; return;
} else if(c.getTempBanCalendar() != null && c.getTempBanCalendar().getTimeInMillis() + (30*24*60*60*1000) > Calendar.getInstance().getTimeInMillis()) { } else if (c.getTempBanCalendar() != null && c.getTempBanCalendar().getTimeInMillis() + (30 * 24 * 60 * 60 * 1000) > Calendar.getInstance().getTimeInMillis()) {
c.sendPacket(PacketCreator.showCashShopMessage((byte)0)); c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
c.enableCSActions(); c.enableCSActions();
return; return;
} }
if(chr.registerNameChange(newName)) { //success if (chr.registerNameChange(newName)) { //success
Item item = cItem.toItem(); Item item = cItem.toItem();
c.sendPacket(PacketCreator.showNameChangeSuccess(item, c.getAccID())); c.sendPacket(PacketCreator.showNameChangeSuccess(item, c.getAccID()));
cs.gainCash(4, cItem, chr.getWorld()); cs.gainCash(4, cItem, chr.getWorld());
cs.addToInventory(item); cs.addToInventory(item);
} else { } else {
c.sendPacket(PacketCreator.showCashShopMessage((byte)0)); c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
} }
} }
c.enableCSActions(); c.enableCSActions();
} else if(action == 0x31) { //world transfer } else if (action == 0x31) { //world transfer
CashItem cItem = CashItemFactory.getItem(p.readInt()); CashItem cItem = CashItemFactory.getItem(p.readInt());
if (cItem == null || !canBuy(chr, cItem, cs.getCash(4))) { if (cItem == null || !canBuy(chr, cItem, cs.getCash(4))) {
c.sendPacket(PacketCreator.showCashShopMessage((byte)0)); c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
c.enableCSActions(); c.enableCSActions();
return; return;
} }
if(cItem.getSN() == 50600001 && YamlConfig.config.server.ALLOW_CASHSHOP_WORLD_TRANSFER) { if (cItem.getSN() == 50600001 && YamlConfig.config.server.ALLOW_CASHSHOP_WORLD_TRANSFER) {
int newWorldSelection = p.readInt(); int newWorldSelection = p.readInt();
int worldTransferError = chr.checkWorldTransferEligibility(); int worldTransferError = chr.checkWorldTransferEligibility();
if(worldTransferError != 0 || newWorldSelection >= Server.getInstance().getWorldsSize() || Server.getInstance().getWorldsSize() <= 1) { if (worldTransferError != 0 || newWorldSelection >= Server.getInstance().getWorldsSize() || Server.getInstance().getWorldsSize() <= 1) {
c.sendPacket(PacketCreator.showCashShopMessage((byte)0)); c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
return; return;
} else if(newWorldSelection == c.getWorld()) { } else if (newWorldSelection == c.getWorld()) {
c.sendPacket(PacketCreator.showCashShopMessage((byte)0xDC)); c.sendPacket(PacketCreator.showCashShopMessage((byte) 0xDC));
return; return;
} else if(c.getAvailableCharacterWorldSlots(newWorldSelection) < 1 || Server.getInstance().getAccountWorldCharacterCount(c.getAccID(), newWorldSelection) >= 3) { } else if (c.getAvailableCharacterWorldSlots(newWorldSelection) < 1 || Server.getInstance().getAccountWorldCharacterCount(c.getAccID(), newWorldSelection) >= 3) {
c.sendPacket(PacketCreator.showCashShopMessage((byte)0xDF)); c.sendPacket(PacketCreator.showCashShopMessage((byte) 0xDF));
return; return;
} else if(chr.registerWorldTransfer(newWorldSelection)) { } else if (chr.registerWorldTransfer(newWorldSelection)) {
Item item = cItem.toItem(); Item item = cItem.toItem();
c.sendPacket(PacketCreator.showWorldTransferSuccess(item, c.getAccID())); c.sendPacket(PacketCreator.showWorldTransferSuccess(item, c.getAccID()));
cs.gainCash(4, cItem, chr.getWorld()); cs.gainCash(4, cItem, chr.getWorld());
cs.addToInventory(item); cs.addToInventory(item);
} else { } else {
c.sendPacket(PacketCreator.showCashShopMessage((byte)0)); c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
} }
} }
c.enableCSActions(); c.enableCSActions();
@@ -28,7 +28,6 @@ import tools.PacketCreator;
import tools.Pair; import tools.Pair;
/** /**
*
* @author RonanLana * @author RonanLana
*/ */
public class CashShopSurpriseHandler extends AbstractPacketHandler { public class CashShopSurpriseHandler extends AbstractPacketHandler {
@@ -36,10 +35,10 @@ public class CashShopSurpriseHandler extends AbstractPacketHandler {
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
CashShop cs = c.getPlayer().getCashShop(); CashShop cs = c.getPlayer().getCashShop();
if(cs.isOpened()) { if (cs.isOpened()) {
Pair<Item, Item> cssResult = cs.openCashShopSurprise(); Pair<Item, Item> cssResult = cs.openCashShopSurprise();
if(cssResult != null) { if (cssResult != null) {
Item cssItem = cssResult.getLeft(), cssBox = cssResult.getRight(); Item cssItem = cssResult.getLeft(), cssBox = cssResult.getRight();
c.sendPacket(PacketCreator.onCashGachaponOpenSuccess(c.getAccID(), cssBox.getSN(), cssBox.getQuantity(), cssItem, cssItem.getItemId(), cssItem.getQuantity(), true)); c.sendPacket(PacketCreator.onCashGachaponOpenSuccess(c.getAccID(), cssBox.getSN(), cssBox.getQuantity(), cssItem, cssItem.getItemId(), cssItem.getQuantity(), true));
} else { } else {
@@ -28,7 +28,6 @@ import net.packet.InPacket;
import net.server.Server; import net.server.Server;
/** /**
*
* @author Matze * @author Matze
*/ */
public final class ChangeChannelHandler extends AbstractPacketHandler { public final class ChangeChannelHandler extends AbstractPacketHandler {
@@ -38,13 +37,13 @@ public final class ChangeChannelHandler extends AbstractPacketHandler {
int channel = p.readByte() + 1; int channel = p.readByte() + 1;
p.readInt(); p.readInt();
c.getPlayer().getAutobanManager().setTimestamp(6, Server.getInstance().getCurrentTimestamp(), 3); c.getPlayer().getAutobanManager().setTimestamp(6, Server.getInstance().getCurrentTimestamp(), 3);
if(c.getChannel() == channel) { if (c.getChannel() == channel) {
AutobanFactory.GENERAL.alert(c.getPlayer(), "CCing to same channel."); AutobanFactory.GENERAL.alert(c.getPlayer(), "CCing to same channel.");
c.disconnect(false, false); c.disconnect(false, false);
return; return;
} else if (c.getPlayer().getCashShop().isOpened() || c.getPlayer().getMiniGame() != null || c.getPlayer().getPlayerShop() != null) { } else if (c.getPlayer().getCashShop().isOpened() || c.getPlayer().getMiniGame() != null || c.getPlayer().getPlayerShop() != null) {
return; return;
} }
c.changeChannel(channel); c.changeChannel(channel);
} }
@@ -46,7 +46,7 @@ public final class ChangeMapHandler extends AbstractPacketHandler {
if (chr.isChangingMaps() || chr.isBanned()) { if (chr.isChangingMaps() || chr.isBanned()) {
if (chr.isChangingMaps()) { if (chr.isChangingMaps()) {
FilePrinter.printError(FilePrinter.PORTAL_STUCK + chr.getName() + ".txt", "Player " + chr.getName() + " got stuck when changing maps. Timestamp: " + Calendar.getInstance().getTime().toString() + " Last visited mapids: " + chr.getLastVisitedMapids()); FilePrinter.printError(FilePrinter.PORTAL_STUCK + chr.getName() + ".txt", "Player " + chr.getName() + " got stuck when changing maps. Timestamp: " + Calendar.getInstance().getTime() + " Last visited mapids: " + chr.getLastVisitedMapids());
} }
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
@@ -32,21 +32,21 @@ import tools.PacketCreator;
public final class ChangeMapSpecialHandler extends AbstractPacketHandler { public final class ChangeMapSpecialHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
p.readByte(); p.readByte();
String startwp = p.readString(); String startwp = p.readString();
p.readShort(); p.readShort();
Portal portal = c.getPlayer().getMap().getPortal(startwp); Portal portal = c.getPlayer().getMap().getPortal(startwp);
if (portal == null || c.getPlayer().portalDelay() > currentServerTime() || c.getPlayer().getBlockedPortals().contains(portal.getScriptName())) { if (portal == null || c.getPlayer().portalDelay() > currentServerTime() || c.getPlayer().getBlockedPortals().contains(portal.getScriptName())) {
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
if (c.getPlayer().isChangingMaps() || c.getPlayer().isBanned()) { if (c.getPlayer().isChangingMaps() || c.getPlayer().isBanned()) {
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
if (c.getPlayer().getTrade() != null) { if (c.getPlayer().getTrade() != null) {
Trade.cancelTrade(c.getPlayer(), TradeResult.UNSUCCESSFUL_ANOTHER_MAP); Trade.cancelTrade(c.getPlayer(), TradeResult.UNSUCCESSFUL_ANOTHER_MAP);
} }
portal.enterPortal(c); portal.enterPortal(c);
} }
} }
@@ -39,7 +39,7 @@ public final class CharInfoRequestHandler extends AbstractPacketHandler {
if (target instanceof Character) { if (target instanceof Character) {
Character player = (Character) target; Character player = (Character) target;
if(c.getPlayer().getId() != player.getId()) { if (c.getPlayer().getId() != player.getId()) {
player.exportExcludedItems(c); player.exportExcludedItems(c);
} }
c.sendPacket(PacketCreator.charInfo(player)); c.sendPacket(PacketCreator.charInfo(player));
@@ -29,7 +29,6 @@ import net.packet.InPacket;
import scripting.npc.NPCScriptManager; import scripting.npc.NPCScriptManager;
/** /**
*
* @author kevintjuh93 * @author kevintjuh93
*/ */
public class ClickGuideHandler extends AbstractPacketHandler { public class ClickGuideHandler extends AbstractPacketHandler {
@@ -27,7 +27,6 @@ import net.packet.InPacket;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author Xterminator * @author Xterminator
*/ */
public final class CloseChalkboardHandler extends AbstractPacketHandler { public final class CloseChalkboardHandler extends AbstractPacketHandler {
@@ -49,7 +49,7 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
AttackInfo attack = parseDamage(p, chr, false, false); AttackInfo attack = parseDamage(p, chr, false, false);
if (chr.getBuffEffect(BuffStat.MORPH) != null) { if (chr.getBuffEffect(BuffStat.MORPH) != null) {
if(chr.getBuffEffect(BuffStat.MORPH).isMorphWithoutAttack()) { if (chr.getBuffEffect(BuffStat.MORPH).isMorphWithoutAttack()) {
// How are they attacking when the client won't let them? // How are they attacking when the client won't let them?
chr.getClient().disconnect(false, false); chr.getClient().disconnect(false, false);
return; return;
@@ -57,7 +57,9 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
} }
if (chr.getDojoEnergy() < 10000 && (attack.skill == 1009 || attack.skill == 10001009 || attack.skill == 20001009)) // PE hacking or maybe just lagging if (chr.getDojoEnergy() < 10000 && (attack.skill == 1009 || attack.skill == 10001009 || attack.skill == 20001009)) // PE hacking or maybe just lagging
{
return; return;
}
if (GameConstants.isDojo(chr.getMap().getId()) && attack.numAttacked > 0) { if (GameConstants.isDojo(chr.getMap().getId()) && attack.numAttacked > 0) {
chr.setDojoEnergy(chr.getDojoEnergy() + YamlConfig.config.server.DOJO_ENERGY_ATK); chr.setDojoEnergy(chr.getDojoEnergy() + YamlConfig.config.server.DOJO_ENERGY_ATK);
c.sendPacket(PacketCreator.getEnergy("energy", chr.getDojoEnergy())); c.sendPacket(PacketCreator.getEnergy("energy", chr.getDojoEnergy()));
@@ -84,12 +86,17 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
ceffect = advcombo.getEffect(advComboSkillLevel); ceffect = advcombo.getEffect(advComboSkillLevel);
} else { } else {
int comboLv = chr.getSkillLevel(combo); int comboLv = chr.getSkillLevel(combo);
if(comboLv <= 0 || chr.isGM()) comboLv = SkillFactory.getSkill(oid).getMaxLevel(); if (comboLv <= 0 || chr.isGM()) {
comboLv = SkillFactory.getSkill(oid).getMaxLevel();
}
if(comboLv > 0) ceffect = combo.getEffect(comboLv); if (comboLv > 0) {
else ceffect = null; ceffect = combo.getEffect(comboLv);
} else {
ceffect = null;
}
} }
if(ceffect != null) { if (ceffect != null) {
if (orbcount < ceffect.getX() + 1) { if (orbcount < ceffect.getX() + 1) {
int neworbcount = orbcount + 1; int neworbcount = orbcount + 1;
if (advComboSkillLevel > 0 && ceffect.makeChanceResult()) { if (advComboSkillLevel > 0 && ceffect.makeChanceResult()) {
@@ -99,7 +106,9 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
} }
int olv = chr.getSkillLevel(oid); int olv = chr.getSkillLevel(oid);
if(olv <= 0) olv = SkillFactory.getSkill(oid).getMaxLevel(); if (olv <= 0) {
olv = SkillFactory.getSkill(oid).getMaxLevel();
}
int duration = combo.getEffect(olv).getDuration(); int duration = combo.getEffect(olv).getDuration();
List<Pair<BuffStat, Integer>> stat = Collections.singletonList(new Pair<>(BuffStat.COMBO, neworbcount)); List<Pair<BuffStat, Integer>> stat = Collections.singletonList(new Pair<>(BuffStat.COMBO, neworbcount));
@@ -164,7 +173,7 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
if ((chr.getSkillLevel(SkillFactory.getSkill(NightWalker.VANISH)) > 0 || chr.getSkillLevel(SkillFactory.getSkill(Rogue.DARK_SIGHT)) > 0) && chr.getBuffedValue(BuffStat.DARKSIGHT) != null) {// && chr.getBuffSource(BuffStat.DARKSIGHT) != 9101004 if ((chr.getSkillLevel(SkillFactory.getSkill(NightWalker.VANISH)) > 0 || chr.getSkillLevel(SkillFactory.getSkill(Rogue.DARK_SIGHT)) > 0) && chr.getBuffedValue(BuffStat.DARKSIGHT) != null) {// && chr.getBuffSource(BuffStat.DARKSIGHT) != 9101004
chr.cancelEffectFromBuffStat(BuffStat.DARKSIGHT); chr.cancelEffectFromBuffStat(BuffStat.DARKSIGHT);
chr.cancelBuffStats(BuffStat.DARKSIGHT); chr.cancelBuffStats(BuffStat.DARKSIGHT);
} else if(chr.getSkillLevel(SkillFactory.getSkill(WindArcher.WIND_WALK)) > 0 && chr.getBuffedValue(BuffStat.WIND_WALK) != null) { } else if (chr.getSkillLevel(SkillFactory.getSkill(WindArcher.WIND_WALK)) > 0 && chr.getBuffedValue(BuffStat.WIND_WALK) != null) {
chr.cancelEffectFromBuffStat(BuffStat.WIND_WALK); chr.cancelEffectFromBuffStat(BuffStat.WIND_WALK);
chr.cancelBuffStats(BuffStat.WIND_WALK); chr.cancelBuffStats(BuffStat.WIND_WALK);
} }
@@ -31,55 +31,54 @@ import server.maps.MapleMap;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author kevintjuh93 * @author kevintjuh93
*/ */
public final class CoconutHandler extends AbstractPacketHandler { public final class CoconutHandler extends AbstractPacketHandler {
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
/*CB 00 A6 00 06 01 /*CB 00 A6 00 06 01
* A6 00 = coconut id * A6 00 = coconut id
* 06 01 = ? * 06 01 = ?
*/ */
int id = p.readShort(); int id = p.readShort();
MapleMap map = c.getPlayer().getMap(); MapleMap map = c.getPlayer().getMap();
Coconut event = map.getCoconut(); Coconut event = map.getCoconut();
Coconuts nut = event.getCoconut(id); Coconuts nut = event.getCoconut(id);
if (!nut.isHittable()){ if (!nut.isHittable()) {
return; return;
} }
if (event == null){ if (event == null) {
return; return;
} }
if (currentServerTime() < nut.getHitTime()){ if (currentServerTime() < nut.getHitTime()) {
return; return;
} }
if (nut.getHits() > 2 && Math.random() < 0.4) { if (nut.getHits() > 2 && Math.random() < 0.4) {
if (Math.random() < 0.01 && event.getStopped() > 0) { if (Math.random() < 0.01 && event.getStopped() > 0) {
nut.setHittable(false); nut.setHittable(false);
event.stopCoconut(); event.stopCoconut();
map.broadcastMessage(PacketCreator.hitCoconut(false, id, 1)); map.broadcastMessage(PacketCreator.hitCoconut(false, id, 1));
return; return;
} }
nut.setHittable(false); // for sure :) nut.setHittable(false); // for sure :)
nut.resetHits(); // For next event (without restarts) nut.resetHits(); // For next event (without restarts)
if (Math.random() < 0.05 && event.getBombings() > 0) { if (Math.random() < 0.05 && event.getBombings() > 0) {
map.broadcastMessage(PacketCreator.hitCoconut(false, id, 2)); map.broadcastMessage(PacketCreator.hitCoconut(false, id, 2));
event.bombCoconut(); event.bombCoconut();
} else if (event.getFalling() > 0) { } else if (event.getFalling() > 0) {
map.broadcastMessage(PacketCreator.hitCoconut(false, id, 3)); map.broadcastMessage(PacketCreator.hitCoconut(false, id, 3));
event.fallCoconut(); event.fallCoconut();
if (c.getPlayer().getTeam() == 0) { if (c.getPlayer().getTeam() == 0) {
event.addMapleScore(); event.addMapleScore();
map.broadcastMessage(PacketCreator.serverNotice(5, c.getPlayer().getName() + " of Team Maple knocks down a coconut.")); map.broadcastMessage(PacketCreator.serverNotice(5, c.getPlayer().getName() + " of Team Maple knocks down a coconut."));
} else { } else {
event.addStoryScore(); event.addStoryScore();
map.broadcastMessage(PacketCreator.serverNotice(5, c.getPlayer().getName() + " of Team Story knocks down a coconut.")); map.broadcastMessage(PacketCreator.serverNotice(5, c.getPlayer().getName() + " of Team Story knocks down a coconut."));
} }
map.broadcastMessage(PacketCreator.coconutScore(event.getMapleScore(), event.getStoryScore())); map.broadcastMessage(PacketCreator.coconutScore(event.getMapleScore(), event.getStoryScore()));
} }
} else { } else {
nut.hit(); nut.hit();
map.broadcastMessage(PacketCreator.hitCoconut(false, id, 1)); map.broadcastMessage(PacketCreator.hitCoconut(false, id, 1));
} }
} }
} }
@@ -45,7 +45,6 @@ import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
/** /**
*
* @author Penguins (Acrylic) * @author Penguins (Acrylic)
* @author Ronan (HeavenMS) * @author Ronan (HeavenMS)
*/ */
@@ -250,11 +249,11 @@ public final class CouponCodeHandler extends AbstractPacketHandler {
break; break;
} }
} }
if(cashItems.size() > 255) { if (cashItems.size() > 255) {
List<Item> oldList = cashItems; List<Item> oldList = cashItems;
cashItems = Arrays.asList(new Item[255]); cashItems = Arrays.asList(new Item[255]);
int index = 0; int index = 0;
for(Item item : oldList) { for (Item item : oldList) {
cashItems.set(index, item); cashItems.set(index, item);
index++; index++;
} }
@@ -41,7 +41,7 @@ public final class DamageSummonHandler extends AbstractPacketHandler {
Character player = c.getPlayer(); Character player = c.getPlayer();
MapObject mmo = player.getMap().getMapObject(oid); MapObject mmo = player.getMap().getMapObject(oid);
if(mmo != null && mmo instanceof Summon) { if (mmo != null && mmo instanceof Summon) {
Summon summon = (Summon) mmo; Summon summon = (Summon) mmo;
summon.addHP(-damage); summon.addHP(-damage);
@@ -28,7 +28,6 @@ import net.packet.InPacket;
import net.server.guild.Guild; import net.server.guild.Guild;
/** /**
*
* @author Xterminator * @author Xterminator
*/ */
public final class DenyGuildRequestHandler extends AbstractPacketHandler { public final class DenyGuildRequestHandler extends AbstractPacketHandler {
@@ -30,7 +30,6 @@ import server.maps.MapObject;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author Matze * @author Matze
*/ */
public final class DoorHandler extends AbstractPacketHandler { public final class DoorHandler extends AbstractPacketHandler {
@@ -32,10 +32,10 @@ public final class DueyHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
if (!YamlConfig.config.server.USE_DUEY){ if (!YamlConfig.config.server.USE_DUEY) {
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
byte operation = p.readByte(); byte operation = p.readByte();
if (operation == DueyProcessor.Actions.TOSERVER_RECV_ITEM.getCode()) { // on click 'O' Button, thanks inhyuk if (operation == DueyProcessor.Actions.TOSERVER_RECV_ITEM.getCode()) { // on click 'O' Button, thanks inhyuk
@@ -30,7 +30,6 @@ import server.maps.MiniDungeonInfo;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author Flav * @author Flav
*/ */
public class EnterCashShopHandler extends AbstractPacketHandler { public class EnterCashShopHandler extends AbstractPacketHandler {
@@ -44,13 +43,13 @@ public class EnterCashShopHandler extends AbstractPacketHandler {
return; return;
} }
if(mc.getEventInstance() != null) { if (mc.getEventInstance() != null) {
c.sendPacket(PacketCreator.serverNotice(5, "Entering Cash Shop or MTS are disabled when registered on an event.")); c.sendPacket(PacketCreator.serverNotice(5, "Entering Cash Shop or MTS are disabled when registered on an event."));
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
if(MiniDungeonInfo.isDungeonMap(mc.getMapId())) { if (MiniDungeonInfo.isDungeonMap(mc.getMapId())) {
c.sendPacket(PacketCreator.serverNotice(5, "Changing channels or entering Cash Shop or MTS are disabled when inside a Mini-Dungeon.")); c.sendPacket(PacketCreator.serverNotice(5, "Changing channels or entering Cash Shop or MTS are disabled when inside a Mini-Dungeon."));
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
@@ -49,7 +49,7 @@ public final class EnterMTSHandler extends AbstractPacketHandler {
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
Character chr = c.getPlayer(); Character chr = c.getPlayer();
if(!chr.isAlive() && YamlConfig.config.server.USE_BUYBACK_SYSTEM) { if (!chr.isAlive() && YamlConfig.config.server.USE_BUYBACK_SYSTEM) {
BuybackProcessor.processBuyback(c); BuybackProcessor.processBuyback(c);
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
} else { } else {
@@ -58,13 +58,13 @@ public final class EnterMTSHandler extends AbstractPacketHandler {
return; return;
} }
if(chr.getEventInstance() != null) { if (chr.getEventInstance() != null) {
c.sendPacket(PacketCreator.serverNotice(5, "Entering Cash Shop or MTS are disabled when registered on an event.")); c.sendPacket(PacketCreator.serverNotice(5, "Entering Cash Shop or MTS are disabled when registered on an event."));
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
if(MiniDungeonInfo.isDungeonMap(chr.getMapId())) { if (MiniDungeonInfo.isDungeonMap(chr.getMapId())) {
c.sendPacket(PacketCreator.serverNotice(5, "Changing channels or entering Cash Shop or MTS are disabled when inside a Mini-Dungeon.")); c.sendPacket(PacketCreator.serverNotice(5, "Changing channels or entering Cash Shop or MTS are disabled when inside a Mini-Dungeon."));
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
@@ -42,7 +42,7 @@ public final class FaceExpressionHandler extends AbstractPacketHandler {
return; return;
} }
if(c.tryacquireClient()) { if (c.tryacquireClient()) {
try { // expecting players never intends to wear the emote 0 (default face, that changes back after 5sec timeout) try { // expecting players never intends to wear the emote 0 (default face, that changes back after 5sec timeout)
if (chr.isLoggedinWorld()) { if (chr.isLoggedinWorld()) {
chr.changeFaceExpression(emote); chr.changeFaceExpression(emote);
@@ -31,34 +31,33 @@ import net.server.coordinator.world.InviteCoordinator.InviteType;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author Jay Estrella * @author Jay Estrella
* @author Ubaware * @author Ubaware
*/ */
public final class FamilyAddHandler extends AbstractPacketHandler { public final class FamilyAddHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
if(!YamlConfig.config.server.USE_FAMILY_SYSTEM) { if (!YamlConfig.config.server.USE_FAMILY_SYSTEM) {
return; return;
} }
String toAdd = p.readString(); String toAdd = p.readString();
Character addChr = c.getChannelServer().getPlayerStorage().getCharacterByName(toAdd); Character addChr = c.getChannelServer().getPlayerStorage().getCharacterByName(toAdd);
Character chr = c.getPlayer(); Character chr = c.getPlayer();
if(addChr == null) { if (addChr == null) {
c.sendPacket(PacketCreator.sendFamilyMessage(65, 0)); c.sendPacket(PacketCreator.sendFamilyMessage(65, 0));
} else if(addChr == chr) { //only possible through packet editing/client editing i think? } else if (addChr == chr) { //only possible through packet editing/client editing i think?
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
} else if(addChr.getMap() != chr.getMap() || (addChr.isHidden()) && chr.gmLevel() < addChr.gmLevel()) { } else if (addChr.getMap() != chr.getMap() || (addChr.isHidden()) && chr.gmLevel() < addChr.gmLevel()) {
c.sendPacket(PacketCreator.sendFamilyMessage(69, 0)); c.sendPacket(PacketCreator.sendFamilyMessage(69, 0));
} else if(addChr.getLevel() <= 10) { } else if (addChr.getLevel() <= 10) {
c.sendPacket(PacketCreator.sendFamilyMessage(77, 0)); c.sendPacket(PacketCreator.sendFamilyMessage(77, 0));
} else if(Math.abs(addChr.getLevel() - chr.getLevel()) > 20) { } else if (Math.abs(addChr.getLevel() - chr.getLevel()) > 20) {
c.sendPacket(PacketCreator.sendFamilyMessage(72, 0)); c.sendPacket(PacketCreator.sendFamilyMessage(72, 0));
} else if(addChr.getFamily() != null && addChr.getFamily() == chr.getFamily()) { //same family } else if (addChr.getFamily() != null && addChr.getFamily() == chr.getFamily()) { //same family
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
} else if(InviteCoordinator.hasInvite(InviteType.FAMILY, addChr.getId())) { } else if (InviteCoordinator.hasInvite(InviteType.FAMILY, addChr.getId())) {
c.sendPacket(PacketCreator.sendFamilyMessage(73, 0)); c.sendPacket(PacketCreator.sendFamilyMessage(73, 0));
} else if(chr.getFamily() != null && addChr.getFamily() != null && addChr.getFamily().getTotalGenerations() + chr.getFamily().getTotalGenerations() > YamlConfig.config.server.FAMILY_MAX_GENERATIONS) { } else if (chr.getFamily() != null && addChr.getFamily() != null && addChr.getFamily().getTotalGenerations() + chr.getFamily().getTotalGenerations() > YamlConfig.config.server.FAMILY_MAX_GENERATIONS) {
c.sendPacket(PacketCreator.sendFamilyMessage(76, 0)); c.sendPacket(PacketCreator.sendFamilyMessage(76, 0));
} else { } else {
InviteCoordinator.createInvite(InviteType.FAMILY, chr, addChr, addChr.getId()); InviteCoordinator.createInvite(InviteType.FAMILY, chr, addChr, addChr.getId());
@@ -11,10 +11,16 @@ public class FamilyPreceptsHandler extends AbstractPacketHandler {
@Override @Override
public void handlePacket(InPacket p, Client c) { public void handlePacket(InPacket p, Client c) {
Family family = c.getPlayer().getFamily(); Family family = c.getPlayer().getFamily();
if(family == null) return; if (family == null) {
if(family.getLeader().getChr() != c.getPlayer()) return; //only the leader can set the precepts return;
}
if (family.getLeader().getChr() != c.getPlayer()) {
return; //only the leader can set the precepts
}
String newPrecepts = p.readString(); String newPrecepts = p.readString();
if(newPrecepts.length() > 200) return; if (newPrecepts.length() > 200) {
return;
}
family.setMessage(newPrecepts, true); family.setMessage(newPrecepts, true);
//family.broadcastFamilyInfoUpdate(); //probably don't need to broadcast for this? //family.broadcastFamilyInfoUpdate(); //probably don't need to broadcast for this?
c.sendPacket(PacketCreator.getFamilyInfo(c.getPlayer().getFamilyEntry())); c.sendPacket(PacketCreator.getFamilyInfo(c.getPlayer().getFamilyEntry()));
@@ -31,34 +31,46 @@ public class FamilySeparateHandler extends AbstractPacketHandler {
@Override @Override
public void handlePacket(InPacket p, Client c) { public void handlePacket(InPacket p, Client c) {
if(!YamlConfig.config.server.USE_FAMILY_SYSTEM) return; if (!YamlConfig.config.server.USE_FAMILY_SYSTEM) {
return;
}
Family oldFamily = c.getPlayer().getFamily(); Family oldFamily = c.getPlayer().getFamily();
if(oldFamily == null) return; if (oldFamily == null) {
return;
}
FamilyEntry forkOn = null; FamilyEntry forkOn = null;
boolean isSenior; boolean isSenior;
if(p.available() > 0) { //packet 0x95 doesn't send id, since there is only one senior if (p.available() > 0) { //packet 0x95 doesn't send id, since there is only one senior
forkOn = c.getPlayer().getFamily().getEntryByID(p.readInt()); forkOn = c.getPlayer().getFamily().getEntryByID(p.readInt());
if(!c.getPlayer().getFamilyEntry().isJunior(forkOn)) return; //packet editing? if (!c.getPlayer().getFamilyEntry().isJunior(forkOn)) {
return; //packet editing?
}
isSenior = true; isSenior = true;
} else { } else {
forkOn = c.getPlayer().getFamilyEntry(); forkOn = c.getPlayer().getFamilyEntry();
isSenior = false; isSenior = false;
} }
if(forkOn == null) return; if (forkOn == null) {
return;
}
FamilyEntry senior = forkOn.getSenior(); FamilyEntry senior = forkOn.getSenior();
if(senior == null) return; if (senior == null) {
return;
}
int levelDiff = Math.abs(c.getPlayer().getLevel() - senior.getLevel()); int levelDiff = Math.abs(c.getPlayer().getLevel() - senior.getLevel());
int cost = 2500 * levelDiff; int cost = 2500 * levelDiff;
cost += levelDiff * levelDiff; cost += levelDiff * levelDiff;
if(c.getPlayer().getMeso() < cost) { if (c.getPlayer().getMeso() < cost) {
c.sendPacket(PacketCreator.sendFamilyMessage(isSenior ? 81 : 80, cost)); c.sendPacket(PacketCreator.sendFamilyMessage(isSenior ? 81 : 80, cost));
return; return;
} }
c.getPlayer().gainMeso(-cost); c.getPlayer().gainMeso(-cost);
int repCost = separateRepCost(forkOn); int repCost = separateRepCost(forkOn);
senior.gainReputation(-repCost, false); senior.gainReputation(-repCost, false);
if(senior.getSenior() != null) senior.getSenior().gainReputation(-(repCost/2), false); if (senior.getSenior() != null) {
senior.getSenior().gainReputation(-(repCost / 2), false);
}
forkOn.announceToSenior(PacketCreator.serverNotice(5, forkOn.getName() + " has left the family."), true); forkOn.announceToSenior(PacketCreator.serverNotice(5, forkOn.getName() + " has left the family."), true);
forkOn.fork(); forkOn.fork();
c.sendPacket(PacketCreator.getFamilyInfo(forkOn)); //pedigree info will be requested from the client if the window is open c.sendPacket(PacketCreator.getFamilyInfo(forkOn)); //pedigree info will be requested from the client if the window is open
@@ -18,16 +18,22 @@ public class FamilySummonResponseHandler extends AbstractPacketHandler {
@Override @Override
public void handlePacket(InPacket p, Client c) { public void handlePacket(InPacket p, Client c) {
if(!YamlConfig.config.server.USE_FAMILY_SYSTEM) return; if (!YamlConfig.config.server.USE_FAMILY_SYSTEM) {
return;
}
p.readString(); //family name p.readString(); //family name
boolean accept = p.readByte() != 0; boolean accept = p.readByte() != 0;
InviteResult inviteResult = InviteCoordinator.answerInvite(InviteType.FAMILY_SUMMON, c.getPlayer().getId(), c.getPlayer(), accept); InviteResult inviteResult = InviteCoordinator.answerInvite(InviteType.FAMILY_SUMMON, c.getPlayer().getId(), c.getPlayer(), accept);
if(inviteResult.result == InviteResultType.NOT_FOUND) return; if (inviteResult.result == InviteResultType.NOT_FOUND) {
return;
}
Character inviter = inviteResult.from; Character inviter = inviteResult.from;
FamilyEntry inviterEntry = inviter.getFamilyEntry(); FamilyEntry inviterEntry = inviter.getFamilyEntry();
if(inviterEntry == null) return; if (inviterEntry == null) {
return;
}
MapleMap map = (MapleMap) inviteResult.params[0]; MapleMap map = (MapleMap) inviteResult.params[0];
if(accept && inviter.getMap() == map) { //cancel if inviter has changed maps if (accept && inviter.getMap() == map) { //cancel if inviter has changed maps
c.getPlayer().changeMap(map, map.getPortal(0)); c.getPlayer().changeMap(map, map.getPortal(0));
} else { } else {
inviterEntry.refundEntitlement(FamilyEntitlement.SUMMON_FAMILY); inviterEntry.refundEntitlement(FamilyEntitlement.SUMMON_FAMILY);
@@ -35,33 +35,32 @@ import server.maps.MapleMap;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author Moogra * @author Moogra
* @author Ubaware * @author Ubaware
*/ */
public final class FamilyUseHandler extends AbstractPacketHandler { public final class FamilyUseHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
if(!YamlConfig.config.server.USE_FAMILY_SYSTEM) { if (!YamlConfig.config.server.USE_FAMILY_SYSTEM) {
return; return;
} }
FamilyEntitlement type = FamilyEntitlement.values()[p.readInt()]; FamilyEntitlement type = FamilyEntitlement.values()[p.readInt()];
int cost = type.getRepCost(); int cost = type.getRepCost();
FamilyEntry entry = c.getPlayer().getFamilyEntry(); FamilyEntry entry = c.getPlayer().getFamilyEntry();
if(entry.getReputation() < cost || entry.isEntitlementUsed(type)) { if (entry.getReputation() < cost || entry.isEntitlementUsed(type)) {
return; // shouldn't even be able to request it return; // shouldn't even be able to request it
} }
c.sendPacket(PacketCreator.getFamilyInfo(entry)); c.sendPacket(PacketCreator.getFamilyInfo(entry));
Character victim; Character victim;
if(type == FamilyEntitlement.FAMILY_REUINION || type == FamilyEntitlement.SUMMON_FAMILY) { if (type == FamilyEntitlement.FAMILY_REUINION || type == FamilyEntitlement.SUMMON_FAMILY) {
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(p.readString()); victim = c.getChannelServer().getPlayerStorage().getCharacterByName(p.readString());
if(victim != null && victim != c.getPlayer()) { if (victim != null && victim != c.getPlayer()) {
if(victim.getFamily() == c.getPlayer().getFamily()) { if (victim.getFamily() == c.getPlayer().getFamily()) {
MapleMap targetMap = victim.getMap(); MapleMap targetMap = victim.getMap();
MapleMap ownMap = c.getPlayer().getMap(); MapleMap ownMap = c.getPlayer().getMap();
if(targetMap != null) { if (targetMap != null) {
if(type == FamilyEntitlement.FAMILY_REUINION) { if (type == FamilyEntitlement.FAMILY_REUINION) {
if(!FieldLimit.CANNOTMIGRATE.check(ownMap.getFieldLimit()) && !FieldLimit.CANNOTVIPROCK.check(targetMap.getFieldLimit()) if (!FieldLimit.CANNOTMIGRATE.check(ownMap.getFieldLimit()) && !FieldLimit.CANNOTVIPROCK.check(targetMap.getFieldLimit())
&& (targetMap.getForcedReturnId() == 999999999 || targetMap.getId() < 100000000) && targetMap.getEventInstance() == null) { && (targetMap.getForcedReturnId() == 999999999 || targetMap.getId() < 100000000) && targetMap.getEventInstance() == null) {
c.getPlayer().changeMap(victim.getMap(), victim.getMap().getPortal(0)); c.getPlayer().changeMap(victim.getMap(), victim.getMap().getPortal(0));
@@ -71,10 +70,10 @@ public final class FamilyUseHandler extends AbstractPacketHandler {
return; return;
} }
} else { } else {
if(!FieldLimit.CANNOTMIGRATE.check(targetMap.getFieldLimit()) && !FieldLimit.CANNOTVIPROCK.check(ownMap.getFieldLimit()) if (!FieldLimit.CANNOTMIGRATE.check(targetMap.getFieldLimit()) && !FieldLimit.CANNOTVIPROCK.check(ownMap.getFieldLimit())
&& (ownMap.getForcedReturnId() == 999999999 || ownMap.getId() < 100000000) && ownMap.getEventInstance() == null) { && (ownMap.getForcedReturnId() == 999999999 || ownMap.getId() < 100000000) && ownMap.getEventInstance() == null) {
if(InviteCoordinator.hasInvite(InviteType.FAMILY_SUMMON, victim.getId())) { if (InviteCoordinator.hasInvite(InviteType.FAMILY_SUMMON, victim.getId())) {
c.sendPacket(PacketCreator.sendFamilyMessage(74, 0)); c.sendPacket(PacketCreator.sendFamilyMessage(74, 0));
return; return;
} }
@@ -91,7 +90,7 @@ public final class FamilyUseHandler extends AbstractPacketHandler {
c.sendPacket(PacketCreator.sendFamilyMessage(67, 0)); c.sendPacket(PacketCreator.sendFamilyMessage(67, 0));
} }
} }
} else if(type == FamilyEntitlement.FAMILY_BONDING) { } else if (type == FamilyEntitlement.FAMILY_BONDING) {
//not implemented //not implemented
} else { } else {
boolean party = false; boolean party = false;
@@ -99,39 +98,39 @@ public final class FamilyUseHandler extends AbstractPacketHandler {
float rate = 1.5f; float rate = 1.5f;
int duration = 15; int duration = 15;
do { do {
switch(type) { switch (type) {
case PARTY_EXP_2_30MIN: case PARTY_EXP_2_30MIN:
party = true; party = true;
isExp = true; isExp = true;
type = FamilyEntitlement.SELF_EXP_2_30MIN; type = FamilyEntitlement.SELF_EXP_2_30MIN;
continue; continue;
case PARTY_DROP_2_30MIN: case PARTY_DROP_2_30MIN:
party = true; party = true;
type = FamilyEntitlement.SELF_DROP_2_30MIN; type = FamilyEntitlement.SELF_DROP_2_30MIN;
continue; continue;
case SELF_DROP_2_30MIN: case SELF_DROP_2_30MIN:
duration = 30; duration = 30;
case SELF_DROP_2: case SELF_DROP_2:
rate = 2.0f; rate = 2.0f;
case SELF_DROP_1_5: case SELF_DROP_1_5:
break; break;
case SELF_EXP_2_30MIN: case SELF_EXP_2_30MIN:
duration = 30; duration = 30;
case SELF_EXP_2: case SELF_EXP_2:
rate = 2.0f; rate = 2.0f;
case SELF_EXP_1_5: case SELF_EXP_1_5:
isExp = true; isExp = true;
default: default:
break; break;
} }
break; break;
} while(true); } while (true);
//not implemented //not implemented
} }
} }
private boolean useEntitlement(FamilyEntry entry, FamilyEntitlement entitlement) { private boolean useEntitlement(FamilyEntry entry, FamilyEntitlement entitlement) {
if(entry.useEntitlement(entitlement)) { if (entry.useEntitlement(entitlement)) {
entry.gainReputation(-entitlement.getRepCost(), false); entry.gainReputation(-entitlement.getRepCost(), false);
entry.getChr().sendPacket(PacketCreator.getFamilyInfo(entry)); entry.getChr().sendPacket(PacketCreator.getFamilyInfo(entry));
return true; return true;
@@ -28,7 +28,6 @@ import net.AbstractPacketHandler;
import net.packet.InPacket; import net.packet.InPacket;
/** /**
*
* @author kevintjuh93 * @author kevintjuh93
*/ */
public class FredrickHandler extends AbstractPacketHandler { public class FredrickHandler extends AbstractPacketHandler {
@@ -33,43 +33,43 @@ import tools.LogHelper;
import tools.PacketCreator; import tools.PacketCreator;
public final class GeneralChatHandler extends AbstractPacketHandler { public final class GeneralChatHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
String s = p.readString(); String s = p.readString();
Character chr = c.getPlayer(); Character chr = c.getPlayer();
if(chr.getAutobanManager().getLastSpam(7) + 200 > currentServerTime()) { if (chr.getAutobanManager().getLastSpam(7) + 200 > currentServerTime()) {
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
}
if (s.length() > Byte.MAX_VALUE && !chr.isGM()) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit in General Chat.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to send text with length of " + s.length());
c.disconnect(true, false);
return;
}
char heading = s.charAt(0);
if (CommandsExecutor.isCommand(c, s)) {
CommandsExecutor.getInstance().handle(c, s);
} else if (heading != '/') {
int show = p.readByte();
if(chr.getMap().isMuted() && !chr.isGM()) {
chr.dropMessage(5, "The map you are in is currently muted. Please try again later.");
return;
}
if (!chr.isHidden()) {
chr.getMap().broadcastMessage(PacketCreator.getChatText(chr.getId(), s, chr.getWhiteChat(), show));
if (YamlConfig.config.server.USE_ENABLE_CHAT_LOG) {
LogHelper.logChat(c, "General", s);
}
} else {
chr.getMap().broadcastGMMessage(PacketCreator.getChatText(chr.getId(), s, chr.getWhiteChat(), show));
if (YamlConfig.config.server.USE_ENABLE_CHAT_LOG) {
LogHelper.logChat(c, "GM General", s);
}
}
chr.getAutobanManager().spam(7);
}
} }
if (s.length() > Byte.MAX_VALUE && !chr.isGM()) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit in General Chat.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to send text with length of " + s.length());
c.disconnect(true, false);
return;
}
char heading = s.charAt(0);
if (CommandsExecutor.isCommand(c, s)) {
CommandsExecutor.getInstance().handle(c, s);
} else if (heading != '/') {
int show = p.readByte();
if (chr.getMap().isMuted() && !chr.isGM()) {
chr.dropMessage(5, "The map you are in is currently muted. Please try again later.");
return;
}
if (!chr.isHidden()) {
chr.getMap().broadcastMessage(PacketCreator.getChatText(chr.getId(), s, chr.getWhiteChat(), show));
if (YamlConfig.config.server.USE_ENABLE_CHAT_LOG) {
LogHelper.logChat(c, "General", s);
}
} else {
chr.getMap().broadcastGMMessage(PacketCreator.getChatText(chr.getId(), s, chr.getWhiteChat(), show));
if (YamlConfig.config.server.USE_ENABLE_CHAT_LOG) {
LogHelper.logChat(c, "GM General", s);
}
}
chr.getAutobanManager().spam(7);
}
}
} }
@@ -111,7 +111,8 @@ public final class GuildOperationHandler extends AbstractPacketHandler {
GuildResponse mgr = Guild.sendInvitation(c, targetName); GuildResponse mgr = Guild.sendInvitation(c, targetName);
if (mgr != null) { if (mgr != null) {
c.sendPacket(mgr.getPacket(targetName)); c.sendPacket(mgr.getPacket(targetName));
} else {} // already sent invitation, do nothing } else {
} // already sent invitation, do nothing
break; break;
case 0x06: case 0x06:
@@ -144,7 +145,9 @@ public final class GuildOperationHandler extends AbstractPacketHandler {
c.sendPacket(GuildPackets.showGuildInfo(mc)); c.sendPacket(GuildPackets.showGuildInfo(mc));
allianceId = mc.getGuild().getAllianceId(); allianceId = mc.getGuild().getAllianceId();
if(allianceId > 0) Server.getInstance().getAlliance(allianceId).updateAlliancePackets(mc); if (allianceId > 0) {
Server.getInstance().getAlliance(allianceId).updateAlliancePackets(mc);
}
mc.saveGuildStatus(); // update database mc.saveGuildStatus(); // update database
mc.getMap().broadcastPacket(mc, GuildPackets.guildNameChanged(mc.getId(), mc.getGuild().getName())); // thanks Vcoc for pointing out an issue with updating guild tooltip to players in the map mc.getMap().broadcastPacket(mc, GuildPackets.guildNameChanged(mc.getId(), mc.getGuild().getName())); // thanks Vcoc for pointing out an issue with updating guild tooltip to players in the map
@@ -164,7 +167,9 @@ public final class GuildOperationHandler extends AbstractPacketHandler {
Server.getInstance().leaveGuild(mc.getMGC()); Server.getInstance().leaveGuild(mc.getMGC());
c.sendPacket(GuildPackets.showGuildInfo(null)); c.sendPacket(GuildPackets.showGuildInfo(null));
if(allianceId > 0) Server.getInstance().getAlliance(allianceId).updateAlliancePackets(mc); if (allianceId > 0) {
Server.getInstance().getAlliance(allianceId).updateAlliancePackets(mc);
}
mc.getMGC().setGuildId(0); mc.getMGC().setGuildId(0);
mc.getMGC().setGuildRank(5); mc.getMGC().setGuildRank(5);
@@ -182,7 +187,9 @@ public final class GuildOperationHandler extends AbstractPacketHandler {
} }
Server.getInstance().expelMember(mc.getMGC(), name, cid); Server.getInstance().expelMember(mc.getMGC(), name, cid);
if(allianceId > 0) Server.getInstance().getAlliance(allianceId).updateAlliancePackets(mc); if (allianceId > 0) {
Server.getInstance().getAlliance(allianceId).updateAlliancePackets(mc);
}
break; break;
case 0x0d: case 0x0d:
if (mc.getGuildId() <= 0 || mc.getGuildRank() != 1) { if (mc.getGuildId() <= 0 || mc.getGuildRank() != 1) {
@@ -234,7 +241,9 @@ public final class GuildOperationHandler extends AbstractPacketHandler {
break; break;
case 0x10: case 0x10:
if (mc.getGuildId() <= 0 || mc.getGuildRank() > 2) { if (mc.getGuildId() <= 0 || mc.getGuildRank() > 2) {
if(mc.getGuildId() <= 0) System.out.println("[Hack] " + mc.getName() + " tried to change guild notice while not in a guild."); if (mc.getGuildId() <= 0) {
System.out.println("[Hack] " + mc.getName() + " tried to change guild notice while not in a guild.");
}
return; return;
} }
String notice = p.readString(); String notice = p.readString();
@@ -270,7 +279,7 @@ public final class GuildOperationHandler extends AbstractPacketHandler {
break; break;
default: default:
System.out.println("Unhandled GUILD_OPERATION packet: \n" + p.toString()); System.out.println("Unhandled GUILD_OPERATION packet: \n" + p);
} }
} }
} }
@@ -35,7 +35,9 @@ public final class HealOvertimeHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
Character chr = c.getPlayer(); Character chr = c.getPlayer();
if(!chr.isLoggedinWorld()) return; if (!chr.isLoggedinWorld()) {
return;
}
AutobanManager abm = chr.getAutobanManager(); AutobanManager abm = chr.getAutobanManager();
int timestamp = Server.getInstance().getCurrentTimestamp(); int timestamp = Server.getInstance().getCurrentTimestamp();
@@ -44,10 +46,12 @@ public final class HealOvertimeHandler extends AbstractPacketHandler {
short healHP = p.readShort(); short healHP = p.readShort();
if (healHP != 0) { if (healHP != 0) {
abm.setTimestamp(8, timestamp, 28); // thanks Vcoc & Thora for pointing out d/c happening here abm.setTimestamp(8, timestamp, 28); // thanks Vcoc & Thora for pointing out d/c happening here
if ((abm.getLastSpam(0) + 1500) > timestamp) AutobanFactory.FAST_HP_HEALING.addPoint(abm, "Fast hp healing"); if ((abm.getLastSpam(0) + 1500) > timestamp) {
AutobanFactory.FAST_HP_HEALING.addPoint(abm, "Fast hp healing");
}
MapleMap map = chr.getMap(); MapleMap map = chr.getMap();
int abHeal = (int)(77 * map.getRecovery() * 1.5); // thanks Ari for noticing players not getting healed in sauna in certain cases int abHeal = (int) (77 * map.getRecovery() * 1.5); // thanks Ari for noticing players not getting healed in sauna in certain cases
if (healHP > abHeal) { if (healHP > abHeal) {
AutobanFactory.HIGH_HP_HEALING.autoban(chr, "Healing: " + healHP + "; Max is " + abHeal + "."); AutobanFactory.HIGH_HP_HEALING.autoban(chr, "Healing: " + healHP + "; Max is " + abHeal + ".");
return; return;
@@ -38,7 +38,6 @@ import java.sql.SQLException;
import java.util.Arrays; import java.util.Arrays;
/** /**
*
* @author XoticStory * @author XoticStory
*/ */
public final class HiredMerchantRequest extends AbstractPacketHandler { public final class HiredMerchantRequest extends AbstractPacketHandler {
@@ -26,7 +26,6 @@ import net.AbstractPacketHandler;
import net.packet.InPacket; import net.packet.InPacket;
/** /**
*
* @author BubblesDev * @author BubblesDev
*/ */
public final class InnerPortalHandler extends AbstractPacketHandler { public final class InnerPortalHandler extends AbstractPacketHandler {
@@ -42,10 +42,10 @@ public final class InventoryMergeHandler extends AbstractPacketHandler {
p.readInt(); p.readInt();
chr.getAutobanManager().setTimestamp(2, Server.getInstance().getCurrentTimestamp(), 4); chr.getAutobanManager().setTimestamp(2, Server.getInstance().getCurrentTimestamp(), 4);
if(!YamlConfig.config.server.USE_ITEM_SORT) { if (!YamlConfig.config.server.USE_ITEM_SORT) {
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
byte invType = p.readByte(); byte invType = p.readByte();
if (invType < 1 || invType > 5) { if (invType < 1 || invType > 5) {
@@ -54,7 +54,7 @@ public final class InventoryMergeHandler extends AbstractPacketHandler {
} }
InventoryType inventoryType = InventoryType.getByType(invType); InventoryType inventoryType = InventoryType.getByType(invType);
Inventory inventory = c.getPlayer().getInventory(inventoryType); Inventory inventory = c.getPlayer().getInventory(inventoryType);
inventory.lockInventory(); inventory.lockInventory();
try { try {
//------------------- RonanLana's SLOT MERGER ----------------- //------------------- RonanLana's SLOT MERGER -----------------
@@ -62,16 +62,24 @@ public final class InventoryMergeHandler extends AbstractPacketHandler {
ItemInformationProvider ii = ItemInformationProvider.getInstance(); ItemInformationProvider ii = ItemInformationProvider.getInstance();
Item srcItem, dstItem; Item srcItem, dstItem;
for(short dst = 1; dst <= inventory.getSlotLimit(); dst++) { for (short dst = 1; dst <= inventory.getSlotLimit(); dst++) {
dstItem = inventory.getItem(dst); dstItem = inventory.getItem(dst);
if(dstItem == null) continue; if (dstItem == null) {
continue;
}
for(short src = (short)(dst + 1); src <= inventory.getSlotLimit(); src++) { for (short src = (short) (dst + 1); src <= inventory.getSlotLimit(); src++) {
srcItem = inventory.getItem(src); srcItem = inventory.getItem(src);
if(srcItem == null) continue; if (srcItem == null) {
continue;
}
if(dstItem.getItemId() != srcItem.getItemId()) continue; if (dstItem.getItemId() != srcItem.getItemId()) {
if(dstItem.getQuantity() == ii.getSlotMax(c, inventory.getItem(dst).getItemId())) break; continue;
}
if (dstItem.getQuantity() == ii.getSlotMax(c, inventory.getItem(dst).getItemId())) {
break;
}
InventoryManipulator.move(c, inventoryType, src, dst); InventoryManipulator.move(c, inventoryType, src, dst);
} }
@@ -35,7 +35,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
*
* @author BubblesDev * @author BubblesDev
* @author Ronan * @author Ronan
*/ */
@@ -54,8 +53,12 @@ class PairedQuicksort {
x = A.get((i + j) / 2); x = A.get((i + j) / 2);
do { do {
while (x.getItemId() > A.get(i).getItemId()) i++; while (x.getItemId() > A.get(i).getItemId()) {
while (x.getItemId() < A.get(j).getItemId()) j--; i++;
}
while (x.getItemId() < A.get(j).getItemId()) {
j--;
}
if (i <= j) { if (i <= j) {
w = A.get(i); w = A.get(i);
@@ -81,8 +84,12 @@ class PairedQuicksort {
x = A.get((i + j) / 2); x = A.get((i + j) / 2);
do { do {
int watk = getWatkForProjectile(x); int watk = getWatkForProjectile(x);
while (watk < getWatkForProjectile(A.get(i))) i++; while (watk < getWatkForProjectile(A.get(i))) {
while (watk > getWatkForProjectile(A.get(j))) j--; i++;
}
while (watk > getWatkForProjectile(A.get(j))) {
j--;
}
if (i <= j) { if (i <= j) {
w = A.get(i); w = A.get(i);
@@ -103,8 +110,12 @@ class PairedQuicksort {
x = A.get((i + j) / 2); x = A.get((i + j) / 2);
do { do {
while (ii.getName(x.getItemId()).compareTo(ii.getName(A.get(i).getItemId())) > 0) i++; while (ii.getName(x.getItemId()).compareTo(ii.getName(A.get(i).getItemId())) > 0) {
while (ii.getName(x.getItemId()).compareTo(ii.getName(A.get(j).getItemId())) < 0) j--; i++;
}
while (ii.getName(x.getItemId()).compareTo(ii.getName(A.get(j).getItemId())) < 0) {
j--;
}
if (i <= j) { if (i <= j) {
w = A.get(i); w = A.get(i);
@@ -125,8 +136,12 @@ class PairedQuicksort {
x = A.get((i + j) / 2); x = A.get((i + j) / 2);
do { do {
while (x.getQuantity() > A.get(i).getQuantity()) i++; while (x.getQuantity() > A.get(i).getQuantity()) {
while (x.getQuantity() < A.get(j).getQuantity()) j--; i++;
}
while (x.getQuantity() < A.get(j).getQuantity()) {
j--;
}
if (i <= j) { if (i <= j) {
w = A.get(i); w = A.get(i);
@@ -145,15 +160,19 @@ class PairedQuicksort {
i = Esq; i = Esq;
j = Dir; j = Dir;
x = (Equip)(A.get((i + j) / 2)); x = (Equip) (A.get((i + j) / 2));
do { do {
while (x.getLevel() > ((Equip)A.get(i)).getLevel()) i++; while (x.getLevel() > ((Equip) A.get(i)).getLevel()) {
while (x.getLevel() < ((Equip)A.get(j)).getLevel()) j--; i++;
}
while (x.getLevel() < ((Equip) A.get(j)).getLevel()) {
j--;
}
if (i <= j) { if (i <= j) {
w = (Equip)A.get(i); w = (Equip) A.get(i);
A.set(i, A.get(j)); A.set(i, A.get(j));
A.set(j, w); A.set(j, w);
@@ -164,7 +183,7 @@ class PairedQuicksort {
} }
void MapleQuicksort(int Esq, int Dir, ArrayList<Item> A, int sort) { void MapleQuicksort(int Esq, int Dir, ArrayList<Item> A, int sort) {
switch(sort) { switch (sort) {
case 3: case 3:
PartitionByLevel(Esq, Dir, A); PartitionByLevel(Esq, Dir, A);
break; break;
@@ -182,8 +201,12 @@ class PairedQuicksort {
} }
if (Esq < j) MapleQuicksort(Esq, j, A, sort); if (Esq < j) {
if (i < Dir) MapleQuicksort(i, Dir, A, sort); MapleQuicksort(Esq, j, A, sort);
}
if (i < Dir) {
MapleQuicksort(i, Dir, A, sort);
}
} }
private static int getItemSubtype(Item it) { private static int getItemSubtype(Item it) {
@@ -235,7 +258,7 @@ class PairedQuicksort {
public PairedQuicksort(ArrayList<Item> A, int primarySort, int secondarySort) { public PairedQuicksort(ArrayList<Item> A, int primarySort, int secondarySort) {
intersect = new ArrayList<>(); intersect = new ArrayList<>();
if(A.size() > 0) { if (A.size() > 0) {
MapleQuicksort(0, A.size() - 1, A, primarySort); MapleQuicksort(0, A.size() - 1, A, primarySort);
if (A.get(0).getInventoryType().equals(InventoryType.USE)) { // thanks KDA & Vcoc for suggesting stronger projectiles coming before weaker ones if (A.get(0).getInventoryType().equals(InventoryType.USE)) { // thanks KDA & Vcoc for suggesting stronger projectiles coming before weaker ones
@@ -246,15 +269,17 @@ class PairedQuicksort {
} }
intersect.add(0); intersect.add(0);
for(int ind = 1; ind < A.size(); ind++) { for (int ind = 1; ind < A.size(); ind++) {
if(A.get(ind - 1).getItemId() != A.get(ind).getItemId()) { if (A.get(ind - 1).getItemId() != A.get(ind).getItemId()) {
intersect.add(ind); intersect.add(ind);
} }
} }
intersect.add(A.size()); intersect.add(A.size());
for(int ind = 0; ind < intersect.size() - 1; ind++) { for (int ind = 0; ind < intersect.size() - 1; ind++) {
if(intersect.get(ind + 1) > intersect.get(ind)) MapleQuicksort(intersect.get(ind), intersect.get(ind + 1) - 1, A, secondarySort); if (intersect.get(ind + 1) > intersect.get(ind)) {
MapleQuicksort(intersect.get(ind), intersect.get(ind + 1) - 1, A, secondarySort);
}
} }
} }
} }
@@ -266,7 +291,7 @@ public final class InventorySortHandler extends AbstractPacketHandler {
p.readInt(); p.readInt();
chr.getAutobanManager().setTimestamp(3, Server.getInstance().getCurrentTimestamp(), 4); chr.getAutobanManager().setTimestamp(3, Server.getInstance().getCurrentTimestamp(), 4);
if(!YamlConfig.config.server.USE_ITEM_SORT) { if (!YamlConfig.config.server.USE_ITEM_SORT) {
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
@@ -29,14 +29,13 @@ import net.packet.InPacket;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author Matze * @author Matze
*/ */
public final class ItemMoveHandler extends AbstractPacketHandler { public final class ItemMoveHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
p.skip(4); p.skip(4);
if(c.getPlayer().getAutobanManager().getLastSpam(6) + 300 > currentServerTime()) { if (c.getPlayer().getAutobanManager().getLastSpam(6) + 300 > currentServerTime()) {
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
@@ -56,7 +55,9 @@ public final class ItemMoveHandler extends AbstractPacketHandler {
InventoryManipulator.move(c, type, src, action); InventoryManipulator.move(c, type, src, action);
} }
if (c.getPlayer().getMap().getHPDec() > 0) c.getPlayer().resetHpDecreaseTask(); if (c.getPlayer().getMap().getHPDec() > 0) {
c.getPlayer().resetHpDecreaseTask();
}
c.getPlayer().getAutobanManager().spam(6); c.getPlayer().getAutobanManager().spam(6);
} }
} }
@@ -31,7 +31,6 @@ import tools.FilePrinter;
import java.awt.*; import java.awt.*;
/** /**
*
* @author Matze * @author Matze
* @author Ronan * @author Ronan
*/ */
@@ -45,7 +44,9 @@ public final class ItemPickupHandler extends AbstractPacketHandler {
int oid = p.readInt(); int oid = p.readInt();
Character chr = c.getPlayer(); Character chr = c.getPlayer();
MapObject ob = chr.getMap().getMapObject(oid); MapObject ob = chr.getMap().getMapObject(oid);
if(ob == null) return; if (ob == null) {
return;
}
Point charPos = chr.getPosition(); Point charPos = chr.getPosition();
Point obPos = ob.getPosition(); Point obPos = ob.getPosition();
@@ -48,7 +48,9 @@ public final class ItemRewardHandler extends AbstractPacketHandler {
int itemId = p.readInt(); // will load from xml I don't care. int itemId = p.readInt(); // will load from xml I don't care.
Item it = c.getPlayer().getInventory(InventoryType.USE).getItem(slot); // null check here thanks to Thora Item it = c.getPlayer().getInventory(InventoryType.USE).getItem(slot); // null check here thanks to Thora
if (it == null || it.getItemId() != itemId || c.getPlayer().getInventory(InventoryType.USE).countById(itemId) < 1) return; if (it == null || it.getItemId() != itemId || c.getPlayer().getInventory(InventoryType.USE).countById(itemId) < 1) {
return;
}
ItemInformationProvider ii = ItemInformationProvider.getInstance(); ItemInformationProvider ii = ItemInformationProvider.getInstance();
Pair<Integer, List<RewardItem>> rewards = ii.getItemReward(itemId); Pair<Integer, List<RewardItem>> rewards = ii.getItemReward(itemId);
@@ -58,10 +60,10 @@ public final class ItemRewardHandler extends AbstractPacketHandler {
break; break;
} }
if (Randomizer.nextInt(rewards.getLeft()) < reward.prob) {//Is it even possible to get an item with prob 1? if (Randomizer.nextInt(rewards.getLeft()) < reward.prob) {//Is it even possible to get an item with prob 1?
if (ItemConstants.getInventoryType(reward.itemid) == InventoryType.EQUIP) { if (ItemConstants.getInventoryType(reward.itemid) == InventoryType.EQUIP) {
final Item item = ii.getEquipById(reward.itemid); final Item item = ii.getEquipById(reward.itemid);
if (reward.period != -1) { if (reward.period != -1) {
item.setExpiration(currentServerTime() + (reward.period * 60 * 60 * 10)); item.setExpiration(currentServerTime() + (reward.period * 60 * 60 * 10));
} }
InventoryManipulator.addFromDrop(c, item, false); InventoryManipulator.addFromDrop(c, item, false);
} else { } else {
@@ -31,53 +31,53 @@ import net.AbstractPacketHandler;
import net.packet.InPacket; import net.packet.InPacket;
public final class KeymapChangeHandler extends AbstractPacketHandler { public final class KeymapChangeHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
if (p.available() >= 8) { if (p.available() >= 8) {
int mode = p.readInt(); int mode = p.readInt();
if(mode == 0) { if (mode == 0) {
int numChanges = p.readInt(); int numChanges = p.readInt();
for (int i = 0; i < numChanges; i++) { for (int i = 0; i < numChanges; i++) {
int key = p.readInt(); int key = p.readInt();
int type = p.readByte(); int type = p.readByte();
int action = p.readInt(); int action = p.readInt();
if(type == 1) { if (type == 1) {
Skill skill = SkillFactory.getSkill(action); Skill skill = SkillFactory.getSkill(action);
boolean isBanndedSkill; boolean isBanndedSkill;
if (skill != null) { if (skill != null) {
isBanndedSkill = GameConstants.bannedBindSkills(skill.getId()); isBanndedSkill = GameConstants.bannedBindSkills(skill.getId());
if (isBanndedSkill || (!c.getPlayer().isGM() && GameConstants.isGMSkills(skill.getId())) || (!GameConstants.isInJobTree(skill.getId(), c.getPlayer().getJob().getId()) && !c.getPlayer().isGM())) { //for those skills are are "technically" in the beginner tab, like bamboo rain in Dojo or skills you find in PYPQ if (isBanndedSkill || (!c.getPlayer().isGM() && GameConstants.isGMSkills(skill.getId())) || (!GameConstants.isInJobTree(skill.getId(), c.getPlayer().getJob().getId()) && !c.getPlayer().isGM())) { //for those skills are are "technically" in the beginner tab, like bamboo rain in Dojo or skills you find in PYPQ
//AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit keymapping."); //AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit keymapping.");
//FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to use skill " + skill.getId()); //FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to use skill " + skill.getId());
//c.disconnect(true, false); //c.disconnect(true, false);
//return; //return;
continue; // fk that continue; // fk that
} }
/* if (c.getPlayer().getSkillLevel(skill) < 1) { HOW WOULD A SKILL EVEN BE AVAILABLE TO KEYBINDING /* if (c.getPlayer().getSkillLevel(skill) < 1) { HOW WOULD A SKILL EVEN BE AVAILABLE TO KEYBINDING
continue; IF THERE IS NOT EVEN A SINGLE POINT USED INTO IT?? continue; IF THERE IS NOT EVEN A SINGLE POINT USED INTO IT??
} */ } */
} }
} }
c.getPlayer().changeKeybinding(key, new KeyBinding(type, action)); c.getPlayer().changeKeybinding(key, new KeyBinding(type, action));
} }
} else if(mode == 1) { // Auto HP Potion } else if (mode == 1) { // Auto HP Potion
int itemID = p.readInt(); int itemID = p.readInt();
if(itemID != 0 && c.getPlayer().getInventory(InventoryType.USE).findById(itemID) == null) { if (itemID != 0 && c.getPlayer().getInventory(InventoryType.USE).findById(itemID) == null) {
c.disconnect(false, false); // Don't let them send a packet with a use item they dont have. c.disconnect(false, false); // Don't let them send a packet with a use item they dont have.
return; return;
} }
c.getPlayer().changeKeybinding(91, new KeyBinding(7, itemID)); c.getPlayer().changeKeybinding(91, new KeyBinding(7, itemID));
} else if(mode == 2) { // Auto MP Potion } else if (mode == 2) { // Auto MP Potion
int itemID = p.readInt(); int itemID = p.readInt();
if(itemID != 0 && c.getPlayer().getInventory(InventoryType.USE).findById(itemID) == null) { if (itemID != 0 && c.getPlayer().getInventory(InventoryType.USE).findById(itemID) == null) {
c.disconnect(false, false); // Don't let them send a packet with a use item they dont have. c.disconnect(false, false); // Don't let them send a packet with a use item they dont have.
return; return;
} }
c.getPlayer().changeKeybinding(92, new KeyBinding(7, itemID)); c.getPlayer().changeKeybinding(92, new KeyBinding(7, itemID));
} }
} }
} }
} }
@@ -28,12 +28,11 @@ import net.packet.InPacket;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author kevintjuh93 * @author kevintjuh93
*/ */
public class LeftKnockbackHandler extends AbstractPacketHandler { public class LeftKnockbackHandler extends AbstractPacketHandler {
public void handlePacket(InPacket p, final Client c) { public void handlePacket(InPacket p, final Client c) {
c.sendPacket(PacketCreator.leftKnockBack()); c.sendPacket(PacketCreator.leftKnockBack());
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
} }
} }
@@ -537,7 +537,7 @@ public final class MTSHandler extends AbstractPacketHandler {
c.sendPacket(PacketCreator.MTSFailBuy()); c.sendPacket(PacketCreator.MTSFailBuy());
} }
} else { } else {
System.out.println("Unhandled OP(MTS): " + op + " Packet: " + p.toString()); System.out.println("Unhandled OP(MTS): " + op + " Packet: " + p);
} }
} else { } else {
c.sendPacket(PacketCreator.showMTSCash(c.getPlayer())); c.sendPacket(PacketCreator.showMTSCash(c.getPlayer()));
@@ -35,9 +35,9 @@ import server.StatEffect;
import tools.PacketCreator; import tools.PacketCreator;
public final class MagicDamageHandler extends AbstractDealDamageHandler { public final class MagicDamageHandler extends AbstractDealDamageHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
Character chr = c.getPlayer(); Character chr = c.getPlayer();
/*long timeElapsed = currentServerTime() - chr.getAutobanManager().getLastSpam(8); /*long timeElapsed = currentServerTime() - chr.getAutobanManager().getLastSpam(8);
if(timeElapsed < 300) { if(timeElapsed < 300) {
@@ -45,43 +45,43 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
} }
chr.getAutobanManager().spam(8);*/ chr.getAutobanManager().spam(8);*/
AttackInfo attack = parseDamage(p, chr, false, true); AttackInfo attack = parseDamage(p, chr, false, true);
if (chr.getBuffEffect(BuffStat.MORPH) != null) { if (chr.getBuffEffect(BuffStat.MORPH) != null) {
if(chr.getBuffEffect(BuffStat.MORPH).isMorphWithoutAttack()) { if (chr.getBuffEffect(BuffStat.MORPH).isMorphWithoutAttack()) {
// How are they attacking when the client won't let them? // How are they attacking when the client won't let them?
chr.getClient().disconnect(false, false); chr.getClient().disconnect(false, false);
return; return;
} }
} }
if (GameConstants.isDojo(chr.getMap().getId()) && attack.numAttacked > 0) { if (GameConstants.isDojo(chr.getMap().getId()) && attack.numAttacked > 0) {
chr.setDojoEnergy(chr.getDojoEnergy() + + YamlConfig.config.server.DOJO_ENERGY_ATK); chr.setDojoEnergy(chr.getDojoEnergy() + +YamlConfig.config.server.DOJO_ENERGY_ATK);
c.sendPacket(PacketCreator.getEnergy("energy", chr.getDojoEnergy())); c.sendPacket(PacketCreator.getEnergy("energy", chr.getDojoEnergy()));
} }
int charge = (attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG) ? attack.charge : -1; int charge = (attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG) ? attack.charge : -1;
Packet packet = PacketCreator.magicAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, charge, attack.speed, attack.direction, attack.display); Packet packet = PacketCreator.magicAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, charge, attack.speed, attack.direction, attack.display);
chr.getMap().broadcastMessage(chr, packet, false, true); chr.getMap().broadcastMessage(chr, packet, false, true);
StatEffect effect = attack.getAttackEffect(chr, null); StatEffect effect = attack.getAttackEffect(chr, null);
Skill skill = SkillFactory.getSkill(attack.skill); Skill skill = SkillFactory.getSkill(attack.skill);
StatEffect effect_ = skill.getEffect(chr.getSkillLevel(skill)); StatEffect effect_ = skill.getEffect(chr.getSkillLevel(skill));
if (effect_.getCooldown() > 0) { if (effect_.getCooldown() > 0) {
if (chr.skillIsCooling(attack.skill)) { if (chr.skillIsCooling(attack.skill)) {
return; return;
} else { } else {
c.sendPacket(PacketCreator.skillCooldown(attack.skill, effect_.getCooldown())); c.sendPacket(PacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
chr.addCooldown(attack.skill, currentServerTime(), effect_.getCooldown() * 1000); chr.addCooldown(attack.skill, currentServerTime(), effect_.getCooldown() * 1000);
} }
} }
applyAttack(attack, chr, effect.getAttackCount()); applyAttack(attack, chr, effect.getAttackCount());
Skill eaterSkill = SkillFactory.getSkill((chr.getJob().getId() - (chr.getJob().getId() % 10)) * 10000);// MP Eater, works with right job Skill eaterSkill = SkillFactory.getSkill((chr.getJob().getId() - (chr.getJob().getId() % 10)) * 10000);// MP Eater, works with right job
int eaterLevel = chr.getSkillLevel(eaterSkill); int eaterLevel = chr.getSkillLevel(eaterSkill);
if (eaterLevel > 0) { if (eaterLevel > 0) {
for (Integer singleDamage : attack.allDamage.keySet()) { for (Integer singleDamage : attack.allDamage.keySet()) {
eaterSkill.getEffect(eaterLevel).applyPassive(chr, chr.getMap().getMapObject(singleDamage), 0); eaterSkill.getEffect(eaterLevel).applyPassive(chr, chr.getMap().getMapObject(singleDamage), 0);
} }
} }
} }
} }
@@ -27,7 +27,6 @@ import net.AbstractPacketHandler;
import net.packet.InPacket; import net.packet.InPacket;
/** /**
*
* @author Jay Estrella, Ronan * @author Jay Estrella, Ronan
*/ */
public final class MakerSkillHandler extends AbstractPacketHandler { public final class MakerSkillHandler extends AbstractPacketHandler {
@@ -28,41 +28,40 @@ import net.packet.InPacket;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author Matze * @author Matze
* @author Ronan - concurrency protection * @author Ronan - concurrency protection
*/ */
public final class MesoDropHandler extends AbstractPacketHandler { public final class MesoDropHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
Character player = c.getPlayer(); Character player = c.getPlayer();
if (!player.isAlive()) { if (!player.isAlive()) {
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
}
p.skip(4);
int meso = p.readInt();
if (c.tryacquireClient()) { // thanks imbee for noticing players not being able to throw mesos too fast
try {
if (meso <= player.getMeso() && meso > 9 && meso < 50001) {
player.gainMeso(-meso, false, true, false);
} else {
c.sendPacket(PacketCreator.enableActions());
return;
}
} finally {
c.releaseClient();
}
} else {
c.sendPacket(PacketCreator.enableActions());
return;
}
if (player.attemptCatchFish(meso)) {
player.getMap().disappearingMesoDrop(meso, player, player, player.getPosition());
} else {
player.getMap().spawnMesoDrop(meso, player.getPosition(), player, player, true, (byte) 2);
}
} }
p.skip(4);
int meso = p.readInt();
if (c.tryacquireClient()) { // thanks imbee for noticing players not being able to throw mesos too fast
try {
if (meso <= player.getMeso() && meso > 9 && meso < 50001) {
player.gainMeso(-meso, false, true, false);
} else {
c.sendPacket(PacketCreator.enableActions());
return;
}
} finally {
c.releaseClient();
}
} else {
c.sendPacket(PacketCreator.enableActions());
return;
}
if (player.attemptCatchFish(meso)) {
player.getMap().disappearingMesoDrop(meso, player, player, player.getPosition());
} else {
player.getMap().spawnMesoDrop(meso, player.getPosition(), player, player, true, (byte) 2);
}
}
} }
@@ -31,59 +31,58 @@ import tools.PacketCreator;
import tools.Randomizer; import tools.Randomizer;
/** /**
*
* @author Xotic (XoticStory) & BubblesDev * @author Xotic (XoticStory) & BubblesDev
*/ */
public final class MobDamageMobFriendlyHandler extends AbstractPacketHandler { public final class MobDamageMobFriendlyHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
int attacker = p.readInt(); int attacker = p.readInt();
p.readInt(); p.readInt();
int damaged = p.readInt(); int damaged = p.readInt();
MapleMap map = c.getPlayer().getMap(); MapleMap map = c.getPlayer().getMap();
Monster monster = map.getMonsterByOid(damaged); Monster monster = map.getMonsterByOid(damaged);
if (monster == null || map.getMonsterByOid(attacker) == null) { if (monster == null || map.getMonsterByOid(attacker) == null) {
return; return;
} }
int damage = Randomizer.nextInt(((monster.getMaxHp() / 13 + monster.getPADamage() * 10)) * 2 + 500) / 10; // Formula planned by Beng. int damage = Randomizer.nextInt(((monster.getMaxHp() / 13 + monster.getPADamage() * 10)) * 2 + 500) / 10; // Formula planned by Beng.
if (monster.getHp() - damage < 1) { // friendly dies if (monster.getHp() - damage < 1) { // friendly dies
if(monster.getId() == 9300102) { if (monster.getId() == 9300102) {
map.broadcastMessage(PacketCreator.serverNotice(6, "The Watch Hog has been injured by the aliens. Better luck next time...")); map.broadcastMessage(PacketCreator.serverNotice(6, "The Watch Hog has been injured by the aliens. Better luck next time..."));
} else if (monster.getId() == 9300061) { //moon bunny } else if (monster.getId() == 9300061) { //moon bunny
map.broadcastMessage(PacketCreator.serverNotice(6, "The Moon Bunny went home because he was sick.")); map.broadcastMessage(PacketCreator.serverNotice(6, "The Moon Bunny went home because he was sick."));
} else if(monster.getId() == 9300093) { //tylus } else if (monster.getId() == 9300093) { //tylus
map.broadcastMessage(PacketCreator.serverNotice(6, "Tylus has fallen by the overwhelming forces of the ambush.")); map.broadcastMessage(PacketCreator.serverNotice(6, "Tylus has fallen by the overwhelming forces of the ambush."));
} else if(monster.getId() == 9300137) { //juliet } else if (monster.getId() == 9300137) { //juliet
map.broadcastMessage(PacketCreator.serverNotice(6, "Juliet has fainted in the middle of the combat.")); map.broadcastMessage(PacketCreator.serverNotice(6, "Juliet has fainted in the middle of the combat."));
} else if(monster.getId() == 9300138) { //romeo } else if (monster.getId() == 9300138) { //romeo
map.broadcastMessage(PacketCreator.serverNotice(6, "Romeo has fainted in the middle of the combat.")); map.broadcastMessage(PacketCreator.serverNotice(6, "Romeo has fainted in the middle of the combat."));
} else if(monster.getId() == 9400322 || monster.getId() == 9400327 || monster.getId() == 9400332) { //snowman } else if (monster.getId() == 9400322 || monster.getId() == 9400327 || monster.getId() == 9400332) { //snowman
map.broadcastMessage(PacketCreator.serverNotice(6, "The Snowman has melted on the heat of the battle.")); map.broadcastMessage(PacketCreator.serverNotice(6, "The Snowman has melted on the heat of the battle."));
} else if(monster.getId() == 9300162) { //delli } else if (monster.getId() == 9300162) { //delli
map.broadcastMessage(PacketCreator.serverNotice(6, "Delli vanished after the ambush, sheets still laying on the ground...")); map.broadcastMessage(PacketCreator.serverNotice(6, "Delli vanished after the ambush, sheets still laying on the ground..."));
} }
map.killFriendlies(monster); map.killFriendlies(monster);
} else { } else {
EventInstanceManager eim = map.getEventInstance(); EventInstanceManager eim = map.getEventInstance();
if (eim != null) { if (eim != null) {
eim.friendlyDamaged(monster); eim.friendlyDamaged(monster);
} }
} }
monster.applyAndGetHpDamage(damage, false); monster.applyAndGetHpDamage(damage, false);
int remainingHp = monster.getHp(); int remainingHp = monster.getHp();
if(remainingHp <= 0) { if (remainingHp <= 0) {
remainingHp = 0; remainingHp = 0;
map.removeMapObject(monster); map.removeMapObject(monster);
} }
map.broadcastMessage(PacketCreator.MobDamageMobFriendly(monster, damage, remainingHp), monster.getPosition()); map.broadcastMessage(PacketCreator.MobDamageMobFriendly(monster, damage, remainingHp), monster.getPosition());
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
} }
} }
@@ -37,7 +37,6 @@ import tools.PacketCreator;
import java.util.Map; import java.util.Map;
/** /**
*
* @author Jay Estrella * @author Jay Estrella
* @author Ronan * @author Ronan
*/ */
@@ -41,8 +41,8 @@ import java.util.List;
/** /**
*@author Drago (Dragohe4rt) * @author Drago (Dragohe4rt)
*/ */
public final class MonsterCarnivalHandler extends AbstractPacketHandler { public final class MonsterCarnivalHandler extends AbstractPacketHandler {
@@ -171,7 +171,7 @@ public final class MonsterCarnivalHandler extends AbstractPacketHandler {
} }
c.getPlayer().gainCP(-neededCP); c.getPlayer().gainCP(-neededCP);
c.getPlayer().getMap().broadcastMessage(PacketCreator.playerSummoned(c.getPlayer().getName(), tab, num)); c.getPlayer().getMap().broadcastMessage(PacketCreator.playerSummoned(c.getPlayer().getName(), tab, num));
}catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} finally { } finally {
@@ -49,7 +49,8 @@ public class MoveDragonHandler extends AbstractMovementPacketHandler {
} else { } else {
chr.getMap().broadcastMessage(chr, PacketCreator.moveDragon(dragon, startPos, p, movementDataLength), dragon.getPosition()); chr.getMap().broadcastMessage(chr, PacketCreator.moveDragon(dragon, startPos, p, movementDataLength), dragon.getPosition());
} }
} catch (EmptyMovementException e) {} } catch (EmptyMovementException e) {
}
} }
} }
} }
@@ -48,137 +48,140 @@ import java.util.List;
*/ */
public final class MoveLifeHandler extends AbstractMovementPacketHandler { public final class MoveLifeHandler extends AbstractMovementPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
Character player = c.getPlayer(); Character player = c.getPlayer();
MapleMap map = player.getMap(); MapleMap map = player.getMap();
if (player.isChangingMaps()) { // thanks Lame for noticing mob movement shuffle (mob OID on different maps) happening on map transitions if (player.isChangingMaps()) { // thanks Lame for noticing mob movement shuffle (mob OID on different maps) happening on map transitions
return; return;
}
int objectid = p.readInt();
short moveid = p.readShort();
MapObject mmo = map.getMapObject(objectid);
if (mmo == null || mmo.getType() != MapObjectType.MONSTER) {
return;
}
Monster monster = (Monster) mmo;
List<Character> banishPlayers = null;
byte pNibbles = p.readByte();
byte rawActivity = p.readByte();
int skillId = p.readByte() & 0xff;
int skillLv = p.readByte() & 0xff;
short pOption = p.readShort();
p.skip(8);
if (rawActivity >= 0) {
rawActivity = (byte) (rawActivity & 0xFF >> 1);
}
boolean isAttack = inRangeInclusive(rawActivity, 24, 41);
boolean isSkill = inRangeInclusive(rawActivity, 42, 59);
MobSkill toUse = null;
int useSkillId = 0, useSkillLevel = 0;
MobSkill nextUse = null;
int nextSkillId = 0, nextSkillLevel = 0;
boolean nextMovementCouldBeSkill = !(isSkill || (pNibbles != 0));
int castPos;
if (isSkill) {
useSkillId = skillId;
useSkillLevel = skillLv;
castPos = monster.getSkillPos(useSkillId, useSkillLevel);
if (castPos != -1) {
toUse = MobSkillFactory.getMobSkill(useSkillId, useSkillLevel);
if (monster.canUseSkill(toUse, true)) {
int animationTime = MonsterInformationProvider.getInstance().getMobSkillAnimationTime(toUse);
if (animationTime > 0 && toUse.getSkillId() != 129) {
toUse.applyDelayedEffect(player, monster, true, animationTime);
} else {
banishPlayers = new LinkedList<>();
toUse.applyEffect(player, monster, true, banishPlayers);
}
} }
}
} else {
castPos = (rawActivity - 24) / 2;
int objectid = p.readInt(); int atkStatus = monster.canUseAttack(castPos, isSkill);
short moveid = p.readShort(); if (atkStatus < 1) {
MapObject mmo = map.getMapObject(objectid); rawActivity = -1;
if (mmo == null || mmo.getType() != MapObjectType.MONSTER) { pOption = 0;
return; }
} }
Monster monster = (Monster) mmo; int mobMp = monster.getMp();
List<Character> banishPlayers = null; if (nextMovementCouldBeSkill) {
int noSkills = monster.getNoSkills();
if (noSkills > 0) {
int rndSkill = Randomizer.nextInt(noSkills);
byte pNibbles = p.readByte(); Pair<Integer, Integer> skillToUse = monster.getSkills().get(rndSkill);
byte rawActivity = p.readByte(); nextSkillId = skillToUse.getLeft();
int skillId = p.readByte() & 0xff; nextSkillLevel = skillToUse.getRight();
int skillLv = p.readByte() & 0xff; nextUse = MobSkillFactory.getMobSkill(nextSkillId, nextSkillLevel);
short pOption = p.readShort();
p.skip(8);
if (rawActivity >= 0) { if (!(nextUse != null && monster.canUseSkill(nextUse, false) && nextUse.getHP() >= (int) (((float) monster.getHp() / monster.getMaxHp()) * 100) && mobMp >= nextUse.getMpCon())) {
rawActivity = (byte) (rawActivity & 0xFF >> 1); // thanks OishiiKawaiiDesu for noticing mobs trying to cast skills they are not supposed to be able
}
boolean isAttack = inRangeInclusive(rawActivity, 24, 41); nextSkillId = 0;
boolean isSkill = inRangeInclusive(rawActivity, 42, 59); nextSkillLevel = 0;
nextUse = null;
MobSkill toUse = null;
int useSkillId = 0, useSkillLevel = 0;
MobSkill nextUse = null;
int nextSkillId = 0, nextSkillLevel = 0;
boolean nextMovementCouldBeSkill = !(isSkill || (pNibbles != 0));
int castPos;
if (isSkill) {
useSkillId = skillId;
useSkillLevel = skillLv;
castPos = monster.getSkillPos(useSkillId, useSkillLevel);
if (castPos != -1) {
toUse = MobSkillFactory.getMobSkill(useSkillId, useSkillLevel);
if (monster.canUseSkill(toUse, true)) {
int animationTime = MonsterInformationProvider.getInstance().getMobSkillAnimationTime(toUse);
if(animationTime > 0 && toUse.getSkillId() != 129) {
toUse.applyDelayedEffect(player, monster, true, animationTime);
} else {
banishPlayers = new LinkedList<>();
toUse.applyEffect(player, monster, true, banishPlayers);
}
}
}
} else {
castPos = (rawActivity - 24) / 2;
int atkStatus = monster.canUseAttack(castPos, isSkill);
if (atkStatus < 1) {
rawActivity = -1;
pOption = 0;
}
} }
}
}
int mobMp = monster.getMp(); p.readByte();
if (nextMovementCouldBeSkill) { p.readInt(); // whatever
int noSkills = monster.getNoSkills(); short start_x = p.readShort(); // hmm.. startpos?
if (noSkills > 0) { short start_y = p.readShort(); // hmm...
int rndSkill = Randomizer.nextInt(noSkills); Point startPos = new Point(start_x, start_y - 2);
Point serverStartPos = new Point(monster.getPosition());
Pair<Integer, Integer> skillToUse = monster.getSkills().get(rndSkill); Boolean aggro = monster.aggroMoveLifeUpdate(player);
nextSkillId = skillToUse.getLeft(); if (aggro == null) {
nextSkillLevel = skillToUse.getRight(); return;
nextUse = MobSkillFactory.getMobSkill(nextSkillId, nextSkillLevel); }
if (!(nextUse != null && monster.canUseSkill(nextUse, false) && nextUse.getHP() >= (int) (((float) monster.getHp() / monster.getMaxHp()) * 100) && mobMp >= nextUse.getMpCon())) { if (nextUse != null) {
// thanks OishiiKawaiiDesu for noticing mobs trying to cast skills they are not supposed to be able c.sendPacket(PacketCreator.moveMonsterResponse(objectid, moveid, mobMp, aggro, nextSkillId, nextSkillLevel));
} else {
nextSkillId = 0; c.sendPacket(PacketCreator.moveMonsterResponse(objectid, moveid, mobMp, aggro));
nextSkillLevel = 0; }
nextUse = null;
}
}
}
p.readByte();
p.readInt(); // whatever
short start_x = p.readShort(); // hmm.. startpos?
short start_y = p.readShort(); // hmm...
Point startPos = new Point(start_x, start_y - 2);
Point serverStartPos = new Point(monster.getPosition());
Boolean aggro = monster.aggroMoveLifeUpdate(player);
if (aggro == null) return;
if (nextUse != null) {
c.sendPacket(PacketCreator.moveMonsterResponse(objectid, moveid, mobMp, aggro, nextSkillId, nextSkillLevel));
} else {
c.sendPacket(PacketCreator.moveMonsterResponse(objectid, moveid, mobMp, aggro));
}
try { try {
int movementDataStart = p.getPosition(); int movementDataStart = p.getPosition();
updatePosition(p, monster, -2); // Thanks Doodle & ZERO傑洛 for noticing sponge-based bosses moving out of stage in case of no-offset applied updatePosition(p, monster, -2); // Thanks Doodle & ZERO傑洛 for noticing sponge-based bosses moving out of stage in case of no-offset applied
long movementDataLength = p.getPosition() - movementDataStart; //how many bytes were read by updatePosition long movementDataLength = p.getPosition() - movementDataStart; //how many bytes were read by updatePosition
p.seek(movementDataStart); p.seek(movementDataStart);
if (YamlConfig.config.server.USE_DEBUG_SHOW_RCVD_MVLIFE) { if (YamlConfig.config.server.USE_DEBUG_SHOW_RCVD_MVLIFE) {
System.out.println((isSkill ? "SKILL " : (isAttack ? "ATTCK " : " ")) + "castPos: " + castPos + " rawAct: " + rawActivity + " opt: " + pOption + " skillID: " + useSkillId + " skillLV: " + useSkillLevel + " " + "allowSkill: " + nextMovementCouldBeSkill + " mobMp: " + mobMp); System.out.println((isSkill ? "SKILL " : (isAttack ? "ATTCK " : " ")) + "castPos: " + castPos + " rawAct: " + rawActivity + " opt: " + pOption + " skillID: " + useSkillId + " skillLV: " + useSkillLevel + " " + "allowSkill: " + nextMovementCouldBeSkill + " mobMp: " + mobMp);
} }
map.broadcastMessage(player, PacketCreator.moveMonster(objectid, nextMovementCouldBeSkill, rawActivity, useSkillId, useSkillLevel, pOption, startPos, p, movementDataLength), serverStartPos); map.broadcastMessage(player, PacketCreator.moveMonster(objectid, nextMovementCouldBeSkill, rawActivity, useSkillId, useSkillLevel, pOption, startPos, p, movementDataLength), serverStartPos);
//updatePosition(res, monster, -2); //does this need to be done after the packet is broadcast? //updatePosition(res, monster, -2); //does this need to be done after the packet is broadcast?
map.moveMonster(monster, monster.getPosition()); map.moveMonster(monster, monster.getPosition());
} catch (EmptyMovementException e) {} } catch (EmptyMovementException e) {
}
if (banishPlayers != null) { if (banishPlayers != null) {
for (Character chr : banishPlayers) { for (Character chr : banishPlayers) {
chr.changeMapBanish(monster.getBanish().getMap(), monster.getBanish().getPortal(), monster.getBanish().getMsg()); chr.changeMapBanish(monster.getBanish().getMap(), monster.getBanish().getPortal(), monster.getBanish().getMsg());
} }
} }
} }
private static boolean inRangeInclusive(Byte pVal, Integer pMin, Integer pMax) { private static boolean inRangeInclusive(Byte pVal, Integer pMin, Integer pMax) {
return !(pVal < pMin) || (pVal > pMax); return !(pVal < pMin) || (pVal > pMax);
} }
} }
@@ -42,6 +42,7 @@ public final class MovePlayerHandler extends AbstractMovementPacketHandler {
} else { } else {
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), PacketCreator.movePlayer(c.getPlayer().getId(), p, movementDataLength), false); c.getPlayer().getMap().broadcastMessage(c.getPlayer(), PacketCreator.movePlayer(c.getPlayer().getId(), p, movementDataLength), false);
} }
} catch (EmptyMovementException e) {} } catch (EmptyMovementException e) {
}
} }
} }
@@ -53,7 +53,8 @@ public final class MoveSummonHandler extends AbstractMovementPacketHandler {
p.seek(movementDataStart); p.seek(movementDataStart);
player.getMap().broadcastMessage(player, PacketCreator.moveSummon(player.getId(), oid, startPos, p, movementDataLength), summon.getPosition()); player.getMap().broadcastMessage(player, PacketCreator.moveSummon(player.getId(), oid, startPos, p, movementDataLength), summon.getPosition());
} catch (EmptyMovementException e) {} } catch (EmptyMovementException e) {
}
} }
} }
} }
@@ -37,8 +37,8 @@ public final class MultiChatHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
Character player = c.getPlayer(); Character player = c.getPlayer();
if(player.getAutobanManager().getLastSpam(7) + 200 > currentServerTime()) { if (player.getAutobanManager().getLastSpam(7) + 200 > currentServerTime()) {
return; return;
} }
int type = p.readByte(); // 0 for buddys, 1 for partys int type = p.readByte(); // 0 for buddys, 1 for partys
@@ -49,10 +49,10 @@ public final class MultiChatHandler extends AbstractPacketHandler {
} }
String chattext = p.readString(); String chattext = p.readString();
if (chattext.length() > Byte.MAX_VALUE && !player.isGM()) { if (chattext.length() > Byte.MAX_VALUE && !player.isGM()) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit chats."); AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit chats.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to send text with length of " + chattext.length()); FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to send text with length of " + chattext.length());
c.disconnect(true, false); c.disconnect(true, false);
return; return;
} }
World world = c.getWorldServer(); World world = c.getWorldServer();
if (type == 0) { if (type == 0) {
@@ -28,7 +28,6 @@ import scripting.npc.NPCScriptManager;
import scripting.quest.QuestScriptManager; import scripting.quest.QuestScriptManager;
/** /**
*
* @author Matze * @author Matze
*/ */
public final class NPCMoreTalkHandler extends AbstractPacketHandler { public final class NPCMoreTalkHandler extends AbstractPacketHandler {
@@ -29,7 +29,6 @@ import net.packet.InPacket;
import tools.FilePrinter; import tools.FilePrinter;
/** /**
*
* @author Matze * @author Matze
*/ */
public final class NPCShopHandler extends AbstractPacketHandler { public final class NPCShopHandler extends AbstractPacketHandler {
@@ -40,10 +39,10 @@ public final class NPCShopHandler extends AbstractPacketHandler {
int itemId = p.readInt(); int itemId = p.readInt();
short quantity = p.readShort(); short quantity = p.readShort();
if (quantity < 1) { if (quantity < 1) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit a npc shop."); AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit a npc shop.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to buy quantity " + quantity + " of item id " + itemId); FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to buy quantity " + quantity + " of item id " + itemId);
c.disconnect(true, false); c.disconnect(true, false);
return; return;
} }
c.getPlayer().getShop().buy(c, slot, itemId, quantity); c.getPlayer().getShop().buy(c, slot, itemId, quantity);
} else if (bmode == 1) { // sell ;) } else if (bmode == 1) { // sell ;)
@@ -41,7 +41,7 @@ public final class NPCTalkHandler extends AbstractPacketHandler {
return; return;
} }
if(currentServerTime() - c.getPlayer().getNpcCooldown() < YamlConfig.config.server.BLOCK_NPC_RACE_CONDT) { if (currentServerTime() - c.getPlayer().getNpcCooldown() < YamlConfig.config.server.BLOCK_NPC_RACE_CONDT) {
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
@@ -50,7 +50,9 @@ public final class NPCTalkHandler extends AbstractPacketHandler {
MapObject obj = c.getPlayer().getMap().getMapObject(oid); MapObject obj = c.getPlayer().getMap().getMapObject(oid);
if (obj instanceof NPC) { if (obj instanceof NPC) {
NPC npc = (NPC) obj; NPC npc = (NPC) obj;
if(YamlConfig.config.server.USE_DEBUG == true) c.getPlayer().dropMessage(5, "Talking to NPC " + npc.getId()); if (YamlConfig.config.server.USE_DEBUG == true) {
c.getPlayer().dropMessage(5, "Talking to NPC " + npc.getId());
}
if (npc.getId() == 9010009) { //is duey if (npc.getId() == 9010009) { //is duey
DueyProcessor.dueySendTalk(c, false); DueyProcessor.dueySendTalk(c, false);
@@ -36,9 +36,8 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
/** /**
*
* @author Ronan * @author Ronan
* * <p>
* Header layout thanks to Eric * Header layout thanks to Eric
*/ */
public final class NewYearCardHandler extends AbstractPacketHandler { public final class NewYearCardHandler extends AbstractPacketHandler {
@@ -48,26 +47,26 @@ public final class NewYearCardHandler extends AbstractPacketHandler {
final Character player = c.getPlayer(); final Character player = c.getPlayer();
byte reqMode = p.readByte(); //[00] -> NewYearReq (0 = Send) byte reqMode = p.readByte(); //[00] -> NewYearReq (0 = Send)
if(reqMode == 0) { // card has been sent if (reqMode == 0) { // card has been sent
if(player.haveItem(2160101)) { // new year's card if (player.haveItem(2160101)) { // new year's card
short slot = p.readShort(); //[00 2C] -> nPOS (Item Slot Pos) short slot = p.readShort(); //[00 2C] -> nPOS (Item Slot Pos)
int itemid = p.readInt(); //[00 20 F5 E5] -> nItemID (item id) int itemid = p.readInt(); //[00 20 F5 E5] -> nItemID (item id)
int status = getValidNewYearCardStatus(itemid, player, slot); int status = getValidNewYearCardStatus(itemid, player, slot);
if(status == 0) { if (status == 0) {
if(player.canHold(4300000, 1)) { if (player.canHold(4300000, 1)) {
String receiver = p.readString(); //[04 00 54 65 73 74] -> sReceiverName (person to send to) String receiver = p.readString(); //[04 00 54 65 73 74] -> sReceiverName (person to send to)
int receiverid = getReceiverId(receiver, c.getWorld()); int receiverid = getReceiverId(receiver, c.getWorld());
if(receiverid != -1) { if (receiverid != -1) {
if(receiverid != c.getPlayer().getId()) { if (receiverid != c.getPlayer().getId()) {
String message = p.readString(); //[06 00 4C 65 74 74 65 72] -> sContent (message) String message = p.readString(); //[06 00 4C 65 74 74 65 72] -> sContent (message)
NewYearCardRecord newyear = new NewYearCardRecord(player.getId(), player.getName(), receiverid, receiver, message); NewYearCardRecord newyear = new NewYearCardRecord(player.getId(), player.getName(), receiverid, receiver, message);
NewYearCardRecord.saveNewYearCard(newyear); NewYearCardRecord.saveNewYearCard(newyear);
player.addNewYearRecord(newyear); player.addNewYearRecord(newyear);
player.getAbstractPlayerInteraction().gainItem(2160101, (short)-1); player.getAbstractPlayerInteraction().gainItem(2160101, (short) -1);
player.getAbstractPlayerInteraction().gainItem(4300000, (short) 1); player.getAbstractPlayerInteraction().gainItem(4300000, (short) 1);
Server.getInstance().setNewYearCard(newyear); Server.getInstance().setNewYearCard(newyear);
@@ -93,14 +92,16 @@ public final class NewYearCardHandler extends AbstractPacketHandler {
NewYearCardRecord newyear = NewYearCardRecord.loadNewYearCard(cardid); NewYearCardRecord newyear = NewYearCardRecord.loadNewYearCard(cardid);
if(newyear != null && newyear.getReceiverId() == player.getId() && !newyear.isReceiverCardReceived()) { if (newyear != null && newyear.getReceiverId() == player.getId() && !newyear.isReceiverCardReceived()) {
if(!newyear.isSenderCardDiscarded()) { if (!newyear.isSenderCardDiscarded()) {
if(player.canHold(4301000, 1)) { if (player.canHold(4301000, 1)) {
newyear.stopNewYearCardTask(); newyear.stopNewYearCardTask();
NewYearCardRecord.updateNewYearCard(newyear); NewYearCardRecord.updateNewYearCard(newyear);
player.getAbstractPlayerInteraction().gainItem(4301000, (short)1); player.getAbstractPlayerInteraction().gainItem(4301000, (short) 1);
if(!newyear.getMessage().isEmpty()) player.dropMessage(6, "[New Year] " + newyear.getSenderName() + ": " + newyear.getMessage()); if (!newyear.getMessage().isEmpty()) {
player.dropMessage(6, "[New Year] " + newyear.getSenderName() + ": " + newyear.getMessage());
}
player.addNewYearRecord(newyear); player.addNewYearRecord(newyear);
player.sendPacket(PacketCreator.onNewYearCardRes(player, newyear, 6, 0)); // successfully rcvd player.sendPacket(PacketCreator.onNewYearCardRes(player, newyear, 6, 0)); // successfully rcvd
@@ -108,7 +109,7 @@ public final class NewYearCardHandler extends AbstractPacketHandler {
player.getMap().broadcastMessage(PacketCreator.onNewYearCardRes(player, newyear, 0xD, 0)); player.getMap().broadcastMessage(PacketCreator.onNewYearCardRes(player, newyear, 0xD, 0));
Character sender = c.getWorldServer().getPlayerStorage().getCharacterById(newyear.getSenderId()); Character sender = c.getWorldServer().getPlayerStorage().getCharacterById(newyear.getSenderId());
if(sender != null && sender.isLoggedinWorld()) { if (sender != null && sender.isLoggedinWorld()) {
sender.getMap().broadcastMessage(PacketCreator.onNewYearCardRes(sender, newyear, 0xD, 0)); sender.getMap().broadcastMessage(PacketCreator.onNewYearCardRes(sender, newyear, 0xD, 0));
sender.dropMessage(6, "[New Year] Your addressee successfully received the New Year card."); sender.dropMessage(6, "[New Year] Your addressee successfully received the New Year card.");
} }
@@ -119,7 +120,7 @@ public final class NewYearCardHandler extends AbstractPacketHandler {
player.dropMessage(6, "[New Year] The sender of the New Year card already dropped it. Nothing to receive."); player.dropMessage(6, "[New Year] The sender of the New Year card already dropped it. Nothing to receive.");
} }
} else { } else {
if(newyear == null) { if (newyear == null) {
player.dropMessage(6, "[New Year] The sender of the New Year card already dropped it. Nothing to receive."); player.dropMessage(6, "[New Year] The sender of the New Year card already dropped it. Nothing to receive.");
} }
} }
@@ -132,13 +133,13 @@ public final class NewYearCardHandler extends AbstractPacketHandler {
ps.setString(1, receiver); ps.setString(1, receiver);
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) { if (rs.next()) {
if(rs.getInt("world") == world) { if (rs.getInt("world") == world) {
return rs.getInt("id"); return rs.getInt("id");
} }
} }
} }
} }
} catch(SQLException sqle) { } catch (SQLException sqle) {
sqle.printStackTrace(); sqle.printStackTrace();
} }
@@ -146,7 +147,9 @@ public final class NewYearCardHandler extends AbstractPacketHandler {
} }
private static int getValidNewYearCardStatus(int itemid, Character player, short slot) { private static int getValidNewYearCardStatus(int itemid, Character player, short slot) {
if(!ItemConstants.isNewYearCardUse(itemid)) return 0x14; if (!ItemConstants.isNewYearCardUse(itemid)) {
return 0x14;
}
Item it = player.getInventory(ItemConstants.getInventoryType(itemid)).getItem(slot); Item it = player.getInventory(ItemConstants.getInventoryType(itemid)).getItem(slot);
return (it != null && it.getItemId() == itemid) ? 0 : 0x12; return (it != null && it.getItemId() == itemid) ? 0 : 0x12;
@@ -27,13 +27,14 @@ import net.packet.InPacket;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author Ubaware * @author Ubaware
*/ */
public final class OpenFamilyHandler extends AbstractPacketHandler { public final class OpenFamilyHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
if(!YamlConfig.config.server.USE_FAMILY_SYSTEM) return; if (!YamlConfig.config.server.USE_FAMILY_SYSTEM) {
return;
}
Character chr = c.getPlayer(); Character chr = c.getPlayer();
c.sendPacket(PacketCreator.getFamilyInfo(chr.getFamilyEntry())); c.sendPacket(PacketCreator.getFamilyInfo(chr.getFamilyEntry()));
} }
@@ -27,15 +27,16 @@ import net.packet.InPacket;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author Ubaware * @author Ubaware
*/ */
public final class OpenFamilyPedigreeHandler extends AbstractPacketHandler { public final class OpenFamilyPedigreeHandler extends AbstractPacketHandler {
@Override @Override
public final void handlePacket(InPacket p, Client c) { public final void handlePacket(InPacket p, Client c) {
if(!YamlConfig.config.server.USE_FAMILY_SYSTEM) return; if (!YamlConfig.config.server.USE_FAMILY_SYSTEM) {
return;
}
Character target = c.getChannelServer().getPlayerStorage().getCharacterByName(p.readString()); Character target = c.getChannelServer().getPlayerStorage().getCharacterByName(p.readString());
if(target != null && target.getFamily() != null) { if (target != null && target.getFamily() != null) {
c.sendPacket(PacketCreator.showPedigree(target.getFamilyEntry())); c.sendPacket(PacketCreator.showPedigree(target.getFamilyEntry()));
} }
} }
@@ -37,30 +37,36 @@ public final class OwlWarpHandler extends AbstractPacketHandler {
int ownerid = p.readInt(); int ownerid = p.readInt();
int mapid = p.readInt(); int mapid = p.readInt();
if(ownerid == c.getPlayer().getId()) { if (ownerid == c.getPlayer().getId()) {
c.sendPacket(PacketCreator.serverNotice(1, "You cannot visit your own shop.")); c.sendPacket(PacketCreator.serverNotice(1, "You cannot visit your own shop."));
return; return;
} }
HiredMerchant hm = c.getWorldServer().getHiredMerchant(ownerid); // if both hired merchant and player shop is on the same map HiredMerchant hm = c.getWorldServer().getHiredMerchant(ownerid); // if both hired merchant and player shop is on the same map
PlayerShop ps; PlayerShop ps;
if(hm == null || hm.getMapId() != mapid || !hm.hasItem(c.getPlayer().getOwlSearch())) { if (hm == null || hm.getMapId() != mapid || !hm.hasItem(c.getPlayer().getOwlSearch())) {
ps = c.getWorldServer().getPlayerShop(ownerid); ps = c.getWorldServer().getPlayerShop(ownerid);
if(ps == null || ps.getMapId() != mapid || !ps.hasItem(c.getPlayer().getOwlSearch())) { if (ps == null || ps.getMapId() != mapid || !ps.hasItem(c.getPlayer().getOwlSearch())) {
if(hm == null && ps == null) c.sendPacket(PacketCreator.getOwlMessage(1)); if (hm == null && ps == null) {
else c.sendPacket(PacketCreator.getOwlMessage(3)); c.sendPacket(PacketCreator.getOwlMessage(1));
} else {
c.sendPacket(PacketCreator.getOwlMessage(3));
}
return; return;
} }
if(ps.isOpen()) { if (ps.isOpen()) {
if(GameConstants.isFreeMarketRoom(mapid)) { if (GameConstants.isFreeMarketRoom(mapid)) {
if(ps.getChannel() == c.getChannel()) { if (ps.getChannel() == c.getChannel()) {
c.getPlayer().changeMap(mapid); c.getPlayer().changeMap(mapid);
if(ps.isOpen()) { //change map has a delay, must double check if (ps.isOpen()) { //change map has a delay, must double check
if(!ps.visitShop(c.getPlayer())) { if (!ps.visitShop(c.getPlayer())) {
if(!ps.isBanned(c.getPlayer().getName())) c.sendPacket(PacketCreator.getOwlMessage(2)); if (!ps.isBanned(c.getPlayer().getName())) {
else c.sendPacket(PacketCreator.getOwlMessage(17)); c.sendPacket(PacketCreator.getOwlMessage(2));
} else {
c.sendPacket(PacketCreator.getOwlMessage(17));
}
} }
} else { } else {
//c.sendPacket(PacketCreator.serverNotice(1, "That merchant has either been closed or is under maintenance.")); //c.sendPacket(PacketCreator.serverNotice(1, "That merchant has either been closed or is under maintenance."));
@@ -77,13 +83,13 @@ public final class OwlWarpHandler extends AbstractPacketHandler {
c.sendPacket(PacketCreator.getOwlMessage(18)); c.sendPacket(PacketCreator.getOwlMessage(18));
} }
} else { } else {
if(hm.isOpen()) { if (hm.isOpen()) {
if(GameConstants.isFreeMarketRoom(mapid)) { if (GameConstants.isFreeMarketRoom(mapid)) {
if(hm.getChannel() == c.getChannel()) { if (hm.getChannel() == c.getChannel()) {
c.getPlayer().changeMap(mapid); c.getPlayer().changeMap(mapid);
if(hm.isOpen()) { //change map has a delay, must double check if (hm.isOpen()) { //change map has a delay, must double check
if(hm.addVisitor(c.getPlayer())) { if (hm.addVisitor(c.getPlayer())) {
c.sendPacket(PacketCreator.getHiredMerchant(c.getPlayer(), hm, false)); c.sendPacket(PacketCreator.getHiredMerchant(c.getPlayer(), hm, false));
c.getPlayer().setHiredMerchant(hm); c.getPlayer().setHiredMerchant(hm);
} else { } else {
@@ -48,7 +48,7 @@ public final class PartyOperationHandler extends AbstractPacketHandler {
Party party = player.getParty(); Party party = player.getParty();
switch (operation) { switch (operation) {
case 1: { // create case 1: { // create
Party.createParty(player, false); Party.createParty(player, false);
break; break;
} }
case 2: { // leave/disband case 2: { // leave/disband
@@ -77,11 +77,11 @@ public final class PartyOperationHandler extends AbstractPacketHandler {
String name = p.readString(); String name = p.readString();
Character invited = world.getPlayerStorage().getCharacterByName(name); Character invited = world.getPlayerStorage().getCharacterByName(name);
if (invited != null) { if (invited != null) {
if(invited.getLevel() < 10 && (!YamlConfig.config.server.USE_PARTY_FOR_STARTERS || player.getLevel() >= 10)) { //min requirement is level 10 if (invited.getLevel() < 10 && (!YamlConfig.config.server.USE_PARTY_FOR_STARTERS || player.getLevel() >= 10)) { //min requirement is level 10
c.sendPacket(PacketCreator.serverNotice(5, "The player you have invited does not meet the requirements.")); c.sendPacket(PacketCreator.serverNotice(5, "The player you have invited does not meet the requirements."));
return; return;
} }
if(YamlConfig.config.server.USE_PARTY_FOR_STARTERS && invited.getLevel() >= 10 && player.getLevel() < 10) { //trying to invite high level if (YamlConfig.config.server.USE_PARTY_FOR_STARTERS && invited.getLevel() >= 10 && player.getLevel() < 10) { //trying to invite high level
c.sendPacket(PacketCreator.serverNotice(5, "The player you have invited does not meet the requirements.")); c.sendPacket(PacketCreator.serverNotice(5, "The player you have invited does not meet the requirements."));
return; return;
} }
@@ -26,7 +26,6 @@ import net.AbstractPacketHandler;
import net.packet.InPacket; import net.packet.InPacket;
/** /**
*
* @author Quasar * @author Quasar
*/ */
public class PartySearchRegisterHandler extends AbstractPacketHandler { public class PartySearchRegisterHandler extends AbstractPacketHandler {
@@ -30,43 +30,44 @@ import net.server.world.World;
import tools.PacketCreator; import tools.PacketCreator;
/** /**
*
* @author XoticStory * @author XoticStory
* @author BubblesDev * @author BubblesDev
* @author Ronan * @author Ronan
*/ */
public class PartySearchStartHandler extends AbstractPacketHandler { public class PartySearchStartHandler extends AbstractPacketHandler {
@Override @Override
public void handlePacket(InPacket p, Client c) { public void handlePacket(InPacket p, Client c) {
int min = p.readInt(); int min = p.readInt();
int max = p.readInt(); int max = p.readInt();
Character chr = c.getPlayer(); Character chr = c.getPlayer();
if (min > max) { if (min > max) {
chr.dropMessage(1, "The min. value is higher than the max!"); chr.dropMessage(1, "The min. value is higher than the max!");
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
if (max - min > 30) { if (max - min > 30) {
chr.dropMessage(1, "You can only search for party members within a range of 30 levels."); chr.dropMessage(1, "You can only search for party members within a range of 30 levels.");
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
if (chr.getLevel() < min || chr.getLevel() > max) { if (chr.getLevel() < min || chr.getLevel() > max) {
chr.dropMessage(1, "The range of level for search has to include your own level."); chr.dropMessage(1, "The range of level for search has to include your own level.");
c.sendPacket(PacketCreator.enableActions()); c.sendPacket(PacketCreator.enableActions());
return; return;
} }
p.readInt(); // members p.readInt(); // members
int jobs = p.readInt(); int jobs = p.readInt();
Party party = c.getPlayer().getParty(); Party party = c.getPlayer().getParty();
if (party == null || !c.getPlayer().isPartyLeader()) return; if (party == null || !c.getPlayer().isPartyLeader()) {
return;
}
World world = c.getWorldServer(); World world = c.getWorldServer();
world.getPartySearchCoordinator().registerPartyLeader(chr, min, max, jobs); world.getPartySearchCoordinator().registerPartyLeader(chr, min, max, jobs);
} }
} }
@@ -40,14 +40,14 @@ public final class PetChatHandler extends AbstractPacketHandler {
int act = p.readByte(); int act = p.readByte();
byte pet = c.getPlayer().getPetIndex(petId); byte pet = c.getPlayer().getPetIndex(petId);
if ((pet < 0 || pet > 3) || (act < 0 || act > 9)) { if ((pet < 0 || pet > 3) || (act < 0 || act > 9)) {
return; return;
} }
String text = p.readString(); String text = p.readString();
if (text.length() > Byte.MAX_VALUE) { if (text.length() > Byte.MAX_VALUE) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with pets."); AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with pets.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to send text with length of " + text.length()); FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to send text with length of " + text.length());
c.disconnect(true, false); c.disconnect(true, false);
return; return;
} }
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), PacketCreator.petChat(c.getPlayer().getId(), pet, act, text), true); c.getPlayer().getMap().broadcastMessage(c.getPlayer(), PacketCreator.petChat(c.getPlayer().getId(), pet, act, text), true);
if (YamlConfig.config.server.USE_ENABLE_CHAT_LOG) { if (YamlConfig.config.server.USE_ENABLE_CHAT_LOG) {
@@ -41,7 +41,9 @@ public final class PetExcludeItemsHandler extends AbstractPacketHandler {
Character chr = c.getPlayer(); Character chr = c.getPlayer();
byte petIndex = chr.getPetIndex(petId); byte petIndex = chr.getPetIndex(petId);
if (petIndex < 0) return; if (petIndex < 0) {
return;
}
final Pet pet = chr.getPet(petIndex); final Pet pet = chr.getPet(petIndex);
if (pet == null) { if (pet == null) {
@@ -64,7 +64,9 @@ public final class PetFoodHandler extends AbstractPacketHandler {
} }
Pet pet = chr.getPet(slot); Pet pet = chr.getPet(slot);
if(pet == null) return; if (pet == null) {
return;
}
short pos = p.readShort(); short pos = p.readShort();
int itemId = p.readInt(); int itemId = p.readInt();

Some files were not shown because too many files have changed in this diff Show More