2021-12-05 17:54:36 +00:00
|
|
|
#include "Mail.h"
|
|
|
|
#include <functional>
|
|
|
|
#include <string>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <regex>
|
|
|
|
#include <time.h>
|
|
|
|
#include <future>
|
|
|
|
|
|
|
|
#include "GeneralUtils.h"
|
|
|
|
#include "Database.h"
|
|
|
|
#include "Game.h"
|
|
|
|
#include "dServer.h"
|
|
|
|
#include "Entity.h"
|
|
|
|
#include "Character.h"
|
|
|
|
#include "PacketUtils.h"
|
2023-09-21 01:06:28 +00:00
|
|
|
#include "BitStreamUtils.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
#include "dLogger.h"
|
|
|
|
#include "EntityManager.h"
|
|
|
|
#include "InventoryComponent.h"
|
|
|
|
#include "GameMessages.h"
|
|
|
|
#include "Item.h"
|
|
|
|
#include "MissionComponent.h"
|
|
|
|
#include "ChatPackets.h"
|
|
|
|
#include "Character.h"
|
2023-01-01 12:51:22 +00:00
|
|
|
#include "dZoneManager.h"
|
|
|
|
#include "WorldConfig.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
#include "eMissionTaskType.h"
|
2023-03-04 07:16:37 +00:00
|
|
|
#include "eReplicaComponentType.h"
|
2023-05-03 21:38:32 +00:00
|
|
|
#include "eConnectionType.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
void Mail::SendMail(const Entity* recipient, const std::string& subject, const std::string& body, const LOT attachment,
|
|
|
|
const uint16_t attachmentCount) {
|
|
|
|
SendMail(
|
|
|
|
LWOOBJID_EMPTY,
|
|
|
|
ServerName,
|
|
|
|
recipient->GetObjectID(),
|
|
|
|
recipient->GetCharacter()->GetName(),
|
|
|
|
subject,
|
|
|
|
body,
|
|
|
|
attachment,
|
|
|
|
attachmentCount,
|
|
|
|
recipient->GetSystemAddress()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::SendMail(const LWOOBJID recipient, const std::string& recipientName, const std::string& subject,
|
|
|
|
const std::string& body, const LOT attachment, const uint16_t attachmentCount, const SystemAddress& sysAddr) {
|
|
|
|
SendMail(
|
|
|
|
LWOOBJID_EMPTY,
|
|
|
|
ServerName,
|
|
|
|
recipient,
|
|
|
|
recipientName,
|
|
|
|
subject,
|
|
|
|
body,
|
|
|
|
attachment,
|
|
|
|
attachmentCount,
|
|
|
|
sysAddr
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::SendMail(const LWOOBJID sender, const std::string& senderName, const Entity* recipient, const std::string& subject,
|
|
|
|
const std::string& body, const LOT attachment, const uint16_t attachmentCount) {
|
|
|
|
SendMail(
|
|
|
|
sender,
|
|
|
|
senderName,
|
|
|
|
recipient->GetObjectID(),
|
|
|
|
recipient->GetCharacter()->GetName(),
|
|
|
|
subject,
|
|
|
|
body,
|
|
|
|
attachment,
|
|
|
|
attachmentCount,
|
|
|
|
recipient->GetSystemAddress()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::SendMail(const LWOOBJID sender, const std::string& senderName, LWOOBJID recipient,
|
|
|
|
const std::string& recipientName, const std::string& subject, const std::string& body, const LOT attachment,
|
|
|
|
const uint16_t attachmentCount, const SystemAddress& sysAddr) {
|
2023-10-10 11:59:30 +00:00
|
|
|
Database::Connection->WriteMail(sender, senderName, recipient, recipientName, time(nullptr), subject, body, 0, attachment, 0, attachmentCount, false);
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) return; // TODO: Echo to chat server
|
2022-07-25 02:26:51 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
SendNotification(sysAddr, 1); //Show the "one new mail" message
|
|
|
|
}
|
|
|
|
|
|
|
|
//Because we need it:
|
|
|
|
std::string ReadWStringAsString(RakNet::BitStream* bitStream, uint32_t size) {
|
|
|
|
std::string toReturn = "";
|
|
|
|
uint8_t buffer;
|
|
|
|
bool isFinishedReading = false;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < size; ++i) {
|
|
|
|
bitStream->Read(buffer);
|
|
|
|
if (!isFinishedReading) toReturn.push_back(buffer);
|
|
|
|
if (buffer == '\0') isFinishedReading = true; //so we don't continue to read garbage as part of the string.
|
|
|
|
bitStream->Read(buffer); //Read the null term
|
|
|
|
}
|
|
|
|
|
|
|
|
return toReturn;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WriteStringAsWString(RakNet::BitStream* bitStream, std::string str, uint32_t size) {
|
|
|
|
uint32_t sizeToFill = size - str.size();
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < str.size(); ++i) {
|
|
|
|
bitStream->Write(str[i]);
|
|
|
|
bitStream->Write(uint8_t(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < sizeToFill; ++i) {
|
|
|
|
bitStream->Write(uint16_t(0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::HandleMailStuff(RakNet::BitStream* packet, const SystemAddress& sysAddr, Entity* entity) {
|
|
|
|
int mailStuffID = 0;
|
|
|
|
packet->Read(mailStuffID);
|
|
|
|
|
2023-04-12 16:48:20 +00:00
|
|
|
auto returnVal = std::async(std::launch::async, [packet, &sysAddr, entity, mailStuffID]() {
|
2021-12-05 17:54:36 +00:00
|
|
|
Mail::MailMessageID stuffID = MailMessageID(mailStuffID);
|
|
|
|
switch (stuffID) {
|
|
|
|
case MailMessageID::AttachmentCollect:
|
|
|
|
Mail::HandleAttachmentCollect(packet, sysAddr, entity);
|
|
|
|
break;
|
|
|
|
case MailMessageID::DataRequest:
|
|
|
|
Mail::HandleDataRequest(packet, sysAddr, entity);
|
|
|
|
break;
|
|
|
|
case MailMessageID::MailDelete:
|
|
|
|
Mail::HandleMailDelete(packet, sysAddr);
|
|
|
|
break;
|
|
|
|
case MailMessageID::MailRead:
|
|
|
|
Mail::HandleMailRead(packet, sysAddr);
|
|
|
|
break;
|
|
|
|
case MailMessageID::NotificationRequest:
|
|
|
|
Mail::HandleNotificationRequest(sysAddr, entity->GetObjectID());
|
|
|
|
break;
|
|
|
|
case MailMessageID::Send:
|
|
|
|
Mail::HandleSendMail(packet, sysAddr, entity);
|
|
|
|
break;
|
|
|
|
default:
|
2022-07-25 02:26:51 +00:00
|
|
|
Game::logger->Log("Mail", "Unhandled and possibly undefined MailStuffID: %i", int(stuffID));
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAddr, Entity* entity) {
|
|
|
|
//std::string subject = GeneralUtils::WStringToString(ReadFromPacket(packet, 50));
|
|
|
|
//std::string body = GeneralUtils::WStringToString(ReadFromPacket(packet, 400));
|
|
|
|
//std::string recipient = GeneralUtils::WStringToString(ReadFromPacket(packet, 32));
|
|
|
|
|
|
|
|
// Check if the player has restricted mail access
|
|
|
|
auto* character = entity->GetCharacter();
|
|
|
|
|
|
|
|
if (!character) return;
|
|
|
|
|
|
|
|
if (character->HasPermission(ePermissionMap::RestrictedMailAccess)) {
|
|
|
|
// Send a message to the player
|
|
|
|
ChatPackets::SendSystemMessage(
|
|
|
|
sysAddr,
|
|
|
|
u"This character has restricted mail access."
|
|
|
|
);
|
|
|
|
|
|
|
|
Mail::SendSendResponse(sysAddr, Mail::MailSendResponse::AccountIsMuted);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string subject = ReadWStringAsString(packet, 50);
|
|
|
|
std::string body = ReadWStringAsString(packet, 400);
|
|
|
|
std::string recipient = ReadWStringAsString(packet, 32);
|
|
|
|
//Cleanse recipient:
|
|
|
|
recipient = std::regex_replace(recipient, std::regex("[^0-9a-zA-Z]+"), "");
|
|
|
|
|
|
|
|
uint64_t unknown64 = 0;
|
|
|
|
LWOOBJID attachmentID;
|
|
|
|
uint16_t attachmentCount;
|
|
|
|
|
|
|
|
packet->Read(unknown64);
|
|
|
|
packet->Read(attachmentID);
|
|
|
|
packet->Read(attachmentCount); //We don't care about the rest of the packet.
|
|
|
|
uint32_t itemID = static_cast<uint32_t>(attachmentID);
|
|
|
|
LOT itemLOT = 0;
|
|
|
|
//Inventory::InventoryType itemType;
|
2023-07-17 22:55:33 +00:00
|
|
|
int mailCost = Game::zoneManager->GetWorldConfig()->mailBaseFee;
|
2021-12-05 17:54:36 +00:00
|
|
|
int stackSize = 0;
|
2023-03-04 07:16:37 +00:00
|
|
|
auto inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY));
|
2021-12-05 17:54:36 +00:00
|
|
|
Item* item = nullptr;
|
|
|
|
|
|
|
|
if (itemID > 0 && attachmentCount > 0 && inv) {
|
|
|
|
item = inv->FindItemById(attachmentID);
|
|
|
|
if (item) {
|
2023-07-17 22:55:33 +00:00
|
|
|
mailCost += (item->GetInfo().baseValue * Game::zoneManager->GetWorldConfig()->mailPercentAttachmentFee);
|
2021-12-05 17:54:36 +00:00
|
|
|
stackSize = item->GetCount();
|
|
|
|
itemLOT = item->GetLot();
|
|
|
|
} else {
|
|
|
|
Mail::SendSendResponse(sysAddr, MailSendResponse::AttachmentNotFound);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Check if we can even send this mail (negative coins bug):
|
|
|
|
if (entity->GetCharacter()->GetCoins() - mailCost < 0) {
|
|
|
|
Mail::SendSendResponse(sysAddr, MailSendResponse::NotEnoughCoins);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Get the receiver's id:
|
2023-10-10 11:59:30 +00:00
|
|
|
auto recipientInfo = Database::Connection->GetCharacterInfoByName(recipient);
|
|
|
|
uint32_t receiverID = recipientInfo.ID;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
if (receiverID == 0) {
|
2021-12-05 17:54:36 +00:00
|
|
|
Mail::SendSendResponse(sysAddr, Mail::MailSendResponse::RecipientNotFound);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Check if we have a valid receiver:
|
|
|
|
if (GeneralUtils::CaseInsensitiveStringCompare(recipient, character->GetName()) || receiverID == character->GetObjectID()) {
|
|
|
|
Mail::SendSendResponse(sysAddr, Mail::MailSendResponse::CannotMailSelf);
|
|
|
|
return;
|
|
|
|
} else {
|
2023-10-10 11:59:30 +00:00
|
|
|
Database::Connection->WriteMail(character->GetObjectID(), character->GetName(), receiverID, recipient, time(nullptr), subject, body, itemID, itemLOT, 0, attachmentCount, false);
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Mail::SendSendResponse(sysAddr, Mail::MailSendResponse::Success);
|
2023-05-02 22:39:21 +00:00
|
|
|
entity->GetCharacter()->SetCoins(entity->GetCharacter()->GetCoins() - mailCost, eLootSourceType::MAIL);
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-25 02:26:51 +00:00
|
|
|
Game::logger->Log("Mail", "Seeing if we need to remove item with ID/count/LOT: %i %i %i", itemID, attachmentCount, itemLOT);
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
if (inv && itemLOT != 0 && attachmentCount > 0 && item) {
|
2022-07-25 02:26:51 +00:00
|
|
|
Game::logger->Log("Mail", "Trying to remove item with ID/count/LOT: %i %i %i", itemID, attachmentCount, itemLOT);
|
2021-12-05 17:54:36 +00:00
|
|
|
inv->RemoveItem(itemLOT, attachmentCount, INVALID, true);
|
|
|
|
|
|
|
|
auto* missionCompoent = entity->GetComponent<MissionComponent>();
|
|
|
|
|
|
|
|
if (missionCompoent != nullptr) {
|
|
|
|
missionCompoent->Progress(eMissionTaskType::GATHER, itemLOT, LWOOBJID_EMPTY, "", -attachmentCount);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
character->SaveXMLToDatabase();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::HandleDataRequest(RakNet::BitStream* packet, const SystemAddress& sysAddr, Entity* player) {
|
2023-10-10 11:59:30 +00:00
|
|
|
auto mail = Database::Connection->GetAllRecentMailOfUser(player->GetCharacter()->GetObjectID());
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
RakNet::BitStream bitStream;
|
2023-09-21 01:06:28 +00:00
|
|
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
2021-12-05 17:54:36 +00:00
|
|
|
bitStream.Write(int(MailMessageID::MailData));
|
|
|
|
bitStream.Write(int(0));
|
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
bitStream.Write(uint16_t(mail.size()));
|
2021-12-05 17:54:36 +00:00
|
|
|
bitStream.Write(uint16_t(0));
|
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
for (const auto& mailInfo : mail) {
|
|
|
|
bitStream.Write(mailInfo.ID); //MailID
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
WriteStringAsWString(&bitStream, mailInfo.Subject, 50); //subject
|
|
|
|
WriteStringAsWString(&bitStream, mailInfo.Body, 400); //body
|
|
|
|
WriteStringAsWString(&bitStream, mailInfo.SenderName, 32); //sender
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
bitStream.Write(uint32_t(0));
|
|
|
|
bitStream.Write(uint64_t(0));
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
bitStream.Write(mailInfo.AttachmentID); //Attachment ID
|
|
|
|
LOT lot = mailInfo.AttachmentLOT;
|
|
|
|
if (lot <= 0) bitStream.Write(LOT(-1));
|
|
|
|
else bitStream.Write(lot);
|
|
|
|
bitStream.Write(uint32_t(0));
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
bitStream.Write(mailInfo.AttachmentSubkey); //Attachment subKey
|
|
|
|
bitStream.Write(uint16_t(mailInfo.AttachmentCount)); //Attachment count
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
bitStream.Write(uint32_t(0));
|
|
|
|
bitStream.Write(uint16_t(0));
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
bitStream.Write(uint64_t(mailInfo.TimeSent)); //time sent (twice?)
|
|
|
|
bitStream.Write(uint64_t(mailInfo.TimeSent));
|
|
|
|
bitStream.Write(uint8_t(mailInfo.WasRead)); //was read
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
bitStream.Write(uint8_t(0));
|
|
|
|
bitStream.Write(uint16_t(0));
|
|
|
|
bitStream.Write(uint32_t(0));
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Game::server->Send(&bitStream, sysAddr, false);
|
|
|
|
PacketUtils::SavePacket("Max_Mail_Data.bin", (const char*)bitStream.GetData(), bitStream.GetNumberOfBytesUsed());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::HandleAttachmentCollect(RakNet::BitStream* packet, const SystemAddress& sysAddr, Entity* player) {
|
|
|
|
int unknown;
|
|
|
|
uint64_t mailID;
|
|
|
|
LWOOBJID playerID;
|
|
|
|
packet->Read(unknown);
|
|
|
|
packet->Read(mailID);
|
|
|
|
packet->Read(playerID);
|
|
|
|
|
|
|
|
if (mailID > 0 && playerID == player->GetObjectID()) {
|
2023-10-10 11:59:30 +00:00
|
|
|
auto mailInfo = Database::Connection->GetMailByID(mailID);
|
|
|
|
if (mailInfo.ID == 0) return;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-03-04 07:16:37 +00:00
|
|
|
auto inv = static_cast<InventoryComponent*>(player->GetComponent(eReplicaComponentType::INVENTORY));
|
2021-12-05 17:54:36 +00:00
|
|
|
if (!inv) return;
|
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
inv->AddItem(mailInfo.AttachmentLOT, mailInfo.AttachmentCount, eLootSourceType::MAIL);
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
Mail::SendAttachmentRemoveConfirm(sysAddr, mailID);
|
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
Database::Connection->RemoveAttachmentFromMail(mailID);
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::HandleMailDelete(RakNet::BitStream* packet, const SystemAddress& sysAddr) {
|
|
|
|
int unknown;
|
|
|
|
uint64_t mailID;
|
|
|
|
LWOOBJID playerID;
|
|
|
|
packet->Read(unknown);
|
|
|
|
packet->Read(mailID);
|
|
|
|
packet->Read(playerID);
|
|
|
|
|
|
|
|
if (mailID > 0) Mail::SendDeleteConfirm(sysAddr, mailID, playerID);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::HandleMailRead(RakNet::BitStream* packet, const SystemAddress& sysAddr) {
|
|
|
|
int unknown;
|
|
|
|
uint64_t mailID;
|
|
|
|
packet->Read(unknown);
|
|
|
|
packet->Read(mailID);
|
|
|
|
|
|
|
|
if (mailID > 0) Mail::SendReadConfirm(sysAddr, mailID);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::HandleNotificationRequest(const SystemAddress& sysAddr, uint32_t objectID) {
|
2023-04-12 16:48:20 +00:00
|
|
|
auto returnVal = std::async(std::launch::async, [&]() {
|
2023-10-10 11:59:30 +00:00
|
|
|
auto unreadCount = Database::Connection->GetUnreadMailCountForUser(objectID);
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
if (unreadCount > 0) Mail::SendNotification(sysAddr, unreadCount);
|
|
|
|
});
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse response) {
|
|
|
|
RakNet::BitStream bitStream;
|
2023-09-21 01:06:28 +00:00
|
|
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
2021-12-05 17:54:36 +00:00
|
|
|
bitStream.Write(int(MailMessageID::SendResponse));
|
|
|
|
bitStream.Write(int(response));
|
|
|
|
Game::server->Send(&bitStream, sysAddr, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) {
|
|
|
|
RakNet::BitStream bitStream;
|
2023-09-21 01:06:28 +00:00
|
|
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
2021-12-05 17:54:36 +00:00
|
|
|
uint64_t messageType = 2;
|
|
|
|
uint64_t s1 = 0;
|
|
|
|
uint64_t s2 = 0;
|
|
|
|
uint64_t s3 = 0;
|
|
|
|
uint64_t s4 = 0;
|
|
|
|
|
|
|
|
bitStream.Write(messageType);
|
|
|
|
bitStream.Write(s1);
|
|
|
|
bitStream.Write(s2);
|
|
|
|
bitStream.Write(s3);
|
|
|
|
bitStream.Write(s4);
|
|
|
|
bitStream.Write(mailCount);
|
|
|
|
bitStream.Write(int(0)); //Unknown
|
|
|
|
Game::server->Send(&bitStream, sysAddr, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t mailID) {
|
|
|
|
RakNet::BitStream bitStream;
|
2023-09-21 01:06:28 +00:00
|
|
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
2021-12-05 17:54:36 +00:00
|
|
|
bitStream.Write(int(MailMessageID::AttachmentCollectConfirm));
|
|
|
|
bitStream.Write(int(0)); //unknown
|
|
|
|
bitStream.Write(mailID);
|
|
|
|
Game::server->Send(&bitStream, sysAddr, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOOBJID playerID) {
|
|
|
|
RakNet::BitStream bitStream;
|
2023-09-21 01:06:28 +00:00
|
|
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
2021-12-05 17:54:36 +00:00
|
|
|
bitStream.Write(int(MailMessageID::MailDeleteConfirm));
|
|
|
|
bitStream.Write(int(0)); //unknown
|
|
|
|
bitStream.Write(mailID);
|
|
|
|
Game::server->Send(&bitStream, sysAddr, false);
|
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
Database::Connection->DeleteMail(mailID);
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Mail::SendReadConfirm(const SystemAddress& sysAddr, uint64_t mailID) {
|
|
|
|
RakNet::BitStream bitStream;
|
2023-09-21 01:06:28 +00:00
|
|
|
BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
2021-12-05 17:54:36 +00:00
|
|
|
bitStream.Write(int(MailMessageID::MailReadConfirm));
|
|
|
|
bitStream.Write(int(0)); //unknown
|
|
|
|
bitStream.Write(mailID);
|
|
|
|
Game::server->Send(&bitStream, sysAddr, false);
|
|
|
|
|
2023-10-10 11:59:30 +00:00
|
|
|
Database::Connection->SetMailAsRead(mailID);
|
2021-12-05 17:54:36 +00:00
|
|
|
}
|