Change LUBitstream to make more sense and only read what it needs from the bitstream at each level

This commit is contained in:
Aaron Kimbrell
2025-09-12 22:25:55 -05:00
parent b36b440eba
commit 500a72dc11
16 changed files with 217 additions and 101 deletions

View File

@@ -36,6 +36,18 @@ namespace AuthPackets {
}}
};
// Struct Functions
void AuthLUBitStream::Serialize(RakNet::BitStream& bitStream) const {
bitStream.Write(this->messageType);
bitStream.Write<uint8_t>(0); // padding
}
bool AuthLUBitStream::Deserialize(RakNet::BitStream& bitStream) {
VALIDATE_READ(bitStream.Read(this->messageType));
uint8_t padding = 0;
VALIDATE_READ(bitStream.Read(padding));
return true;
}
bool LoginRequest::Deserialize(RakNet::BitStream& bitStream) {
LUWString usernameLUString;
VALIDATE_READ(bitStream.Read(usernameLUString));
@@ -228,22 +240,21 @@ void AuthPackets::LoadClaimCodes() {
// Non Stuct Functions
void AuthPackets::Handle(RakNet::BitStream& inStream, const SystemAddress& sysAddr) {
inStream.ResetReadPointer();
LUBitStream lubitstream;
if (!lubitstream.ReadHeader(inStream)) return;
AuthLUBitStream authLUBitStream;
if (!authLUBitStream.Deserialize(inStream)) return;
auto it = g_Handlers.find(static_cast<MessageType::Auth>(lubitstream.internalPacketID));
auto it = g_Handlers.find(authLUBitStream.messageType);
if (it != g_Handlers.end()) {
auto request = it->second();
request->sysAddr = sysAddr;
if (!request->Deserialize(inStream)) {
LOG_DEBUG("Error Reading Auth Packet: %s", StringifiedEnum::ToString(static_cast<MessageType::Auth>(lubitstream.internalPacketID)).data());
LOG_DEBUG("Error Reading Auth Packet: %s", StringifiedEnum::ToString(authLUBitStream.messageType).data());
return;
}
LOG_DEBUG("Received Auth Packet: %s", StringifiedEnum::ToString(static_cast<MessageType::Auth>(lubitstream.internalPacketID)).data());
LOG_DEBUG("Received Auth Packet: %s", StringifiedEnum::ToString(authLUBitStream.messageType).data());
request->Handle();
} else {
LOG_DEBUG("Unhandled Auth Packet with ID: %i", lubitstream.internalPacketID);
LOG_DEBUG("Unhandled Auth Packet with ID: %i", authLUBitStream.messageType);
}
}

View File

@@ -34,7 +34,18 @@ struct magic_enum::customize::enum_range<LanguageCodeID> {
namespace AuthPackets {
struct LoginRequest : public LUBitStream {
struct AuthLUBitStream : public LUBitStream {
MessageType::Auth messageType = MessageType::Auth::LOGIN_REQUEST;
AuthLUBitStream() : LUBitStream(ServiceType::AUTH) {};
AuthLUBitStream(MessageType::Auth _messageType) : LUBitStream(ServiceType::AUTH), messageType{_messageType} {};
virtual void Serialize(RakNet::BitStream& bitStream) const override;
virtual bool Deserialize(RakNet::BitStream& bitStream) override;
virtual void Handle() override {};
};
struct LoginRequest : public AuthLUBitStream {
std::string username;
std::string password;
LanguageCodeID locale_id;
@@ -57,7 +68,7 @@ namespace AuthPackets {
} osVersionInfo;
} computerInfo;
LoginRequest() : LUBitStream(ServiceType::AUTH, MessageType::Auth::LOGIN_REQUEST) {}
LoginRequest() : AuthLUBitStream(MessageType::Auth::LOGIN_REQUEST) {}
bool Deserialize(RakNet::BitStream& bitStream) override;
void Handle() override;
};

View File

@@ -6,18 +6,12 @@
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
bitStream.Write(this->serviceType);
}
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));
bitStream.IgnoreBytes(1);
VALIDATE_READ(bitStream.Read(this->rakNetID));
VALIDATE_READ(bitStream.Read(this->serviceType));
return true;
}

View File

@@ -47,16 +47,16 @@ struct LUWString {
};
struct LUBitStream {
ServiceType connectionType = ServiceType::UNKNOWN;
uint32_t internalPacketID = 0xFFFFFFFF;
// Common header data that is serialized
MessageID rakNetID = ID_USER_PACKET_ENUM;
ServiceType serviceType = ServiceType::UNKNOWN;
SystemAddress sysAddr = UNASSIGNED_SYSTEM_ADDRESS;
LUBitStream() = default;
template <typename T>
LUBitStream(ServiceType connectionType, T internalPacketID) {
this->connectionType = connectionType;
this->internalPacketID = static_cast<uint32_t>(internalPacketID);
LUBitStream(ServiceType serviceType) {
this->serviceType = serviceType;
}
void WriteHeader(RakNet::BitStream& bitStream) const;

View File

@@ -12,6 +12,20 @@
#include "ServiceType.h"
#include "MessageType/Chat.h"
namespace ChatPackets {
// Struct Functions
void ChatLUBitStream::Serialize(RakNet::BitStream& bitStream) const {
bitStream.Write(this->messageType);
bitStream.Write<uint8_t>(0); // padding
}
bool ChatLUBitStream::Deserialize(RakNet::BitStream& bitStream) {
VALIDATE_READ(bitStream.Read(this->messageType));
uint8_t padding = 0;
VALIDATE_READ(bitStream.Read(padding));
return true;
}
}
void ShowAllRequest::Serialize(RakNet::BitStream& bitStream) {
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::SHOW_ALL);
bitStream.Write(this->requestor);

View File

@@ -12,6 +12,7 @@ struct SystemAddress;
#include "dCommonVars.h"
#include "MessageType/Chat.h"
#include "BitStreamUtils.h"
#include "ClientPackets.h"
struct ShowAllRequest{
LWOOBJID requestor = LWOOBJID_EMPTY;
@@ -30,28 +31,39 @@ struct FindPlayerRequest{
namespace ChatPackets {
struct Announcement : public LUBitStream {
struct ChatLUBitStream : public LUBitStream {
MessageType::Chat messageType = MessageType::Chat::GENERAL_CHAT_MESSAGE;
ChatLUBitStream() : LUBitStream(ServiceType::CHAT) {};
ChatLUBitStream(MessageType::Chat _messageType) : LUBitStream(ServiceType::CHAT), messageType{_messageType} {};
virtual void Serialize(RakNet::BitStream& bitStream) const override;
virtual bool Deserialize(RakNet::BitStream& bitStream) override;
virtual void Handle() override {};
};
struct Announcement : public ChatLUBitStream {
std::string title;
std::string message;
Announcement() : LUBitStream(ServiceType::CHAT, MessageType::Chat::GM_ANNOUNCE) {};
Announcement() : ChatLUBitStream(MessageType::Chat::GM_ANNOUNCE) {};
virtual void Serialize(RakNet::BitStream& bitStream) const override;
};
struct AchievementNotify : public LUBitStream {
struct AchievementNotify : public ChatLUBitStream {
LUWString targetPlayerName{};
uint32_t missionEmailID{};
LWOOBJID earningPlayerID{};
LUWString earnerName{};
AchievementNotify() : LUBitStream(ServiceType::CHAT, MessageType::Chat::ACHIEVEMENT_NOTIFY) {}
AchievementNotify() : ChatLUBitStream(MessageType::Chat::ACHIEVEMENT_NOTIFY) {}
void Serialize(RakNet::BitStream& bitstream) const override;
bool Deserialize(RakNet::BitStream& bitstream) override;
};
struct TeamInviteInitialResponse : public LUBitStream {
struct TeamInviteInitialResponse : public ClientPackets::ClientLUBitStream {
bool inviteFailedToSend{};
LUWString playerName{};
TeamInviteInitialResponse() : LUBitStream(ServiceType::CLIENT, MessageType::Client::TEAM_INVITE_INITIAL_RESPONSE) {}
TeamInviteInitialResponse() : ClientPackets::ClientLUBitStream(MessageType::Client::TEAM_INVITE_INITIAL_RESPONSE) {}
void Serialize(RakNet::BitStream& bitstream) const override;
// No Deserialize needed on our end

View File

@@ -16,7 +16,18 @@ namespace ClientPackets {
bitStream.Write(timestamp);
};
void ClientLUBitStream::Serialize(RakNet::BitStream& bitStream) const {
bitStream.Write(this->messageType);
bitStream.Write<uint8_t>(0); // padding
}
bool ClientLUBitStream::Deserialize(RakNet::BitStream& bitStream) {
VALIDATE_READ(bitStream.Read(this->messageType));
uint8_t padding = 0;
VALIDATE_READ(bitStream.Read(padding)); return true;
}
void LoginResponse::Serialize(RakNet::BitStream& bitStream) const {
ClientLUBitStream::Serialize(bitStream);
bitStream.Write(responseCode);
bitStream.Write(events[0]);
bitStream.Write(events[1]);

View File

@@ -97,6 +97,18 @@ enum class Language : uint32_t {
};
namespace ClientPackets {
// Structs
struct ClientLUBitStream : public LUBitStream {
MessageType::Client messageType = MessageType::Client::LOGIN_RESPONSE;
ClientLUBitStream() : LUBitStream(ServiceType::CLIENT) {};
ClientLUBitStream(MessageType::Client _messageType) : LUBitStream(ServiceType::CLIENT), messageType{_messageType} {};
virtual void Serialize(RakNet::BitStream& bitStream) const override;
virtual bool Deserialize(RakNet::BitStream& bitStream) override;
virtual void Handle() override {};
};
struct Stamp {
eStamps type;
uint32_t value;
@@ -111,7 +123,7 @@ namespace ClientPackets {
void Serialize(RakNet::BitStream& bitStream) const;
};
struct LoginResponse : public LUBitStream {
struct LoginResponse : public ClientLUBitStream {
eLoginResponse responseCode = eLoginResponse::GENERAL_FAILED;
std::vector<LUString> events;
uint16_t version_major = 0;
@@ -132,7 +144,7 @@ namespace ClientPackets {
std::string errorMessage;
std::vector<Stamp> stamps;
LoginResponse() : LUBitStream(ServiceType::CLIENT, MessageType::Client::LOGIN_RESPONSE) {}
LoginResponse() : ClientLUBitStream(MessageType::Client::LOGIN_RESPONSE) {}
void Serialize(RakNet::BitStream& bitStream) const override;
};

View File

@@ -22,7 +22,20 @@ namespace CommonPackets {
}}
};
// Struct Functions
void CommonLUBitStream::Serialize(RakNet::BitStream& bitStream) const {
bitStream.Write(this->messageType);
bitStream.Write<uint8_t>(0); // padding
}
bool CommonLUBitStream::Deserialize(RakNet::BitStream& bitStream) {
VALIDATE_READ(bitStream.Read(this->messageType));
uint8_t padding = 0;
VALIDATE_READ(bitStream.Read(padding));
return true;
}
void VersionConfirm::Serialize(RakNet::BitStream& bitStream) const {
CommonLUBitStream::Serialize(bitStream);
bitStream.Write<uint32_t>(netVersion);
bitStream.Write<uint32_t>(861228100);
bitStream.Write(static_cast<uint32_t>(serviceType));
@@ -59,28 +72,28 @@ namespace CommonPackets {
}
void GeneralNotify::Serialize(RakNet::BitStream& bitStream) const {
CommonLUBitStream::Serialize(bitStream);
bitStream.Write(notifyID);
bitStream.Write(notifyUser);
}
}
void CommonPackets::Handle(RakNet::BitStream& inStream, const SystemAddress& sysAddr) {
inStream.ResetReadPointer();
LUBitStream lubitstream;
if (!lubitstream.ReadHeader(inStream)) return;
CommonLUBitStream lubitstream;
if (!lubitstream.Deserialize(inStream)) return;
auto it = g_Handlers.find(static_cast<MessageType::Server>(lubitstream.internalPacketID));
auto it = g_Handlers.find(lubitstream.messageType);
if (it != g_Handlers.end()) {
auto request = it->second();
request->sysAddr = sysAddr;
if (!request->Deserialize(inStream)) {
LOG_DEBUG("Error Reading Common Packet: %s", StringifiedEnum::ToString(static_cast<MessageType::Server>(lubitstream.internalPacketID)).data());
LOG_DEBUG("Error Reading Common Packet: %s", StringifiedEnum::ToString(lubitstream.messageType).data());
return;
}
LOG_DEBUG("Received Common Packet: %s", StringifiedEnum::ToString(static_cast<MessageType::Server>(lubitstream.internalPacketID)).data());
LOG_DEBUG("Received Common Packet: %s", StringifiedEnum::ToString(lubitstream.messageType).data());
request->Handle();
} else {
LOG_DEBUG("Unhandled Common Packet with ID: %i", lubitstream.internalPacketID);
LOG_DEBUG("Unhandled Common Packet with ID: %i", lubitstream.messageType);
}
}

View File

@@ -23,31 +23,42 @@ enum class eServerDisconnectIdentifiers : uint32_t {
// Packet Struct Functions
namespace CommonPackets {
// Structs
struct CommonLUBitStream : public LUBitStream {
MessageType::Server messageType = MessageType::Server::VERSION_CONFIRM;
struct VersionConfirm : public LUBitStream {
CommonLUBitStream() : LUBitStream(ServiceType::COMMON) {};
CommonLUBitStream(MessageType::Server _messageType) : LUBitStream(ServiceType::COMMON), messageType{_messageType} {};
virtual void Serialize(RakNet::BitStream& bitStream) const override;
virtual bool Deserialize(RakNet::BitStream& bitStream) override;
virtual void Handle() override {};
};
struct VersionConfirm : public CommonLUBitStream {
uint32_t netVersion = 0;
ServiceType serviceType;
uint32_t processID = 0;
uint16_t port = 0;
VersionConfirm() : LUBitStream(ServiceType::COMMON, MessageType::Server::VERSION_CONFIRM) {}
VersionConfirm() : CommonLUBitStream(MessageType::Server::VERSION_CONFIRM) {}
void Serialize(RakNet::BitStream& bitStream) const override;
bool Deserialize(RakNet::BitStream& bitStream) override;
void Handle() override;
};
struct DisconnectNotify : public LUBitStream {
struct DisconnectNotify : public CommonLUBitStream {
eServerDisconnectIdentifiers disconnectID = eServerDisconnectIdentifiers::UNKNOWN_SERVER_ERROR;
DisconnectNotify() : LUBitStream(ServiceType::COMMON, MessageType::Server::DISCONNECT_NOTIFY) {}
DisconnectNotify() : CommonLUBitStream(MessageType::Server::DISCONNECT_NOTIFY) {}
void Serialize(RakNet::BitStream& bitStream) const override;
};
struct GeneralNotify : public LUBitStream {
struct GeneralNotify : public CommonLUBitStream {
uint32_t notifyID = 0; // only one known value: 0, which is Duplicate account login
bool notifyUser = true;
GeneralNotify() : LUBitStream(ServiceType::COMMON, MessageType::Server::GENERAL_NOTIFY) {}
GeneralNotify() : CommonLUBitStream(MessageType::Server::GENERAL_NOTIFY) {}
void Serialize(RakNet::BitStream& bitStream) const override;
};

View File

@@ -12,6 +12,20 @@
#include <iostream>
namespace WorldPackets {
// Struct Functions
void WorldLUBitStream::Serialize(RakNet::BitStream& bitStream) const {
bitStream.Write(this->messageType);
bitStream.Write<uint8_t>(0); // padding
}
bool WorldLUBitStream::Deserialize(RakNet::BitStream& bitStream) {
VALIDATE_READ(bitStream.Read(this->messageType));
uint8_t padding = 0;
VALIDATE_READ(bitStream.Read(padding));
return true;
}
}
void HTTPMonitorInfo::Serialize(RakNet::BitStream& bitStream) const {
bitStream.Write(port);
bitStream.Write<uint8_t>(openWeb);

View File

@@ -4,6 +4,7 @@
#include "dCommonVars.h"
#include <vector>
#include <string>
#include "MessageType/World.h"
class User;
struct SystemAddress;
@@ -25,6 +26,16 @@ struct HTTPMonitorInfo {
};
namespace WorldPackets {
struct WorldLUBitStream : public LUBitStream {
MessageType::World messageType = MessageType::World::VALIDATION;
WorldLUBitStream() : LUBitStream(ServiceType::WORLD) {};
WorldLUBitStream(MessageType::World messageType) : LUBitStream(ServiceType::WORLD), messageType{messageType} {};
virtual void Serialize(RakNet::BitStream& bitStream) const override;
virtual bool Deserialize(RakNet::BitStream& bitStream) override;
virtual void Handle() override {};
};
void SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum, LWOZONEID zone);
void SendCharacterCreationResponse(const SystemAddress& sysAddr, eCharacterCreationResponse response);
void SendCharacterRenameResponse(const SystemAddress& sysAddr, eRenameResponse response);