mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-04-27 09:06:31 +00:00
Overaul, need to test
This commit is contained in:
parent
6cd1310460
commit
7b1d6948c3
@ -7,7 +7,8 @@ enum class eConnectionType : uint16_t {
|
|||||||
CHAT,
|
CHAT,
|
||||||
WORLD = 4,
|
WORLD = 4,
|
||||||
CLIENT,
|
CLIENT,
|
||||||
MASTER
|
MASTER,
|
||||||
|
UNKNOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //!__ECONNECTIONTYPE__H__
|
#endif //!__ECONNECTIONTYPE__H__
|
||||||
|
@ -8,27 +8,14 @@
|
|||||||
#include "dCommonVars.h"
|
#include "dCommonVars.h"
|
||||||
#include "NiQuaternion.h"
|
#include "NiQuaternion.h"
|
||||||
#include "NiPoint3.h"
|
#include "NiPoint3.h"
|
||||||
|
#include "MailInfo.h"
|
||||||
|
|
||||||
|
namespace RakNet {
|
||||||
|
class BitStream;
|
||||||
|
}
|
||||||
|
|
||||||
class IMail {
|
class IMail {
|
||||||
public:
|
public:
|
||||||
struct MailInfo {
|
|
||||||
std::string senderUsername;
|
|
||||||
std::string recipient;
|
|
||||||
std::string subject;
|
|
||||||
std::string body;
|
|
||||||
uint64_t id{};
|
|
||||||
uint32_t senderId{};
|
|
||||||
uint32_t receiverId{};
|
|
||||||
uint64_t timeSent{};
|
|
||||||
bool wasRead{};
|
|
||||||
struct {
|
|
||||||
LWOOBJID itemID{};
|
|
||||||
int32_t itemCount{};
|
|
||||||
LOT itemLOT{};
|
|
||||||
LWOOBJID itemSubkey{};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Insert a new mail into the database.
|
// Insert a new mail into the database.
|
||||||
virtual void InsertNewMail(const MailInfo& mail) = 0;
|
virtual void InsertNewMail(const MailInfo& mail) = 0;
|
||||||
|
|
||||||
|
@ -79,14 +79,14 @@ public:
|
|||||||
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
|
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
|
||||||
void InsertNewBugReport(const IBugReports::Info& info) override;
|
void InsertNewBugReport(const IBugReports::Info& info) override;
|
||||||
void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override;
|
void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override;
|
||||||
void InsertNewMail(const IMail::MailInfo& mail) override;
|
void InsertNewMail(const MailInfo& mail) override;
|
||||||
void InsertNewUgcModel(
|
void InsertNewUgcModel(
|
||||||
std::istringstream& sd0Data,
|
std::istringstream& sd0Data,
|
||||||
const uint32_t blueprintId,
|
const uint32_t blueprintId,
|
||||||
const uint32_t accountId,
|
const uint32_t accountId,
|
||||||
const uint32_t characterId) override;
|
const uint32_t characterId) override;
|
||||||
std::vector<IMail::MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
|
std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
|
||||||
std::optional<IMail::MailInfo> GetMail(const uint64_t mailId) override;
|
std::optional<MailInfo> GetMail(const uint64_t mailId) override;
|
||||||
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
|
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
|
||||||
void MarkMailRead(const uint64_t mailId) override;
|
void MarkMailRead(const uint64_t mailId) override;
|
||||||
void DeleteMail(const uint64_t mailId) override;
|
void DeleteMail(const uint64_t mailId) override;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "MySQLDatabase.h"
|
#include "MySQLDatabase.h"
|
||||||
|
|
||||||
void MySQLDatabase::InsertNewMail(const IMail::MailInfo& mail) {
|
|
||||||
|
void MySQLDatabase::InsertNewMail(const MailInfo& mail) {
|
||||||
ExecuteInsert(
|
ExecuteInsert(
|
||||||
"INSERT INTO `mail` "
|
"INSERT INTO `mail` "
|
||||||
"(`sender_id`, `sender_name`, `receiver_id`, `receiver_name`, `time_sent`, `subject`, `body`, `attachment_id`, `attachment_lot`, `attachment_subkey`, `attachment_count`, `was_read`)"
|
"(`sender_id`, `sender_name`, `receiver_id`, `receiver_name`, `time_sent`, `subject`, `body`, `attachment_id`, `attachment_lot`, `attachment_subkey`, `attachment_count`, `was_read`)"
|
||||||
@ -18,17 +19,17 @@ void MySQLDatabase::InsertNewMail(const IMail::MailInfo& mail) {
|
|||||||
mail.itemCount);
|
mail.itemCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<IMail::MailInfo> MySQLDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
|
std::vector<MailInfo> MySQLDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
|
||||||
auto res = ExecuteSelect(
|
auto res = ExecuteSelect(
|
||||||
"SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent"
|
"SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent"
|
||||||
" FROM mail WHERE receiver_id=? limit ?;",
|
" FROM mail WHERE receiver_id=? limit ?;",
|
||||||
characterId, numberOfMail);
|
characterId, numberOfMail);
|
||||||
|
|
||||||
std::vector<IMail::MailInfo> toReturn;
|
std::vector<MailInfo> toReturn;
|
||||||
toReturn.reserve(res->rowsCount());
|
toReturn.reserve(res->rowsCount());
|
||||||
|
|
||||||
while (res->next()) {
|
while (res->next()) {
|
||||||
IMail::MailInfo mail;
|
MailInfo mail;
|
||||||
mail.id = res->getUInt64("id");
|
mail.id = res->getUInt64("id");
|
||||||
mail.subject = res->getString("subject").c_str();
|
mail.subject = res->getString("subject").c_str();
|
||||||
mail.body = res->getString("body").c_str();
|
mail.body = res->getString("body").c_str();
|
||||||
@ -46,14 +47,14 @@ std::vector<IMail::MailInfo> MySQLDatabase::GetMailForPlayer(const uint32_t char
|
|||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<IMail::MailInfo> MySQLDatabase::GetMail(const uint64_t mailId) {
|
std::optional<MailInfo> MySQLDatabase::GetMail(const uint64_t mailId) {
|
||||||
auto res = ExecuteSelect("SELECT attachment_lot, attachment_count FROM mail WHERE id=? LIMIT 1;", mailId);
|
auto res = ExecuteSelect("SELECT attachment_lot, attachment_count FROM mail WHERE id=? LIMIT 1;", mailId);
|
||||||
|
|
||||||
if (!res->next()) {
|
if (!res->next()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMail::MailInfo toReturn;
|
MailInfo toReturn;
|
||||||
toReturn.itemLOT = res->getInt("attachment_lot");
|
toReturn.itemLOT = res->getInt("attachment_lot");
|
||||||
toReturn.itemCount = res->getInt("attachment_count");
|
toReturn.itemCount = res->getInt("attachment_count");
|
||||||
|
|
||||||
|
@ -77,14 +77,14 @@ public:
|
|||||||
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
|
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
|
||||||
void InsertNewBugReport(const IBugReports::Info& info) override;
|
void InsertNewBugReport(const IBugReports::Info& info) override;
|
||||||
void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override;
|
void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override;
|
||||||
void InsertNewMail(const IMail::MailInfo& mail) override;
|
void InsertNewMail(const MailInfo& mail) override;
|
||||||
void InsertNewUgcModel(
|
void InsertNewUgcModel(
|
||||||
std::istringstream& sd0Data,
|
std::istringstream& sd0Data,
|
||||||
const uint32_t blueprintId,
|
const uint32_t blueprintId,
|
||||||
const uint32_t accountId,
|
const uint32_t accountId,
|
||||||
const uint32_t characterId) override;
|
const uint32_t characterId) override;
|
||||||
std::vector<IMail::MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
|
std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
|
||||||
std::optional<IMail::MailInfo> GetMail(const uint64_t mailId) override;
|
std::optional<MailInfo> GetMail(const uint64_t mailId) override;
|
||||||
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
|
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
|
||||||
void MarkMailRead(const uint64_t mailId) override;
|
void MarkMailRead(const uint64_t mailId) override;
|
||||||
void DeleteMail(const uint64_t mailId) override;
|
void DeleteMail(const uint64_t mailId) override;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "SQLiteDatabase.h"
|
#include "SQLiteDatabase.h"
|
||||||
|
|
||||||
void SQLiteDatabase::InsertNewMail(const IMail::MailInfo& mail) {
|
void SQLiteDatabase::InsertNewMail(const MailInfo& mail) {
|
||||||
ExecuteInsert(
|
ExecuteInsert(
|
||||||
"INSERT INTO `mail` "
|
"INSERT INTO `mail` "
|
||||||
"(`sender_id`, `sender_name`, `receiver_id`, `receiver_name`, `time_sent`, `subject`, `body`, `attachment_id`, `attachment_lot`, `attachment_subkey`, `attachment_count`, `was_read`)"
|
"(`sender_id`, `sender_name`, `receiver_id`, `receiver_name`, `time_sent`, `subject`, `body`, `attachment_id`, `attachment_lot`, `attachment_subkey`, `attachment_count`, `was_read`)"
|
||||||
@ -18,16 +18,16 @@ void SQLiteDatabase::InsertNewMail(const IMail::MailInfo& mail) {
|
|||||||
mail.itemCount);
|
mail.itemCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<IMail::MailInfo> SQLiteDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
|
std::vector<MailInfo> SQLiteDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
|
||||||
auto [_, res] = ExecuteSelect(
|
auto [_, res] = ExecuteSelect(
|
||||||
"SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent"
|
"SELECT id, subject, body, sender_name, attachment_id, attachment_lot, attachment_subkey, attachment_count, was_read, time_sent"
|
||||||
" FROM mail WHERE receiver_id=? limit ?;",
|
" FROM mail WHERE receiver_id=? limit ?;",
|
||||||
characterId, numberOfMail);
|
characterId, numberOfMail);
|
||||||
|
|
||||||
std::vector<IMail::MailInfo> toReturn;
|
std::vector<MailInfo> toReturn;
|
||||||
|
|
||||||
while (!res.eof()) {
|
while (!res.eof()) {
|
||||||
IMail::MailInfo mail;
|
MailInfo mail;
|
||||||
mail.id = res.getInt64Field("id");
|
mail.id = res.getInt64Field("id");
|
||||||
mail.subject = res.getStringField("subject");
|
mail.subject = res.getStringField("subject");
|
||||||
mail.body = res.getStringField("body");
|
mail.body = res.getStringField("body");
|
||||||
@ -46,14 +46,14 @@ std::vector<IMail::MailInfo> SQLiteDatabase::GetMailForPlayer(const uint32_t cha
|
|||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<IMail::MailInfo> SQLiteDatabase::GetMail(const uint64_t mailId) {
|
std::optional<MailInfo> SQLiteDatabase::GetMail(const uint64_t mailId) {
|
||||||
auto [_, res] = ExecuteSelect("SELECT attachment_lot, attachment_count FROM mail WHERE id=? LIMIT 1;", mailId);
|
auto [_, res] = ExecuteSelect("SELECT attachment_lot, attachment_count FROM mail WHERE id=? LIMIT 1;", mailId);
|
||||||
|
|
||||||
if (res.eof()) {
|
if (res.eof()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMail::MailInfo toReturn;
|
MailInfo toReturn;
|
||||||
toReturn.itemLOT = res.getIntField("attachment_lot");
|
toReturn.itemLOT = res.getIntField("attachment_lot");
|
||||||
toReturn.itemCount = res.getIntField("attachment_count");
|
toReturn.itemCount = res.getIntField("attachment_count");
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ void TestSQLDatabase::InsertCheatDetection(const IPlayerCheatDetections::Info& i
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestSQLDatabase::InsertNewMail(const IMail::MailInfo& mail) {
|
void TestSQLDatabase::InsertNewMail(const MailInfo& mail) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,11 +192,11 @@ void TestSQLDatabase::InsertNewUgcModel(std::istringstream& sd0Data, const uint3
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<IMail::MailInfo> TestSQLDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
|
std::vector<MailInfo> TestSQLDatabase::GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<IMail::MailInfo> TestSQLDatabase::GetMail(const uint64_t mailId) {
|
std::optional<MailInfo> TestSQLDatabase::GetMail(const uint64_t mailId) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,14 +56,14 @@ class TestSQLDatabase : public GameDatabase {
|
|||||||
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
|
void UpdatePerformanceCost(const LWOZONEID& zoneId, const float performanceCost) override;
|
||||||
void InsertNewBugReport(const IBugReports::Info& info) override;
|
void InsertNewBugReport(const IBugReports::Info& info) override;
|
||||||
void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override;
|
void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override;
|
||||||
void InsertNewMail(const IMail::MailInfo& mail) override;
|
void InsertNewMail(const MailInfo& mail) override;
|
||||||
void InsertNewUgcModel(
|
void InsertNewUgcModel(
|
||||||
std::istringstream& sd0Data,
|
std::istringstream& sd0Data,
|
||||||
const uint32_t blueprintId,
|
const uint32_t blueprintId,
|
||||||
const uint32_t accountId,
|
const uint32_t accountId,
|
||||||
const uint32_t characterId) override;
|
const uint32_t characterId) override;
|
||||||
std::vector<IMail::MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
|
std::vector<MailInfo> GetMailForPlayer(const uint32_t characterId, const uint32_t numberOfMail) override;
|
||||||
std::optional<IMail::MailInfo> GetMail(const uint64_t mailId) override;
|
std::optional<MailInfo> GetMail(const uint64_t mailId) override;
|
||||||
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
|
uint32_t GetUnreadMailCount(const uint32_t characterId) override;
|
||||||
void MarkMailRead(const uint64_t mailId) override;
|
void MarkMailRead(const uint64_t mailId) override;
|
||||||
void DeleteMail(const uint64_t mailId) override;
|
void DeleteMail(const uint64_t mailId) override;
|
||||||
|
@ -786,7 +786,7 @@ void CharacterComponent::AwardClaimCodes() {
|
|||||||
subject << "%[RewardCodes_" << rewardCode << "_subjectText]";
|
subject << "%[RewardCodes_" << rewardCode << "_subjectText]";
|
||||||
std::ostringstream body;
|
std::ostringstream body;
|
||||||
body << "%[RewardCodes_" << rewardCode << "_bodyText]";
|
body << "%[RewardCodes_" << rewardCode << "_bodyText]";
|
||||||
Mail::SendMail(LWOOBJID_EMPTY, "%[MAIL_SYSTEM_NOTIFICATION]", m_Parent, subject.str(), body.str(), attachmentLOT, 1);
|
Mail::SendMail(m_Parent, subject.str(), body.str(), attachmentLOT, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ void InventoryComponent::AddItem(
|
|||||||
|
|
||||||
switch (sourceType) {
|
switch (sourceType) {
|
||||||
case 0:
|
case 0:
|
||||||
Mail::SendMail(LWOOBJID_EMPTY, "Darkflame Universe", m_Parent, "Lost Reward", "You received an item and didn't have room for it.", lot, size);
|
Mail::SendMail(m_Parent, "%[MAIL_ACTIVITY_OVERFLOW_HEADER]", "%[MAIL_ACTIVITY_OVERFLOW_BODY]", lot, size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -26,12 +26,280 @@
|
|||||||
#include "eMissionTaskType.h"
|
#include "eMissionTaskType.h"
|
||||||
#include "eReplicaComponentType.h"
|
#include "eReplicaComponentType.h"
|
||||||
#include "eConnectionType.h"
|
#include "eConnectionType.h"
|
||||||
|
#include "User.h"
|
||||||
|
#include "StringifiedEnum.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const std::string DefaultSender = "%[MAIL_SYSTEM_NOTIFICATION]";
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Mail {
|
||||||
|
std::map<eMessageID, std::function<std::unique_ptr<MailLUBitStream>(const SystemAddress&, Entity* const)>> handlers = {
|
||||||
|
{eMessageID::SendRequest, [](const SystemAddress& sysAddr, Entity* const player) {
|
||||||
|
return std::make_unique<SendRequest>();
|
||||||
|
}},
|
||||||
|
{eMessageID::DataRequest, [](const SystemAddress& sysAddr, Entity* const player) {
|
||||||
|
return std::make_unique<DataRequest>();
|
||||||
|
}},
|
||||||
|
{eMessageID::AttachmentCollectRequest, [](const SystemAddress& sysAddr, Entity* const player) {
|
||||||
|
return std::make_unique<AttachmentCollectRequest>();
|
||||||
|
}},
|
||||||
|
{eMessageID::DeleteRequest, [](const SystemAddress& sysAddr, Entity* const player) {
|
||||||
|
return std::make_unique<DeleteRequest>();
|
||||||
|
}},
|
||||||
|
{eMessageID::ReadRequest, [](const SystemAddress& sysAddr, Entity* const player) {
|
||||||
|
return std::make_unique<ReadRequest>();
|
||||||
|
}},
|
||||||
|
{eMessageID::NotificationRequest, [](const SystemAddress& sysAddr, Entity* const player) {
|
||||||
|
return std::make_unique<NotificationRequest>();
|
||||||
|
}},
|
||||||
|
};
|
||||||
|
|
||||||
|
void MailLUBitStream::Serialize(RakNet::BitStream& bitStream) const {
|
||||||
|
bitStream.Write(messageID);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MailLUBitStream::Deserialize(RakNet::BitStream& bitstream) {
|
||||||
|
VALIDATE_READ(bitstream.Read(messageID));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SendRequest::Deserialize(RakNet::BitStream& bitStream) {
|
||||||
|
VALIDATE_READ(mailInfo.Deserialize(bitStream));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendRequest::Handle() {
|
||||||
|
//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 = player->GetCharacter();
|
||||||
|
|
||||||
|
if (!character) return;
|
||||||
|
|
||||||
|
if (character->HasPermission(ePermissionMap::RestrictedMailAccess) || character->GetParentUser()->GetIsMuted()) {
|
||||||
|
// Send a message to the player
|
||||||
|
ChatPackets::SendSystemMessage(
|
||||||
|
sysAddr,
|
||||||
|
u"This character has restricted mail access."
|
||||||
|
);
|
||||||
|
|
||||||
|
SendResponse(Mail::eSendResponse::SenderAccountIsMuted).Send(sysAddr);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Cleanse recipient:
|
||||||
|
mailInfo.recipient = std::regex_replace(mailInfo.recipient, std::regex("[^0-9a-zA-Z]+"), "");
|
||||||
|
|
||||||
|
//Inventory::InventoryType itemType;
|
||||||
|
int mailCost = Game::zoneManager->GetWorldConfig()->mailBaseFee;
|
||||||
|
int stackSize = 0;
|
||||||
|
auto inv = static_cast<InventoryComponent*>(player->GetComponent(eReplicaComponentType::INVENTORY));
|
||||||
|
Item* item = nullptr;
|
||||||
|
|
||||||
|
if (mailInfo.itemID > 0 && mailInfo.itemCount > 0 && inv) {
|
||||||
|
item = inv->FindItemById(mailInfo.itemID);
|
||||||
|
if (item) {
|
||||||
|
mailCost += (item->GetInfo().baseValue * Game::zoneManager->GetWorldConfig()->mailPercentAttachmentFee);
|
||||||
|
stackSize = item->GetCount();
|
||||||
|
mailInfo.itemLOT = item->GetLot();
|
||||||
|
} else {
|
||||||
|
SendResponse(eSendResponse::AttachmentNotFound).Send(sysAddr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if we can even send this mail (negative coins bug):
|
||||||
|
if (player->GetCharacter()->GetCoins() - mailCost < 0) {
|
||||||
|
SendResponse(eSendResponse::NotEnoughCoins).Send(sysAddr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the receiver's id:
|
||||||
|
auto receiverID = Database::Get()->GetCharacterInfo(mailInfo.recipient);
|
||||||
|
|
||||||
|
if (!receiverID) {
|
||||||
|
SendResponse(Mail::eSendResponse::RecipientNotFound).Send(sysAddr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if we have a valid receiver:
|
||||||
|
if (GeneralUtils::CaseInsensitiveStringCompare(mailInfo.recipient, character->GetName()) || receiverID->id == character->GetID()) {
|
||||||
|
SendResponse(Mail::eSendResponse::CannotMailSelf).Send(sysAddr);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Database::Get()->InsertNewMail(mailInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendResponse(Mail::eSendResponse::Success).Send(sysAddr);
|
||||||
|
player->GetCharacter()->SetCoins(player->GetCharacter()->GetCoins() - mailCost, eLootSourceType::MAIL);
|
||||||
|
|
||||||
|
LOG("Seeing if we need to remove item with ID/count/LOT: %i %i %i", mailInfo.itemID, mailInfo.itemCount, mailInfo.itemLOT);
|
||||||
|
|
||||||
|
if (inv && mailInfo.itemLOT != 0 && mailInfo.itemCount > 0 && item) {
|
||||||
|
LOG("Trying to remove item with ID/count/LOT: %i %i %i", mailInfo.itemID, mailInfo.itemCount, mailInfo.itemLOT);
|
||||||
|
inv->RemoveItem(mailInfo.itemLOT, mailInfo.itemCount, INVALID, true);
|
||||||
|
|
||||||
|
auto* missionCompoent = player->GetComponent<MissionComponent>();
|
||||||
|
|
||||||
|
if (missionCompoent != nullptr) {
|
||||||
|
missionCompoent->Progress(eMissionTaskType::GATHER, mailInfo.itemLOT, LWOOBJID_EMPTY, "", -mailInfo.itemCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
character->SaveXMLToDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendResponse::Serialize(RakNet::BitStream& bitStream) const {
|
||||||
|
MailLUBitStream::Serialize(bitStream);
|
||||||
|
bitStream.Write(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationResponse::Serialize(RakNet::BitStream& bitStream) const {
|
||||||
|
MailLUBitStream::Serialize(bitStream);
|
||||||
|
bitStream.Write(notification);
|
||||||
|
bitStream.Write<uint64_t>(0); // unused
|
||||||
|
bitStream.Write<uint64_t>(0); // unused
|
||||||
|
bitStream.Write(auctionID);
|
||||||
|
bitStream.Write<uint64_t>(0); // unused
|
||||||
|
bitStream.Write(mailCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataRequest::Handle() {
|
||||||
|
auto playerMail = Database::Get()->GetMailForPlayer(player->GetObjectID());
|
||||||
|
|
||||||
|
if (playerMail.size() > 0) {
|
||||||
|
DataResponse response;
|
||||||
|
response.playerMail = playerMail;
|
||||||
|
response.Send(sysAddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataResponse::Serialize(RakNet::BitStream& bitStream) const {
|
||||||
|
MailLUBitStream::Serialize(bitStream);
|
||||||
|
|
||||||
|
bitStream.Write(this->throttled);
|
||||||
|
bitStream.Write<uint16_t>(this->playerMail.size());
|
||||||
|
bitStream.Write<uint16_t>(0); // packing
|
||||||
|
for (const auto& mail : this->playerMail) {
|
||||||
|
mail.Serialize(bitStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AttachmentCollectRequest::Deserialize(RakNet::BitStream& bitStream) {
|
||||||
|
VALIDATE_READ(bitStream.Read(mailID));
|
||||||
|
VALIDATE_READ(bitStream.Read(playerID));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachmentCollectRequest::Handle() {
|
||||||
|
if (mailID > 0 && playerID == player->GetObjectID()) {
|
||||||
|
auto playerMail = Database::Get()->GetMail(mailID);
|
||||||
|
|
||||||
|
LOT attachmentLOT = 0;
|
||||||
|
uint32_t attachmentCount = 0;
|
||||||
|
|
||||||
|
if (playerMail) {
|
||||||
|
attachmentLOT = playerMail->itemLOT;
|
||||||
|
attachmentCount = playerMail->itemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto inv = player->GetComponent<InventoryComponent>();
|
||||||
|
if (!inv) return;
|
||||||
|
|
||||||
|
inv->AddItem(attachmentLOT, attachmentCount, eLootSourceType::MAIL);
|
||||||
|
|
||||||
|
Database::Get()->ClaimMailItem(mailID);
|
||||||
|
|
||||||
|
AttachmentCollectResponse(eRemoveAttachmentResponse::Success, mailID).Send(sysAddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachmentCollectResponse::Serialize(RakNet::BitStream& bitStream) const {
|
||||||
|
MailLUBitStream::Serialize(bitStream);
|
||||||
|
bitStream.Write(status);
|
||||||
|
bitStream.Write(mailID);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeleteRequest::Deserialize(RakNet::BitStream& bitStream) {
|
||||||
|
VALIDATE_READ(bitStream.Read(mailID));
|
||||||
|
VALIDATE_READ(bitStream.Read(playerID));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteRequest::Handle() {
|
||||||
|
DeleteResponse response(mailID);
|
||||||
|
if (mailID > 0) {
|
||||||
|
Database::Get()->DeleteMail(mailID);
|
||||||
|
response.status = eDeleteResponse::Success;
|
||||||
|
}
|
||||||
|
response.Send(sysAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteResponse::Serialize(RakNet::BitStream& bitStream) const {
|
||||||
|
MailLUBitStream::Serialize(bitStream);
|
||||||
|
bitStream.Write(status);
|
||||||
|
bitStream.Write(mailID);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadRequest::Deserialize(RakNet::BitStream& bitStream) {
|
||||||
|
int32_t unknown;
|
||||||
|
VALIDATE_READ(bitStream.Read(unknown));
|
||||||
|
VALIDATE_READ(bitStream.Read(mailID));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadRequest::Handle() {
|
||||||
|
ReadResponse response;
|
||||||
|
response.mailID = mailID;
|
||||||
|
response.status = eReadResponse::Success;
|
||||||
|
|
||||||
|
if (mailID > 0) Database::Get()->MarkMailRead(mailID);
|
||||||
|
else response.status = eReadResponse::UnknownError;
|
||||||
|
response.Send(sysAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadResponse::Serialize(RakNet::BitStream& bitStream) const {
|
||||||
|
MailLUBitStream::Serialize(bitStream);
|
||||||
|
bitStream.Write(status);
|
||||||
|
bitStream.Write(mailID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationRequest::Handle() {
|
||||||
|
auto unreadMailCount = Database::Get()->GetUnreadMailCount(player->GetObjectID());
|
||||||
|
if (unreadMailCount > 0) NotificationResponse(eNotificationResponse::NewMail, unreadMailCount).Send(sysAddr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non Stuct Functions
|
||||||
|
void Mail::HandleMail(RakNet::BitStream& inStream, const SystemAddress& sysAddr, Entity* player) {
|
||||||
|
MailLUBitStream data;
|
||||||
|
if (!data.Deserialize(inStream)) {
|
||||||
|
LOG_DEBUG("Error Reading Mail header");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = handlers.find(data.messageID);
|
||||||
|
if (it != handlers.end()) {
|
||||||
|
auto mail_data = it->second(sysAddr, player);
|
||||||
|
if (!mail_data->Deserialize(inStream)) {
|
||||||
|
LOG_DEBUG("Error Reading Mail Data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mail_data->Handle();
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("Unhandled Mail Packet with ID: %i", data.messageID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Mail::SendMail(const Entity* recipient, const std::string& subject, const std::string& body, const LOT attachment,
|
void Mail::SendMail(const Entity* recipient, const std::string& subject, const std::string& body, const LOT attachment,
|
||||||
const uint16_t attachmentCount) {
|
const uint16_t attachmentCount) {
|
||||||
SendMail(
|
SendMail(
|
||||||
LWOOBJID_EMPTY,
|
LWOOBJID_EMPTY,
|
||||||
ServerName,
|
DefaultSender,
|
||||||
recipient->GetObjectID(),
|
recipient->GetObjectID(),
|
||||||
recipient->GetCharacter()->GetName(),
|
recipient->GetCharacter()->GetName(),
|
||||||
subject,
|
subject,
|
||||||
@ -46,7 +314,7 @@ void Mail::SendMail(const LWOOBJID recipient, const std::string& recipientName,
|
|||||||
const std::string& body, const LOT attachment, const uint16_t attachmentCount, const SystemAddress& sysAddr) {
|
const std::string& body, const LOT attachment, const uint16_t attachmentCount, const SystemAddress& sysAddr) {
|
||||||
SendMail(
|
SendMail(
|
||||||
LWOOBJID_EMPTY,
|
LWOOBJID_EMPTY,
|
||||||
ServerName,
|
DefaultSender,
|
||||||
recipient,
|
recipient,
|
||||||
recipientName,
|
recipientName,
|
||||||
subject,
|
subject,
|
||||||
@ -75,7 +343,7 @@ void Mail::SendMail(const LWOOBJID sender, const std::string& senderName, const
|
|||||||
void Mail::SendMail(const LWOOBJID sender, const std::string& senderName, LWOOBJID recipient,
|
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 std::string& recipientName, const std::string& subject, const std::string& body, const LOT attachment,
|
||||||
const uint16_t attachmentCount, const SystemAddress& sysAddr) {
|
const uint16_t attachmentCount, const SystemAddress& sysAddr) {
|
||||||
IMail::MailInfo mailInsert;
|
MailInfo mailInsert;
|
||||||
mailInsert.senderUsername = senderName;
|
mailInsert.senderUsername = senderName;
|
||||||
mailInsert.recipient = recipientName;
|
mailInsert.recipient = recipientName;
|
||||||
mailInsert.subject = subject;
|
mailInsert.subject = subject;
|
||||||
@ -91,254 +359,5 @@ void Mail::SendMail(const LWOOBJID sender, const std::string& senderName, LWOOBJ
|
|||||||
|
|
||||||
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) return; // TODO: Echo to chat server
|
if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) return; // TODO: Echo to chat server
|
||||||
|
|
||||||
SendNotification(sysAddr, 1); //Show the "one new mail" message
|
NotificationResponse(eNotificationResponse::NewMail).Send(sysAddr);
|
||||||
}
|
|
||||||
|
|
||||||
void Mail::HandleMail(RakNet::BitStream& packet, const SystemAddress& sysAddr, Entity* entity) {
|
|
||||||
int mailStuffID = 0;
|
|
||||||
packet.Read(mailStuffID);
|
|
||||||
|
|
||||||
auto returnVal = std::async(std::launch::async, [&packet, &sysAddr, entity, mailStuffID]() {
|
|
||||||
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:
|
|
||||||
LOG("Unhandled and possibly undefined MailStuffID: %i", int(stuffID));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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::SenderAccountIsMuted);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LUWString subjectRead(50);
|
|
||||||
packet.Read(subjectRead);
|
|
||||||
|
|
||||||
LUWString bodyRead(400);
|
|
||||||
packet.Read(bodyRead);
|
|
||||||
|
|
||||||
LUWString recipientRead(32);
|
|
||||||
packet.Read(recipientRead);
|
|
||||||
|
|
||||||
const std::string subject = subjectRead.GetAsString();
|
|
||||||
const std::string body = bodyRead.GetAsString();
|
|
||||||
|
|
||||||
//Cleanse recipient:
|
|
||||||
const std::string recipient = std::regex_replace(recipientRead.GetAsString(), 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;
|
|
||||||
int mailCost = Game::zoneManager->GetWorldConfig()->mailBaseFee;
|
|
||||||
int stackSize = 0;
|
|
||||||
auto inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY));
|
|
||||||
Item* item = nullptr;
|
|
||||||
|
|
||||||
if (itemID > 0 && attachmentCount > 0 && inv) {
|
|
||||||
item = inv->FindItemById(attachmentID);
|
|
||||||
if (item) {
|
|
||||||
mailCost += (item->GetInfo().baseValue * Game::zoneManager->GetWorldConfig()->mailPercentAttachmentFee);
|
|
||||||
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:
|
|
||||||
auto receiverID = Database::Get()->GetCharacterInfo(recipient);
|
|
||||||
|
|
||||||
if (!receiverID) {
|
|
||||||
Mail::SendSendResponse(sysAddr, Mail::MailSendResponse::RecipientNotFound);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check if we have a valid receiver:
|
|
||||||
if (GeneralUtils::CaseInsensitiveStringCompare(recipient, character->GetName()) || receiverID->id == character->GetID()) {
|
|
||||||
Mail::SendSendResponse(sysAddr, Mail::MailSendResponse::CannotMailSelf);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
IMail::MailInfo mailInsert;
|
|
||||||
mailInsert.senderUsername = character->GetName();
|
|
||||||
mailInsert.recipient = recipient;
|
|
||||||
mailInsert.subject = subject;
|
|
||||||
mailInsert.body = body;
|
|
||||||
mailInsert.senderId = character->GetID();
|
|
||||||
mailInsert.receiverId = receiverID->id;
|
|
||||||
mailInsert.itemCount = attachmentCount;
|
|
||||||
mailInsert.itemID = itemID;
|
|
||||||
mailInsert.itemLOT = itemLOT;
|
|
||||||
mailInsert.itemSubkey = LWOOBJID_EMPTY;
|
|
||||||
Database::Get()->InsertNewMail(mailInsert);
|
|
||||||
}
|
|
||||||
|
|
||||||
Mail::SendSendResponse(sysAddr, Mail::MailSendResponse::Success);
|
|
||||||
entity->GetCharacter()->SetCoins(entity->GetCharacter()->GetCoins() - mailCost, eLootSourceType::MAIL);
|
|
||||||
|
|
||||||
LOG("Seeing if we need to remove item with ID/count/LOT: %i %i %i", itemID, attachmentCount, itemLOT);
|
|
||||||
|
|
||||||
if (inv && itemLOT != 0 && attachmentCount > 0 && item) {
|
|
||||||
LOG("Trying to remove item with ID/count/LOT: %i %i %i", itemID, attachmentCount, itemLOT);
|
|
||||||
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) {
|
|
||||||
auto playerMail = Database::Get()->GetMailForPlayer(player->GetCharacter()->GetID(), 20);
|
|
||||||
RakNet::BitStream bitStream;
|
|
||||||
Mail::Data data = Mail::Data(playerMail);
|
|
||||||
bitStream.Write(data);
|
|
||||||
Game::server->Send(bitStream, sysAddr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
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()) {
|
|
||||||
auto playerMail = Database::Get()->GetMail(mailID);
|
|
||||||
|
|
||||||
LOT attachmentLOT = 0;
|
|
||||||
uint32_t attachmentCount = 0;
|
|
||||||
|
|
||||||
if (playerMail) {
|
|
||||||
attachmentLOT = playerMail->itemLOT;
|
|
||||||
attachmentCount = playerMail->itemCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto inv = player->GetComponent<InventoryComponent>();
|
|
||||||
if (!inv) return;
|
|
||||||
|
|
||||||
inv->AddItem(attachmentLOT, attachmentCount, eLootSourceType::MAIL);
|
|
||||||
|
|
||||||
Mail::SendAttachmentRemoveConfirm(sysAddr, mailID);
|
|
||||||
|
|
||||||
Database::Get()->ClaimMailItem(mailID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
auto unreadMailCount = Database::Get()->GetUnreadMailCount(objectID);
|
|
||||||
|
|
||||||
if (unreadMailCount > 0) Mail::SendNotification(sysAddr, unreadMailCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse response) {
|
|
||||||
RakNet::BitStream bitStream;
|
|
||||||
Mail::Response data = Mail::Response(response);
|
|
||||||
bitStream.Write(data);
|
|
||||||
Game::server->Send(bitStream, sysAddr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) {
|
|
||||||
RakNet::BitStream bitStream;
|
|
||||||
Mail::Notification data = Mail::Notification(MailNotification::NewMail, mailCount);
|
|
||||||
Game::server->Send(bitStream, sysAddr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t mailID) {
|
|
||||||
RakNet::BitStream bitStream;
|
|
||||||
AttachmentCollect data = AttachmentCollect(MailRemoveAttachment::Success, mailID);
|
|
||||||
bitStream.Write(data);
|
|
||||||
Game::server->Send(bitStream, sysAddr, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOOBJID playerID) {
|
|
||||||
RakNet::BitStream bitStream;
|
|
||||||
DeleteMail data = DeleteMail(MailDeleteResponse::Success, mailID);
|
|
||||||
bitStream.Write(data);
|
|
||||||
Game::server->Send(bitStream, sysAddr, false);
|
|
||||||
|
|
||||||
Database::Get()->DeleteMail(mailID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mail::SendReadConfirm(const SystemAddress& sysAddr, uint64_t mailID) {
|
|
||||||
RakNet::BitStream bitStream;
|
|
||||||
Read data = Read(MailReadResponse::Success, mailID);
|
|
||||||
bitStream.Write(data);
|
|
||||||
Game::server->Send(bitStream, sysAddr, false);
|
|
||||||
|
|
||||||
Database::Get()->MarkMailRead(mailID);
|
|
||||||
}
|
}
|
||||||
|
@ -5,25 +5,24 @@
|
|||||||
#include "BitStream.h"
|
#include "BitStream.h"
|
||||||
#include "RakNetTypes.h"
|
#include "RakNetTypes.h"
|
||||||
#include "dCommonVars.h"
|
#include "dCommonVars.h"
|
||||||
|
#include "BitStreamUtils.h"
|
||||||
template <typename T>
|
#include "MailInfo.h"
|
||||||
struct LUHeader;
|
|
||||||
|
|
||||||
class Entity;
|
class Entity;
|
||||||
|
|
||||||
namespace Mail {
|
namespace Mail {
|
||||||
enum class MailMessageID : uint32_t {
|
enum class eMessageID : uint32_t {
|
||||||
Send = 0,
|
SendRequest = 0,
|
||||||
SendResponse,
|
SendResponse,
|
||||||
Notification,
|
NotificationResponse,
|
||||||
DataRequest,
|
DataRequest,
|
||||||
MailData,
|
DataResponse,
|
||||||
AttachmentCollect,
|
AttachmentCollectRequest,
|
||||||
AttachmentCollectConfirm,
|
AttachmentCollectResponse,
|
||||||
MailDelete,
|
DeleteRequest,
|
||||||
MailDeleteConfirm,
|
DeleteResponse,
|
||||||
MailRead,
|
ReadRequest,
|
||||||
MailReadConfirm,
|
ReadResponse,
|
||||||
NotificationRequest,
|
NotificationRequest,
|
||||||
AuctionCreate,
|
AuctionCreate,
|
||||||
AuctionCreationResponse,
|
AuctionCreationResponse,
|
||||||
@ -36,7 +35,7 @@ namespace Mail {
|
|||||||
UnknownError
|
UnknownError
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class MailSendResponse : uint32_t {
|
enum class eSendResponse : uint32_t {
|
||||||
Success = 0,
|
Success = 0,
|
||||||
NotEnoughCoins,
|
NotEnoughCoins,
|
||||||
AttachmentNotFound,
|
AttachmentNotFound,
|
||||||
@ -54,15 +53,15 @@ namespace Mail {
|
|||||||
UnknownError
|
UnknownError
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class MailDeleteResponse : uint32_t {
|
enum class eDeleteResponse : uint32_t {
|
||||||
Success = 0,
|
Success = 0,
|
||||||
HasAttachements,
|
HasAttachements,
|
||||||
NotFoud,
|
NotFound,
|
||||||
Throttled,
|
Throttled,
|
||||||
UnknownError
|
UnknownError
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class MailRemoveAttachment : uint32_t {
|
enum class eRemoveAttachmentResponse : uint32_t {
|
||||||
Success = 0,
|
Success = 0,
|
||||||
AttachmentNotFound,
|
AttachmentNotFound,
|
||||||
NoSpaceInInventory,
|
NoSpaceInInventory,
|
||||||
@ -71,7 +70,7 @@ namespace Mail {
|
|||||||
UnknownError
|
UnknownError
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class MailNotification : uint32_t {
|
enum class eNotificationResponse : uint32_t {
|
||||||
NewMail = 0,
|
NewMail = 0,
|
||||||
UnHandled,
|
UnHandled,
|
||||||
AuctionWon,
|
AuctionWon,
|
||||||
@ -83,106 +82,118 @@ namespace Mail {
|
|||||||
UnknownError
|
UnknownError
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class MailReadResponse : uint32_t {
|
enum class eReadResponse : uint32_t {
|
||||||
Success = 0,
|
Success = 0,
|
||||||
UnknownError
|
UnknownError
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MailInfo {
|
struct MailLUBitStream : public LUBitStream {
|
||||||
uint64_t id;
|
eMessageID messageID = eMessageID::UnknownError;
|
||||||
std::string senderUsername;
|
const SystemAddress sysAddr = UNASSIGNED_SYSTEM_ADDRESS;
|
||||||
std::string recipient;
|
Entity* const player = nullptr;
|
||||||
std::string subject;
|
|
||||||
std::string body;
|
MailLUBitStream() = default;
|
||||||
uint32_t senderId;
|
MailLUBitStream(eMessageID _messageID) : LUBitStream(eConnectionType::CLIENT, MessageType::Client::MAIL), messageID{_messageID} {};
|
||||||
uint32_t receiverId;
|
MailLUBitStream(const SystemAddress& _sysAddr, Entity* const _player) : sysAddr(_sysAddr), player(_player) {};
|
||||||
uint32_t itemCount;
|
|
||||||
uint32_t itemID;
|
virtual void Serialize(RakNet::BitStream& bitStream) const override;
|
||||||
LOT itemLOT;
|
virtual bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||||
LWOOBJID itemSubkey;
|
virtual void Handle() override {};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MailLUHeader {
|
struct SendRequest : public MailLUBitStream {
|
||||||
LUHeader<MessageType::Client> header = LUHeader<MessageType::Client>(eConnectionType::CLIENT, MessageType::Client::MAIL);
|
MailInfo mailInfo;
|
||||||
MailMessageID messageID;
|
|
||||||
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||||
|
void Handle() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Data {
|
struct SendResponse :public MailLUBitStream {
|
||||||
MailLUHeader header;
|
eSendResponse response = eSendResponse::UnknownError;
|
||||||
|
|
||||||
|
SendResponse(eSendResponse _response) : MailLUBitStream(eMessageID::SendResponse), response{_response} {};
|
||||||
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NotificationResponse : public MailLUBitStream {
|
||||||
|
eNotificationResponse notification = eNotificationResponse::UnknownError;
|
||||||
|
LWOOBJID auctionID = LWOOBJID_EMPTY;
|
||||||
|
uint32_t mailCount = 1;
|
||||||
|
|
||||||
|
NotificationResponse(eNotificationResponse _notification) : MailLUBitStream(eMessageID::NotificationResponse), notification{_notification} {};
|
||||||
|
NotificationResponse(eNotificationResponse _notification, uint32_t _mailCount) : MailLUBitStream(eMessageID::NotificationResponse), notification{_notification}, mailCount{_mailCount} {};
|
||||||
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DataRequest : public MailLUBitStream {
|
||||||
|
void Handle() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DataResponse : public MailLUBitStream {
|
||||||
uint32_t throttled = 0;
|
uint32_t throttled = 0;
|
||||||
std::vector<IMail::MailInfo> playerMail;
|
std::vector<MailInfo> playerMail;
|
||||||
|
|
||||||
|
DataResponse() : MailLUBitStream(eMessageID::DataRequest) {};
|
||||||
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||||
|
|
||||||
Data() = delete;
|
|
||||||
Data(std::vector<IMail::MailInfo> mailData) {
|
|
||||||
this->header.messageID = MailMessageID::MailData;
|
|
||||||
this->playerMail = mailData;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Response {
|
struct AttachmentCollectRequest : public MailLUBitStream {
|
||||||
MailLUHeader header;
|
uint64_t mailID = 0;
|
||||||
MailSendResponse response;
|
LWOOBJID playerID = LWOOBJID_EMPTY;
|
||||||
|
|
||||||
Response() = delete;
|
AttachmentCollectRequest() : MailLUBitStream(eMessageID::AttachmentCollectRequest) {};
|
||||||
Response(MailSendResponse response) {
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||||
this->header.messageID = MailMessageID::SendResponse;
|
void Handle() override;
|
||||||
this->response = response;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Notification {
|
struct AttachmentCollectResponse : public MailLUBitStream {
|
||||||
MailLUHeader header;
|
eRemoveAttachmentResponse status = eRemoveAttachmentResponse::UnknownError;
|
||||||
MailNotification notification;
|
uint64_t mailID = 0;
|
||||||
LWOOBJID auctionID = 0;
|
|
||||||
uint32_t mailCount = 0;
|
|
||||||
|
|
||||||
Notification() = delete;
|
AttachmentCollectResponse(eRemoveAttachmentResponse _status, uint64_t _mailID) : MailLUBitStream(eMessageID::AttachmentCollectResponse), status{_status}, mailID{_mailID} {};
|
||||||
Notification(MailNotification notification, uint32_t mailCount, LWOOBJID auctionID = LWOOBJID_EMPTY) {
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||||
this->header.messageID = MailMessageID::Notification;
|
|
||||||
this->notification = notification;
|
|
||||||
this->auctionID = auctionID;
|
|
||||||
this->mailCount = mailCount;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AttachmentCollect {
|
struct DeleteRequest : public MailLUBitStream {
|
||||||
MailLUHeader header;
|
uint64_t mailID = 0;
|
||||||
MailRemoveAttachment status;
|
LWOOBJID playerID = LWOOBJID_EMPTY;
|
||||||
uint64_t mailID;
|
|
||||||
|
|
||||||
AttachmentCollect() = delete;
|
|
||||||
AttachmentCollect(MailRemoveAttachment status, uint64_t mailID) {
|
DeleteRequest() : MailLUBitStream(eMessageID::DeleteRequest) {};
|
||||||
this->header.messageID = MailMessageID::AttachmentCollect;
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||||
this->status = status;
|
void Handle() override;
|
||||||
this->mailID = mailID;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DeleteMail {
|
struct DeleteResponse : public MailLUBitStream {
|
||||||
MailLUHeader header;
|
eDeleteResponse status = eDeleteResponse::UnknownError;
|
||||||
MailDeleteResponse status;
|
uint64_t mailID = 0;
|
||||||
uint64_t mailID;
|
DeleteResponse(uint64_t _mailID) : MailLUBitStream(eMessageID::DeleteResponse), mailID{_mailID} {};
|
||||||
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||||
DeleteMail() = delete;
|
|
||||||
DeleteMail(MailDeleteResponse status, uint64_t mailID) {
|
|
||||||
this->status = status;
|
|
||||||
this->mailID = mailID;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Read {
|
struct ReadRequest : public MailLUBitStream {
|
||||||
MailLUHeader header;
|
uint64_t mailID = 0;
|
||||||
MailReadResponse status;
|
|
||||||
uint64_t mailID;
|
|
||||||
|
|
||||||
Read() = delete;
|
ReadRequest() : MailLUBitStream(eMessageID::ReadRequest) {};
|
||||||
Read(MailReadResponse status, uint64_t mailID) {
|
bool Deserialize(RakNet::BitStream& bitStream) override;
|
||||||
this->status = status;
|
void Handle() override;
|
||||||
this->mailID = mailID;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string ServerName = "Darkflame Universe";
|
struct ReadResponse : public MailLUBitStream {
|
||||||
|
uint64_t mailID = 0;
|
||||||
|
eReadResponse status = eReadResponse::UnknownError;
|
||||||
|
|
||||||
|
ReadResponse() : MailLUBitStream(eMessageID::ReadResponse) {};
|
||||||
|
void Serialize(RakNet::BitStream& bitStream) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NotificationRequest : public MailLUBitStream {
|
||||||
|
NotificationRequest() : MailLUBitStream(eMessageID::NotificationRequest) {};
|
||||||
|
void Handle() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
void HandleMail(RakNet::BitStream& inStream, const SystemAddress& sysAddr, Entity* player);
|
||||||
|
|
||||||
void SendMail(
|
void SendMail(
|
||||||
const Entity* recipient,
|
const Entity* recipient,
|
||||||
@ -223,113 +234,6 @@ namespace Mail {
|
|||||||
uint16_t attachmentCount,
|
uint16_t attachmentCount,
|
||||||
const SystemAddress& sysAddr
|
const SystemAddress& sysAddr
|
||||||
);
|
);
|
||||||
|
|
||||||
void HandleMail(RakNet::BitStream& packet, const SystemAddress& sysAddr, Entity* entity);
|
|
||||||
void HandleSendMail(RakNet::BitStream& packet, const SystemAddress& sysAddr, Entity* entity);
|
|
||||||
void HandleDataRequest(RakNet::BitStream& packet, const SystemAddress& sysAddr, Entity* player);
|
|
||||||
void HandleAttachmentCollect(RakNet::BitStream& packet, const SystemAddress& sysAddr, Entity* player);
|
|
||||||
void HandleMailDelete(RakNet::BitStream& packet, const SystemAddress& sysAddr);
|
|
||||||
void HandleMailRead(RakNet::BitStream& packet, const SystemAddress& sysAddr);
|
|
||||||
void HandleNotificationRequest(const SystemAddress& sysAddr, uint32_t objectID);
|
|
||||||
|
|
||||||
void SendSendResponse(const SystemAddress& sysAddr, MailSendResponse response);
|
|
||||||
void SendNotification(const SystemAddress& sysAddr, int mailCount);
|
|
||||||
void SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t mailID);
|
|
||||||
void SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOOBJID playerID);
|
|
||||||
void SendReadConfirm(const SystemAddress& sysAddr, uint64_t mailID);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace RakNet {
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<Mail::MailLUHeader>(Mail::MailLUHeader data) {
|
|
||||||
this->Write<LUHeader<MessageType::Client>>(data.header);
|
|
||||||
this->Write<uint32_t>(static_cast<uint32_t>(data.messageID));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<Mail::Data>(Mail::Data data) {
|
|
||||||
|
|
||||||
this->Write<Mail::MailLUHeader>(data.header);
|
|
||||||
this->Write(data.throttled);
|
|
||||||
|
|
||||||
this->Write<uint16_t>(data.playerMail.size());
|
|
||||||
this->Write<uint16_t>(0); // packing
|
|
||||||
for (auto& mail : data.playerMail) {
|
|
||||||
this->Write(mail.id);
|
|
||||||
|
|
||||||
const LUWString subject(mail.subject, 50);
|
|
||||||
this->Write(subject);
|
|
||||||
|
|
||||||
const LUWString body(mail.body, 400);
|
|
||||||
this->Write(body);
|
|
||||||
|
|
||||||
const LUWString sender(mail.senderUsername, 32);
|
|
||||||
this->Write(sender);
|
|
||||||
this->Write(uint32_t(0)); // packing
|
|
||||||
|
|
||||||
this->Write(uint64_t(0)); // attachedCurrency
|
|
||||||
this->Write(mail.itemID);
|
|
||||||
|
|
||||||
LOT lot = mail.itemLOT;
|
|
||||||
if (lot <= 0) this->Write(LOT(-1));
|
|
||||||
else this->Write(lot);
|
|
||||||
this->Write(uint32_t(0)); // packing
|
|
||||||
|
|
||||||
this->Write(mail.itemSubkey);
|
|
||||||
|
|
||||||
this->Write<uint16_t>(mail.itemCount);
|
|
||||||
this->Write(uint8_t(0)); // subject type (used for auction)
|
|
||||||
this->Write(uint8_t(0)); // packing
|
|
||||||
this->Write(uint32_t(0)); // packing
|
|
||||||
|
|
||||||
this->Write<uint64_t>(mail.timeSent); // expiration date
|
|
||||||
this->Write<uint64_t>(mail.timeSent);// send date
|
|
||||||
this->Write<uint8_t>(mail.wasRead); // was read
|
|
||||||
|
|
||||||
this->Write(uint8_t(0)); // isLocalized
|
|
||||||
this->Write(uint16_t(0)); // packing
|
|
||||||
this->Write(uint32_t(0)); // packing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<Mail::Response>(Mail::Response data) {
|
|
||||||
this->Write<Mail::MailLUHeader>(data.header);
|
|
||||||
this->Write<uint32_t>(static_cast<uint32_t>(data.response));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<Mail::Notification>(Mail::Notification data) {
|
|
||||||
this->Write<Mail::MailLUHeader>(data.header);
|
|
||||||
this->Write(data.notification);
|
|
||||||
this->Write<uint64_t>(0); // unused
|
|
||||||
this->Write<uint64_t>(0); // unused
|
|
||||||
this->Write(data.auctionID);
|
|
||||||
this->Write<uint64_t>(0); // unused
|
|
||||||
this->Write(data.mailCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<Mail::AttachmentCollect>(Mail::AttachmentCollect data) {
|
|
||||||
this->Write<Mail::MailLUHeader>(data.header);
|
|
||||||
this->Write(data.status);
|
|
||||||
this->Write(data.mailID);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<Mail::DeleteMail>(Mail::DeleteMail data) {
|
|
||||||
this->Write<Mail::MailLUHeader>(data.header);
|
|
||||||
this->Write(data.status);
|
|
||||||
this->Write(data.mailID);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<Mail::Read>(Mail::Read data) {
|
|
||||||
this->Write<Mail::MailLUHeader>(data.header);
|
|
||||||
this->Write(data.status);
|
|
||||||
this->Write(data.mailID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !__MAIL_H__
|
#endif // !__MAIL_H__
|
||||||
|
@ -102,7 +102,7 @@ namespace GMGreaterThanZeroCommands {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IMail::MailInfo mailInsert;
|
MailInfo mailInsert;
|
||||||
mailInsert.senderId = entity->GetObjectID();
|
mailInsert.senderId = entity->GetObjectID();
|
||||||
mailInsert.senderUsername = "Darkflame Universe";
|
mailInsert.senderUsername = "Darkflame Universe";
|
||||||
mailInsert.receiverId = receiverID;
|
mailInsert.receiverId = receiverID;
|
||||||
|
29
dNet/BitStreamUtils.cpp
Normal file
29
dNet/BitStreamUtils.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "BitStreamUtils.h"
|
||||||
|
#include "dServer.h"
|
||||||
|
#include "BitStream.h"
|
||||||
|
|
||||||
|
|
||||||
|
void LUBitStream::WriteHeader(RakNet::BitStream& bitStream) const {
|
||||||
|
bitStream.Write<MessageID>(ID_USER_PACKET_ENUM);
|
||||||
|
bitStream.Write(this->connectionType);
|
||||||
|
bitStream.Write(this->internalPacketID);
|
||||||
|
bitStream.Write<uint8_t>(0); // padding
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LUBitStream::ReadHeader(RakNet::BitStream& bitStream) {
|
||||||
|
MessageID messageID;
|
||||||
|
bitStream.Read(messageID);
|
||||||
|
if (messageID != ID_USER_PACKET_ENUM) return false;
|
||||||
|
VALIDATE_READ(bitStream.Read(this->connectionType));
|
||||||
|
VALIDATE_READ(bitStream.Read(this->internalPacketID));
|
||||||
|
uint8_t padding;
|
||||||
|
VALIDATE_READ(bitStream.Read<uint8_t>(padding));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LUBitStream::Send(const SystemAddress& sysAddr) const {
|
||||||
|
RakNet::BitStream bitStream;
|
||||||
|
this->WriteHeader(bitStream);
|
||||||
|
this->Serialize(bitStream);
|
||||||
|
Game::server->Send(bitStream, sysAddr, sysAddr == UNASSIGNED_SYSTEM_ADDRESS);
|
||||||
|
}
|
@ -3,18 +3,12 @@
|
|||||||
|
|
||||||
#include "GeneralUtils.h"
|
#include "GeneralUtils.h"
|
||||||
#include "BitStream.h"
|
#include "BitStream.h"
|
||||||
|
#include "MessageIdentifiers.h"
|
||||||
|
#include "eConnectionType.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace MessageType {
|
#define VALIDATE_READ(x) do { if (!x) return false; } while (0)
|
||||||
enum class Auth : uint32_t;
|
|
||||||
enum class Client : uint32_t;
|
|
||||||
enum class Server : uint32_t;
|
|
||||||
enum class World : uint32_t;
|
|
||||||
enum class Master : uint32_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class eConnectionType : uint16_t;
|
|
||||||
|
|
||||||
struct LUString {
|
struct LUString {
|
||||||
std::string string;
|
std::string string;
|
||||||
@ -52,19 +46,28 @@ struct LUWString {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
struct LUBitStream {
|
||||||
struct LUHeader {
|
eConnectionType connectionType = eConnectionType::UNKNOWN;
|
||||||
MessageID messageID;
|
uint32_t internalPacketID = 0xFFFFFFFF;
|
||||||
eConnectionType connectionType;
|
|
||||||
T internalPacketID;
|
|
||||||
|
|
||||||
LUHeader(eConnectionType connectionType, T internalPacketID, MessageID messageID = ID_USER_PACKET_ENUM) {
|
LUBitStream() = default;
|
||||||
this->messageID = messageID;
|
|
||||||
|
template <typename T>
|
||||||
|
LUBitStream(eConnectionType connectionType, T internalPacketID) {
|
||||||
this->connectionType = connectionType;
|
this->connectionType = connectionType;
|
||||||
this->internalPacketID = internalPacketID;
|
this->internalPacketID = static_cast<uint32_t>(internalPacketID);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
void WriteHeader(RakNet::BitStream& bitStream) const;
|
||||||
|
bool ReadHeader(RakNet::BitStream& bitStream);
|
||||||
|
void Send(const SystemAddress& sysAddr) const;
|
||||||
|
|
||||||
|
virtual void Serialize(RakNet::BitStream& bitStream) const {}
|
||||||
|
virtual bool Deserialize(RakNet::BitStream& bitStream) { return true; }
|
||||||
|
virtual void Handle() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace BitStreamUtils {
|
namespace BitStreamUtils {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) {
|
void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) {
|
||||||
@ -119,46 +122,6 @@ namespace RakNet {
|
|||||||
value.string.resize(value.size);
|
value.string.resize(value.size);
|
||||||
this->Write(value.string);
|
this->Write(value.string);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<LUHeader<MessageType::Auth>>(LUHeader<MessageType::Auth> value) {
|
|
||||||
this->Write<MessageID>(value.messageID);
|
|
||||||
this->Write<eConnectionType>(value.connectionType);
|
|
||||||
this->Write<uint32_t>(static_cast<uint32_t>(value.internalPacketID));
|
|
||||||
this->Write<uint8_t>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<LUHeader<MessageType::Client>>(LUHeader<MessageType::Client> value) {
|
|
||||||
this->Write<MessageID>(value.messageID);
|
|
||||||
this->Write<eConnectionType>(value.connectionType);
|
|
||||||
this->Write<uint32_t>(static_cast<uint32_t>(value.internalPacketID));
|
|
||||||
this->Write<uint8_t>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<LUHeader<MessageType::Server>>(LUHeader<MessageType::Server> value) {
|
|
||||||
this->Write<MessageID>(value.messageID);
|
|
||||||
this->Write<eConnectionType>(value.connectionType);
|
|
||||||
this->Write<uint32_t>(static_cast<uint32_t>(value.internalPacketID));
|
|
||||||
this->Write<uint8_t>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<LUHeader<MessageType::World>>(LUHeader<MessageType::World> value) {
|
|
||||||
this->Write<MessageID>(value.messageID);
|
|
||||||
this->Write<eConnectionType>(value.connectionType);
|
|
||||||
this->Write<uint32_t>(static_cast<uint32_t>(value.internalPacketID));
|
|
||||||
this->Write<uint8_t>(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
inline void RakNet::BitStream::Write<LUHeader<MessageType::Master>>(LUHeader<MessageType::Master> value) {
|
|
||||||
this->Write<MessageID>(value.messageID);
|
|
||||||
this->Write<eConnectionType>(value.connectionType);
|
|
||||||
this->Write<uint32_t>(static_cast<uint32_t>(value.internalPacketID));
|
|
||||||
this->Write<uint8_t>(0);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //!__BITSTREAMUTILS__H__
|
#endif //!__BITSTREAMUTILS__H__
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
set(DNET_SOURCES "AuthPackets.cpp"
|
set(DNET_SOURCES "AuthPackets.cpp"
|
||||||
|
"BitStreamUtils.cpp"
|
||||||
"ChatPackets.cpp"
|
"ChatPackets.cpp"
|
||||||
"ClientPackets.cpp"
|
"ClientPackets.cpp"
|
||||||
"dServer.cpp"
|
"dServer.cpp"
|
||||||
|
87
dNet/MailInfo.cpp
Normal file
87
dNet/MailInfo.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include "MailInfo.h"
|
||||||
|
#include "BitStream.h"
|
||||||
|
#include "DluAssert.h"
|
||||||
|
|
||||||
|
void MailInfo::Serialize(RakNet::BitStream& bitStream) const {
|
||||||
|
bitStream.Write(id);
|
||||||
|
|
||||||
|
const LUWString subject(this->subject, 50);
|
||||||
|
bitStream.Write(subject);
|
||||||
|
|
||||||
|
const LUWString body(this->body, 400);
|
||||||
|
bitStream.Write(body);
|
||||||
|
|
||||||
|
const LUWString sender(this->senderUsername, 32);
|
||||||
|
bitStream.Write(sender);
|
||||||
|
bitStream.Write<uint32_t>(0); // packing
|
||||||
|
|
||||||
|
bitStream.Write<uint64_t>(0); // attachedCurrency
|
||||||
|
bitStream.Write(itemID);
|
||||||
|
|
||||||
|
LOT lot = itemLOT;
|
||||||
|
if (lot <= 0) bitStream.Write<LOT>(LOT_NULL);
|
||||||
|
else bitStream.Write(lot);
|
||||||
|
bitStream.Write<uint32_t>(0); // packing
|
||||||
|
|
||||||
|
bitStream.Write(itemSubkey);
|
||||||
|
|
||||||
|
bitStream.Write<uint16_t>(itemCount);
|
||||||
|
bitStream.Write<uint8_t>(0); // subject type (used for auction)
|
||||||
|
bitStream.Write<uint8_t>(0); // packing
|
||||||
|
bitStream.Write<uint32_t>(0); // packing
|
||||||
|
|
||||||
|
bitStream.Write<uint64_t>(timeSent); // expiration date
|
||||||
|
bitStream.Write<uint64_t>(timeSent);// send date
|
||||||
|
bitStream.Write<uint8_t>(wasRead); // was read
|
||||||
|
|
||||||
|
bitStream.Write<uint8_t>(0); // isLocalized
|
||||||
|
bitStream.Write<uint16_t>(0); // packing
|
||||||
|
bitStream.Write<uint32_t>(0); // packing
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MailInfo::Deserialize(RakNet::BitStream& bitStream) {
|
||||||
|
VALIDATE_READ(bitStream.Read(id));
|
||||||
|
|
||||||
|
LUWString subject(50);
|
||||||
|
VALIDATE_READ(bitStream.Read(subject));
|
||||||
|
this->subject = subject.GetAsString();
|
||||||
|
|
||||||
|
LUWString body(400);
|
||||||
|
VALIDATE_READ(bitStream.Read(body));
|
||||||
|
this->body = body.GetAsString();
|
||||||
|
|
||||||
|
LUWString sender(32);
|
||||||
|
VALIDATE_READ(bitStream.Read(sender));
|
||||||
|
this->senderUsername = sender.GetAsString();
|
||||||
|
|
||||||
|
bitStream.IgnoreBytes(4); // packing
|
||||||
|
|
||||||
|
bitStream.IgnoreBytes(8); // attachedCurrency
|
||||||
|
VALIDATE_READ(bitStream.Read(itemID));
|
||||||
|
|
||||||
|
LOT lot;
|
||||||
|
VALIDATE_READ(bitStream.Read(lot));
|
||||||
|
if (lot == LOT_NULL) itemLOT = 0;
|
||||||
|
else itemLOT = lot;
|
||||||
|
bitStream.IgnoreBytes(4); // packing
|
||||||
|
|
||||||
|
VALIDATE_READ(bitStream.Read(itemSubkey));
|
||||||
|
|
||||||
|
VALIDATE_READ(bitStream.Read(itemCount));
|
||||||
|
|
||||||
|
bitStream.IgnoreBytes(1); // subject type (used for auction)
|
||||||
|
bitStream.IgnoreBytes(1); // packing
|
||||||
|
bitStream.IgnoreBytes(4); // packing
|
||||||
|
|
||||||
|
VALIDATE_READ(bitStream.Read(timeSent)); // expiration date
|
||||||
|
VALIDATE_READ(bitStream.Read(timeSent)); // send date
|
||||||
|
VALIDATE_READ(bitStream.Read(wasRead)); // was read
|
||||||
|
|
||||||
|
bitStream.IgnoreBytes(1); // isLocalized
|
||||||
|
bitStream.IgnoreBytes(2); // packing
|
||||||
|
bitStream.IgnoreBytes(4); // packing
|
||||||
|
|
||||||
|
DluAssert(bitStream.GetNumberOfUnreadBits() == 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
33
dNet/MailInfo.h
Normal file
33
dNet/MailInfo.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef __MAILINFO_H__
|
||||||
|
#define __MAILINFO_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
#include "dCommonVars.h"
|
||||||
|
|
||||||
|
namespace RakNet {
|
||||||
|
class BitStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MailInfo {
|
||||||
|
std::string senderUsername;
|
||||||
|
std::string recipient;
|
||||||
|
std::string subject;
|
||||||
|
std::string body;
|
||||||
|
uint64_t id{};
|
||||||
|
uint32_t senderId{};
|
||||||
|
uint32_t receiverId{};
|
||||||
|
uint64_t timeSent{};
|
||||||
|
bool wasRead{};
|
||||||
|
struct {
|
||||||
|
LWOOBJID itemID{};
|
||||||
|
int32_t itemCount{};
|
||||||
|
LOT itemLOT{};
|
||||||
|
LWOOBJID itemSubkey{};
|
||||||
|
};
|
||||||
|
|
||||||
|
void Serialize(RakNet::BitStream& bitStream) const {}
|
||||||
|
bool Deserialize(RakNet::BitStream& bitStream) { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __MAILINFO_H__
|
@ -831,15 +831,20 @@ void HandlePacket(Packet* packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (packet->data[0] != ID_USER_PACKET_ENUM || packet->length < 4) return;
|
if (packet->data[0] != ID_USER_PACKET_ENUM || packet->length < 4) return;
|
||||||
if (static_cast<eConnectionType>(packet->data[1]) == eConnectionType::SERVER) {
|
|
||||||
if (static_cast<MessageType::Server>(packet->data[3]) == MessageType::Server::VERSION_CONFIRM) {
|
CINSTREAM;
|
||||||
|
LUBitStream luBitStream;
|
||||||
|
luBitStream.ReadHeader(inStream);
|
||||||
|
|
||||||
|
if (luBitStream.connectionType == eConnectionType::SERVER) {
|
||||||
|
if (static_cast<MessageType::Server>(luBitStream.internalPacketID) == MessageType::Server::VERSION_CONFIRM) {
|
||||||
AuthPackets::HandleHandshake(Game::server, packet);
|
AuthPackets::HandleHandshake(Game::server, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (static_cast<eConnectionType>(packet->data[1]) != eConnectionType::WORLD) return;
|
if (luBitStream.connectionType != eConnectionType::WORLD) return;
|
||||||
|
|
||||||
switch (static_cast<MessageType::World>(packet->data[3])) {
|
switch (static_cast<MessageType::World>(luBitStream.internalPacketID)) {
|
||||||
case MessageType::World::VALIDATION: {
|
case MessageType::World::VALIDATION: {
|
||||||
CINSTREAM_SKIP_HEADER;
|
CINSTREAM_SKIP_HEADER;
|
||||||
LUWString username;
|
LUWString username;
|
||||||
@ -1185,11 +1190,7 @@ void HandlePacket(Packet* packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case MessageType::World::MAIL: {
|
case MessageType::World::MAIL: {
|
||||||
RakNet::BitStream bitStream(packet->data, packet->length, false);
|
Mail::HandleMail(inStream, packet->systemAddress, UserManager::Instance()->GetUser(packet->systemAddress)->GetLastUsedChar()->GetEntity());
|
||||||
// FIXME: Change this to the macro to skip the header...
|
|
||||||
LWOOBJID space;
|
|
||||||
bitStream.Read(space);
|
|
||||||
Mail::HandleMail(bitStream, packet->systemAddress, UserManager::Instance()->GetUser(packet->systemAddress)->GetLastUsedChar()->GetEntity());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user