- 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)
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.
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)
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:
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.
These are the send/recv opcodes for v83, v90, and v95.
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):
Have fun!
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!