package handling;
import clientside.MapleCharacter;
import clientside.MapleClient;
import client.inventory.Item;
import client.inventory.MaplePet;
import client.inventory.PetDataFactory;
import constants.GameConstants;
import constants.ServerConstants;
import handling.cashshop.CashShopServer;
import handling.cashshop.handler.CashShopOperation;
import handling.cashshop.handler.MTSOperation;
import handling.channel.ChannelServer;
import handling.channel.handler.AllianceHandler;
import handling.channel.handler.BBSHandler;
import handling.channel.handler.BuddyListHandler;
import handling.channel.handler.ChatHandler;
import handling.channel.handler.DueyHandler;
import handling.channel.handler.FamilyHandler;
import handling.channel.handler.GuildHandler;
import handling.channel.handler.HiredMerchantHandler;
import handling.channel.handler.InterServerHandler;
import handling.channel.handler.InventoryHandler;
import handling.channel.handler.ItemMakerHandler;
import handling.channel.handler.MobHandler;
import handling.channel.handler.MonsterCarnivalHandler;
import handling.channel.handler.NPCHandler;
import handling.channel.handler.PartyHandler;
import handling.channel.handler.PetHandler;
import handling.channel.handler.PlayerHandler;
import handling.channel.handler.PlayerInteractionHandler;
import handling.channel.handler.PlayersHandler;
import handling.channel.handler.StatsHandling;
import handling.channel.handler.SummonHandler;
import handling.channel.handler.UserInterfaceHandler;
import handling.login.LoginServer;
import handling.login.handler.CharLoginHandler;
import handling.mina.MaplePacketDecoder;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import scripting.NPCScriptManager;
import server.CashItemFactory;
import server.CashItemInfo;
import server.MTSStorage;
import server.Randomizer;
import tools.FileoutputUtil;
import tools.HexTool;
import tools.MapleAESOFB;
import tools.Pair;
import tools.StringUtil;
import tools.data.ByteArrayByteStream;
import tools.data.LittleEndianAccessor;
import tools.packet.CField;
import tools.packet.CWvsContext;
import tools.packet.LoginPacket;
import tools.packet.MTSCSPacket;
public class MapleServerHandler extends IoHandlerAdapter implements MapleServerHandlerMBean {
public static boolean Log_Packets = false;
private int channel = -1;
private static int numDC = 0;
private static long lastDC = System.currentTimeMillis();
private boolean cs;
private boolean farm;
private final List<String> BlockedIP = new ArrayList<>();
private final Map<String, Pair<Long, Byte>> tracker = new ConcurrentHashMap<>();
private static final EnumSet<RecvPacketOpcode> blocked = EnumSet.noneOf(RecvPacketOpcode.class), sBlocked = EnumSet.noneOf(RecvPacketOpcode.class);
private static String client_username;
private static String client_password;
// <editor-fold defaultstate="collapsed" desc="Packet Log Implementation">
private static final int Log_Size = 10000, Packet_Log_Size = 25;
private static final ArrayList<LoggedPacket> Packet_Log = new ArrayList<>(Log_Size);
private static final ReentrantReadWriteLock Packet_Log_Lock = new ReentrantReadWriteLock();
private static String Packet_Log_Output = "/var/www/logs/";
private static int Packet_Log_Index = 0;
public static void log(String packet, String op, MapleClient c, IoSession io) {
try {
Packet_Log_Lock.writeLock().lock();
LoggedPacket logged = null;
if (Packet_Log.size() == Log_Size) {
logged = Packet_Log.remove(0);
}
//This way, we don't create new LoggedPacket objects, we reuse them =]
if (logged == null) {
logged = new LoggedPacket(packet, op, io.getRemoteAddress().toString(),
c == null ? -1 : c.getAccID(), FileoutputUtil.CurrentReadable_Time(),
c == null || c.getAccountName() == null ? "[Null]" : c.getAccountName(),
c == null || c.getPlayer() == null || c.getPlayer().getName() == null ? "[Null]" : c.getPlayer().getName(),
c == null || c.getPlayer() == null || c.getPlayer().getMap() == null ? "[Null]" : String.valueOf(c.getPlayer().getMapId()),
c == null || NPCScriptManager.getInstance().getCM(c) == null ? "[Null]" : String.valueOf(NPCScriptManager.getInstance().getCM(c).getNpc()));
} else {
logged.setInfo(packet, op, io.getRemoteAddress().toString(),
c == null ? -1 : c.getAccID(), FileoutputUtil.CurrentReadable_Time(),
c == null || c.getAccountName() == null ? "[Null]" : c.getAccountName(),
c == null || c.getPlayer() == null || c.getPlayer().getName() == null ? "[Null]" : c.getPlayer().getName(),
c == null || c.getPlayer() == null || c.getPlayer().getMap() == null ? "[Null]" : String.valueOf(c.getPlayer().getMapId()),
c == null || NPCScriptManager.getInstance().getCM(c) == null ? "[Null]" : String.valueOf(NPCScriptManager.getInstance().getCM(c).getNpc()));
}
Packet_Log.add(logged);
} finally {
Packet_Log_Lock.writeLock().unlock();
}
}
private static class LoggedPacket {
private static final String nl = System.getProperty("line.separator");
private String ip, accName, accId, chrName, packet, mapId, npcId, op, time;
private long timestamp;
public LoggedPacket(String p, String op, String ip, int id, String time, String accName, String chrName, String mapId, String npcId) {
setInfo(p, op, ip, id, time, accName, chrName, mapId, npcId);
}
public final void setInfo(String p, String op, String ip, int id, String time, String accName, String chrName, String mapId, String npcId) {
this.ip = ip;
this.op = op;
this.time = time;
this.packet = p;
this.accName = accName;
this.chrName = chrName;
this.mapId = mapId;
this.npcId = npcId;
timestamp = System.currentTimeMillis();
this.accId = String.valueOf(id);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[IP: ").append(ip).append("] [").append(accId).append('|').append(accName).append('|').append(chrName).append("] [").append(npcId).append('|').append(mapId).append("] [Time: ").append(timestamp).append("] [").append(time).append(']');
sb.append(nl);
sb.append("[Op: ").append(op).append("] [").append(packet).append(']');
return sb.toString();
}
}
public static void registerMBean() {
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
try {
MapleServerHandler mbean = new MapleServerHandler();
//The log is a static object, so we can just use this hacky method.
mBeanServer.registerMBean(mbean, new ObjectName("handling:type=MapleServerHandler"));
} catch (MalformedObjectNameException | InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
System.out.println("Error registering PacketLog MBean");
}
}
@Override
public void writeLog() {
writeLog(false);
}
public void writeLog(boolean crash) {
Packet_Log_Lock.readLock().lock();
try {
try (FileWriter fw = new FileWriter(new File(Packet_Log_Output + Packet_Log_Index + (crash ? "_DC.txt" : ".txt")), true)) {
String nl = System.getProperty("line.separator");
for (LoggedPacket loggedPacket : Packet_Log) {
fw.write(loggedPacket.toString());
fw.write(nl);
}
final String logString = "Log has been written at " + lastDC + " [" + FileoutputUtil.CurrentReadable_Time() + "] - " + numDC + " have disconnected, within " + (System.currentTimeMillis() - lastDC) + " milliseconds. (" + System.currentTimeMillis() + ")";
System.out.println(logString);
fw.write(logString);
fw.write(nl);
fw.flush();
}
Packet_Log.clear();
Packet_Log_Index++;
if (Packet_Log_Index > Packet_Log_Size) {
Packet_Log_Index = 0;
Log_Packets = false;
}
} catch (IOException ex) {
System.out.println("Error writing log to file.");
} finally {
Packet_Log_Lock.readLock().unlock();
}
}
public static void initiate() {
//RecvPacketOpcode[] block = new RecvPacketOpcode[]{RecvPacketOpcode.NPC_ACTION, RecvPacketOpcode.MOVE_PLAYER, RecvPacketOpcode.PONG, RecvPacketOpcode.MOVE_PET, RecvPacketOpcode.MOVE_SUMMON, RecvPacketOpcode.MOVE_DRAGON, RecvPacketOpcode.MOVE_LIFE, RecvPacketOpcode.MOVE_ANDROID, RecvPacketOpcode.HEAL_OVER_TIME, RecvPacketOpcode.AUTO_AGGRO, RecvPacketOpcode.CANCEL_DEBUFF, RecvPacketOpcode.MOVE_FAMILIAR};
// RecvPacketOpcode[] serverBlock = new RecvPacketOpcode[]{RecvPacketOpcode.CHANGE_KEYMAP, RecvPacketOpcode.ITEM_PICKUP, RecvPacketOpcode.PET_LOOT, RecvPacketOpcode.TAKE_DAMAGE, RecvPacketOpcode.FACE_EXPRESSION, RecvPacketOpcode.USE_ITEM, RecvPacketOpcode.CLOSE_RANGE_ATTACK, RecvPacketOpcode.MAGIC_ATTACK, RecvPacketOpcode.RANGED_ATTACK, RecvPacketOpcode.ARAN_COMBO, RecvPacketOpcode.SPECIAL_MOVE, RecvPacketOpcode.GENERAL_CHAT, RecvPacketOpcode.MONSTER_BOMB, RecvPacketOpcode.PASSIVE_ENERGY, RecvPacketOpcode.PET_AUTO_POT, RecvPacketOpcode.USE_CASH_ITEM, RecvPacketOpcode.PARTYCHAT, RecvPacketOpcode.CANCEL_BUFF, RecvPacketOpcode.SKILL_EFFECT, RecvPacketOpcode.CHAR_INFO_REQUEST, RecvPacketOpcode.ALLIANCE_OPERATION, RecvPacketOpcode.AUTO_ASSIGN_AP, RecvPacketOpcode.DISTRIBUTE_AP, RecvPacketOpcode.USE_MAGNIFY_GLASS, RecvPacketOpcode.SPAWN_PET, RecvPacketOpcode.SUMMON_ATTACK, RecvPacketOpcode.ITEM_MOVE, RecvPacketOpcode.PARTY_SEARCH_STOP};
// blocked.addAll(Arrays.asList(block));
// sBlocked.addAll(Arrays.asList(serverBlock));
if (Log_Packets) {
for (int i = 1; i <= Packet_Log_Size; i++) {
if (!(new File(Packet_Log_Output + i + ".txt")).exists() && !(new File(Packet_Log_Output + i + "_DC.txt")).exists()) {
Packet_Log_Index = i;
break;
}
}
// if (Packet_Log_Index <= 0) { //25+ files, do not log
// Log_Packets = false;
// }
}
registerMBean();
}
public MapleServerHandler() {
//ONLY FOR THE MBEAN
}
// </editor-fold>
public MapleServerHandler(final int channel, final boolean cs, final boolean farm) {
this.channel = channel;
this.cs = cs;
this.farm = farm;
}
@Override
public void exceptionCaught(final IoSession session, final Throwable cause) throws Exception {
// MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);
// FileoutputUtil.log("wtf.txt", MapleClient.getLogMessage(client, cause.getMessage()) + " " + cause);
// cause.printStackTrace();
}
@Override
public void sessionOpened(final IoSession session) throws Exception {
// Start of IP checking
final String address = session.getRemoteAddress().toString().split(":")[0];
if (BlockedIP.contains(address)) {
session.close(true);
return;
}
final Pair<Long, Byte> track = tracker.get(address);
byte count;
if (track == null) {
count = 1;
} else {
count = track.right;
final long difference = System.currentTimeMillis() - track.left;
if (difference < 2000) { // Less than 2 sec
count++;
} else if (difference > 20000) { // Over 20 sec
count = 1;
}
if (count >= 10) {
BlockedIP.add(address);
tracker.remove(address); // Cleanup
session.close(true);
return;
}
}
tracker.put(address, new Pair<>(System.currentTimeMillis(), count));
// End of IP checking.
String IP = address.substring(address.indexOf('/') + 1, address.length());
if (channel > -1) {
if (ChannelServer.getInstance(channel).isShutdown()) {
session.close(true);
return;
}
if (!LoginServer.containsIPAuth(IP)) {
session.close(true);
return;
}
} else if (cs) {
if (CashShopServer.isShutdown()) {
session.close(true);
return;
}
} else {
if (LoginServer.isShutdown()) {
session.close(true);
return;
}
}
LoginServer.removeIPAuth(IP);
byte[] ivRecv = {(byte) Randomizer.nextInt(254), (byte) Randomizer.nextInt(254), (byte) Randomizer.nextInt(254), (byte) Randomizer.nextInt(254)};
byte[] ivSend = {(byte) Randomizer.nextInt(254), (byte) Randomizer.nextInt(254), (byte) Randomizer.nextInt(254), (byte) Randomizer.nextInt(254)};
MapleClient client = new MapleClient(new MapleAESOFB(ivSend, (short) (0xFFFF - ServerConstants.MAPLE_VERSION)), new MapleAESOFB(ivRecv, (short) ServerConstants.MAPLE_VERSION), session);
client.setChannel(channel);
MaplePacketDecoder.DecoderState decoderState = new MaplePacketDecoder.DecoderState();
session.setAttribute(MaplePacketDecoder.DECODER_STATE_KEY, decoderState);
session.write(LoginPacket.getHello(ServerConstants.MAPLE_VERSION, ivSend, ivRecv));
//System.out.println("GETHELLO SENT TO " + address);
session.setAttribute(MapleClient.CLIENT_KEY, client);
session.setAttribute(IdleStatus.READER_IDLE, 60);
session.setAttribute(IdleStatus.WRITER_IDLE, 60);
StringBuilder sb = new StringBuilder();
sb.append("IoSession opened with ").append(address);
System.out.println(sb.toString());
}
@Override
public void sessionClosed(final IoSession session) throws Exception {
final MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);
if (client != null) {
byte state = MapleClient.CHANGE_CHANNEL;
if (Log_Packets && !LoginServer.isShutdown() && !cs && channel > -1) {
state = client.getLoginState();
}
if (state != MapleClient.CHANGE_CHANNEL) {
log("Data: " + numDC, "CLOSED", client, session);
if (System.currentTimeMillis() - lastDC < 600000) { //within the minute
numDC++;
if (numDC >= 1) { //100+ people have dc'd in minute in channelserver
System.out.println("Writing log...");
writeLog();
numDC = 0;
lastDC = System.currentTimeMillis(); //intentionally place here
}
} else {
numDC = 0;
lastDC = System.currentTimeMillis(); //intentionally place here
}
}
try {
client.disconnect(true, cs);
} finally {
session.close(true);
session.removeAttribute(MapleClient.CLIENT_KEY);
}
}
super.sessionClosed(session);
}
@Override
public void sessionIdle(final IoSession session, final IdleStatus status) throws Exception {
//final MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);
/* if (client != null && client.getPlayer() != null) {
System.out.println("Player "+ client.getPlayer().getName() +" went idle");
}*/
// if (client != null) {
// client.sendPing();
// }
//super.sessionIdle(session, status);
}
@Override
public void messageReceived(final IoSession session, final Object message) {
if (message == null || session == null) {
return;
}
final LittleEndianAccessor slea = new LittleEndianAccessor(new ByteArrayByteStream((byte[]) message));
if (slea.available() < 2) {
return;
}
final MapleClient c = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);
if (c == null || !c.isReceiving()) {
return;
}
final short header_num = slea.readShort();
// System.out.println(header_num);
////
////
// final StringBuilder sb = new StringBuilder("Received data :\n");
// sb.append(HexTool.toString((byte[]) message)).append("\n").append(HexTool.toStringFromAscii((byte[]) message));
//
// System.out.println(sb.toString());
for (final RecvPacketOpcode recv : RecvPacketOpcode.values()) {
if (recv.getValue() == header_num) {
if (recv.NeedsChecking()) {
if (!c.isLoggedIn()) {
return;
}
}
try {
//no login packets
if (Log_Packets && !blocked.contains(recv) && !sBlocked.contains(recv) && (cs || channel > -1)) {
log(slea.toString(), recv.toString(), c, session);
}
handlePacket(recv, slea, c, cs, farm);
//Log after the packet is handle. You'll see why =]
} catch (NegativeArraySizeException | ArrayIndexOutOfBoundsException e) {
//swallow, no one cares
FileoutputUtil.outputFileError(FileoutputUtil.PacketEx_Log, e);
FileoutputUtil.log(FileoutputUtil.PacketEx_Log, "Packet: " + header_num + "\n" + slea.toString(true));
} catch (Exception e) {
FileoutputUtil.outputFileError(FileoutputUtil.PacketEx_Log, e);
FileoutputUtil.log(FileoutputUtil.PacketEx_Log, "Packet: " + header_num + "\n" + slea.toString(true));
}
return;
}
}
// final StringBuilder sbd = new StringBuilder("Received data : (Unhandled)\n");
//sbd.append(HexTool.toString((byte[]) message)).append("\n").append(HexTool.toStringFromAscii((byte[]) message));
//System.out.println(sbd.toString());
}
public static void handlePacket(RecvPacketOpcode header, LittleEndianAccessor slea, MapleClient c, final boolean cs, final boolean farm)
throws Exception {
Item itemz;
int tokenId;
// System.out.println(header.toString() + " Data: " + slea); //debug, remove this when done
switch (header) {
case LOGIN_REDIRECTOR:
client_username = slea.readMapleAsciiString();
client_password = slea.readMapleAsciiString();
if (client_password.isEmpty()) {
c.getSession().close(true);
}
c.login(client_username, client_password, false);
c.getSession().write(LoginPacket.getAuthSuccessRequest(c));
break;
case PONG:
c.pongReceived();
break;
case STRANGE_DATA:
break;
case LOGIN_PASSWORD:
System.out.println(slea);
break;
// case LOGIN_PASSWORD:
// case LOGIN_PASSWORD2:
case CLIENT_START:
if (c.getSessionIPAddress().contains("8.31.99.143")
|| c.getSessionIPAddress().contains("127.0.0.1")|| c.getSessionIPAddress().contains("8.31.99.141")) {
c.loginData("admin");
c.getSession().write(LoginPacket.getAuthSuccessRequest(c));
} else if (c.getSessionIPAddress().contains("86.90.68.25")) {
c.loginData("jennn");
c.getSession().write(LoginPacket.getAuthSuccessRequest(c));
} else if (c.getSessionIPAddress().contains("62.107.134.22")) {//|| c.getSessionIPAddress().contains("188.178.2.74")) {
c.loginData("hemmi");
c.getSession().write(LoginPacket.getAuthSuccessRequest(c));
}
break;
case CLIENT_AUTH:
int pRequest = slea.readInt();
int pResponse;
pResponse = ((pRequest >> 5) << 5) + (((((pRequest & 0x1F) >> 3) ^ 2) << 3) + (7 - (pRequest & 7)));
pResponse |= ((pRequest >> 7) << 7);
pResponse -= 2;
c.getSession().write(CField.getClientAuth(pResponse));
break;
case VIEW_SERVERLIST:
if (slea.readByte() == 0) {
CharLoginHandler.ServerListRequest(c);
}
break;
case REDISPLAY_SERVERLIST:
case SERVERLIST_REQUEST:
CharLoginHandler.ServerListRequest(c);
break;
case CLIENT_HELLO:
if (slea.readByte() != 8 || slea.readShort() != ServerConstants.MAPLE_VERSION || !String.valueOf(slea.readShort()).equals(ServerConstants.MAPLE_PATCH)) {
c.getSession().close(true);
}
break;
case CHARLIST_REQUEST:
CharLoginHandler.CharlistRequest(slea, c);
break;
case SERVERSTATUS_REQUEST:
CharLoginHandler.ServerStatusRequest(c);
break;
case CHECK_CHAR_NAME:
CharLoginHandler.CheckCharName(slea.readMapleAsciiString(), c);
break;
case CREATE_CHAR:
case CREATE_SPECIAL_CHAR:
CharLoginHandler.CreateChar(slea, c);
break;
case CREATE_ULTIMATE:
CharLoginHandler.CreateUltimate(slea, c);
break;
case DELETE_CHAR:
CharLoginHandler.DeleteChar(slea, c);
break;
case VIEW_ALL_CHAR:
CharLoginHandler.ViewChar(slea, c);
break;
case PICK_ALL_CHAR:
CharLoginHandler.Character_WithoutSecondPassword(slea, c, false, true);
break;
case CHAR_SELECT_NO_PIC:
CharLoginHandler.Character_WithoutSecondPassword(slea, c, false, false);
break;
case VIEW_REGISTER_PIC:
CharLoginHandler.Character_WithoutSecondPassword(slea, c, true, true);
break;
case CHAR_SELECT:
CharLoginHandler.Character_WithoutSecondPassword(slea, c, true, false);
break;
case VIEW_SELECT_PIC:
CharLoginHandler.Character_WithSecondPassword(slea, c, true);
break;
case AUTH_SECOND_PASSWORD:
CharLoginHandler.Character_WithSecondPassword(slea, c, false);
break;
case CHARACTER_CARDS:
CharLoginHandler.updateCCards(slea, c);
break;
case CLIENT_ERROR: //might not be correct
if (slea.available() >= 6L) {
slea.skip(6);
short badPacketSize = slea.readShort();
slea.skip(4);
int pHeader = slea.readShort();
String pHeaderStr = Integer.toHexString(pHeader).toUpperCase();
pHeaderStr = StringUtil.getLeftPaddedStr(pHeaderStr, '0', 4);
String op = SendPacketOpcode.getOpcodeName(pHeader);
String from = "";
if (c.getPlayer() != null) {
from = new StringBuilder().append("Chr: ").append(c.getPlayer().getName()).append(" LVL(").append(c.getPlayer().getLevel()).append(") job: ").append(c.getPlayer().getJob()).append(" MapID: ").append(c.getPlayer().getMapId()).toString();
if (c.getPlayer() != null) {
from = new StringBuilder().append(from).append(" MAPCHR: ").toString();
for (ChannelServer css : ChannelServer.getAllInstances()) {
if ((css.getChannel() == c.getChannel())
&& (css.getPlayerStorage().getAllCharacters().size() > 0)) {
for (MapleCharacter chrss : css.getPlayerStorage().getAllCharacters()) {
if (chrss.getMapId() == c.getPlayer().getMapId()) {
from = new StringBuilder().append(from).append(chrss.getName()).append("[").append(chrss.getId()).append("] ,Lv").append(chrss.getLevel()).append(",job:").append(chrss.getJob()).append(" .").toString();
}
}
}
}
}
}
String Recv = new StringBuilder().append(from).append("\r\n").append("SendOP(-38): ").append(op).append(" [").append(pHeaderStr).append("] (").append(badPacketSize - 4).append(")").append(slea.toString(false)).append("\r\n\r\n").toString();
FileoutputUtil.log("38.txt", Recv);
}
break;
case ENABLE_SPECIAL_CREATION:
c.getSession().write(LoginPacket.enableSpecialCreation(c.getAccID(), true));
break;
case RSA_KEY:
break;
case CHANGE_CHANNEL:
case CHANGE_ROOM_CHANNEL:
InterServerHandler.ChangeChannel(slea, c, c.getPlayer(), header == RecvPacketOpcode.CHANGE_ROOM_CHANNEL);
break;
case PLAYER_LOGGEDIN:
final int playerid = slea.readInt();
if (cs) {
CashShopOperation.EnterCS(playerid, c);
} else {
InterServerHandler.Loggedin(playerid, c);
}
break;
case ENTER_PVP:
case ENTER_PVP_PARTY:
PlayersHandler.EnterPVP(slea, c);
break;
case PVP_RESPAWN:
PlayersHandler.RespawnPVP(slea, c);
break;
case LEAVE_PVP:
PlayersHandler.LeavePVP(slea, c);
break;
case PVP_ATTACK:
PlayersHandler.AttackPVP(slea, c);
break;
case PVP_SUMMON:
SummonHandler.SummonPVP(slea, c);
break;
case ENTER_CASH_SHOP:
InterServerHandler.EnterCS(c, c.getPlayer(), false);
break;
case ENTER_MTS:
InterServerHandler.EnterMTS(c, c.getPlayer());
break;
case MOVE_PLAYER:
PlayerHandler.MovePlayer(slea, c, c.getPlayer());
break;
case CHAR_INFO_REQUEST:
slea.readInt();
PlayerHandler.CharInfoRequest(slea.readInt(), c, c.getPlayer());
break;
case CLOSE_RANGE_ATTACK:
PlayerHandler.closeRangeAttack(slea, c, c.getPlayer(), false);
break;
case RANGED_ATTACK:
PlayerHandler.rangedAttack(slea, c, c.getPlayer());
break;
case MAGIC_ATTACK:
PlayerHandler.MagicDamage(slea, c, c.getPlayer());
break;
case SPECIAL_MOVE:
PlayerHandler.SpecialMove(slea, c, c.getPlayer());
break;
case PASSIVE_ENERGY:
PlayerHandler.closeRangeAttack(slea, c, c.getPlayer(), false);
break;
case GET_BOOK_INFO:
PlayersHandler.MonsterBookInfoRequest(slea, c, c.getPlayer());
break;
case MONSTER_BOOK_DROPS:
PlayersHandler.MonsterBookDropsRequest(slea, c, c.getPlayer());
break;
case CHANGE_SET:
PlayersHandler.ChangeSet(slea, c, c.getPlayer());
break;
case PROFESSION_INFO:
ItemMakerHandler.ProfessionInfo(slea, c);
break;
case CRAFT_DONE:
ItemMakerHandler.CraftComplete(slea, c, c.getPlayer());
break;
case CRAFT_MAKE:
ItemMakerHandler.CraftMake(slea, c, c.getPlayer());
break;
case CRAFT_EFFECT:
ItemMakerHandler.CraftEffect(slea, c, c.getPlayer());
break;
case START_HARVEST:
ItemMakerHandler.StartHarvest(slea, c, c.getPlayer());
break;
case STOP_HARVEST:
ItemMakerHandler.StopHarvest(slea, c, c.getPlayer());
break;
case MAKE_EXTRACTOR:
ItemMakerHandler.MakeExtractor(slea, c, c.getPlayer());
break;
case USE_BAG:
ItemMakerHandler.UseBag(slea, c, c.getPlayer());
break;
case USE_FAMILIAR:
MobHandler.UseFamiliar(slea, c, c.getPlayer());
break;
case SPAWN_FAMILIAR:
MobHandler.SpawnFamiliar(slea, c, c.getPlayer());
break;
case RENAME_FAMILIAR:
MobHandler.RenameFamiliar(slea, c, c.getPlayer());
break;
case MOVE_FAMILIAR:
MobHandler.MoveFamiliar(slea, c, c.getPlayer());
break;
case ATTACK_FAMILIAR:
MobHandler.AttackFamiliar(slea, c, c.getPlayer());
break;
case TOUCH_FAMILIAR:
MobHandler.TouchFamiliar(slea, c, c.getPlayer());
break;
case USE_RECIPE:
ItemMakerHandler.UseRecipe(slea, c, c.getPlayer());
break;
case MOVE_HAKU:
PlayerHandler.MoveHaku(slea, c, c.getPlayer());
break;
case CHANGE_HAKU:
PlayerHandler.ChangeHaku(slea, c, c.getPlayer());
break;
case MOVE_ANDROID:
PlayerHandler.MoveAndroid(slea, c, c.getPlayer());
break;
case FACE_EXPRESSION:
PlayerHandler.ChangeEmotion(slea.readInt(), c.getPlayer());
break;
case FACE_ANDROID:
PlayerHandler.ChangeAndroidEmotion(slea.readInt(), c.getPlayer());
break;
case TAKE_DAMAGE:
PlayerHandler.TakeDamage(slea, c, c.getPlayer());
break;
case HEAL_OVER_TIME:
PlayerHandler.Heal(slea, c.getPlayer());
break;
case CANCEL_BUFF:
PlayerHandler.CancelBuffHandler(slea.readInt(), c.getPlayer());
break;
case MECH_CANCEL:
PlayerHandler.CancelMech(slea, c.getPlayer());
break;
case CANCEL_ITEM_EFFECT:
PlayerHandler.CancelItemEffect(slea.readInt(), c.getPlayer());
break;
case USE_TITLE:
PlayerHandler.UseTitle(slea.readInt(), c, c.getPlayer());
break;
case ANGELIC_CHANGE:
PlayerHandler.ANGELICCHANGE(slea, c, c.getPlayer());
break;
case USE_CHAIR:
PlayerHandler.UseChair(slea.readInt(), c, c.getPlayer());
break;
case CANCEL_CHAIR:
PlayerHandler.CancelChair(slea.readShort(), c, c.getPlayer());
break;
case WHEEL_OF_FORTUNE:
break;
case USE_ITEMEFFECT:
PlayerHandler.UseItemEffect(slea.readInt(), c, c.getPlayer());
break;
case SKILL_EFFECT:
PlayerHandler.SkillEffect(slea, c.getPlayer());
break;
case QUICK_SLOT:
PlayerHandler.QuickSlot(slea, c.getPlayer());
break;
case MESO_DROP:
slea.readInt();
PlayerHandler.DropMeso(slea.readInt(), c.getPlayer());
break;
case CHANGE_KEYMAP:
PlayerHandler.ChangeKeymap(slea, c.getPlayer());
break;
case UPDATE_ENV:
break;
case CHANGE_MAP:
if (cs) {
CashShopOperation.LeaveCS(slea, c, c.getPlayer());
} else {
PlayerHandler.ChangeMap(slea, c, c.getPlayer());
}
break;
case CHANGE_MAP_SPECIAL:
slea.skip(1);
PlayerHandler.ChangeMapSpecial(slea.readMapleAsciiString(), c, c.getPlayer());
break;
case USE_INNER_PORTAL:
slea.skip(1);
PlayerHandler.InnerPortal(slea, c, c.getPlayer());
break;
case TROCK_ADD_MAP:
PlayerHandler.TrockAddMap(slea, c, c.getPlayer());
break;
case ARAN_COMBO:
PlayerHandler.AranCombo(c, c.getPlayer(), 1);
break;
case SKILL_MACRO:
PlayerHandler.ChangeSkillMacro(slea, c.getPlayer());
break;
case GIVE_FAME:
PlayersHandler.GiveFame(slea, c, c.getPlayer());
break;
case TRANSFORM_PLAYER:
PlayersHandler.TransformPlayer(slea, c, c.getPlayer());
break;
case NOTE_ACTION:
PlayersHandler.Note(slea, c.getPlayer());
break;
case USE_DOOR:
PlayersHandler.UseDoor(slea, c.getPlayer());
break;
case USE_MECH_DOOR:
PlayersHandler.UseMechDoor(slea, c.getPlayer());
break;
case DAMAGE_REACTOR:
PlayersHandler.HitReactor(slea, c);
break;
case CLICK_REACTOR:
case TOUCH_REACTOR:
PlayersHandler.TouchReactor(slea, c);
break;
case CLOSE_CHALKBOARD:
c.getPlayer().setChalkboard(null);
break;
case ITEM_SORT:
InventoryHandler.ItemSort(slea, c);
break;
case ITEM_GATHER:
InventoryHandler.ItemGather(slea, c);
break;
case ITEM_MOVE:
InventoryHandler.ItemMove(slea, c);
break;
case MOVE_BAG:
InventoryHandler.MoveBag(slea, c);
break;
case SWITCH_BAG:
InventoryHandler.SwitchBag(slea, c);
break;
case ITEM_MAKER:
ItemMakerHandler.ItemMaker(slea, c);
break;
case ITEM_PICKUP:
InventoryHandler.Pickup_Player(slea, c, c.getPlayer());
break;
case USE_CASH_ITEM:
InventoryHandler.UseCashItem(slea, c);
break;
case USE_ITEM:
InventoryHandler.UseItem(slea, c, c.getPlayer());
break;
case USE_COSMETIC:
InventoryHandler.UseCosmetic(slea, c, c.getPlayer());
break;
case USE_MAGNIFY_GLASS:
InventoryHandler.UseMagnify(slea, c);
break;
case USE_SCRIPTED_NPC_ITEM:
InventoryHandler.UseScriptedNPCItem(slea, c, c.getPlayer());
break;
case USE_RETURN_SCROLL:
InventoryHandler.UseReturnScroll(slea, c, c.getPlayer());
break;
case USE_NEBULITE:
InventoryHandler.UseNebulite(slea, c);
break;
case USE_ALIEN_SOCKET:
InventoryHandler.UseAlienSocket(slea, c);
break;
case USE_ALIEN_SOCKET_RESPONSE:
slea.skip(4);
c.getSession().write(MTSCSPacket.useAlienSocket(false));
break;
case VICIOUS_HAMMER:
slea.skip(4);
slea.skip(4);
c.getSession().write(MTSCSPacket.ViciousHammer(false, 0));
break;
case GOLD_HAMMER:
InventoryHandler.UseGoldHammer(slea, c);
break;
case USE_NEBULITE_FUSION:
InventoryHandler.UseNebuliteFusion(slea, c);
break;
case USE_UPGRADE_SCROLL:
slea.readInt();
InventoryHandler.UseUpgradeScroll(slea.readShort(), slea.readShort(), slea.readShort(), c, c.getPlayer(), false, slea.readByte() > 0);
break;
case USE_FLAG_SCROLL: //maybe?
slea.readInt();
InventoryHandler.UseSpecialScroll(slea, c.getPlayer());
break;
case USE_POTENTIAL_SCROLL:
case USE_EQUIP_SCROLL:
slea.readInt();
InventoryHandler.UseUpgradeScroll(slea.readShort(), slea.readShort(), (short) 0, c, c.getPlayer(), false, slea.readByte() > 0);
break;
case USE_SUMMON_BAG:
InventoryHandler.UseSummonBag(slea, c, c.getPlayer());
break;
case USE_TREASURE_CHEST:
InventoryHandler.UseTreasureChest(slea, c, c.getPlayer());
break;
case USE_SKILL_BOOK:
slea.readInt();
InventoryHandler.UseSkillBook((byte) slea.readShort(), slea.readInt(), c, c.getPlayer());
break;
case USE_CATCH_ITEM:
InventoryHandler.UseCatchItem(slea, c, c.getPlayer());
break;
case USE_MOUNT_FOOD:
InventoryHandler.UseMountFood(slea, c, c.getPlayer());
break;
case REWARD_ITEM:
InventoryHandler.UseRewardItem((byte) slea.readShort(), slea.readInt(), c, c.getPlayer());
break;
case HYPNOTIZE_DMG:
MobHandler.HypnotizeDmg(slea, c.getPlayer());
break;
case MOB_NODE:
MobHandler.MobNode(slea, c.getPlayer());
break;
case DISPLAY_NODE:
MobHandler.DisplayNode(slea, c.getPlayer());
break;
case MOVE_LIFE:
MobHandler.MoveMonster(slea, c, c.getPlayer());
break;
case AUTO_AGGRO:
MobHandler.AutoAggro(slea.readInt(), c.getPlayer());
break;
case FRIENDLY_DAMAGE:
MobHandler.FriendlyDamage(slea, c.getPlayer());
break;
case REISSUE_MEDAL:
PlayerHandler.ReIssueMedal(slea, c, c.getPlayer());
break;
case MONSTER_BOMB:
MobHandler.MonsterBomb(slea.readInt(), c.getPlayer());
break;
case MOB_BOMB:
MobHandler.MobBomb(slea, c.getPlayer());
break;
case NPC_SHOP:
NPCHandler.NPCShop(slea, c, c.getPlayer());
break;
case NPC_TALK:
NPCHandler.NPCTalk(slea, c, c.getPlayer());
break;
case NPC_TALK_MORE:
NPCHandler.NPCMoreTalk(slea, c);
break;
case NPC_ACTION:
NPCHandler.NPCAnimation(slea, c);
break;
case QUEST_ACTION:
NPCHandler.QuestAction(slea, c, c.getPlayer());
break;
case STORAGE:
if (c.getPlayer().getGMLevel() == 6 && c.getPlayer().getDGM() == 0) {
c.getPlayer().dropMessage(1, "You may not do this as a GM.");
c.getPlayer().getClient().getSession().write(CWvsContext.enableActions());
break;
}
NPCHandler.Storage(slea, c, c.getPlayer());
break;
case GENERAL_CHAT:
if ((c.getPlayer() != null) && (c.getPlayer().getMap() != null)) {
slea.readInt();
ChatHandler.GeneralChat(slea.readMapleAsciiString(), slea.readByte(), c, c.getPlayer());
}
break;
case PARTYCHAT:
slea.readInt();
ChatHandler.Others(slea, c, c.getPlayer());
break;
case WHISPER:
ChatHandler.Whisper_Find(slea, c);
break;
case MESSENGER:
ChatHandler.Messenger(slea, c);
break;
case AUTO_ASSIGN_AP:
StatsHandling.AutoAssignAP(slea, c, c.getPlayer());
break;
case DISTRIBUTE_AP:
StatsHandling.DistributeAP(slea, c, c.getPlayer());
break;
case DISTRIBUTE_SP:
slea.readInt();
StatsHandling.DistributeSP(slea.readInt(), slea.readByte(), c, c.getPlayer());
break;
case PLAYER_INTERACTION:
PlayerInteractionHandler.PlayerInteraction(slea, c, c.getPlayer());
break;
case GUILD_OPERATION:
GuildHandler.Guild(slea, c);
break;
case DENY_GUILD_REQUEST:
slea.skip(1);
GuildHandler.DenyGuildRequest(slea.readMapleAsciiString(), c);
break;
case ALLIANCE_OPERATION:
AllianceHandler.HandleAlliance(slea, c, false);
break;
case DENY_ALLIANCE_REQUEST:
AllianceHandler.HandleAlliance(slea, c, true);
break;
case PUBLIC_NPC:
NPCHandler.OpenPublicNpc(slea, c);
break;
case BBS_OPERATION:
BBSHandler.BBSOperation(slea, c);
break;
case PARTY_OPERATION:
PartyHandler.PartyOperation(slea, c);
break;
case DENY_PARTY_REQUEST:
PartyHandler.DenyPartyRequest(slea, c);
break;
case ALLOW_PARTY_INVITE:
PartyHandler.AllowPartyInvite(slea, c);
break;
case BUDDYLIST_MODIFY:
BuddyListHandler.BuddyOperation(slea, c);
break;
case CYGNUS_SUMMON:
UserInterfaceHandler.CygnusSummon_NPCRequest(c);
break;
case SHIP_OBJECT:
UserInterfaceHandler.ShipObjectRequest(slea.readInt(), c);
break;
case BUY_CS_ITEM:
CashShopOperation.BuyCashItem(slea, c, c.getPlayer());
break;
case CS_UPDATE_ITEM:
CashShopOperation.BuyCashItem(slea, c, c.getPlayer());
break;
case COUPON_CODE:
CashShopOperation.doCSPackets(c);
break;
case TWIN_DRAGON_EGG:
System.out.println(new StringBuilder().append("TWIN_DRAGON_EGG: ").append(slea.toString()).toString());
CashItemInfo item = CashItemFactory.getInstance().getItem(10003055);
itemz = c.getPlayer().getCashInventory().toItem(item);
break;
case XMAS_SURPRISE:
System.out.println(new StringBuilder().append("XMAS_SURPRISE: ").append(slea.toString()).toString());
break;
case CS_UPDATE:
CashShopOperation.CSUpdate(c);
break;
case TOUCHING_MTS:
MTSOperation.MTSUpdate(MTSStorage.getInstance().getCart(c.getPlayer().getId()), c);
break;
case MTS_TAB:
MTSOperation.MTSOperation(slea, c);
break;
case USE_POT:
ItemMakerHandler.UsePot(slea, c);
break;
case CLEAR_POT:
ItemMakerHandler.ClearPot(slea, c);
break;
case FEED_POT:
ItemMakerHandler.FeedPot(slea, c);
break;
case CURE_POT:
ItemMakerHandler.CurePot(slea, c);
break;
case REWARD_POT:
ItemMakerHandler.RewardPot(slea, c);
break;
case DAMAGE_SUMMON:
slea.skip(4);
SummonHandler.DamageSummon(slea, c.getPlayer());
break;
case MOVE_SUMMON:
SummonHandler.MoveSummon(slea, c.getPlayer());
break;
case SUMMON_ATTACK:
SummonHandler.SummonAttack(slea, c, c.getPlayer());
break;
case MOVE_DRAGON:
SummonHandler.MoveDragon(slea, c.getPlayer());
break;
case SUB_SUMMON:
SummonHandler.SubSummon(slea, c.getPlayer());
break;
case REMOVE_SUMMON:
SummonHandler.RemoveSummon(slea, c);
break;
case SPAWN_PET:
PetHandler.SpawnPet(slea, c, c.getPlayer());
break;
case MOVE_PET:
PetHandler.MovePet(slea, c.getPlayer());
break;
case PET_CHAT:
if (slea.available() >= 12L) {
int petid = GameConstants.GMS ? c.getPlayer().getPetIndex((int) slea.readLong()) : slea.readInt();
slea.readInt();
PetHandler.PetChat(petid, slea.readShort(), slea.readMapleAsciiString(), c.getPlayer());
}
break;
case PET_COMMAND:
MaplePet pet = null;
if (GameConstants.GMS) {
pet = c.getPlayer().getPet(c.getPlayer().getPetIndex((int) slea.readLong()));
} else {
pet = c.getPlayer().getPet((byte) slea.readInt());
}
slea.readByte();
if (pet == null) {
return;
}
PetHandler.PetCommand(pet, PetDataFactory.getPetCommand(pet.getPetItemId(), slea.readByte()), c, c.getPlayer());
break;
case PET_FOOD:
PetHandler.PetFood(slea, c, c.getPlayer());
break;
case PET_LOOT:
InventoryHandler.Pickup_Pet(slea, c, c.getPlayer());
break;
case PET_AUTO_POT:
PetHandler.Pet_AutoPotion(slea, c, c.getPlayer());
break;
case MONSTER_CARNIVAL:
MonsterCarnivalHandler.MonsterCarnival(slea, c);
break;
case DUEY_ACTION:
DueyHandler.DueyOperation(slea, c);
break;
case USE_HIRED_MERCHANT:
HiredMerchantHandler.UseHiredMerchant(c, true);
break;
case MERCH_ITEM_STORE:
HiredMerchantHandler.MerchantItemStore(slea, c);
break;
case CANCEL_DEBUFF:
break;
case MAPLETV:
break;
case REPAIR:
NPCHandler.repair(slea, c);
break;
case REPAIR_ALL:
NPCHandler.repairAll(c);
break;
case GAME_POLL:
UserInterfaceHandler.InGame_Poll(slea, c);
break;
case OWL:
InventoryHandler.Owl(slea, c);
break;
case OWL_WARP:
InventoryHandler.OwlWarp(slea, c);
break;
case USE_OWL_MINERVA:
InventoryHandler.OwlMinerva(slea, c);
break;
case RPS_GAME:
NPCHandler.RPSGame(slea, c);
break;
case UPDATE_QUEST:
NPCHandler.UpdateQuest(slea, c);
break;
case USE_ITEM_QUEST:
NPCHandler.UseItemQuest(slea, c);
break;
case FOLLOW_REQUEST:
PlayersHandler.FollowRequest(slea, c);
break;
case AUTO_FOLLOW_REPLY:
case FOLLOW_REPLY:
PlayersHandler.FollowReply(slea, c);
break;
case RING_ACTION:
PlayersHandler.RingAction(slea, c);
break;
case REQUEST_FAMILY:
FamilyHandler.RequestFamily(slea, c);
break;
case OPEN_FAMILY:
FamilyHandler.OpenFamily(slea, c);
break;
case FAMILY_OPERATION:
FamilyHandler.FamilyOperation(slea, c);
break;
case DELETE_JUNIOR:
FamilyHandler.DeleteJunior(slea, c);
break;
case DELETE_SENIOR:
FamilyHandler.DeleteSenior(slea, c);
break;
case USE_FAMILY:
FamilyHandler.UseFamily(slea, c);
break;
case FAMILY_PRECEPT:
FamilyHandler.FamilyPrecept(slea, c);
break;
case FAMILY_SUMMON:
FamilyHandler.FamilySummon(slea, c);
break;
case ACCEPT_FAMILY:
FamilyHandler.AcceptFamily(slea, c);
break;
case SOLOMON:
PlayersHandler.Solomon(slea, c);
break;
case GACH_EXP:
PlayersHandler.GachExp(slea, c);
break;
case PARTY_SEARCH_START:
PartyHandler.MemberSearch(slea, c);
break;
case PARTY_SEARCH_STOP:
PartyHandler.PartySearch(slea, c);
break;
case EXPEDITION_LISTING:
PartyHandler.PartyListing(slea, c);
break;
case EXPEDITION_OPERATION:
PartyHandler.Expedition(slea, c);
break;
case USE_TELE_ROCK:
InventoryHandler.TeleRock(slea, c);
break;
case INNER_CIRCULATOR:
InventoryHandler.useInnerCirculator(slea, c);
break;
case PAM_SONG:
InventoryHandler.PamSong(slea, c);
break;
case RESET_CORE_AURA:
InventoryHandler.ResetCoreAura(slea.readInt(), c, c.getPlayer());
break;
case REPORT:
break;
case CANCEL_OUT_SWIPE:
slea.readInt();
break;
case VIEW_SKILLS:
PlayersHandler.viewSkills(slea, c);
break;
case SKILL_SWIPE:
PlayersHandler.StealSkill(slea, c);
break;
case CHOOSE_SKILL:
PlayersHandler.ChooseSkill(slea, c);
break;
case MAGIC_WHEEL:
System.out.println(new StringBuilder().append("[MAGIC_WHEEL] [").append(slea.toString()).append("]").toString());
byte mode = slea.readByte();
if (mode == 2) {
int idk = slea.readInt();
short toUseSlot = (short) slea.readInt();
tokenId = slea.readInt();
}
break;
default:
System.out.println(new StringBuilder().append("[UNHANDLED] Recv [").append(header.toString()).append("] found").toString());
}
}
}