package tools.packet;
import client.MapleCharacter;
import client.MapleClient;
import client.PartTimeJob;
import constants.GameConstants;
import constants.JobConstants;
import constants.JobConstants.LoginJob;
import constants.ServerConfig;
import constants.ServerConstants;
import constants.WorldConstants.WorldOption;
import handling.SendPacketOpcode;
import handling.login.LoginServer;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import server.Randomizer;
import tools.HexTool;
import tools.Triple;
import tools.data.MaplePacketLittleEndianWriter;
public class LoginPacket {
public static byte[] getHello(short mapleVersion, byte[] sendIv, byte[] recvIv) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(14);
mplew.writeShort(mapleVersion);
mplew.writeMapleAsciiString(ServerConstants.MAPLE_PATCH);
if (ServerConfig.USE_FIXED_IV) {
mplew.write(HexTool.getByteArrayFromHexString("66 75 63 6B 79 6F 75 21"));
} else {
mplew.write(recvIv);
mplew.write(sendIv);
}
mplew.write(8);
return mplew.getPacket();
}
public static final byte[] getPing() {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(2);
mplew.writeShort(SendPacketOpcode.PING.getValue());
return mplew.getPacket();
}
public static byte[] getAuthSuccessRequest(MapleClient client) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.LOGIN_STATUS.getValue());
mplew.write(0);
mplew.write(0);
mplew.writeInt(0);
mplew.writeInt(client.getAccID());
mplew.writeZeroBytes(9); //gm stuff and new int
mplew.writeMapleAsciiString(client.getAccountName());
mplew.writeLong(0);
mplew.writeShort(0);
mplew.writeLong(0);
mplew.writeInt(0x2E); //random shit
// Jobs
mplew.write(JobConstants.enableJobs ? 1 : 0); //toggle
mplew.write(JobConstants.jobOrder); //Job Order (orders are located in wz)
for (LoginJob j : LoginJob.values()) {
mplew.write(j.getFlag());
}
mplew.write(1);
mplew.write(4);
// End of Jobs
mplew.writeLong(0); // Create date
return mplew.getPacket();
}
public static final byte[] getLoginFailed(int reason) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(16);
mplew.writeShort(SendPacketOpcode.LOGIN_STATUS.getValue());
mplew.write(reason);
mplew.write(0);
mplew.writeInt(0);
return mplew.getPacket();
}
/*
* location: UI.wz/Login.img/Notice/text
* reasons:
* useful:
* 32 - server under maintenance check site for updates
* 35 - your computer is running thirdy part programs close them and play again
* 36 - due to high population char creation has been disabled
* 43 - revision needed your ip is temporary blocked
* 75-78 are cool for auto register
*/
public static byte[] getPermBan(byte reason) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(16);
mplew.writeShort(SendPacketOpcode.LOGIN_STATUS.getValue());
mplew.write(2);
mplew.write(0);
mplew.writeInt(0);
mplew.writeShort(reason);
mplew.write(HexTool.getByteArrayFromHexString("01 01 01 01 00"));
return mplew.getPacket();
}
public static byte[] getTempBan(long timestampTill, byte reason) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(17);
mplew.writeShort(SendPacketOpcode.LOGIN_STATUS.getValue());
mplew.write(2);
mplew.write(0);
mplew.writeInt(0);
mplew.write(reason);
mplew.writeLong(timestampTill);
return mplew.getPacket();
}
public static byte[] sendPicResponse(int response) {
MaplePacketLittleEndianWriter packet = new MaplePacketLittleEndianWriter();
packet.writeShort(SendPacketOpcode.PIC_RESPONSE.getValue());
packet.write(response);
return packet.getPacket();
}
public static final byte[] getSecondAuthSuccess(MapleClient client) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.LOGIN_SECOND.getValue());
mplew.write(0);
mplew.writeInt(client.getAccID());
mplew.writeZeroBytes(5);
mplew.writeMapleAsciiString(client.getAccountName());
mplew.writeLong(2L);
mplew.writeZeroBytes(3);
mplew.writeInt(Randomizer.nextInt());
mplew.writeInt(Randomizer.nextInt());
mplew.writeInt(28);
mplew.writeInt(Randomizer.nextInt());
mplew.writeInt(Randomizer.nextInt());
mplew.write(1);
return mplew.getPacket();
}
public static final byte[] deleteCharResponse(int cid, int state) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.DELETE_CHAR_RESPONSE.getValue());
mplew.writeInt(cid);
mplew.write(state);
return mplew.getPacket();
}
public static byte[] secondPwError(byte mode) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(3);
mplew.writeShort(SendPacketOpcode.SECONDPW_ERROR.getValue());
mplew.write(0);
return mplew.getPacket();
}
public static byte[] sendAuthResponse(int response) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.AUTH_RESPONSE.getValue());
mplew.writeInt(response);
return mplew.getPacket();
}
public static byte[] enableRecommended(int world) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.ENABLE_RECOMMENDED.getValue());
mplew.writeInt(world);
return mplew.getPacket();
}
public static byte[] sendRecommended(int world, String message) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.SEND_RECOMMENDED.getValue());
mplew.write(message != null ? 1 : 0);
if (message != null) {
mplew.writeInt(world);
mplew.writeMapleAsciiString(message);
}
return mplew.getPacket();
}
public static byte[] ResetScreen() {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.RESET_SCREEN.getValue());
mplew.write(HexTool.getByteArrayFromHexString("02 08 00 32 30 31 32 30 38 30 38 00 08 00 32 30 31 32 30 38 31 35 00"));
return mplew.getPacket();
}
public static byte[] getServerList(int serverId, Map<Integer, Integer> channelLoad) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.SERVERLIST.getValue());
mplew.write(serverId);
String worldName = LoginServer.getTrueServerName();
mplew.writeMapleAsciiString(worldName);
mplew.write(WorldOption.getById(serverId).getFlag());
mplew.writeMapleAsciiString(LoginServer.getEventMessage());
mplew.writeShort(100);
mplew.writeShort(100);
mplew.write(0);
int lastChannel = 1;
Set<Integer> channels = channelLoad.keySet();
for (int i = 30; i > 0; i--) {
if (channels.contains(Integer.valueOf(i))) {
lastChannel = i;
break;
}
}
mplew.write(lastChannel);
for (int i = 1; i <= lastChannel; i++) {
int load;
if (channels.contains(i)) {
load = channelLoad.get(i);
} else {
load = 1200;
}
mplew.writeMapleAsciiString(worldName + "-" + i);
mplew.writeInt(load);
mplew.write(serverId);
mplew.writeShort(i - 1);
}
mplew.writeShort(0);
mplew.writeInt(0);
mplew.write(0);
return mplew.getPacket();
}
public static byte[] getEndOfServerList() {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.SERVERLIST.getValue());
mplew.write(0xFF);
mplew.write(0); //boolean disable cash shop and trade msg
return mplew.getPacket();
}
public static final byte[] getLoginWelcome() {
List flags = new LinkedList();
return CField.spawnFlags(flags);
}
public static byte[] getServerStatus(int status) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.SERVERSTATUS.getValue());
mplew.writeShort(status);
return mplew.getPacket();
}
public static byte[] changeBackground(List<Triple<String, Integer, Boolean>> backgrounds) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.CHANGE_BACKGROUND.getValue());
mplew.write(backgrounds.size()); //number of bgs
for (Triple<String, Integer, Boolean> background : backgrounds) {
mplew.writeMapleAsciiString(background.getLeft());
mplew.write(background.getRight() ? Randomizer.nextInt(2) : background.getMid());
}
/* Map.wz/Obj/login.img/WorldSelect/background/background number
Backgrounds ids sometime have more than one background anumation */
/* Background are like layers, backgrounds in the packets are
removed, so the background which was hiden by the last one
is shown.
*/
return mplew.getPacket();
}
public static byte[] getChannelSelected() {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.CHANNEL_SELECTED.getValue());
mplew.writeZeroBytes(3);
return mplew.getPacket();
}
public static byte[] getCharList(String secondpw, List<MapleCharacter> chars, int charslots) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.CHARLIST.getValue());
mplew.write(0);
mplew.write(chars.size());
for (MapleCharacter chr : chars) {
addCharEntry(mplew, chr, (!chr.isGM()) && (chr.getLevel() >= 30), false);
}
mplew.write((secondpw != null) && (secondpw.length() <= 0) ? 2 : (secondpw != null) && (secondpw.length() > 0) ? 1 : 0);
mplew.write(0);
mplew.writeInt(charslots);
mplew.writeInt(0);
mplew.writeInt(-1);
mplew.writeReversedLong(PacketHelper.getTime(System.currentTimeMillis()));
mplew.writeZeroBytes(5);
return mplew.getPacket();
}
public static byte[] addNewCharEntry(MapleCharacter chr, boolean worked) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.ADD_NEW_CHAR_ENTRY.getValue());
mplew.write(worked ? 0 : 1);
addCharEntry(mplew, chr, false, false);
return mplew.getPacket();
}
public static byte[] charNameResponse(String charname, boolean nameUsed) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.CHAR_NAME_RESPONSE.getValue());
mplew.writeMapleAsciiString(charname);
mplew.write(nameUsed ? 1 : 0);
return mplew.getPacket();
}
private static void addCharEntry(MaplePacketLittleEndianWriter mplew, MapleCharacter chr, boolean ranking, boolean viewAll) {
PacketHelper.addCharStats(mplew, chr);
PacketHelper.addCharLook(mplew, chr, true, false);
if (GameConstants.isZero(chr.getJob())) {
PacketHelper.addCharLook(mplew, chr, true, true);
}
if (!viewAll) {
mplew.write(0);
}
mplew.write(ranking ? 1 : 0);
if (ranking) {
mplew.writeInt(chr.getRank());
mplew.writeInt(chr.getRankMove());
mplew.writeInt(chr.getJobRank());
mplew.writeInt(chr.getJobRankMove());
}
}
public static byte[] enableSpecialCreation(int accid, boolean enable) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.SPECIAL_CREATION.getValue());
mplew.writeInt(accid);
mplew.write(enable ? 0 : 1);
mplew.write(0);
return mplew.getPacket();
}
public static byte[] partTimeJob(int cid, short type, long time) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.PART_TIME.getValue());
mplew.writeInt(cid);
mplew.write(0);
mplew.write(type);
//1) 0A D2 CD 01 70 59 9F EA
//2) 0B D2 CD 01 B0 6B 9C 18
mplew.writeReversedLong(PacketHelper.getTime(time));
mplew.writeInt(0);
mplew.write(0);
return mplew.getPacket();
}
public static byte[] updatePartTimeJob(PartTimeJob partTime) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(21);
mplew.writeShort(SendPacketOpcode.PART_TIME.getValue());
mplew.writeInt(partTime.getCharacterId());
mplew.write(0);
PacketHelper.addPartTimeJob(mplew, partTime);
return mplew.getPacket();
}
public static byte[] sendLink() {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendPacketOpcode.SEND_LINK.getValue());
mplew.write(1);
mplew.write(CField.Nexon_IP);
mplew.writeShort(0x2057);
mplew.write(0);
return mplew.getPacket();
}
}