mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-05 06:50:04 +00:00
[refactor] Separate email functions out of BuddyManager into Email
This commit is contained in:
parent
df1ac82300
commit
8981ad8c14
2
Makefile
2
Makefile
@ -37,6 +37,7 @@ CXXSRC=\
|
|||||||
src/CNShared.cpp\
|
src/CNShared.cpp\
|
||||||
src/Database.cpp\
|
src/Database.cpp\
|
||||||
src/Defines.cpp\
|
src/Defines.cpp\
|
||||||
|
src/Email.cpp\
|
||||||
src/main.cpp\
|
src/main.cpp\
|
||||||
src/MissionManager.cpp\
|
src/MissionManager.cpp\
|
||||||
src/MobAI.cpp\
|
src/MobAI.cpp\
|
||||||
@ -80,6 +81,7 @@ CXXHDR=\
|
|||||||
src/CNStructs.hpp\
|
src/CNStructs.hpp\
|
||||||
src/Database.hpp\
|
src/Database.hpp\
|
||||||
src/Defines.hpp\
|
src/Defines.hpp\
|
||||||
|
src/Email.hpp\
|
||||||
vendor/INIReader.hpp\
|
vendor/INIReader.hpp\
|
||||||
vendor/JSON.hpp\
|
vendor/JSON.hpp\
|
||||||
src/MissionManager.hpp\
|
src/MissionManager.hpp\
|
||||||
|
@ -22,15 +22,6 @@ void BuddyManager::init() {
|
|||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_SET_PC_BLOCK, reqPlayerBlock);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_SET_PC_BLOCK, reqPlayerBlock);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_REMOVE_BUDDY, reqBuddyDelete);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_REMOVE_BUDDY, reqBuddyDelete);
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_BUDDY_WARP, reqBuddyWarp);
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_BUDDY_WARP, reqBuddyWarp);
|
||||||
//
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_EMAIL_UPDATE_CHECK, emailUpdateCheck);
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_RECV_EMAIL_PAGE_LIST, emailReceivePageList);
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_READ_EMAIL, emailRead);
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_RECV_EMAIL_CANDY, emailReceiveTaros);
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_RECV_EMAIL_ITEM, emailReceiveItemSingle);
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_RECV_EMAIL_ITEM_ALL, emailReceiveItemAll);
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_DELETE_EMAIL, emailDelete);
|
|
||||||
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_SEND_EMAIL, emailSend);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh buddy list
|
// Refresh buddy list
|
||||||
@ -481,318 +472,6 @@ fail:
|
|||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_BUDDY_WARP_FAIL, sizeof(sP_FE2CL_REP_PC_BUDDY_WARP_FAIL));
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_BUDDY_WARP_FAIL, sizeof(sP_FE2CL_REP_PC_BUDDY_WARP_FAIL));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuddyManager::emailUpdateCheck(CNSocket* sock, CNPacketData* data) {
|
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_EMAIL_UPDATE_CHECK))
|
|
||||||
return; // malformed packet
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_NEW_EMAIL, resp);
|
|
||||||
resp.iNewEmailCnt = Database::getUnreadEmailCount(PlayerManager::getPlayer(sock)->iID);
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_NEW_EMAIL, sizeof(sP_FE2CL_REP_PC_NEW_EMAIL));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuddyManager::emailReceivePageList(CNSocket* sock, CNPacketData* data) {
|
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_RECV_EMAIL_PAGE_LIST))
|
|
||||||
return; // malformed packet
|
|
||||||
|
|
||||||
sP_CL2FE_REQ_PC_RECV_EMAIL_PAGE_LIST* pkt = (sP_CL2FE_REQ_PC_RECV_EMAIL_PAGE_LIST*)data->buf;
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_RECV_EMAIL_PAGE_LIST_SUCC, resp);
|
|
||||||
resp.iPageNum = pkt->iPageNum;
|
|
||||||
|
|
||||||
std::vector<Database::EmailData> emails = Database::getEmails(PlayerManager::getPlayer(sock)->iID, pkt->iPageNum);
|
|
||||||
for (int i = 0; i < emails.size(); i++) {
|
|
||||||
// convert each email and load them into the packet
|
|
||||||
Database::EmailData* email = &emails.at(i);
|
|
||||||
sEmailInfo* emailInfo = new sEmailInfo();
|
|
||||||
emailInfo->iEmailIndex = email->MsgIndex;
|
|
||||||
emailInfo->iReadFlag = email->ReadFlag;
|
|
||||||
emailInfo->iItemCandyFlag = email->ItemFlag;
|
|
||||||
emailInfo->iFromPCUID = email->SenderId;
|
|
||||||
emailInfo->SendTime = timeStampToStruct(email->SendTime);
|
|
||||||
emailInfo->DeleteTime = timeStampToStruct(email->DeleteTime);
|
|
||||||
U8toU16(email->SenderFirstName, emailInfo->szFirstName, sizeof(emailInfo->szFirstName));
|
|
||||||
U8toU16(email->SenderLastName, emailInfo->szLastName, sizeof(emailInfo->szLastName));
|
|
||||||
U8toU16(email->SubjectLine, emailInfo->szSubject, sizeof(emailInfo->szSubject));
|
|
||||||
resp.aEmailInfo[i] = *emailInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_RECV_EMAIL_PAGE_LIST_SUCC, sizeof(sP_FE2CL_REP_PC_RECV_EMAIL_PAGE_LIST_SUCC));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuddyManager::emailRead(CNSocket* sock, CNPacketData* data) {
|
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_READ_EMAIL))
|
|
||||||
return; // malformed packet
|
|
||||||
|
|
||||||
sP_CL2FE_REQ_PC_READ_EMAIL* pkt = (sP_CL2FE_REQ_PC_READ_EMAIL*)data->buf;
|
|
||||||
|
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
|
||||||
|
|
||||||
Database::EmailData email = Database::getEmail(plr->iID, pkt->iEmailIndex);
|
|
||||||
sItemBase* attachments = Database::getEmailAttachments(plr->iID, pkt->iEmailIndex);
|
|
||||||
email.ReadFlag = 1; // mark as read
|
|
||||||
Database::updateEmailContent(&email);
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_READ_EMAIL_SUCC, resp);
|
|
||||||
resp.iEmailIndex = pkt->iEmailIndex;
|
|
||||||
resp.iCash = email.Taros;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
resp.aItem[i] = attachments[i];
|
|
||||||
}
|
|
||||||
U8toU16(email.MsgBody, (char16_t*)resp.szContent, sizeof(resp.szContent));
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_READ_EMAIL_SUCC, sizeof(sP_FE2CL_REP_PC_READ_EMAIL_SUCC));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuddyManager::emailReceiveTaros(CNSocket* sock, CNPacketData* data) {
|
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_RECV_EMAIL_CANDY))
|
|
||||||
return; // malformed packet
|
|
||||||
|
|
||||||
sP_CL2FE_REQ_PC_RECV_EMAIL_CANDY* pkt = (sP_CL2FE_REQ_PC_RECV_EMAIL_CANDY*)data->buf;
|
|
||||||
|
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
|
||||||
|
|
||||||
Database::EmailData email = Database::getEmail(plr->iID, pkt->iEmailIndex);
|
|
||||||
// money transfer
|
|
||||||
plr->money += email.Taros;
|
|
||||||
email.Taros = 0;
|
|
||||||
// update Taros in email
|
|
||||||
Database::updateEmailContent(&email);
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_RECV_EMAIL_CANDY_SUCC, resp);
|
|
||||||
resp.iCandy = plr->money;
|
|
||||||
resp.iEmailIndex = pkt->iEmailIndex;
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_RECV_EMAIL_CANDY_SUCC, sizeof(sP_FE2CL_REP_PC_RECV_EMAIL_CANDY_SUCC));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuddyManager::emailReceiveItemSingle(CNSocket* sock, CNPacketData* data) {
|
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM))
|
|
||||||
return; // malformed packet
|
|
||||||
|
|
||||||
sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM* pkt = (sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM*)data->buf;
|
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
|
||||||
|
|
||||||
if (pkt->iSlotNum < 0 || pkt->iSlotNum >= AINVEN_COUNT || pkt->iSlotNum < 1 || pkt->iSlotNum > 4)
|
|
||||||
return; // sanity check
|
|
||||||
|
|
||||||
// get email item from db and delete it
|
|
||||||
sItemBase* attachments = Database::getEmailAttachments(plr->iID, pkt->iEmailIndex);
|
|
||||||
sItemBase itemFrom = attachments[pkt->iEmailItemSlot - 1];
|
|
||||||
Database::deleteEmailAttachments(plr->iID, pkt->iEmailIndex, pkt->iEmailItemSlot);
|
|
||||||
|
|
||||||
// move item to player inventory
|
|
||||||
sItemBase& itemTo = plr->Inven[pkt->iSlotNum];
|
|
||||||
itemTo.iID = itemFrom.iID;
|
|
||||||
itemTo.iOpt = itemFrom.iOpt;
|
|
||||||
itemTo.iTimeLimit = itemFrom.iTimeLimit;
|
|
||||||
itemTo.iType = itemFrom.iType;
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_RECV_EMAIL_ITEM_SUCC, resp);
|
|
||||||
resp.iEmailIndex = pkt->iEmailIndex;
|
|
||||||
resp.iEmailItemSlot = pkt->iEmailItemSlot;
|
|
||||||
resp.iSlotNum = pkt->iSlotNum;
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_RECV_EMAIL_ITEM_SUCC, sizeof(sP_FE2CL_REP_PC_RECV_EMAIL_ITEM_SUCC));
|
|
||||||
|
|
||||||
// update inventory
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC, resp2);
|
|
||||||
resp2.eIL = 1;
|
|
||||||
resp2.iSlotNum = resp.iSlotNum;
|
|
||||||
resp2.Item = itemTo;
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp2, P_FE2CL_REP_PC_GIVE_ITEM_SUCC, sizeof(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuddyManager::emailReceiveItemAll(CNSocket* sock, CNPacketData* data) {
|
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM_ALL))
|
|
||||||
return; // malformed packet
|
|
||||||
|
|
||||||
sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM_ALL* pkt = (sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM_ALL*)data->buf;
|
|
||||||
|
|
||||||
// move items to player inventory
|
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
|
||||||
sItemBase* itemsFrom = Database::getEmailAttachments(plr->iID, pkt->iEmailIndex);
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
int slot = ItemManager::findFreeSlot(plr);
|
|
||||||
if (slot < 0 || slot >= AINVEN_COUNT) {
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_RECV_EMAIL_ITEM_ALL_FAIL, failResp);
|
|
||||||
failResp.iEmailIndex = pkt->iEmailIndex;
|
|
||||||
failResp.iErrorCode = 0; // ???
|
|
||||||
break; // sanity check; should never happen
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy data over
|
|
||||||
sItemBase itemFrom = itemsFrom[i];
|
|
||||||
sItemBase& itemTo = plr->Inven[slot];
|
|
||||||
itemTo.iID = itemFrom.iID;
|
|
||||||
itemTo.iOpt = itemFrom.iOpt;
|
|
||||||
itemTo.iTimeLimit = itemFrom.iTimeLimit;
|
|
||||||
itemTo.iType = itemFrom.iType;
|
|
||||||
|
|
||||||
// update inventory
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC, resp2);
|
|
||||||
resp2.eIL = 1;
|
|
||||||
resp2.iSlotNum = slot;
|
|
||||||
resp2.Item = itemTo;
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp2, P_FE2CL_REP_PC_GIVE_ITEM_SUCC, sizeof(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC));
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete all items from db
|
|
||||||
Database::deleteEmailAttachments(plr->iID, pkt->iEmailIndex, -1);
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_RECV_EMAIL_ITEM_ALL_SUCC, resp);
|
|
||||||
resp.iEmailIndex = pkt->iEmailIndex;
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_RECV_EMAIL_ITEM_ALL_SUCC, sizeof(sP_FE2CL_REP_PC_RECV_EMAIL_ITEM_ALL_SUCC));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuddyManager::emailDelete(CNSocket* sock, CNPacketData* data) {
|
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_DELETE_EMAIL))
|
|
||||||
return; // malformed packet
|
|
||||||
|
|
||||||
sP_CL2FE_REQ_PC_DELETE_EMAIL* pkt = (sP_CL2FE_REQ_PC_DELETE_EMAIL*)data->buf;
|
|
||||||
|
|
||||||
Database::deleteEmails(PlayerManager::getPlayer(sock)->iID, pkt->iEmailIndexArray);
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_DELETE_EMAIL_SUCC, resp);
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
resp.iEmailIndexArray[i] = pkt->iEmailIndexArray[i]; // i'm scared of memcpy
|
|
||||||
}
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_DELETE_EMAIL_SUCC, sizeof(sP_FE2CL_REP_PC_DELETE_EMAIL_SUCC));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuddyManager::emailSend(CNSocket* sock, CNPacketData* data) {
|
|
||||||
if (data->size != sizeof(sP_CL2FE_REQ_PC_SEND_EMAIL))
|
|
||||||
return; // malformed packet
|
|
||||||
|
|
||||||
sP_CL2FE_REQ_PC_SEND_EMAIL* pkt = (sP_CL2FE_REQ_PC_SEND_EMAIL*)data->buf;
|
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
|
||||||
|
|
||||||
// sanity checks
|
|
||||||
bool invalid = false;
|
|
||||||
int itemCount = 0;
|
|
||||||
|
|
||||||
std::set<int> seen;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
int slot = pkt->aItem[i].iSlotNum;
|
|
||||||
if (slot < 0 || slot >= AINVEN_COUNT) {
|
|
||||||
invalid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sItemBase *item = &pkt->aItem[i].ItemInven;
|
|
||||||
sItemBase *real = &plr->Inven[slot];
|
|
||||||
|
|
||||||
if (item->iID == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// was the same item added multiple times?
|
|
||||||
if (seen.count(slot) > 0) {
|
|
||||||
invalid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
seen.insert(slot);
|
|
||||||
|
|
||||||
itemCount++;
|
|
||||||
if (item->iType != real->iType || item->iID != real->iID
|
|
||||||
|| item->iOpt <= 0 || item->iOpt > real->iOpt) {
|
|
||||||
invalid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pkt->iCash < 0 || pkt->iCash > plr->money + 50 + 20 * itemCount || invalid) {
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL, errResp);
|
|
||||||
errResp.iErrorCode = 1;
|
|
||||||
errResp.iTo_PCUID = pkt->iTo_PCUID;
|
|
||||||
sock->sendPacket((void*)&errResp, P_FE2CL_REP_PC_SEND_EMAIL_FAIL, sizeof(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_SEND_EMAIL_SUCC, resp);
|
|
||||||
|
|
||||||
if (pkt->iCash || pkt->aItem[0].ItemInven.iID) {
|
|
||||||
// if there are item or taro attachments
|
|
||||||
Player otherPlr = {};
|
|
||||||
Database::getPlayer(&otherPlr, pkt->iTo_PCUID);
|
|
||||||
if (otherPlr.iID != 0 && plr->PCStyle2.iPayzoneFlag != otherPlr.PCStyle2.iPayzoneFlag) {
|
|
||||||
// if the players are not in the same time period
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL, resp);
|
|
||||||
resp.iErrorCode = 9; // error code 9 tells the player they can't send attachments across time
|
|
||||||
resp.iTo_PCUID = pkt->iTo_PCUID;
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_SEND_EMAIL_FAIL, sizeof(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle items
|
|
||||||
std::vector<sItemBase> attachments;
|
|
||||||
std::vector<int> attSlots;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
sEmailItemInfoFromCL attachment = pkt->aItem[i];
|
|
||||||
|
|
||||||
// skip empty slots
|
|
||||||
if (attachment.ItemInven.iID == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
resp.aItem[i] = attachment;
|
|
||||||
attachments.push_back(attachment.ItemInven);
|
|
||||||
attSlots.push_back(attachment.iSlotNum);
|
|
||||||
// delete item
|
|
||||||
plr->Inven[attachment.iSlotNum] = { 0, 0, 0, 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
int cost = pkt->iCash + 50 + 20 * attachments.size(); // attached taros + postage
|
|
||||||
plr->money -= cost;
|
|
||||||
Database::EmailData email = {
|
|
||||||
(int)pkt->iTo_PCUID, // PlayerId
|
|
||||||
Database::getNextEmailIndex(pkt->iTo_PCUID), // MsgIndex
|
|
||||||
0, // ReadFlag (unread)
|
|
||||||
(pkt->iCash > 0 || attachments.size() > 0) ? 1 : 0, // ItemFlag
|
|
||||||
plr->iID, // SenderID
|
|
||||||
U16toU8(plr->PCStyle.szFirstName), // SenderFirstName
|
|
||||||
U16toU8(plr->PCStyle.szLastName), // SenderLastName
|
|
||||||
ChatManager::sanitizeText(U16toU8(pkt->szSubject)), // SubjectLine
|
|
||||||
ChatManager::sanitizeText(U16toU8(pkt->szContent), true), // MsgBody
|
|
||||||
pkt->iCash, // Taros
|
|
||||||
(uint64_t)getTimestamp(), // SendTime
|
|
||||||
0 // DeleteTime (unimplemented)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!Database::sendEmail(&email, attachments)) {
|
|
||||||
plr->money += cost; // give money back
|
|
||||||
// give items back
|
|
||||||
while (!attachments.empty()) {
|
|
||||||
sItemBase attachment = attachments.back();
|
|
||||||
plr->Inven[attSlots.back()] = attachment;
|
|
||||||
|
|
||||||
attachments.pop_back();
|
|
||||||
attSlots.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// send error message
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL, errResp);
|
|
||||||
errResp.iErrorCode = 1;
|
|
||||||
errResp.iTo_PCUID = pkt->iTo_PCUID;
|
|
||||||
sock->sendPacket((void*)&errResp, P_FE2CL_REP_PC_SEND_EMAIL_FAIL, sizeof(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK: use set value packet to force GUI taros update
|
|
||||||
INITSTRUCT(sP_FE2CL_GM_REP_PC_SET_VALUE, tarosResp);
|
|
||||||
tarosResp.iPC_ID = plr->iID;
|
|
||||||
tarosResp.iSetValueType = 5;
|
|
||||||
tarosResp.iSetValue = plr->money;
|
|
||||||
sock->sendPacket((void*)&tarosResp, P_FE2CL_GM_REP_PC_SET_VALUE, sizeof(sP_FE2CL_GM_REP_PC_SET_VALUE));
|
|
||||||
|
|
||||||
resp.iCandy = plr->money;
|
|
||||||
resp.iTo_PCUID = pkt->iTo_PCUID;
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_SEND_EMAIL_SUCC, sizeof(sP_FE2CL_REP_PC_SEND_EMAIL_SUCC));
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma region Helper methods
|
#pragma region Helper methods
|
||||||
|
|
||||||
int BuddyManager::getAvailableBuddySlot(Player* plr) {
|
int BuddyManager::getAvailableBuddySlot(Player* plr) {
|
||||||
|
@ -33,16 +33,6 @@ namespace BuddyManager {
|
|||||||
// Buddy warping
|
// Buddy warping
|
||||||
void reqBuddyWarp(CNSocket* sock, CNPacketData* data);
|
void reqBuddyWarp(CNSocket* sock, CNPacketData* data);
|
||||||
|
|
||||||
// Email methods
|
|
||||||
void emailUpdateCheck(CNSocket* sock, CNPacketData* data);
|
|
||||||
void emailReceivePageList(CNSocket* sock, CNPacketData* data);
|
|
||||||
void emailRead(CNSocket* sock, CNPacketData* data);
|
|
||||||
void emailReceiveTaros(CNSocket* sock, CNPacketData* data);
|
|
||||||
void emailReceiveItemSingle(CNSocket* sock, CNPacketData* data);
|
|
||||||
void emailReceiveItemAll(CNSocket* sock, CNPacketData* data);
|
|
||||||
void emailDelete(CNSocket* sock, CNPacketData* data);
|
|
||||||
void emailSend(CNSocket* sock, CNPacketData* data);
|
|
||||||
|
|
||||||
// helper methods
|
// helper methods
|
||||||
|
|
||||||
// Name checks
|
// Name checks
|
||||||
|
332
src/Email.cpp
Normal file
332
src/Email.cpp
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
#include "Email.hpp"
|
||||||
|
|
||||||
|
// New email notification
|
||||||
|
void Email::emailUpdateCheck(CNSocket* sock, CNPacketData* data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_EMAIL_UPDATE_CHECK))
|
||||||
|
return; // malformed packet
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_NEW_EMAIL, resp);
|
||||||
|
resp.iNewEmailCnt = Database::getUnreadEmailCount(PlayerManager::getPlayer(sock)->iID);
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_NEW_EMAIL, sizeof(sP_FE2CL_REP_PC_NEW_EMAIL));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve page of emails
|
||||||
|
void Email::emailReceivePageList(CNSocket* sock, CNPacketData* data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_RECV_EMAIL_PAGE_LIST))
|
||||||
|
return; // malformed packet
|
||||||
|
|
||||||
|
sP_CL2FE_REQ_PC_RECV_EMAIL_PAGE_LIST* pkt = (sP_CL2FE_REQ_PC_RECV_EMAIL_PAGE_LIST*)data->buf;
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_RECV_EMAIL_PAGE_LIST_SUCC, resp);
|
||||||
|
resp.iPageNum = pkt->iPageNum;
|
||||||
|
|
||||||
|
std::vector<Database::EmailData> emails = Database::getEmails(PlayerManager::getPlayer(sock)->iID, pkt->iPageNum);
|
||||||
|
for (int i = 0; i < emails.size(); i++) {
|
||||||
|
// convert each email and load them into the packet
|
||||||
|
Database::EmailData* email = &emails.at(i);
|
||||||
|
sEmailInfo* emailInfo = new sEmailInfo();
|
||||||
|
emailInfo->iEmailIndex = email->MsgIndex;
|
||||||
|
emailInfo->iReadFlag = email->ReadFlag;
|
||||||
|
emailInfo->iItemCandyFlag = email->ItemFlag;
|
||||||
|
emailInfo->iFromPCUID = email->SenderId;
|
||||||
|
emailInfo->SendTime = timeStampToStruct(email->SendTime);
|
||||||
|
emailInfo->DeleteTime = timeStampToStruct(email->DeleteTime);
|
||||||
|
U8toU16(email->SenderFirstName, emailInfo->szFirstName, sizeof(emailInfo->szFirstName));
|
||||||
|
U8toU16(email->SenderLastName, emailInfo->szLastName, sizeof(emailInfo->szLastName));
|
||||||
|
U8toU16(email->SubjectLine, emailInfo->szSubject, sizeof(emailInfo->szSubject));
|
||||||
|
resp.aEmailInfo[i] = *emailInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_RECV_EMAIL_PAGE_LIST_SUCC, sizeof(sP_FE2CL_REP_PC_RECV_EMAIL_PAGE_LIST_SUCC));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read individual email
|
||||||
|
void Email::emailRead(CNSocket* sock, CNPacketData* data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_READ_EMAIL))
|
||||||
|
return; // malformed packet
|
||||||
|
|
||||||
|
sP_CL2FE_REQ_PC_READ_EMAIL* pkt = (sP_CL2FE_REQ_PC_READ_EMAIL*)data->buf;
|
||||||
|
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
|
Database::EmailData email = Database::getEmail(plr->iID, pkt->iEmailIndex);
|
||||||
|
sItemBase* attachments = Database::getEmailAttachments(plr->iID, pkt->iEmailIndex);
|
||||||
|
email.ReadFlag = 1; // mark as read
|
||||||
|
Database::updateEmailContent(&email);
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_READ_EMAIL_SUCC, resp);
|
||||||
|
resp.iEmailIndex = pkt->iEmailIndex;
|
||||||
|
resp.iCash = email.Taros;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
resp.aItem[i] = attachments[i];
|
||||||
|
}
|
||||||
|
U8toU16(email.MsgBody, (char16_t*)resp.szContent, sizeof(resp.szContent));
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_READ_EMAIL_SUCC, sizeof(sP_FE2CL_REP_PC_READ_EMAIL_SUCC));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve attached taros from email
|
||||||
|
void Email::emailReceiveTaros(CNSocket* sock, CNPacketData* data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_RECV_EMAIL_CANDY))
|
||||||
|
return; // malformed packet
|
||||||
|
|
||||||
|
sP_CL2FE_REQ_PC_RECV_EMAIL_CANDY* pkt = (sP_CL2FE_REQ_PC_RECV_EMAIL_CANDY*)data->buf;
|
||||||
|
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
|
Database::EmailData email = Database::getEmail(plr->iID, pkt->iEmailIndex);
|
||||||
|
// money transfer
|
||||||
|
plr->money += email.Taros;
|
||||||
|
email.Taros = 0;
|
||||||
|
// update Taros in email
|
||||||
|
Database::updateEmailContent(&email);
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_RECV_EMAIL_CANDY_SUCC, resp);
|
||||||
|
resp.iCandy = plr->money;
|
||||||
|
resp.iEmailIndex = pkt->iEmailIndex;
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_RECV_EMAIL_CANDY_SUCC, sizeof(sP_FE2CL_REP_PC_RECV_EMAIL_CANDY_SUCC));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve individual attached item from email
|
||||||
|
void Email::emailReceiveItemSingle(CNSocket* sock, CNPacketData* data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM))
|
||||||
|
return; // malformed packet
|
||||||
|
|
||||||
|
sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM* pkt = (sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM*)data->buf;
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
|
if (pkt->iSlotNum < 0 || pkt->iSlotNum >= AINVEN_COUNT || pkt->iSlotNum < 1 || pkt->iSlotNum > 4)
|
||||||
|
return; // sanity check
|
||||||
|
|
||||||
|
// get email item from db and delete it
|
||||||
|
sItemBase* attachments = Database::getEmailAttachments(plr->iID, pkt->iEmailIndex);
|
||||||
|
sItemBase itemFrom = attachments[pkt->iEmailItemSlot - 1];
|
||||||
|
Database::deleteEmailAttachments(plr->iID, pkt->iEmailIndex, pkt->iEmailItemSlot);
|
||||||
|
|
||||||
|
// move item to player inventory
|
||||||
|
sItemBase& itemTo = plr->Inven[pkt->iSlotNum];
|
||||||
|
itemTo.iID = itemFrom.iID;
|
||||||
|
itemTo.iOpt = itemFrom.iOpt;
|
||||||
|
itemTo.iTimeLimit = itemFrom.iTimeLimit;
|
||||||
|
itemTo.iType = itemFrom.iType;
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_RECV_EMAIL_ITEM_SUCC, resp);
|
||||||
|
resp.iEmailIndex = pkt->iEmailIndex;
|
||||||
|
resp.iEmailItemSlot = pkt->iEmailItemSlot;
|
||||||
|
resp.iSlotNum = pkt->iSlotNum;
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_RECV_EMAIL_ITEM_SUCC, sizeof(sP_FE2CL_REP_PC_RECV_EMAIL_ITEM_SUCC));
|
||||||
|
|
||||||
|
// update inventory
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC, resp2);
|
||||||
|
resp2.eIL = 1;
|
||||||
|
resp2.iSlotNum = resp.iSlotNum;
|
||||||
|
resp2.Item = itemTo;
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp2, P_FE2CL_REP_PC_GIVE_ITEM_SUCC, sizeof(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve all attached items from email
|
||||||
|
void Email::emailReceiveItemAll(CNSocket* sock, CNPacketData* data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM_ALL))
|
||||||
|
return; // malformed packet
|
||||||
|
|
||||||
|
sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM_ALL* pkt = (sP_CL2FE_REQ_PC_RECV_EMAIL_ITEM_ALL*)data->buf;
|
||||||
|
|
||||||
|
// move items to player inventory
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
sItemBase* itemsFrom = Database::getEmailAttachments(plr->iID, pkt->iEmailIndex);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int slot = ItemManager::findFreeSlot(plr);
|
||||||
|
if (slot < 0 || slot >= AINVEN_COUNT) {
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_RECV_EMAIL_ITEM_ALL_FAIL, failResp);
|
||||||
|
failResp.iEmailIndex = pkt->iEmailIndex;
|
||||||
|
failResp.iErrorCode = 0; // ???
|
||||||
|
break; // sanity check; should never happen
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy data over
|
||||||
|
sItemBase itemFrom = itemsFrom[i];
|
||||||
|
sItemBase& itemTo = plr->Inven[slot];
|
||||||
|
itemTo.iID = itemFrom.iID;
|
||||||
|
itemTo.iOpt = itemFrom.iOpt;
|
||||||
|
itemTo.iTimeLimit = itemFrom.iTimeLimit;
|
||||||
|
itemTo.iType = itemFrom.iType;
|
||||||
|
|
||||||
|
// update inventory
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC, resp2);
|
||||||
|
resp2.eIL = 1;
|
||||||
|
resp2.iSlotNum = slot;
|
||||||
|
resp2.Item = itemTo;
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp2, P_FE2CL_REP_PC_GIVE_ITEM_SUCC, sizeof(sP_FE2CL_REP_PC_GIVE_ITEM_SUCC));
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete all items from db
|
||||||
|
Database::deleteEmailAttachments(plr->iID, pkt->iEmailIndex, -1);
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_RECV_EMAIL_ITEM_ALL_SUCC, resp);
|
||||||
|
resp.iEmailIndex = pkt->iEmailIndex;
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_RECV_EMAIL_ITEM_ALL_SUCC, sizeof(sP_FE2CL_REP_PC_RECV_EMAIL_ITEM_ALL_SUCC));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete an email
|
||||||
|
void Email::emailDelete(CNSocket* sock, CNPacketData* data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_DELETE_EMAIL))
|
||||||
|
return; // malformed packet
|
||||||
|
|
||||||
|
sP_CL2FE_REQ_PC_DELETE_EMAIL* pkt = (sP_CL2FE_REQ_PC_DELETE_EMAIL*)data->buf;
|
||||||
|
|
||||||
|
Database::deleteEmails(PlayerManager::getPlayer(sock)->iID, pkt->iEmailIndexArray);
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_DELETE_EMAIL_SUCC, resp);
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
resp.iEmailIndexArray[i] = pkt->iEmailIndexArray[i]; // i'm scared of memcpy
|
||||||
|
}
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_DELETE_EMAIL_SUCC, sizeof(sP_FE2CL_REP_PC_DELETE_EMAIL_SUCC));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send an email
|
||||||
|
void Email::emailSend(CNSocket* sock, CNPacketData* data) {
|
||||||
|
if (data->size != sizeof(sP_CL2FE_REQ_PC_SEND_EMAIL))
|
||||||
|
return; // malformed packet
|
||||||
|
|
||||||
|
sP_CL2FE_REQ_PC_SEND_EMAIL* pkt = (sP_CL2FE_REQ_PC_SEND_EMAIL*)data->buf;
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
|
// sanity checks
|
||||||
|
bool invalid = false;
|
||||||
|
int itemCount = 0;
|
||||||
|
|
||||||
|
std::set<int> seen;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
int slot = pkt->aItem[i].iSlotNum;
|
||||||
|
if (slot < 0 || slot >= AINVEN_COUNT) {
|
||||||
|
invalid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sItemBase* item = &pkt->aItem[i].ItemInven;
|
||||||
|
sItemBase* real = &plr->Inven[slot];
|
||||||
|
|
||||||
|
if (item->iID == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// was the same item added multiple times?
|
||||||
|
if (seen.count(slot) > 0) {
|
||||||
|
invalid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
seen.insert(slot);
|
||||||
|
|
||||||
|
itemCount++;
|
||||||
|
if (item->iType != real->iType || item->iID != real->iID
|
||||||
|
|| item->iOpt <= 0 || item->iOpt > real->iOpt) {
|
||||||
|
invalid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkt->iCash < 0 || pkt->iCash > plr->money + 50 + 20 * itemCount || invalid) {
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL, errResp);
|
||||||
|
errResp.iErrorCode = 1;
|
||||||
|
errResp.iTo_PCUID = pkt->iTo_PCUID;
|
||||||
|
sock->sendPacket((void*)&errResp, P_FE2CL_REP_PC_SEND_EMAIL_FAIL, sizeof(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_SEND_EMAIL_SUCC, resp);
|
||||||
|
|
||||||
|
if (pkt->iCash || pkt->aItem[0].ItemInven.iID) {
|
||||||
|
// if there are item or taro attachments
|
||||||
|
Player otherPlr = {};
|
||||||
|
Database::getPlayer(&otherPlr, pkt->iTo_PCUID);
|
||||||
|
if (otherPlr.iID != 0 && plr->PCStyle2.iPayzoneFlag != otherPlr.PCStyle2.iPayzoneFlag) {
|
||||||
|
// if the players are not in the same time period
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL, resp);
|
||||||
|
resp.iErrorCode = 9; // error code 9 tells the player they can't send attachments across time
|
||||||
|
resp.iTo_PCUID = pkt->iTo_PCUID;
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_SEND_EMAIL_FAIL, sizeof(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle items
|
||||||
|
std::vector<sItemBase> attachments;
|
||||||
|
std::vector<int> attSlots;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
sEmailItemInfoFromCL attachment = pkt->aItem[i];
|
||||||
|
|
||||||
|
// skip empty slots
|
||||||
|
if (attachment.ItemInven.iID == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
resp.aItem[i] = attachment;
|
||||||
|
attachments.push_back(attachment.ItemInven);
|
||||||
|
attSlots.push_back(attachment.iSlotNum);
|
||||||
|
// delete item
|
||||||
|
plr->Inven[attachment.iSlotNum] = { 0, 0, 0, 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
int cost = pkt->iCash + 50 + 20 * attachments.size(); // attached taros + postage
|
||||||
|
plr->money -= cost;
|
||||||
|
Database::EmailData email = {
|
||||||
|
(int)pkt->iTo_PCUID, // PlayerId
|
||||||
|
Database::getNextEmailIndex(pkt->iTo_PCUID), // MsgIndex
|
||||||
|
0, // ReadFlag (unread)
|
||||||
|
(pkt->iCash > 0 || attachments.size() > 0) ? 1 : 0, // ItemFlag
|
||||||
|
plr->iID, // SenderID
|
||||||
|
U16toU8(plr->PCStyle.szFirstName), // SenderFirstName
|
||||||
|
U16toU8(plr->PCStyle.szLastName), // SenderLastName
|
||||||
|
ChatManager::sanitizeText(U16toU8(pkt->szSubject)), // SubjectLine
|
||||||
|
ChatManager::sanitizeText(U16toU8(pkt->szContent), true), // MsgBody
|
||||||
|
pkt->iCash, // Taros
|
||||||
|
(uint64_t)getTimestamp(), // SendTime
|
||||||
|
0 // DeleteTime (unimplemented)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!Database::sendEmail(&email, attachments)) {
|
||||||
|
plr->money += cost; // give money back
|
||||||
|
// give items back
|
||||||
|
while (!attachments.empty()) {
|
||||||
|
sItemBase attachment = attachments.back();
|
||||||
|
plr->Inven[attSlots.back()] = attachment;
|
||||||
|
|
||||||
|
attachments.pop_back();
|
||||||
|
attSlots.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
// send error message
|
||||||
|
INITSTRUCT(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL, errResp);
|
||||||
|
errResp.iErrorCode = 1;
|
||||||
|
errResp.iTo_PCUID = pkt->iTo_PCUID;
|
||||||
|
sock->sendPacket((void*)&errResp, P_FE2CL_REP_PC_SEND_EMAIL_FAIL, sizeof(sP_FE2CL_REP_PC_SEND_EMAIL_FAIL));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: use set value packet to force GUI taros update
|
||||||
|
INITSTRUCT(sP_FE2CL_GM_REP_PC_SET_VALUE, tarosResp);
|
||||||
|
tarosResp.iPC_ID = plr->iID;
|
||||||
|
tarosResp.iSetValueType = 5;
|
||||||
|
tarosResp.iSetValue = plr->money;
|
||||||
|
sock->sendPacket((void*)&tarosResp, P_FE2CL_GM_REP_PC_SET_VALUE, sizeof(sP_FE2CL_GM_REP_PC_SET_VALUE));
|
||||||
|
|
||||||
|
resp.iCandy = plr->money;
|
||||||
|
resp.iTo_PCUID = pkt->iTo_PCUID;
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_SEND_EMAIL_SUCC, sizeof(sP_FE2CL_REP_PC_SEND_EMAIL_SUCC));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Email::init() {
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_EMAIL_UPDATE_CHECK, emailUpdateCheck);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_RECV_EMAIL_PAGE_LIST, emailReceivePageList);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_READ_EMAIL, emailRead);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_RECV_EMAIL_CANDY, emailReceiveTaros);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_RECV_EMAIL_ITEM, emailReceiveItemSingle);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_RECV_EMAIL_ITEM_ALL, emailReceiveItemAll);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_DELETE_EMAIL, emailDelete);
|
||||||
|
REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_SEND_EMAIL, emailSend);
|
||||||
|
}
|
23
src/Email.hpp
Normal file
23
src/Email.hpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CNProtocol.hpp"
|
||||||
|
#include "CNStructs.hpp"
|
||||||
|
#include "CNShardServer.hpp"
|
||||||
|
|
||||||
|
#include "Database.hpp"
|
||||||
|
#include "PlayerManager.hpp"
|
||||||
|
#include "ItemManager.hpp"
|
||||||
|
#include "ChatManager.hpp"
|
||||||
|
|
||||||
|
namespace Email {
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void emailUpdateCheck(CNSocket* sock, CNPacketData* data);
|
||||||
|
void emailReceivePageList(CNSocket* sock, CNPacketData* data);
|
||||||
|
void emailRead(CNSocket* sock, CNPacketData* data);
|
||||||
|
void emailReceiveTaros(CNSocket* sock, CNPacketData* data);
|
||||||
|
void emailReceiveItemSingle(CNSocket* sock, CNPacketData* data);
|
||||||
|
void emailReceiveItemAll(CNSocket* sock, CNPacketData* data);
|
||||||
|
void emailDelete(CNSocket* sock, CNPacketData* data);
|
||||||
|
void emailSend(CNSocket* sock, CNPacketData* data);
|
||||||
|
}
|
@ -20,6 +20,7 @@
|
|||||||
#include "Monitor.hpp"
|
#include "Monitor.hpp"
|
||||||
#include "RacingManager.hpp"
|
#include "RacingManager.hpp"
|
||||||
#include "Trading.hpp"
|
#include "Trading.hpp"
|
||||||
|
#include "Email.hpp"
|
||||||
|
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
|
||||||
@ -110,6 +111,7 @@ int main() {
|
|||||||
NPCManager::init();
|
NPCManager::init();
|
||||||
TransportManager::init();
|
TransportManager::init();
|
||||||
BuddyManager::init();
|
BuddyManager::init();
|
||||||
|
Email::init();
|
||||||
GroupManager::init();
|
GroupManager::init();
|
||||||
RacingManager::init();
|
RacingManager::init();
|
||||||
Database::open();
|
Database::open();
|
||||||
|
Loading…
Reference in New Issue
Block a user