Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[New Years] Nexon's New Year Card Packets/Handlers

Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
New Years! I had to make sure to release something for new years and what better than a New Year Event from GMS?!

This is GMS's New Year Event Packets/Handlers. I've never used them but I always wanted to as a special event or something for my server.
Note: This isn't the full implementation. This is all of the information the client has provided and you'll need to code how players gain new years items and stuff from NPC's or whatever.
Also, because this isn't the full implementation, the flag mask in OnSetField (or getCharInfo in OdinMS) for New Years is NewYearCard(0x40000), and comes after MonsterBookCover.
One last thing is in OnUserEnterField (or spawnPlayerMapobject in OdinMS), the byte after Berserk is a boolean for NewYearCardInfo encoding :). These are the two flags that load New Years effects on users in the map.


Anyways, here's all of the new year related packets/handlers from the client. :)

This is used to determine if it is a valid new year item (used in handlers)
Code:
2160101 -> New Year's Card - Double-click on the item to send a New Year's card to a character of your choice.
4300000 -> New Year's Card (Send) - A beautiful card with season's greetings.
4301000 -> New Year's Card (Receive) - A beautiful card with season's greetings. Double click on it to read!

PHP:
public static boolean is_new_year_card_item_etc(int nItemID) {
        return nItemID / 10000 == 430;
    }
    
    public static boolean is_new_year_card_item_con(int nItemID) {
        return nItemID / 10000 == 216;
    }


This is the valid modes used in the packet later on called OnNewYearCardRes. The values under 'NewYearCardRes' is used there.
This also has the error codes and requests for modes used in handlers/etc.

PHP:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package user.newyear;

/**
 * NewYearCard
 * 
 * @author Eric
 */
public enum NewYearCardRes {
    // NewYearCardReq
    Send(0x0),
    Receive(0x1),
    Delete(0x2),
    GetUnreceivedList(0x3),
    // NewYearCardRes
    Send_Done(0x4),
    Send_Failed(0x5),
    Receive_Done(0x6),
    Receive_Failed(0x7),
    Delete_Done(0x8),
    Delete_Failed(0x9),
    GetUnreceivedList_Done(0xA),
    GetUnreceivedList_Failed(0xB),
    NotiArrived(0xC),
    BroadCast_AddCardInfo(0xD),
    BroadCast_RemoveCardInfo(0xE),
    // NewYearCardFailReason
    CannotSendToSelf(0xF),
    NoFreeSlot(0x10),
    NotANewYearCard(0x11),
    IncoherentItem(0x12),
    TargetNotExist(0x13),
    IncoherentData(0x14),
    DBError(0x15),
    UnknownError(0x16);
    private final int result;
    
    private NewYearCardRes(int result) {
        this.result = result;
    }
    
    public int getResult() {
        return result;
    }
}

This (below) will be used to encode in getCharInfo.
This holds your New Year Cards so that when you have the item ingame they will load From and To with their message. (like ring effects)

PHP:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package user.newyear;

import tools.data.output.MaplePacketLittleEndianWriter;

/**
 * GW_NewYearCardRecord
 * 
 * @author Eric
 */
public class GW_NewYearCardRecord {
    public int m_dwSN;
    public int m_dwSenderID;
    public String m_sSenderName;
    public boolean m_bSenderDiscardCard;
    public long m_dateSent;
    public int m_dwReceiverID;
    public String m_sReceiverName;
    public boolean m_bReceiverDiscardCard;
    public boolean m_bReceiverReceivedCard;
    public long m_dateReceived;
    public String m_sContent;
    
    public void Encode(MaplePacketLittleEndianWriter mplew) {
        mplew.writeInt(this.m_dwSN);//4300000
        mplew.writeInt(this.m_dwSenderID);
        mplew.writeMapleAsciiString(this.m_sSenderName);
        mplew.write(this.m_bSenderDiscardCard ? 1 : 0);
        mplew.writeLong(this.m_dateSent);
        mplew.writeInt(this.m_dwReceiverID);
        mplew.writeMapleAsciiString(this.m_sReceiverName);
        mplew.write(this.m_bReceiverDiscardCard ? 1 : 0);
        mplew.write(this.m_bReceiverReceivedCard ? 1 : 0);
        mplew.writeLong(this.m_dateReceived);
        mplew.writeMapleAsciiString(this.m_sContent);
    }
}

This (below) is used to Encode in spawnPlayerMapobject.
This will add the list of serial numbers (dwSN) into your records like it does for your crush rings.
Note: Since my structure looks wack, the proper structure of this is as follows:
Code:
byte -> boolean, if user has at least 1 new year card
int -> size of new year cards to add
foreach when size > 0 :
int -> dwSN (serial number/key of the card)

PHP:
public static void EncodeNewYearCardInfo(MaplePacketLittleEndianWriter mplew, MapleCharacter chr) {
        if (chr.getNewYearRecord() != null) {
            mplew.write(1);
            mplew.writeInt(chr.getNewYearRecord().m_bReceiverReceivedCard ? 1 : 0);
            if (chr.getNewYearRecord().m_bReceiverReceivedCard) {
                mplew.writeInt(4300000);//effect?
            }
            return;
        }
        mplew.write(0);
    }

This is the global packet used to handle all operations for NewYearCards. This will send, receive, delete, send errors, view, etc.
Note: Refer to the above enum for NewYearCardRes to see the operations.
PHP:
public static byte[] OnNewYearCardRes(MapleCharacter pUser, int nMode, int sMsg) {
        MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
        mplew.writeShort(CWvsContext.NewYearCardRes.getVal());
        mplew.write(nMode);
        switch (nMode) {
            case 4: // Successfully sent a New Year Card\r\n to %s.
            case 6: // Successfully received a New Year Card.
                pUser.getNewYearRecord().Encode(mplew);
                break;
            case 8: // Successfully deleted a New Year Card.
                mplew.writeInt(0); // nSN
                break;
            case 5: // Nexon's stupid and makes 4 modes do the same operation..
            case 7:
            case 9:
            case 0xB:
                // 0x10: You have no free slot to store card.\r\ntry later on please.
                // 0x11: You have no card to send.
                // 0x12: Wrong inventory information !
                // 0x13: Cannot find such character !
                // 0x14: Incoherent Data !
                // 0x15: An error occured during DB operation.
                // 0x16: An unknown error occured !
                // 0xF: You cannot send a card to yourself !
                mplew.write(sMsg);
                break;
            case 0xA:
                int nSN = 1;
                mplew.writeInt(nSN);
                if ((nSN - 1) <= 98 && nSN > 0) {//lol nexon are you kidding
                    for (int i = 0; i < nSN; i++) {
                        mplew.writeInt(pUser.getNewYearRecord().m_dwSN);
                        mplew.writeInt(pUser.getNewYearRecord().m_dwSenderID);
                        mplew.writeMapleAsciiString(pUser.getNewYearRecord().m_sSenderName);
                    }
                }
                break;
            case 0xC:
                mplew.writeInt(0); // dwSN
                mplew.writeMapleAsciiString(""); // sSender
                break;
            case 0xD:
                mplew.writeInt(0); // dwSN
                mplew.writeInt(pUser.dwCharacterID);
                break;
            case 0xE:
                mplew.writeInt(0); // dwSN
                break;
        }
        return mplew.getPacket();
    }

These are the send/recv opcodes for v83, v90, and v95.
PHP:
v83 Recv: 
NewYearCardRequest(0x9F),
v83 Send:
NewYearCardRes(0x76),

v90 Recv:
NewYearCardRequest(0xB4),
v90 Send:
NewYearCardRes(0x7B),

v95 Recv:
NewYearCardRequest(0xB7),
v95 Send:
NewYearCardRes(0x7A),

Last, but not least is the handler. I never coded it but here's the packet (you should know what is a byte/int/string):
PHP:
[B4 00] -> Header
[00] -> NewYearReq (0 = Send)
[2C] -> nPOS (Item Slot Pos)
[00 20 F5 E5] -> nItemID (item id)
[04 00 54 65 73 74] -> sReceiverName (person to send to)
[06 00 4C 65 74 74 65 72] -> sContent (message)

Have fun!
 
Initiate Mage
Joined
Mar 28, 2017
Messages
49
Reaction score
1
thanksssssss erick
Eric - [New Years] Nexon's New Year Card Packets/Handlers - RaGEZONE Forums
 
Back
Top