- Joined
- Nov 14, 2008
- Messages
- 1,025
- Reaction score
- 641
I know that it might not be too helpful to anyone but i'm known for sucking alot of cocks when that's not true at all and i'm able to update and i want to prove wrong to those faggots.
handler wise it should be easy. if i forgot anything that you wish to have tell me.
getServerList
getCharList
addCharEntry
addCharStats
addCharLook
getServerIp
now the interserver stuff
getCharInfo
addCharacterInfo
addInventoryInfo
addItemInfo
addSkillInfo
addQuestInfo
addRingInfo
addTeleportInfo
addMonsterBookInfo
addAreaInfo
addCapturedInfo (didn't touch this yet, in case any change occured to it from v97 to v110)
enjoy
might not work with a demon slayer but you should be able to get ingame with an explorer or something
handler wise it should be easy. if i forgot anything that you wish to have tell me.
getServerList
PHP:
public static MaplePacket getServerList(byte serverId, String serverName, Map<Integer, Integer> channelLoad) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.SERVERLIST.getValue());
mplew.write(serverId);
mplew.writeMapleAsciiString(serverName);
mplew.write(ServerConstants.FLAG);
mplew.writeMapleAsciiString(ServerConstants.EVENT_MESSAGE);
mplew.write(0x64); // rate modifier, don't ask O.O!
mplew.write(0x0); // event xp * 2.6 O.O!
mplew.write(0x64); // rate modifier, don't ask O.O!
mplew.writeShort(0); // drop rate * 2.6
int lastChannel = 1;
Set<Integer> channels = channelLoad.keySet();
for (int i = 30; i > 0; i--) {
if (channels.contains(i)) {
lastChannel = i;
break;
}
}
mplew.write(lastChannel);
int load;
for (int i = 1; i <= lastChannel; i++) {
if (channels.contains(i)) {
load = channelLoad.get(i);
} else {
load = 1200;
}
mplew.writeMapleAsciiString(serverName + "-" + i);
mplew.writeInt(load);
mplew.write(serverId);
mplew.writeShort(i - 1);
}
mplew.write0(6); //int + short whatever that is
return mplew.getPacket();
}
getCharList
PHP:
public static MaplePacket getCharList(final boolean secondpw, final List<MapleCharacter> chars, int charslots) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.CHARLIST.getValue());
mplew.write(0);
mplew.write((byte) chars.size());
for (final MapleCharacter chr : chars) {
addCharEntry(mplew, chr, false, false);
}
mplew.write(1);
mplew.write(0); //v109.2 (my guess: some black cipher related stuff since its all that was added in .2)
mplew.writeInt(charslots);
mplew.writeInt(0);
System.out.println(mplew.toString());
return mplew.getPacket();
}
addCharEntry
PHP:
private static void addCharEntry(final MaplePacketLittleEndianWriter mplew, final MapleCharacter chr, boolean ranking, boolean viewall) {
PacketHelper.addCharStats(mplew, chr);
PacketHelper.addCharLook(mplew, chr, false);
if (chr.getJob().getId() % 1000 >= 800) {
mplew.writeShort(0);
return;
}
if (!viewall) {
mplew.writeShort(0);
}
mplew.write(1);
mplew.writeLong(0); //useless ranking poop
mplew.writeLong(0); //useless ranking poop
/*if (ranking) {
mplew.writeInt(chr.getRank());
mplew.writeInt(chr.getRankMove());
mplew.writeInt(chr.getJobRank());
mplew.writeInt(chr.getJobRankMove());
}*/
}
addCharStats
PHP:
public static void addCharStats(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
if (chr.isDemonSlayer()) {
mplew.writeInt(0);
}
mplew.writeInt(chr.getId());
mplew.writeAsciiString(chr.getName(), 13);
mplew.write(chr.getGender());
mplew.write(chr.getSkinColor().getId());
mplew.writeInt(chr.getFace());
mplew.writeInt(chr.getHair());
for (int i = 0; i < 3; i++) {
if (chr.getPet(i) != null) {
mplew.writeLong(chr.getPet(i).getUniqueId());
} else {
mplew.writeLong(0);
}
}
mplew.write(chr.getLevel());
mplew.writeShort(chr.getJob().getId());
mplew.writeShort(chr.getStr());
mplew.writeShort(chr.getDex());
mplew.writeShort(chr.getInt());
mplew.writeShort(chr.getLuk());
mplew.writeInt(chr.getHp());
mplew.writeInt(chr.getMaxHp());
mplew.writeInt(chr.getMp());
mplew.writeInt(chr.getMaxMp());
mplew.writeShort(chr.getRemainingAp());
if (MapleJob.isExtendSPJob(chr.getJobId())) {
chr.getSPTable().addSPData(mplew);
} else {
//mplew.writeShort(chr.getRemainingSp());
mplew.writeShort(0); //remaining sps. not needed in high rate with skill maxer :S
}
mplew.writeInt(chr.getExp());
mplew.writeInt(chr.getFame());
mplew.writeInt(0); //big penis
mplew.writeInt(chr.getMapId());
mplew.write(chr.getInitialSpawnpoint());
mplew.writeInt(0);//time played in seconds
mplew.writeShort(0);//chr.getSpecialJobType()); //1 = db, 2 = cannoneer
if (chr.isDemonSlayer()) {
mplew.writeInt(0);
}
mplew.write(0); //chr.getFatigue()
mplew.writeInt(Integer.parseInt(new SimpleDateFormat("yyyyMMddHH").format(Calendar.getInstance().getTime())));
//MapleTraits t = chr.getTraits();
mplew.writeInt(0); //t.getAmbition()
mplew.writeInt(0); //t.getInsight()
mplew.writeInt(0); //t.getWillpower());
mplew.writeInt(0); //t.getDiligence());
mplew.writeInt(0); //t.getEmpathy());
mplew.writeInt(0); //t.getCharm());
mplew.writeShort(0); //t.getTodaysAmbition());
mplew.writeShort(0); //t.getTodaysInsight());
mplew.writeShort(0); //t.getTodaysWillpower());
mplew.writeShort(0); //t.getTodaysDiligence());
mplew.writeShort(0); //t.getTodaysEmpathy());
mplew.writeShort(0); //t.getTodaysCharm());
mplew.writeInt(0); //chr.getbattleexp
mplew.write(0); //chr.getbattlerank
mplew.writeInt(0); //chr.getbattlepoints
mplew.write(5); //unk
mplew.writeInt(0); //unk
mplew.writeLong(0); //useless fuckery that has to do with time i think
}
addCharLook
PHP:
public static void addCharLook(final MaplePacketLittleEndianWriter mplew, final MapleCharacter chr, final boolean mega) {
mplew.write(chr.getGender());
mplew.write(chr.getSkinColor().getId());
mplew.writeInt(chr.getFace());
mplew.writeShort(chr.getJob().getId());
mplew.write(mega ? 1 : 0);
mplew.writeShort(0);
mplew.writeInt(chr.getHair());
final Map<Byte, Integer> myEquip = new LinkedHashMap<>();
final Map<Byte, Integer> maskedEquip = new LinkedHashMap<>();
MapleInventory equip = chr.getInventory(MapleInventoryType.EQUIPPED);
for (final IItem item : equip.list()) {
if (item.getPosition() < -128) { //not visible
continue;
}
byte pos = (byte) (item.getPosition() * -1);
if (pos < 100 && myEquip.get(pos) == null) {
myEquip.put(pos, item.getItemId());
} else if ((pos > 100 || pos == -128) && pos != 111) {
pos = (byte) (pos == -128 ? 28 : pos - 100);
if (myEquip.get(pos) != null) {
maskedEquip.put(pos, myEquip.get(pos));
}
myEquip.put(pos, item.getItemId());
} else if (myEquip.get(pos) != null) {
maskedEquip.put(pos, item.getItemId());
}
}
for (final Entry<Byte, Integer> entry : myEquip.entrySet()) {
mplew.write(entry.getKey());
mplew.writeInt(entry.getValue());
}
mplew.write(0xFF); // end of visible itens
// masked itens
for (final Entry<Byte, Integer> entry : maskedEquip.entrySet()) {
mplew.write(entry.getKey());
mplew.writeInt(entry.getValue());
}
mplew.write(0xFF); // ending markers
final IItem cWeapon = equip.getItem((byte) -111);
mplew.writeInt(cWeapon != null ? cWeapon.getItemId() : 0);
for (int i = 0; i < 3; i++) {
if (chr.getPet(i) != null) {
mplew.writeInt(chr.getPet(i).getPetId());
} else {
mplew.writeInt(0);
}
}
mplew.write(0); //mercedes ears o.o?
if (chr.isDemonSlayer()) {
mplew.writeInt(0);
}
}
getServerIp
PHP:
public static MaplePacket getServerIP(InetAddress inetAddr, int port, int clientId) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.SERVER_IP.getValue());
mplew.writeShort(0);
byte[] addr = inetAddr.getAddress();
mplew.write(addr);
mplew.writeShort(port);
mplew.writeInt(clientId);
mplew.write0(10);
return mplew.getPacket();
}
now the interserver stuff
getCharInfo
PHP:
public static MaplePacket getCharInfo(MapleCharacter chr) {
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.WARP_TO_MAP.getValue());
mplew.writeShort(2);
mplew.writeLong(1);
mplew.writeLong(2);
mplew.writeInt(chr.getClient().getChannel() - 1);
mplew.writeInt(0);
mplew.write(0);
mplew.write(1);
mplew.writeShort(0); //unk
mplew.writeShort(0); //unk
mplew.write(1); //unk
mplew.writeShort(0); //unk
for (int i = 0; i < 3; i++) {
mplew.writeInt(Randomizer.nextInt());
}
addCharacterInfo(mplew, chr);
mplew.write0(70); //alot of unknow poop that doesn't matter
mplew.write(1); //don't ask. if its a 0, you get error 38...
mplew.write0(20);
mplew.writeLong(getTime(System.currentTimeMillis()));
mplew.write(100);
mplew.writeInt(0);
mplew.write(1);
return mplew.getPacket();
}
addCharacterInfo
PHP:
private static void addCharacterInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
mplew.writeInt(-1);
mplew.writeInt(-3);
mplew.write0(7);
PacketHelper.addCharStats(mplew, chr);
mplew.write(chr.getBuddylist().getCapacity());
mplew.write(0); //if null = 0 else byte 1 + mapleAsciiString
mplew.write(0); //if null = 0 else byte 1 + mapleAsciiString
mplew.write(0); //if null = 0 else byte 1 + mapleAsciiString
addInventoryInfo(mplew, chr);
mplew.writeInt(0);
addSkillInfo(mplew, chr);
addQuestInfo(mplew, chr);
mplew.writeShort(0);
addRingInfo(mplew, chr);
addTeleportInfo(mplew, chr);
addMonsterBookInfo(mplew, chr);
mplew.writeShort(0);
addAreaInfo(mplew, chr);
if (chr.getJob().isA(MapleJob.WILDHUNTER1) || chr.getJob().isA(MapleJob.WILDHUNTER2) || chr.getJob().isA(MapleJob.WILDHUNTER3) || chr.getJob().isA(MapleJob.WILDHUNTER4)) {
addCapturedInfo(mplew, (byte) 0, chr);
}
mplew.writeShort(0);
mplew.writeShort(0);
mplew.writeShort(0);
}
addInventoryInfo
PHP:
private static void addInventoryInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
mplew.writeInt(chr.getMeso());
mplew.writeInt(0);
for (byte i = 1; i <= 5; i++) {
mplew.write(chr.getInventory(MapleInventoryType.getByType(i)).getSlotLimit());
}
mplew.write(new byte[]{0, 64, -32, -3, 59, 55, 79, 1});
MapleInventory iv = chr.getInventory(MapleInventoryType.EQUIPPED);
Collection<IItem> equippedC = iv.list();
List<Item> equipped = new ArrayList<Item>(equippedC.size());
List<Item> equippedCash = new ArrayList<Item>(equippedC.size());
for (IItem item : equippedC) {
if (item.getPosition() <= -100) {
equippedCash.add((Item) item);
} else {
equipped.add((Item) item);
}
}
Collections.sort(equipped);
for (Item item : equipped) {
addItemInfo(mplew, item);
}
mplew.write(0);
for (Item item : equippedCash) {
addItemInfo(mplew, item);
}
mplew.write(0);
for (IItem item : chr.getInventory(MapleInventoryType.EQUIP).list()) {
addItemInfo(mplew, item);
}
mplew.write(0);
mplew.writeShort(0);
mplew.writeShort(0); // Dragon Equipements
mplew.writeShort(0); // Mechanical Equipments
mplew.writeShort(0);
for (IItem item : chr.getInventory(MapleInventoryType.USE).list()) {
addItemInfo(mplew, item);
}
mplew.write(0);
for (IItem item : chr.getInventory(MapleInventoryType.SETUP).list()) {
addItemInfo(mplew, item);
}
mplew.write(0);
for (IItem item : chr.getInventory(MapleInventoryType.ETC).list()) {
//addItemInfo(mplew, item);
}
mplew.write(0);
for (IItem item : chr.getInventory(MapleInventoryType.CASH).list()) {
addItemInfo(mplew, item);
}
mplew.write(0);
mplew.write(0);
mplew.writeInt(-1);
mplew.writeInt(0);
}
addItemInfo
PHP:
private static void addItemInfo(MaplePacketLittleEndianWriter mplew, IItem item, boolean zeroPosition, boolean inTrade) {
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
boolean isCash = ii.isCash(item.getItemId());
boolean isPet = item.getPetId() > -1;
boolean isRing = false;
IEquip equip = null;
byte pos = item.getPosition();
if (item.getType() == 1) {
equip = (IEquip) item;
isRing = equip.getRingId() > -1;
}
if (!zeroPosition) {
if (equip != null) {
if (pos < 0) {
pos = (byte) (pos * -1);
}
mplew.writeShort(pos > 100 ? pos - 100 : pos);
} else {
mplew.write(pos);
}
}
mplew.write(item.getType());
mplew.writeInt(item.getItemId());
mplew.write(isCash ? 1 : 0);
if (isCash) {
mplew.writeLong(item.getCashId());
}
mplew.write(0); //unk
mplew.write(ITEM_MAGIC); //experation time - start
mplew.write(NON_EXPIRE2); // Note: too lazy to make a new method for expiration time :D
mplew.writeInt(-1); // expiration time - end
if (isPet) {
MaplePet pet = item.getPet();
mplew.writeAsciiString(StringUtil.getRightPaddedStr(pet.getName(), '\000', 13));
mplew.write(pet.getLevel());
mplew.writeShort(pet.getCloseness());
mplew.write(pet.getFullness());
addExpirationTime(mplew, item.getExpiration());
mplew.writeInt(0);
mplew.write(new byte[]{80, 70});
mplew.writeInt(0);
return;
}
if (equip == null) {
mplew.writeShort(item.getQuantity());
mplew.writeMapleAsciiString(item.getOwner());
mplew.writeShort(item.getFlag());
if (ItemConstants.isRechargable(item.getItemId())) {
mplew.writeInt(2);
mplew.write(new byte[]{84, 0, 0, 52});
}
return;
}
mplew.write(equip.getUpgradeSlots());
mplew.write(equip.getLevel());
mplew.writeShort(equip.getStr());
mplew.writeShort(equip.getDex());
mplew.writeShort(equip.getInt());
mplew.writeShort(equip.getLuk());
mplew.writeShort(equip.getHp());
mplew.writeShort(equip.getMp());
mplew.writeShort(equip.getWatk());
mplew.writeShort(equip.getMatk());
mplew.writeShort(equip.getWdef());
mplew.writeShort(equip.getMdef());
mplew.writeShort(equip.getAcc());
mplew.writeShort(equip.getAvoid());
mplew.writeShort(equip.getHands());
mplew.writeShort(equip.getSpeed());
mplew.writeShort(equip.getJump());
mplew.writeMapleAsciiString(equip.getOwner());
mplew.writeShort(equip.getFlag());
mplew.write(0);
mplew.write(equip.getItemLevel());
mplew.writeShort(0);
mplew.writeShort(equip.getItemExp());
mplew.writeInt(-1); //Item durability
mplew.writeInt(equip.getVicious());
mplew.writeShort(0);
mplew.write(equip.isPotentialByte());
mplew.write(equip.getStarsByte());
mplew.writeShort(equip.getPotentialStats(1)); //rare
mplew.writeShort(equip.getPotentialStats(2)); //epic
mplew.writeShort(equip.getPotentialStats(3)); //unique
mplew.writeShort(equip.getPotentialStats(4)); //TODO: legendary
mplew.writeShort(0); //HpR
mplew.writeShort(0); //MpR
if (!isCash) {
mplew.writeLong(-1);
}
mplew.writeLong(getTime(-2));
mplew.writeInt(-1);
}
addSkillInfo
PHP:
private static void addSkillInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
mplew.write(0);
mplew.write(1);
final Map<ISkill, SkillEntry> skills = chr.getSkills();
mplew.writeShort(skills.size());
for (final Entry<ISkill, SkillEntry> skill : skills.entrySet()) {
mplew.writeInt(((ISkill) skill.getKey()).getId());
if (((ISkill) skill.getKey()).getId() >= 92000000) {
mplew.writeShort(63);
mplew.write(0);
mplew.write(((MapleCharacter.SkillEntry) skill.getValue()).skillevel);
addExpirationTime(mplew, ((MapleCharacter.SkillEntry) skill.getValue()).expiration);
} else {
mplew.writeInt(((MapleCharacter.SkillEntry) skill.getValue()).skillevel);
addExpirationTime(mplew, ((MapleCharacter.SkillEntry) skill.getValue()).expiration);
if (((ISkill) skill.getKey()).isFourthJob()) {
mplew.writeInt(((MapleCharacter.SkillEntry) skill.getValue()).masterlevel);
}
}
}
mplew.writeShort(chr.getAllCooldowns().size());
for (PlayerCoolDownValueHolder cooling : chr.getAllCooldowns()) {
mplew.writeInt(cooling.skillId);
int timeLeft = (int) (cooling.length + cooling.startTime - System.currentTimeMillis());
mplew.writeInt(timeLeft / 1000);
}
}
addQuestInfo
PHP:
private static void addQuestInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
mplew.write(1);
mplew.writeShort(chr.getStartedQuestsSize());
for (MapleQuestStatus q : chr.getStartedQuests()) {
mplew.writeShort(q.getQuest().getId());
mplew.writeMapleAsciiString(q.getQuestData());
if (q.getQuest().getInfoNumber() > 0) {
mplew.writeShort(q.getQuest().getInfoNumber());
mplew.writeMapleAsciiString(Integer.toString(q.getMedalProgress()));
}
}
List<MapleQuestStatus> completed = chr.getCompletedQuests();
mplew.writeShort(0);
mplew.write(1);
mplew.writeShort(completed.size());
for (MapleQuestStatus q : completed) {
mplew.writeShort(q.getQuest().getId());
int time = getQuestTimestamp(q.getCompletionTime());
mplew.writeInt(time);
mplew.writeInt(time);
}
}
addRingInfo
PHP:
private static void addRingInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
mplew.writeShort(chr.getCrushRings().size());
for (MapleRing ring : chr.getCrushRings()) {
mplew.writeInt(ring.getPartnerChrId());
mplew.writeAsciiString(getRightPaddedStr(ring.getPartnerName(), '\000', 13));
mplew.writeInt(ring.getRingId());
mplew.writeInt(0);
mplew.writeInt(ring.getPartnerRingId());
mplew.writeInt(0);
}
mplew.writeShort(chr.getFriendshipRings().size());
for (MapleRing ring : chr.getFriendshipRings()) {
mplew.writeInt(ring.getPartnerChrId());
mplew.writeAsciiString(getRightPaddedStr(ring.getPartnerName(), '\000', 13));
mplew.writeInt(ring.getRingId());
mplew.writeInt(0);
mplew.writeInt(ring.getPartnerRingId());
mplew.writeInt(0);
mplew.writeInt(ring.getItemId());
}
mplew.writeShort(chr.getMarriageRing() != null ? 1 : 0);
int marriageId = 30000;
if (chr.getMarriageRing() != null) {
mplew.writeInt(marriageId);
mplew.writeInt(chr.getId());
mplew.writeInt(chr.getMarriageRing().getPartnerChrId());
mplew.writeShort(3);
mplew.writeInt(chr.getMarriageRing().getRingId());
mplew.writeInt(chr.getMarriageRing().getPartnerRingId());
mplew.writeAsciiString(getRightPaddedStr(chr.getName(), '\000', 13));
mplew.writeAsciiString(getRightPaddedStr(chr.getMarriageRing().getPartnerName(), '\000', 13));
}
}
addTeleportInfo
PHP:
private static void addTeleportInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
int[] tele = chr.getTrockMaps();
int[] viptele = chr.getVipTrockMaps();
for (int i = 0; i < 5; i++) {
//mplew.writeInt(tele[i]);
mplew.writeInt(999999999);
}
for (int i = 0; i < 10; i++) {
//mplew.writeInt(viptele[i]);
mplew.writeInt(999999999);
}
for (int i = 0; i < 13; i++) {
mplew.writeInt(999999999);
}
for (int i = 0; i < 13; i++) {
mplew.writeInt(999999999);
}
}
addMonsterBookInfo
PHP:
private static void addMonsterBookInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
mplew.writeInt(chr.getMonsterBookCover()); //monster book cover
mplew.write(0);
Map<Integer, Integer> cards = chr.getMonsterBook().getCards();
mplew.writeShort(cards.size());
for (Entry<Integer, Integer> all : cards.entrySet()) {
mplew.writeShort(all.getKey() % 10000); // 아이디
mplew.write(all.getValue()); // 레벨
}
mplew.writeInt(-1);
mplew.writeShort(0);
}
addAreaInfo
PHP:
private static void addAreaInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
Map<Short, String> areaInfos = chr.getAreaInfos();
mplew.writeShort(areaInfos.size());
for (Short area : areaInfos.keySet()) {
mplew.writeShort(area.shortValue());
mplew.writeMapleAsciiString((String) areaInfos.get(area));
}
}
addCapturedInfo (didn't touch this yet, in case any change occured to it from v97 to v110)
PHP:
public static MaplePacket addCapturedInfo(MaplePacketLittleEndianWriter mplew, byte id, MapleCharacter chr) {
mplew.write(id);
for (int i = 0; i < 5; i++) {
mplew.writeInt(0);
}
return mplew.getPacket();
}
enjoy
might not work with a demon slayer but you should be able to get ingame with an explorer or something
Last edited: