I have been trying to fix marriage ring effect in MoopleDev v120 using other sources / repacks as reference and ended up with error code -21...... (invalid pointer), Error code 38, or nothing happens as I was tinkering with the packet. I'm using clean wz files and clean xml for the server. What happens is that neither 1st or 3rd person effect appear. I also have not checked if crush or friendship ring effect work, since I heard that moopledev has working ring effects. I'm not sure if the methods are wrong or if it could be just crush and friendship ring effect working, but all I know is that the server loads the ring information and sends it to the client, but it still doesn't display the effect at all, for the character wearing the rings or for anyone else around them. With what I have currently, I don't disconnect any more, and the rings have proper labels like engaged to ... or married to ..., and character profile also display the heart to show that your married, but the only problem I have left is just this.
Anyway, it be great if someone can point out what is done incorrectly, or give out some suggestion on where to look, or what to do. Most of the stuff below are stuff I reverted back from the changes I made and some with little changed made that shouldn't effect the problem too much.
Current Methods:
addMarriageRingLook()
addRingLook()
spawnPlayerMapobject()
getCharInfo()
updateCharLook()
addRingInfo()
addItemInfo()
addCharacterInfo()
Anyway, it be great if someone can point out what is done incorrectly, or give out some suggestion on where to look, or what to do. Most of the stuff below are stuff I reverted back from the changes I made and some with little changed made that shouldn't effect the problem too much.
Current Methods:
addMarriageRingLook()
Code:
private static void addMarriageRingLook(final MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
if (chr.getMarriageRing() == null && !chr.getMarriageRing().equipped()) {
mplew.write(0);
return;
}
mplew.writeBool(chr.getMarriageRing() != null);
if (chr.getMarriageRing() != null) {
mplew.writeInt(chr.getId());
mplew.writeInt(chr.getMarriageRing().getPartnerChrId());
mplew.writeInt(chr.getMarriageRing().getRingId());
}
}
Code:
private static void addRingLook(final MaplePacketLittleEndianWriter mplew, MapleCharacter chr, boolean crush) {
List<MapleRing> rings;
if (crush) {
rings = chr.getCrushRings();
} else {
rings = chr.getFriendshipRings();
}
boolean yes = false;
for (MapleRing ring : rings) {
if (ring.equipped()) {
if (yes == false) {
yes = true;
mplew.write(1);
}
mplew.writeInt(ring.getRingId());
mplew.writeInt(0);
mplew.writeInt(ring.getPartnerRingId());
mplew.writeInt(0);
mplew.writeInt(ring.getItemId());
}
}
if (yes == false) {
mplew.write(0);
}
}
Code:
public static byte[] spawnPlayerMapobject(MapleCharacter chr) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.SPAWN_PLAYER.getValue());
mplew.writeInt(chr.getId());
mplew.write(chr.getLevel()); //v83
mplew.writeMapleAsciiString(chr.getName());
if (chr.getGuildId() < 1) {
mplew.writeMapleAsciiString("");
mplew.write(new byte[6]);
} else {
MapleGuildSummary gs = chr.getClient().getWorldServer().getGuildSummary(chr.getGuildId());
if (gs != null) {
mplew.writeMapleAsciiString(gs.getName());
mplew.writeShort(gs.getLogoBG());
mplew.write(gs.getLogoBGColor());
mplew.writeShort(gs.getLogo());
mplew.write(gs.getLogoColor());
} else {
mplew.writeMapleAsciiString("");
mplew.write(new byte[6]);
}
}
mplew.writeInt(0);
mplew.writeShort(0); //v83
mplew.write(0xFC);
mplew.write(1);
if (chr.getBuffedValue(MapleBuffStat.MORPH) != null) {
mplew.writeInt(2);
} else {
mplew.writeInt(0);
}
long buffmask = 0;
Integer buffvalue = null;
if (chr.getBuffedValue(MapleBuffStat.DARKSIGHT) != null && !chr.isHidden()) {
buffmask |= MapleBuffStat.DARKSIGHT.getValue();
}
if (chr.getBuffedValue(MapleBuffStat.COMBO) != null) {
buffmask |= MapleBuffStat.COMBO.getValue();
buffvalue = Integer.valueOf(chr.getBuffedValue(MapleBuffStat.COMBO).intValue());
}
if (chr.getBuffedValue(MapleBuffStat.SHADOWPARTNER) != null) {
buffmask |= MapleBuffStat.SHADOWPARTNER.getValue();
}
if (chr.getBuffedValue(MapleBuffStat.SOULARROW) != null) {
buffmask |= MapleBuffStat.SOULARROW.getValue();
}
if (chr.getBuffedValue(MapleBuffStat.MORPH) != null) {
buffvalue = Integer.valueOf(chr.getBuffedValue(MapleBuffStat.MORPH).intValue());
}
if (chr.getBuffedValue(MapleBuffStat.ENERGY_CHARGE) != null) {
buffmask |= MapleBuffStat.ENERGY_CHARGE.getValue();
buffvalue = Integer.valueOf(chr.getBuffedValue(MapleBuffStat.ENERGY_CHARGE).intValue());
}//AREN'T THESE
mplew.writeInt((int) ((buffmask >> 32) & 0xffffffffL));
if (buffvalue != null) {
if (chr.getBuffedValue(MapleBuffStat.MORPH) != null) { //TEST
mplew.writeShort(buffvalue);
} else {
mplew.write(buffvalue.byteValue());
}
}
mplew.writeInt((int) (buffmask & 0xffffffffL));
int CHAR_MAGIC_SPAWN = Randomizer.nextInt();
mplew.skip(6);
mplew.writeInt(CHAR_MAGIC_SPAWN);
mplew.skip(11);
mplew.writeInt(CHAR_MAGIC_SPAWN);//v74
mplew.skip(11);
mplew.writeInt(CHAR_MAGIC_SPAWN);
mplew.writeShort(0);
mplew.write(0);
final Item mount = chr.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -18);
if (chr.getBuffedValue(MapleBuffStat.MONSTER_RIDING) != null && mount != null) {
mplew.writeInt(mount.getItemId());
mplew.writeInt(1004);
} else {
mplew.writeLong(0);
}
mplew.writeInt(CHAR_MAGIC_SPAWN);
mplew.skip(9);
mplew.writeInt(CHAR_MAGIC_SPAWN);
mplew.writeShort(0);
mplew.writeInt(0); // actually not 0, why is it 0 then?
mplew.skip(10);
mplew.writeInt(CHAR_MAGIC_SPAWN);
mplew.skip(13);
mplew.writeInt(CHAR_MAGIC_SPAWN);
mplew.writeShort(0);
mplew.write(0);
mplew.writeShort(chr.getJob().getId());
addCharLook(mplew, chr, false);
mplew.writeInt(chr.getInventory(MapleInventoryType.CASH).countById(5110000));
mplew.writeInt(chr.getItemEffect());
mplew.writeInt(ItemConstants.getInventoryType(chr.getChair()) == MapleInventoryType.SETUP ? chr.getChair() : 0);
mplew.writePos(chr.getPosition());
mplew.write(chr.getStance());
mplew.writeShort(0);//chr.getFh()
mplew.writeBool(chr.isGM());
MaplePet[] pet = chr.getPets();
for (int i = 0; i < 3; i++) {
if (pet[i] != null) {
addPetInfo(mplew, pet[i], false);
}
}
mplew.write(0); //end of pets
if (chr.getMount() == null) {
mplew.writeInt(1); // mob level
mplew.writeLong(0); // mob exp + tiredness
} else {
mplew.writeInt(chr.getMount().getLevel());
mplew.writeInt(chr.getMount().getExp());
mplew.writeInt(chr.getMount().getTiredness());
}
if (chr.getPlayerShop() != null && chr.getPlayerShop().isOwner(chr)) {
if (chr.getPlayerShop().hasFreeSlot()) {
addAnnounceBox(mplew, chr.getPlayerShop(), chr.getPlayerShop().getVisitors().length);
} else {
addAnnounceBox(mplew, chr.getPlayerShop(), 1);
}
} else if (chr.getMiniGame() != null && chr.getMiniGame().isOwner(chr)) {
if (chr.getMiniGame().hasFreeSlot()) {
addAnnounceBox(mplew, chr.getMiniGame(), 1, 0, 1, 0);
} else {
addAnnounceBox(mplew, chr.getMiniGame(), 1, 0, 2, 1);
}
} else {
mplew.write(0);
}
if (chr.getChalkboard() != null) {
mplew.write(1);
mplew.writeMapleAsciiString(chr.getChalkboard());
} else {
mplew.write(0);
}
addRingLook(mplew, chr, true);
addRingLook(mplew, chr, false);
addMarriageRingLook(mplew, chr);
mplew.write(0);//NewYearCards
mplew.write(0);//Berserk
mplew.write(0);//CDragon::CreateEffect lol
mplew.write(chr.getTeam());//only needed in specific fields
return mplew.getPacket();
}
Code:
public static byte[] getCharInfo(MapleCharacter chr) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.SET_FIELD.getValue());
mplew.writeInt(chr.getClient().getChannel() - 1);
mplew.write(1);
mplew.write(1);
mplew.writeShort(0);
for (int i = 0; i < 3; i++) {
mplew.writeInt(Randomizer.nextInt());
}
addCharacterInfo(mplew, chr);
mplew.writeLong(getTime(System.currentTimeMillis()));
return mplew.getPacket();
}
Code:
public static byte[] updateCharLook(MapleCharacter chr) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.UPDATE_CHAR_LOOK.getValue());
mplew.writeInt(chr.getId());
mplew.write(1);
addCharLook(mplew, chr, false);
addRingLook(mplew, chr, true);
addRingLook(mplew, chr, false);
addMarriageRingLook(mplew, chr);
mplew.writeInt(0);
return mplew.getPacket();
}
Code:
private static void addRingInfo(final MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
mplew.writeShort(chr.getCrushRings().size());
for (MapleRing ring : chr.getCrushRings()) {
mplew.writeInt(ring.getPartnerChrId());
mplew.writeAsciiString(getRightPaddedStr(ring.getPartnerName(), '\0', 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(), '\0', 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);
if (chr.getMarriageRing() != null) {
mplew.writeInt(chr.getMarriageId());
mplew.writeInt(chr.getGender() == 0 ? chr.getId() : chr.getMarriageRing().getPartnerChrId());
mplew.writeInt(chr.getGender() == 0 ? chr.getMarriageRing().getPartnerChrId() : chr.getId());
mplew.writeShort(3);
mplew.writeInt(chr.getMarriageRing().getRingId());
mplew.writeInt(chr.getMarriageRing().getPartnerRingId());
mplew.writeAsciiString(StringUtil.getRightPaddedStr(chr.getGender() == 0 ? chr.getName() : chr.getMarriageRing().getPartnerName(), '\0', 13));
mplew.writeAsciiString(StringUtil.getRightPaddedStr(chr.getGender() == 0 ? chr.getMarriageRing().getPartnerName() : chr.getName(), '\0', 13));
}
}
Code:
private static void addItemInfo(final MaplePacketLittleEndianWriter mplew, Item item, boolean zeroPosition) {
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
boolean isCash = ii.isCash(item.getItemId());
boolean isPet = item.getPetId() > -1;
boolean isRing = false;
Equip equip = null;
byte pos = item.getPosition();
if (item.getType() == 1) {
equip = (Equip) item;
isRing = equip.getRingId() > -1;
}
if (!zeroPosition) {
if (equip != null) {
if (pos < 0) {
pos *= -1;
}
mplew.writeShort(pos > 100 ? pos - 100 : pos);
} else {
mplew.write(pos);
}
}
mplew.write(item.getType());
mplew.writeInt(item.getItemId());
mplew.writeBool(isCash);
if (isCash) {
mplew.writeLong(isPet ? item.getPetId() : isRing ? equip.getRingId() : item.getCashId());
}
addExpirationTime(mplew, item.getExpiration());
if (isPet) {
MaplePet pet = item.getPet();
mplew.writeAsciiString(StringUtil.getRightPaddedStr(pet.getName(), '\0', 13));
mplew.write(pet.getLevel());
mplew.writeShort(pet.getCloseness());
mplew.write(pet.getFullness());
addExpirationTime(mplew, pet.getExpiration());
mplew.writeInt(0);
mplew.write(new byte[]{(byte) 0x50, (byte) 0x46}); //wonder what this is
mplew.writeInt(0);
return;
}
if (equip == null) {
mplew.writeShort(item.getQuantity());
mplew.writeMapleAsciiString(item.getOwner());
mplew.writeShort(item.getFlag()); // flag
if (ItemConstants.isRechargable(item.getItemId())) {
mplew.writeInt(2);
mplew.write(new byte[]{(byte) 0x54, 0, 0, (byte) 0x34});
}
return;
}
mplew.write(equip.getUpgradeSlots()); // upgrade slots
mplew.write(equip.getLevel()); // level
mplew.writeShort(equip.getStr()); // str
mplew.writeShort(equip.getDex()); // dex
mplew.writeShort(equip.getInt()); // int
mplew.writeShort(equip.getLuk()); // luk
mplew.writeShort(equip.getHp()); // hp
mplew.writeShort(equip.getMp()); // mp
mplew.writeShort(equip.getWatk()); // watk
mplew.writeShort(equip.getMatk()); // matk
mplew.writeShort(equip.getWdef()); // wdef
mplew.writeShort(equip.getMdef()); // mdef
mplew.writeShort(equip.getAcc()); // accuracy
mplew.writeShort(equip.getAvoid()); // avoid
mplew.writeShort(equip.getHands()); // hands
mplew.writeShort(equip.getSpeed()); // speed
mplew.writeShort(equip.getJump()); // jump
mplew.writeMapleAsciiString(equip.getOwner()); // owner name
mplew.writeShort(equip.getFlag()); //Item Flags
if (isCash) {
for (int i = 0; i < 10; i++) {
mplew.write(0x40);
}
} else {
mplew.write(0);
mplew.write(equip.getItemLevel()); //Item Level
mplew.writeShort(0);
mplew.writeShort(equip.getItemExp()); //Works pretty weird :s
mplew.writeInt(equip.getVicious()); //WTF NEXON ARE YOU SERIOUS?
mplew.writeLong(0);
}
mplew.writeLong(getTime(-2));
mplew.writeInt(-1);
}
Code:
private static void addCharacterInfo(final MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
mplew.writeLong(-1);
mplew.write(0);
addCharStats(mplew, chr);
mplew.write(chr.getBuddylist().getCapacity());
if (chr.getLinkedName() == null) {
mplew.write(0);
} else {
mplew.write(1);
mplew.writeMapleAsciiString(chr.getLinkedName());
}
mplew.writeInt(chr.getMeso());
addInventoryInfo(mplew, chr);
addSkillInfo(mplew, chr);
addQuestInfo(mplew, chr);
addMiniGameInfo(mplew, chr);
addRingInfo(mplew, chr);
addTeleportInfo(mplew, chr);
addMonsterBookInfo(mplew, chr);
addNewYearInfo(mplew, chr);//have fun!
addAreaInfo(mplew, chr);//assuming it stayed here xd
mplew.writeShort(0);
}