diff --git a/dAuthServer/AuthServer.cpp b/dAuthServer/AuthServer.cpp index 1905fa73c..fefa83e70 100644 --- a/dAuthServer/AuthServer.cpp +++ b/dAuthServer/AuthServer.cpp @@ -20,6 +20,7 @@ //Auth includes: #include "AuthPackets.h" +#include "CommonPackets.h" #include "ServiceType.h" #include "MessageType/Server.h" #include "MessageType/Auth.h" @@ -164,17 +165,12 @@ int main(int argc, char** argv) { } void HandlePacket(Packet* packet) { - if (packet->length < 4) return; - - if (packet->data[0] == ID_USER_PACKET_ENUM) { - if (static_cast(packet->data[1]) == ServiceType::COMMON) { - if (static_cast(packet->data[3]) == MessageType::Server::VERSION_CONFIRM) { - AuthPackets::HandleHandshake(Game::server, packet); - } - } else if (static_cast(packet->data[1]) == ServiceType::AUTH) { - if (static_cast(packet->data[3]) == MessageType::Auth::LOGIN_REQUEST) { - AuthPackets::HandleLoginRequest(Game::server, packet); - } - } + CINSTREAM; + LUBitStream luBitStream; + if (!luBitStream.ReadHeader(inStream) && luBitStream.rakNetID != ID_USER_PACKET_ENUM) return; + else if (luBitStream.serviceType == ServiceType::COMMON) { + CommonPackets::Handle(inStream, packet->systemAddress); + } else if (luBitStream.serviceType == ServiceType::AUTH) { + AuthPackets::Handle(inStream, packet->systemAddress); } } diff --git a/dCommon/dEnums/eLoginResponse.h b/dCommon/dEnums/eLoginResponse.h deleted file mode 100644 index 01bba3d55..000000000 --- a/dCommon/dEnums/eLoginResponse.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __ELOGINRESPONSE__H__ -#define __ELOGINRESPONSE__H__ - -#include - -enum class eLoginResponse : uint8_t { - GENERAL_FAILED = 0, - SUCCESS, - BANNED, - // Unused 3 - // Unused 4 - PERMISSIONS_NOT_HIGH_ENOUGH = 5, - INVALID_USER, - ACCOUNT_LOCKED, - WRONG_PASS, - ACCOUNT_ACTIVATION_PENDING, - ACCOUNT_DISABLED, - GAME_TIME_EXPIRED, - FREE_TRIAL_ENDED, - PLAY_SCHEDULE_TIME_UP, - ACCOUNT_NOT_ACTIVATED -}; - -#endif //!__ELOGINRESPONSE__H__ diff --git a/dCommon/dEnums/eServerDisconnectIdentifiers.h b/dCommon/dEnums/eServerDisconnectIdentifiers.h deleted file mode 100644 index 99d2cd442..000000000 --- a/dCommon/dEnums/eServerDisconnectIdentifiers.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __ESERVERDISCONNECTIDENTIFIERS__H__ -#define __ESERVERDISCONNECTIDENTIFIERS__H__ - -#include - -enum class eServerDisconnectIdentifiers : uint32_t { - UNKNOWN_SERVER_ERROR = 0, - WRONG_GAME_VERSION, - WRONG_SERVER_VERSION, - CONNECTION_ON_INVALID_PORT, - DUPLICATE_LOGIN, - SERVER_SHUTDOWN, - SERVER_MAP_LOAD_FAILURE, - INVALID_SESSION_KEY, - ACCOUNT_NOT_IN_PENDING_LIST, - CHARACTER_NOT_FOUND, - CHARACTER_CORRUPTED, - KICK, - SAVE_FAILURE, - FREE_TRIAL_EXPIRED, - PLAY_SCHEDULE_TIME_DONE -}; - -#endif //!__ESERVERDISCONNECTIDENTIFIERS__H__ diff --git a/dGame/User.cpp b/dGame/User.cpp index 7c03daa88..9b5bb38f1 100644 --- a/dGame/User.cpp +++ b/dGame/User.cpp @@ -5,12 +5,12 @@ #include "Logger.h" #include "Game.h" #include "dZoneManager.h" -#include "eServerDisconnectIdentifiers.h" #include "eGameMasterLevel.h" #include "BitStreamUtils.h" #include "MessageType/Chat.h" #include #include +#include "CommonPackets.h" User::User(const SystemAddress& sysAddr, const std::string& username, const std::string& sessionKey) { m_AccountID = 0; @@ -132,7 +132,10 @@ void User::UserOutOfSync() { if (m_AmountOfTimesOutOfSync > m_MaxDesyncAllowed) { //YEET LOG("User %s was out of sync %i times out of %i, disconnecting for suspected speedhacking.", m_Username.c_str(), m_AmountOfTimesOutOfSync, m_MaxDesyncAllowed); - Game::server->Disconnect(this->m_SystemAddress, eServerDisconnectIdentifiers::PLAY_SCHEDULE_TIME_DONE); + CommonPackets::DisconnectNotify notification; + notification.disconnectID = eServerDisconnectIdentifiers::PLAY_SCHEDULE_TIME_DONE; + notification.Send(this->m_SystemAddress); + Game::server->Disconnect(this->m_SystemAddress); } } diff --git a/dGame/dUtilities/Mail.cpp b/dGame/dUtilities/Mail.cpp index 5ab82f617..9b39e26bf 100644 --- a/dGame/dUtilities/Mail.cpp +++ b/dGame/dUtilities/Mail.cpp @@ -34,7 +34,7 @@ namespace { } namespace Mail { - std::map()>> g_Handlers = { + std::map()>> g_Handlers = { {eMessageID::SendRequest, []() { return std::make_unique(); }}, @@ -55,11 +55,11 @@ namespace Mail { }}, }; - void MailLUBitStream::Serialize(RakNet::BitStream& bitStream) const { + void MailClientLUBitStream::Serialize(RakNet::BitStream& bitStream) const { bitStream.Write(messageID); } - bool MailLUBitStream::Deserialize(RakNet::BitStream& bitstream) { + bool MailClientLUBitStream::Deserialize(RakNet::BitStream& bitstream) { VALIDATE_READ(bitstream.Read(messageID)); return true; } @@ -133,16 +133,16 @@ namespace Mail { response.status = eSendResponse::SenderAccountIsMuted; } LOG("Finished send with status %s", StringifiedEnum::ToString(response.status).data()); - response.Send(sysAddr); + response.Send(); } void SendResponse::Serialize(RakNet::BitStream& bitStream) const { - MailLUBitStream::Serialize(bitStream); + MailClientLUBitStream::Serialize(bitStream); bitStream.Write(status); } void NotificationResponse::Serialize(RakNet::BitStream& bitStream) const { - MailLUBitStream::Serialize(bitStream); + MailClientLUBitStream::Serialize(bitStream); bitStream.Write(status); bitStream.Write(0); // unused bitStream.Write(0); // unused @@ -158,12 +158,12 @@ namespace Mail { auto playerMail = Database::Get()->GetMailForPlayer(character->GetID(), 20); DataResponse response; response.playerMail = playerMail; - response.Send(sysAddr); + response.Send(); LOG("DataRequest"); } void DataResponse::Serialize(RakNet::BitStream& bitStream) const { - MailLUBitStream::Serialize(bitStream); + MailClientLUBitStream::Serialize(bitStream); bitStream.Write(this->throttled); bitStream.Write(this->playerMail.size()); @@ -199,11 +199,11 @@ namespace Mail { } } LOG("AttachmentCollectResponse %s", StringifiedEnum::ToString(response.status).data()); - response.Send(sysAddr); + response.Send(); } void AttachmentCollectResponse::Serialize(RakNet::BitStream& bitStream) const { - MailLUBitStream::Serialize(bitStream); + MailClientLUBitStream::Serialize(bitStream); bitStream.Write(status); bitStream.Write(mailID); } @@ -230,11 +230,11 @@ namespace Mail { response.status = eDeleteResponse::NotFound; } LOG("DeleteRequest status %s", StringifiedEnum::ToString(response.status).data()); - response.Send(sysAddr); + response.Send(); } void DeleteResponse::Serialize(RakNet::BitStream& bitStream) const { - MailLUBitStream::Serialize(bitStream); + MailClientLUBitStream::Serialize(bitStream); bitStream.Write(status); bitStream.Write(mailID); } @@ -256,11 +256,11 @@ namespace Mail { } LOG("ReadRequest %s", StringifiedEnum::ToString(response.status).data()); - response.Send(sysAddr); + response.Send(); } void ReadResponse::Serialize(RakNet::BitStream& bitStream) const { - MailLUBitStream::Serialize(bitStream); + MailClientLUBitStream::Serialize(bitStream); bitStream.Write(status); bitStream.Write(mailID); } @@ -275,13 +275,13 @@ namespace Mail { } LOG("NotificationRequest %s", StringifiedEnum::ToString(response.status).data()); - response.Send(sysAddr); + response.Send(); } } // Non Stuct Functions -void Mail::HandleMail(RakNet::BitStream& inStream, const SystemAddress& sysAddr, Entity* player) { - MailLUBitStream data; +void Mail::Handle(RakNet::BitStream& inStream, const SystemAddress& sysAddr, Entity* player) { + MailClientLUBitStream data; if (!data.Deserialize(inStream)) { LOG_DEBUG("Error Reading Mail header"); return; @@ -368,5 +368,5 @@ void Mail::SendMail(const LWOOBJID sender, const std::string& senderName, LWOOBJ if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) return; // TODO: Echo to chat server NotificationResponse response; response.status = eNotificationResponse::NewMail; - response.Send(sysAddr); + response.Send(); } diff --git a/dGame/dUtilities/Mail.h b/dGame/dUtilities/Mail.h index 9c83025f8..5182090a7 100644 --- a/dGame/dUtilities/Mail.h +++ b/dGame/dUtilities/Mail.h @@ -7,6 +7,8 @@ #include "dCommonVars.h" #include "BitStreamUtils.h" #include "MailInfo.h" +#include "MessageType/Client.h" +#include "ClientPackets.h" class Entity; @@ -103,112 +105,111 @@ namespace Mail { UnknownError }; - struct MailLUBitStream : public LUBitStream { + struct MailClientLUBitStream : public ClientPackets::ClientLUBitStream { eMessageID messageID = eMessageID::UnknownError; - SystemAddress sysAddr = UNASSIGNED_SYSTEM_ADDRESS; Entity* player = nullptr; - MailLUBitStream() = default; - MailLUBitStream(eMessageID _messageID) : LUBitStream(ServiceType::CLIENT, MessageType::Client::MAIL), messageID{_messageID} {}; + MailClientLUBitStream() = default; + MailClientLUBitStream(eMessageID _messageID) : ClientPackets::ClientLUBitStream(MessageType::Client::MAIL), messageID{_messageID} {}; virtual void Serialize(RakNet::BitStream& bitStream) const override; virtual bool Deserialize(RakNet::BitStream& bitStream) override; virtual void Handle() override {}; }; - struct SendRequest : public MailLUBitStream { + struct SendRequest : public MailClientLUBitStream { MailInfo mailInfo; - SendRequest() : MailLUBitStream(eMessageID::SendRequest) {} + SendRequest() : MailClientLUBitStream(eMessageID::SendRequest) {} bool Deserialize(RakNet::BitStream& bitStream) override; void Handle() override; }; - struct SendResponse :public MailLUBitStream { + struct SendResponse :public MailClientLUBitStream { eSendResponse status = eSendResponse::UnknownError; - SendResponse() : MailLUBitStream(eMessageID::SendResponse) {} + SendResponse() : MailClientLUBitStream(eMessageID::SendResponse) {} void Serialize(RakNet::BitStream& bitStream) const override; }; - struct NotificationResponse : public MailLUBitStream { + struct NotificationResponse : public MailClientLUBitStream { eNotificationResponse status = eNotificationResponse::UnknownError; LWOOBJID auctionID = LWOOBJID_EMPTY; uint32_t mailCount = 1; - NotificationResponse() : MailLUBitStream(eMessageID::NotificationResponse) {}; + NotificationResponse() : MailClientLUBitStream(eMessageID::NotificationResponse) {}; void Serialize(RakNet::BitStream& bitStream) const override; }; - struct DataRequest : public MailLUBitStream { - DataRequest() : MailLUBitStream(eMessageID::DataRequest) {} + struct DataRequest : public MailClientLUBitStream { + DataRequest() : MailClientLUBitStream(eMessageID::DataRequest) {} bool Deserialize(RakNet::BitStream& bitStream) override { return true; }; void Handle() override; }; - struct DataResponse : public MailLUBitStream { + struct DataResponse : public MailClientLUBitStream { uint32_t throttled = 0; std::vector playerMail; - DataResponse() : MailLUBitStream(eMessageID::DataResponse) {}; + DataResponse() : MailClientLUBitStream(eMessageID::DataResponse) {}; void Serialize(RakNet::BitStream& bitStream) const override; }; - struct AttachmentCollectRequest : public MailLUBitStream { + struct AttachmentCollectRequest : public MailClientLUBitStream { uint64_t mailID = 0; LWOOBJID playerID = LWOOBJID_EMPTY; - AttachmentCollectRequest() : MailLUBitStream(eMessageID::AttachmentCollectRequest) {}; + AttachmentCollectRequest() : MailClientLUBitStream(eMessageID::AttachmentCollectRequest) {}; bool Deserialize(RakNet::BitStream& bitStream) override; void Handle() override; }; - struct AttachmentCollectResponse : public MailLUBitStream { + struct AttachmentCollectResponse : public MailClientLUBitStream { eAttachmentCollectResponse status = eAttachmentCollectResponse::UnknownError; uint64_t mailID = 0; - AttachmentCollectResponse() : MailLUBitStream(eMessageID::AttachmentCollectResponse) {}; + AttachmentCollectResponse() : MailClientLUBitStream(eMessageID::AttachmentCollectResponse) {}; void Serialize(RakNet::BitStream& bitStream) const override; }; - struct DeleteRequest : public MailLUBitStream { + struct DeleteRequest : public MailClientLUBitStream { uint64_t mailID = 0; LWOOBJID playerID = LWOOBJID_EMPTY; - DeleteRequest() : MailLUBitStream(eMessageID::DeleteRequest) {}; + DeleteRequest() : MailClientLUBitStream(eMessageID::DeleteRequest) {}; bool Deserialize(RakNet::BitStream& bitStream) override; void Handle() override; }; - struct DeleteResponse : public MailLUBitStream { + struct DeleteResponse : public MailClientLUBitStream { eDeleteResponse status = eDeleteResponse::UnknownError; uint64_t mailID = 0; - DeleteResponse() : MailLUBitStream(eMessageID::DeleteResponse) {}; + DeleteResponse() : MailClientLUBitStream(eMessageID::DeleteResponse) {}; void Serialize(RakNet::BitStream& bitStream) const override; }; - struct ReadRequest : public MailLUBitStream { + struct ReadRequest : public MailClientLUBitStream { uint64_t mailID = 0; - ReadRequest() : MailLUBitStream(eMessageID::ReadRequest) {}; + ReadRequest() : MailClientLUBitStream(eMessageID::ReadRequest) {}; bool Deserialize(RakNet::BitStream& bitStream) override; void Handle() override; }; - struct ReadResponse : public MailLUBitStream { + struct ReadResponse : public MailClientLUBitStream { uint64_t mailID = 0; eReadResponse status = eReadResponse::UnknownError; - ReadResponse() : MailLUBitStream(eMessageID::ReadResponse) {}; + ReadResponse() : MailClientLUBitStream(eMessageID::ReadResponse) {}; void Serialize(RakNet::BitStream& bitStream) const override; }; - struct NotificationRequest : public MailLUBitStream { - NotificationRequest() : MailLUBitStream(eMessageID::NotificationRequest) {}; + struct NotificationRequest : public MailClientLUBitStream { + NotificationRequest() : MailClientLUBitStream(eMessageID::NotificationRequest) {}; bool Deserialize(RakNet::BitStream& bitStream) override { return true; }; void Handle() override; }; - void HandleMail(RakNet::BitStream& inStream, const SystemAddress& sysAddr, Entity* player); + void Handle(RakNet::BitStream& inStream, const SystemAddress& sysAddr, Entity* player); void SendMail( const Entity* recipient, diff --git a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp index b31291fe0..a131b804a 100644 --- a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp +++ b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp @@ -3,6 +3,7 @@ // Classes #include "Character.h" #include "ChatPackets.h" +#include "CommonPackets.h" #include "dServer.h" #include "PlayerManager.h" #include "User.h" @@ -16,7 +17,6 @@ // Enums #include "MessageType/Chat.h" -#include "eServerDisconnectIdentifiers.h" #include "eObjectBits.h" namespace GMGreaterThanZeroCommands { @@ -31,8 +31,10 @@ namespace GMGreaterThanZeroCommands { ChatPackets::SendSystemMessage(sysAddr, u"Count not find player of name: " + username); return; } - - Game::server->Disconnect(player->GetSystemAddress(), eServerDisconnectIdentifiers::KICK); + CommonPackets::DisconnectNotify notification; + notification.disconnectID = eServerDisconnectIdentifiers::KICK; + notification.Send(player->GetSystemAddress()); + Game::server->Disconnect(player->GetSystemAddress()); ChatPackets::SendSystemMessage(sysAddr, u"Kicked: " + username); } else { @@ -69,7 +71,10 @@ namespace GMGreaterThanZeroCommands { if (accountId != 0) Database::Get()->UpdateAccountBan(accountId, true); if (player != nullptr) { - Game::server->Disconnect(player->GetSystemAddress(), eServerDisconnectIdentifiers::FREE_TRIAL_EXPIRED); + CommonPackets::DisconnectNotify notification; + notification.disconnectID = eServerDisconnectIdentifiers::FREE_TRIAL_EXPIRED; + notification.Send(player->GetSystemAddress()); + Game::server->Disconnect(player->GetSystemAddress()); } ChatPackets::SendSystemMessage(sysAddr, u"Banned: " + GeneralUtils::ASCIIToUTF16(splitArgs[0])); diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index a46ed9f19..a39aa5458 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -17,296 +17,244 @@ #include "Game.h" #include "dConfig.h" -#include "eServerDisconnectIdentifiers.h" -#include "eLoginResponse.h" #include "ServiceType.h" #include "MessageType/Server.h" #include "MessageType/Master.h" #include "eGameMasterLevel.h" #include "StringifiedEnum.h" +#include "CommonPackets.h" +#include "ClientPackets.h" + namespace { std::vector claimCodes; } -void Stamp::Serialize(RakNet::BitStream& outBitStream){ - outBitStream.Write(type); - outBitStream.Write(value); - outBitStream.Write(timestamp); -}; - -void AuthPackets::LoadClaimCodes() { - if(!claimCodes.empty()) return; - auto rcstring = Game::config->GetValue("rewardcodes"); - auto codestrings = GeneralUtils::SplitString(rcstring, ','); - for(auto const &codestring: codestrings){ - const auto code = GeneralUtils::TryParse(codestring); - - if (code && code.value() != -1) claimCodes.push_back(code.value()); +namespace AuthPackets { + std::map()>> g_Handlers = { + {MessageType::Auth::LOGIN_REQUEST, []() { + return std::make_unique(); + }} + }; + + // Struct Functions + void AuthLUBitStream::Serialize(RakNet::BitStream& bitStream) const { + bitStream.Write(this->messageType); + bitStream.Write(0); // padding } -} - -void AuthPackets::HandleHandshake(dServer* server, Packet* packet) { - CINSTREAM_SKIP_HEADER - uint32_t clientVersion = 0; - inStream.Read(clientVersion); - inStream.IgnoreBytes(4); - - ServiceType serviceType; - inStream.Read(serviceType); - if (serviceType != ServiceType::CLIENT) LOG("WARNING: Service is not a Client!"); - inStream.IgnoreBytes(2); - - uint32_t processID; - inStream.Read(processID); - - uint16_t port; - inStream.Read(port); - if (port != packet->systemAddress.port) LOG("WARNING: Port written in packet does not match the port the client is connecting over!"); - - inStream.IgnoreBytes(33); - - LOG_DEBUG("Client Data [Version: %i, Service: %s, Process: %u, Port: %u, Sysaddr Port: %u]", clientVersion, StringifiedEnum::ToString(serviceType).data(), processID, port, packet->systemAddress.port); - - SendHandshake(server, packet->systemAddress, server->GetIP(), server->GetPort(), server->GetServerType()); -} - -void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServiceType serverType) { - RakNet::BitStream bitStream; - BitStreamUtils::WriteHeader(bitStream, ServiceType::COMMON, MessageType::Server::VERSION_CONFIRM); - - const auto& clientNetVersionString = Game::config->GetValue("client_net_version"); - const uint32_t clientNetVersion = GeneralUtils::TryParse(clientNetVersionString).value_or(171022); - - bitStream.Write(clientNetVersion); - bitStream.Write(861228100); - bitStream.Write(static_cast(serverType)); - bitStream.Write(219818307120); - - server->Send(bitStream, sysAddr, false); -} - -std::string CleanReceivedString(const std::string& str) { - std::string toReturn = str; - const auto removed = std::ranges::find_if(toReturn, [](unsigned char c) { return isprint(c) == 0 && isblank(c) == 0; }); - toReturn.erase(removed, toReturn.end()); - return toReturn; -} - -void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) { - CINSTREAM_SKIP_HEADER; - - std::vector stamps; - stamps.emplace_back(eStamps::PASSPORT_AUTH_START, 0); - - LUWString usernameLUString; - inStream.Read(usernameLUString); - const auto username = usernameLUString.GetAsString(); - - LUWString password(41); - inStream.Read(password); - - LanguageCodeID locale_id; - inStream.Read(locale_id); - LOG_DEBUG("Locale ID: %s", StringifiedEnum::ToString(locale_id).data()); - - ClientOS clientOS; - inStream.Read(clientOS); - LOG_DEBUG("Operating System: %s", StringifiedEnum::ToString(clientOS).data()); - stamps.emplace_back(eStamps::PASSPORT_AUTH_CLIENT_OS, 0); - - LUWString memoryStats(256); - inStream.Read(memoryStats); - LOG_DEBUG("Memory Stats [%s]", CleanReceivedString(memoryStats.GetAsString()).c_str()); - - LUWString videoCard(128); - inStream.Read(videoCard); - LOG_DEBUG("VideoCard Info: [%s]", CleanReceivedString(videoCard.GetAsString()).c_str()); - - // Processor/CPU info - uint32_t numOfProcessors; - inStream.Read(numOfProcessors); - uint32_t processorType; - inStream.Read(processorType); - uint16_t processorLevel; - inStream.Read(processorLevel); - uint16_t processorRevision; - inStream.Read(processorRevision); - LOG_DEBUG("CPU Info: [#Processors: %i, Processor Type: %i, Processor Level: %i, Processor Revision: %i]", numOfProcessors, processorType, processorLevel, processorRevision); - - // OS Info - uint32_t osVersionInfoSize; - inStream.Read(osVersionInfoSize); - uint32_t majorVersion; - inStream.Read(majorVersion); - uint32_t minorVersion; - inStream.Read(minorVersion); - uint32_t buildNumber; - inStream.Read(buildNumber); - uint32_t platformID; - inStream.Read(platformID); - LOG_DEBUG("OS Info: [Size: %i, Major: %i, Minor %i, Buid#: %i, platformID: %i]", osVersionInfoSize, majorVersion, minorVersion, buildNumber, platformID); - - // Fetch account details - auto accountInfo = Database::Get()->GetAccountInfo(username); - - if (!accountInfo) { - LOG("No user by name %s found!", username.c_str()); - stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::INVALID_USER, "", "", 2001, username, stamps); - return; + bool AuthLUBitStream::Deserialize(RakNet::BitStream& bitStream) { + VALIDATE_READ(bitStream.Read(this->messageType)); + uint8_t padding = 0; + VALIDATE_READ(bitStream.Read(padding)); + return true; } - //If we aren't running in live mode, then only GMs are allowed to enter: - const auto& closedToNonDevs = Game::config->GetValue("closed_to_non_devs"); - if (closedToNonDevs.size() > 0 && bool(std::stoi(closedToNonDevs)) && accountInfo->maxGmLevel == eGameMasterLevel::CIVILIAN) { - stamps.emplace_back(eStamps::GM_REQUIRED, 1); - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "The server is currently only open to developers.", "", 2001, username, stamps); - return; + bool LoginRequest::Deserialize(RakNet::BitStream& bitStream) { + LUWString usernameLUString; + VALIDATE_READ(bitStream.Read(usernameLUString)); + username = usernameLUString.GetAsString(); + + LUWString passwordLUString(41); + VALIDATE_READ(bitStream.Read(passwordLUString)); + password = passwordLUString.GetAsString(); + VALIDATE_READ(bitStream.Read(locale_id)); + VALIDATE_READ(bitStream.Read(clientOS)); + + LUWString memoryStatsLU(256); + VALIDATE_READ(bitStream.Read(memoryStatsLU)); + computerInfo.memoryStats = memoryStatsLU.GetAsString(); + + LUWString videoCardLU(128); + VALIDATE_READ(bitStream.Read(videoCardLU)); + computerInfo.videoCard = videoCardLU.GetAsString(); + + // Processor/CPU info + VALIDATE_READ(bitStream.Read(computerInfo.processorInfo.count)); + VALIDATE_READ(bitStream.Read(computerInfo.processorInfo.type)); + VALIDATE_READ(bitStream.Read(computerInfo.processorInfo.level)); + VALIDATE_READ(bitStream.Read(computerInfo.processorInfo.revision)); + + // OS Info + VALIDATE_READ(bitStream.Read(computerInfo.osVersionInfo.infoSize)); + VALIDATE_READ(bitStream.Read(computerInfo.osVersionInfo.majorVersion)); + VALIDATE_READ(bitStream.Read(computerInfo.osVersionInfo.minorVersion)); + VALIDATE_READ(bitStream.Read(computerInfo.osVersionInfo.buildNumber)); + VALIDATE_READ(bitStream.Read(computerInfo.osVersionInfo.platformID)); + + return true; } - if (Game::config->GetValue("dont_use_keys") != "1" && accountInfo->maxGmLevel == eGameMasterLevel::CIVILIAN) { - //Check to see if we have a play key: - if (accountInfo->playKeyId == 0) { - stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, username, stamps); - LOG("User %s tried to log in, but they don't have a play key.", username.c_str()); + void LoginRequest::Handle() { + LOG_DEBUG("Login Request from %s", username.c_str()); + LOG_DEBUG("Password: %s", password.c_str()); + + LOG_DEBUG("Locale ID: %s", StringifiedEnum::ToString(locale_id).data()); + + LOG_DEBUG("Operating System: %s", StringifiedEnum::ToString(clientOS).data()); + + LOG_DEBUG("Memory Stats [%s]", computerInfo.memoryStats.c_str()); + + LOG_DEBUG("VideoCard Info: [%s]", computerInfo.videoCard.c_str()); + + LOG_DEBUG("CPU Info: [#Processors: %i, Processor Type: %i, Processor Level: %i, Processor Revision: %i]", + computerInfo.processorInfo.count, + computerInfo.processorInfo.type, + computerInfo.processorInfo.level, + computerInfo.processorInfo.revision + ); + + LOG_DEBUG("OS Info: [Size: %i, Version: %i.%i, Buid#: %i, platformID: %i]", + computerInfo.osVersionInfo.infoSize, + computerInfo.osVersionInfo.majorVersion, + computerInfo.osVersionInfo.minorVersion, + computerInfo.osVersionInfo.buildNumber, + computerInfo.osVersionInfo.platformID + ); + + ClientPackets::LoginResponse response; + response.sysAddr = this->sysAddr; + response.stamps.emplace_back(eStamps::PASSPORT_AUTH_START, 0); + response.stamps.emplace_back(eStamps::PASSPORT_AUTH_CLIENT_OS, 0); + response.events.push_back(LUString(Game::config->GetValue("event_1"))); + response.events.push_back(LUString(Game::config->GetValue("event_2"))); + response.events.push_back(LUString(Game::config->GetValue("event_3"))); + response.events.push_back(LUString(Game::config->GetValue("event_4"))); + response.events.push_back(LUString(Game::config->GetValue("event_5"))); + response.events.push_back(LUString(Game::config->GetValue("event_6"))); + response.events.push_back(LUString(Game::config->GetValue("event_7"))); + response.events.push_back(LUString(Game::config->GetValue("event_8"))); + response.version_major = GeneralUtils::TryParse(Game::config->GetValue("version_major")).value_or(ClientVersion::major); + response.version_current = GeneralUtils::TryParse(Game::config->GetValue("version_current")).value_or(ClientVersion::current); + response.version_minor = GeneralUtils::TryParse(Game::config->GetValue("version_minor")).value_or(ClientVersion::minor); + + uint32_t sessionKey = GeneralUtils::GenerateRandomNumber(); + std::string userHash = std::to_string(sessionKey); + response.userKey = md5(userHash); + + // Fetch account details + auto accountInfo = Database::Get()->GetAccountInfo(username); + + if (!accountInfo) { + LOG("No user by name %s found!", username.c_str()); + response.stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); + response.Send(sysAddr); + return; + } + + //If we aren't running in live mode, then only GMs are allowed to enter: + const auto& closedToNonDevs = Game::config->GetValue("closed_to_non_devs"); + if (closedToNonDevs.size() > 0 && bool(std::stoi(closedToNonDevs)) && accountInfo->maxGmLevel == eGameMasterLevel::CIVILIAN) { + response.stamps.emplace_back(eStamps::GM_REQUIRED, 1); + response.Send(sysAddr); return; } - //Check if the play key is _valid_: - auto playKeyStatus = Database::Get()->IsPlaykeyActive(accountInfo->playKeyId); + if (Game::config->GetValue("dont_use_keys") != "1" && accountInfo->maxGmLevel == eGameMasterLevel::CIVILIAN) { + //Check to see if we have a play key: + if (accountInfo->playKeyId == 0) { + response.stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); + response.responseCode = eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH; + response.errorMessage = "Your account doesn't have a play key associated with it!"; + response.Send(sysAddr); + LOG("User %s tried to log in, but they don't have a play key.", username.c_str()); + return; + } + + //Check if the play key is _valid_: + auto playKeyStatus = Database::Get()->IsPlaykeyActive(accountInfo->playKeyId); + + if (!playKeyStatus) { + response.stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); + response.responseCode = eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH; + response.errorMessage = "Your account doesn't have a valid play key associated with it!"; + response.Send(sysAddr); + return; + } + + if (!playKeyStatus.value()) { + response.stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); + response.responseCode = eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH; + response.errorMessage = "Your play key has been disabled."; + response.Send(sysAddr); + LOG("User %s tried to log in, but their play key was disabled", username.c_str()); + return; + } + } else if (Game::config->GetValue("dont_use_keys") == "1" || accountInfo->maxGmLevel > eGameMasterLevel::CIVILIAN) { + response.stamps.emplace_back(eStamps::PASSPORT_AUTH_BYPASS, 1); + } - if (!playKeyStatus) { - stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a valid play key associated with it!", "", 2001, username, stamps); + if (accountInfo->banned) { + response.stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); + response.responseCode = eLoginResponse::BANNED; + response.errorMessage = "Your account has been banned."; + response.Send(sysAddr); return; } - if (!playKeyStatus.value()) { - stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your play key has been disabled.", "", 2001, username, stamps); - LOG("User %s tried to log in, but their play key was disabled", username.c_str()); + if (accountInfo->locked) { + response.stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); + response.responseCode = eLoginResponse::ACCOUNT_LOCKED; + response.errorMessage = "Your account is locked."; + response.Send(sysAddr); return; } - } else if (Game::config->GetValue("dont_use_keys") == "1" || accountInfo->maxGmLevel > eGameMasterLevel::CIVILIAN){ - stamps.emplace_back(eStamps::PASSPORT_AUTH_BYPASS, 1); - } - if (accountInfo->banned) { - stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::BANNED, "", "", 2001, username, stamps); - return; - } + bool loginSuccess = ::bcrypt_checkpw(password.c_str(), accountInfo->bcryptPassword.c_str()) == 0; + + if (!loginSuccess) { + response.stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); + response.responseCode = eLoginResponse::WRONG_PASS; + response.Send(sysAddr); + } else { + ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, 0, 0, false, [this, response, sessionKey](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string zoneIP, uint16_t zonePort) mutable { + response.responseCode = eLoginResponse::SUCCESS; + response.worldServerIP = LUString(zoneIP); + response.worldServerPort = zonePort; + response.Send(); + + CBITSTREAM; + BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::SET_SESSION_KEY); + bitStream.Write(sessionKey); + LOG_DEBUG("Sending session key for %s to master server", this->username.c_str()); + bitStream.Write(LUString(this->username)); + Game::server->SendToMaster(bitStream); + }); - if (accountInfo->locked) { - stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::ACCOUNT_LOCKED, "", "", 2001, username, stamps); - return; + for (auto const code : claimCodes) { + Database::Get()->InsertRewardCode(accountInfo->id, code); + } + } } +} - bool loginSuccess = ::bcrypt_checkpw(password.GetAsString().c_str(), accountInfo->bcryptPassword.c_str()) == 0; +// Non Stuct Functions +void AuthPackets::LoadClaimCodes() { + if (!claimCodes.empty()) return; + auto rcstring = Game::config->GetValue("rewardcodes"); + auto codestrings = GeneralUtils::SplitString(rcstring, ','); + for (auto const& codestring : codestrings) { + const auto code = GeneralUtils::TryParse(codestring); - if (!loginSuccess) { - stamps.emplace_back(eStamps::PASSPORT_AUTH_ERROR, 1); - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::WRONG_PASS, "", "", 2001, username, stamps); - LOG("Wrong password used"); - } else { - SystemAddress system = packet->systemAddress; //Copy the sysAddr before the Packet gets destroyed from main + if (code && code.value() != -1) claimCodes.push_back(code.value()); + } +} - if (!server->GetIsConnectedToMaster()) { - stamps.emplace_back(eStamps::PASSPORT_AUTH_WORLD_DISCONNECT, 1); - AuthPackets::SendLoginResponse(server, system, eLoginResponse::GENERAL_FAILED, "", "", 0, username, stamps); +// Non Stuct Functions +void AuthPackets::Handle(RakNet::BitStream& inStream, const SystemAddress& sysAddr) { + AuthLUBitStream authLUBitStream; + if (!authLUBitStream.Deserialize(inStream)) return; + + 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(authLUBitStream.messageType).data()); return; } - stamps.emplace_back(eStamps::PASSPORT_AUTH_WORLD_SESSION_CONFIRM_TO_AUTH, 1); - ZoneInstanceManager::Instance()->RequestZoneTransfer(server, 0, 0, false, [system, server, username, stamps](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string zoneIP, uint16_t zonePort) mutable { - AuthPackets::SendLoginResponse(server, system, eLoginResponse::SUCCESS, "", zoneIP, zonePort, username, stamps); - }); - } - - for(auto const code: claimCodes){ - Database::Get()->InsertRewardCode(accountInfo->id, code); + LOG_DEBUG("Received Auth Packet: %s", StringifiedEnum::ToString(authLUBitStream.messageType).data()); + request->Handle(); + } else { + LOG_DEBUG("Unhandled Auth Packet with ID: %i", authLUBitStream.messageType); } } -void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username, std::vector& stamps) { - stamps.emplace_back(eStamps::PASSPORT_AUTH_IM_LOGIN_START, 1); - RakNet::BitStream loginResponse; - BitStreamUtils::WriteHeader(loginResponse, ServiceType::CLIENT, MessageType::Client::LOGIN_RESPONSE); - - loginResponse.Write(responseCode); - - // Event Gating - loginResponse.Write(LUString(Game::config->GetValue("event_1"))); - loginResponse.Write(LUString(Game::config->GetValue("event_2"))); - loginResponse.Write(LUString(Game::config->GetValue("event_3"))); - loginResponse.Write(LUString(Game::config->GetValue("event_4"))); - loginResponse.Write(LUString(Game::config->GetValue("event_5"))); - loginResponse.Write(LUString(Game::config->GetValue("event_6"))); - loginResponse.Write(LUString(Game::config->GetValue("event_7"))); - loginResponse.Write(LUString(Game::config->GetValue("event_8"))); - - const uint16_t version_major = - GeneralUtils::TryParse(Game::config->GetValue("version_major")).value_or(ClientVersion::major); - const uint16_t version_current = - GeneralUtils::TryParse(Game::config->GetValue("version_current")).value_or(ClientVersion::current); - const uint16_t version_minor = - GeneralUtils::TryParse(Game::config->GetValue("version_minor")).value_or(ClientVersion::minor); - - loginResponse.Write(version_major); - loginResponse.Write(version_current); - loginResponse.Write(version_minor); - - // Writes the user key - uint32_t sessionKey = GeneralUtils::GenerateRandomNumber(); - std::string userHash = std::to_string(sessionKey); - userHash = md5(userHash); - loginResponse.Write(LUWString(userHash)); - - // World Server IP - loginResponse.Write(LUString(wServerIP)); - // Chat Server IP (unused) - loginResponse.Write(LUString("")); - - // World Server Redirect port - loginResponse.Write(wServerPort); - // Char Server Redirect port (unused) - loginResponse.Write(static_cast(0)); - - // CDN Key - loginResponse.Write(LUString("")); - - // CDN Ticket - loginResponse.Write(LUString("00000000-0000-0000-0000-000000000000", 37)); - - // Language - loginResponse.Write(Language::en_US); - - // Write the localization - loginResponse.Write(LUString("US", 3)); - - loginResponse.Write(false); // Just upgraded from F2P - loginResponse.Write(false); // User is F2P - loginResponse.Write(0); // Time Remaining in F2P - - // Write custom error message - loginResponse.Write(errorMsg.length()); - loginResponse.Write(LUWString(errorMsg, static_cast(errorMsg.length()))); - - stamps.emplace_back(eStamps::PASSPORT_AUTH_WORLD_COMMUNICATION_FINISH, 1); - - loginResponse.Write((sizeof(Stamp) * stamps.size()) + sizeof(uint32_t)); - for (auto& stamp : stamps) stamp.Serialize(loginResponse); - - server->Send(loginResponse, sysAddr, false); - //Inform the master server that we've created a session for this user: - if (responseCode == eLoginResponse::SUCCESS) { - CBITSTREAM; - BitStreamUtils::WriteHeader(bitStream, ServiceType::MASTER, MessageType::Master::SET_SESSION_KEY); - bitStream.Write(sessionKey); - bitStream.Write(LUString(username)); - server->SendToMaster(bitStream); - - LOG("Set sessionKey: %i for user %s", sessionKey, username.c_str()); - } -} diff --git a/dNet/AuthPackets.h b/dNet/AuthPackets.h index 156862eb5..a4cdfaafe 100644 --- a/dNet/AuthPackets.h +++ b/dNet/AuthPackets.h @@ -5,67 +5,15 @@ #include "dCommonVars.h" #include "dNetCommon.h" #include "magic_enum.hpp" +#include "BitStream.h" +#include "RakNetTypes.h" +#include "BitStreamUtils.h" +#include "MessageType/Auth.h" enum class eLoginResponse : uint8_t; enum class ServiceType : uint16_t; class dServer; -enum class eStamps : uint32_t { - PASSPORT_AUTH_START, - PASSPORT_AUTH_BYPASS, - PASSPORT_AUTH_ERROR, - PASSPORT_AUTH_DB_SELECT_START, - PASSPORT_AUTH_DB_SELECT_FINISH, - PASSPORT_AUTH_DB_INSERT_START, - PASSPORT_AUTH_DB_INSERT_FINISH, - PASSPORT_AUTH_LEGOINT_COMMUNICATION_START, - PASSPORT_AUTH_LEGOINT_RECEIVED, - PASSPORT_AUTH_LEGOINT_THREAD_SPAWN, - PASSPORT_AUTH_LEGOINT_WEBSERVICE_START, - PASSPORT_AUTH_LEGOINT_WEBSERVICE_FINISH, - PASSPORT_AUTH_LEGOINT_LEGOCLUB_START, - PASSPORT_AUTH_LEGOINT_LEGOCLUB_FINISH, - PASSPORT_AUTH_LEGOINT_THREAD_FINISH, - PASSPORT_AUTH_LEGOINT_REPLY, - PASSPORT_AUTH_LEGOINT_ERROR, - PASSPORT_AUTH_LEGOINT_COMMUNICATION_END, - PASSPORT_AUTH_LEGOINT_DISCONNECT, - PASSPORT_AUTH_WORLD_COMMUNICATION_START, - PASSPORT_AUTH_CLIENT_OS, - PASSPORT_AUTH_WORLD_PACKET_RECEIVED, - PASSPORT_AUTH_IM_COMMUNICATION_START, - PASSPORT_AUTH_IM_LOGIN_START, - PASSPORT_AUTH_IM_LOGIN_ALREADY_LOGGED_IN, - PASSPORT_AUTH_IM_OTHER_LOGIN_REMOVED, - PASSPORT_AUTH_IM_LOGIN_QUEUED, - PASSPORT_AUTH_IM_LOGIN_RESPONSE, - PASSPORT_AUTH_IM_COMMUNICATION_END, - PASSPORT_AUTH_WORLD_SESSION_CONFIRM_TO_AUTH, - PASSPORT_AUTH_WORLD_COMMUNICATION_FINISH, - PASSPORT_AUTH_WORLD_DISCONNECT, - NO_LEGO_INTERFACE, - DB_ERROR, - GM_REQUIRED, - NO_LEGO_WEBSERVICE_XML, - LEGO_WEBSERVICE_TIMEOUT, - LEGO_WEBSERVICE_ERROR, - NO_WORLD_SERVER -}; - -struct Stamp { - eStamps type; - uint32_t value; - uint64_t timestamp; - - Stamp(eStamps type, uint32_t value, uint64_t timestamp = time(nullptr)){ - this->type = type; - this->value = value; - this->timestamp = timestamp; - } - - void Serialize(RakNet::BitStream& outBitStream); -}; - enum class ClientOS : uint8_t { UNKNOWN, WINDOWS, @@ -84,20 +32,50 @@ struct magic_enum::customize::enum_range { static constexpr int max = 2057; }; -enum class Language : uint32_t { - en_US, - pl_US, - de_DE, - en_GB, -}; - namespace AuthPackets { - void HandleHandshake(dServer* server, Packet* packet); - void SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServiceType serverType); - void HandleLoginRequest(dServer* server, Packet* packet); - void SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username, std::vector& stamps); + 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; + ClientOS clientOS; + struct ComputerInfo { + std::string memoryStats; + std::string videoCard; + struct ProcessorInfo { + uint32_t count = 0; + uint32_t type = 0; + uint16_t level = 0; + uint16_t revision = 0; + } processorInfo; + struct OSVersionInfo { + uint32_t infoSize = 0; + uint32_t majorVersion = 0; + uint32_t minorVersion = 0; + uint32_t buildNumber = 0; + uint32_t platformID = 0; + } osVersionInfo; + } computerInfo; + + LoginRequest() : AuthLUBitStream(MessageType::Auth::LOGIN_REQUEST) {} + bool Deserialize(RakNet::BitStream& bitStream) override; + void Handle() override; + }; + + // Non struct functions void LoadClaimCodes(); + void Handle(RakNet::BitStream& inStream, const SystemAddress& sysAddr); } diff --git a/dNet/BitStreamUtils.cpp b/dNet/BitStreamUtils.cpp index 912737850..e5dec71eb 100644 --- a/dNet/BitStreamUtils.cpp +++ b/dNet/BitStreamUtils.cpp @@ -6,18 +6,12 @@ void LUBitStream::WriteHeader(RakNet::BitStream& bitStream) const { bitStream.Write(ID_USER_PACKET_ENUM); - bitStream.Write(this->connectionType); - bitStream.Write(this->internalPacketID); - bitStream.Write(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; } diff --git a/dNet/BitStreamUtils.h b/dNet/BitStreamUtils.h index 24d8c4dcb..bcfc94716 100644 --- a/dNet/BitStreamUtils.h +++ b/dNet/BitStreamUtils.h @@ -47,20 +47,22 @@ 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 - LUBitStream(ServiceType connectionType, T internalPacketID) { - this->connectionType = connectionType; - this->internalPacketID = static_cast(internalPacketID); + LUBitStream(ServiceType serviceType) { + this->serviceType = serviceType; } void WriteHeader(RakNet::BitStream& bitStream) const; bool ReadHeader(RakNet::BitStream& bitStream); void Send(const SystemAddress& sysAddr) const; + void Send() const { Send(this->sysAddr); }; void Broadcast() const { Send(UNASSIGNED_SYSTEM_ADDRESS); }; virtual void Serialize(RakNet::BitStream& bitStream) const {} diff --git a/dNet/CMakeLists.txt b/dNet/CMakeLists.txt index 9b780b84f..53b2729e4 100644 --- a/dNet/CMakeLists.txt +++ b/dNet/CMakeLists.txt @@ -2,12 +2,14 @@ set(DNET_SOURCES "AuthPackets.cpp" "BitStreamUtils.cpp" "ChatPackets.cpp" "ClientPackets.cpp" + "CommonPackets.cpp" "dServer.cpp" "MailInfo.cpp" "MasterPackets.cpp" "PacketUtils.cpp" "WorldPackets.cpp" - "ZoneInstanceManager.cpp") + "ZoneInstanceManager.cpp" + ) add_library(dNet STATIC ${DNET_SOURCES}) target_link_libraries(dNet PRIVATE bcrypt MD5 glm::glm) diff --git a/dNet/ChatPackets.cpp b/dNet/ChatPackets.cpp index 86622ad19..931aed0e3 100644 --- a/dNet/ChatPackets.cpp +++ b/dNet/ChatPackets.cpp @@ -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(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); @@ -100,6 +114,7 @@ void ChatPackets::SendMessageFail(const SystemAddress& sysAddr) { namespace ChatPackets { void Announcement::Serialize(RakNet::BitStream& bitStream) const { + ChatLUBitStream::Serialize(bitStream); bitStream.Write(title.size()); bitStream.Write(title); bitStream.Write(message.size()); @@ -108,6 +123,7 @@ namespace ChatPackets { } void ChatPackets::AchievementNotify::Serialize(RakNet::BitStream& bitstream) const { + ChatLUBitStream::Serialize(bitstream); bitstream.Write(0); // Packing bitstream.Write(0); // Packing bitstream.Write(0); // Packing @@ -133,6 +149,7 @@ bool ChatPackets::AchievementNotify::Deserialize(RakNet::BitStream& bitstream) { } void ChatPackets::TeamInviteInitialResponse::Serialize(RakNet::BitStream& bitstream) const { + ClientLUBitStream::Serialize(bitstream); bitstream.Write(inviteFailedToSend); bitstream.Write(playerName); } diff --git a/dNet/ChatPackets.h b/dNet/ChatPackets.h index 53d0eced9..918259d81 100644 --- a/dNet/ChatPackets.h +++ b/dNet/ChatPackets.h @@ -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 diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index a6b9f8c6b..2c48eab92 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -6,6 +6,58 @@ #include "ClientPackets.h" #include "dCommonVars.h" #include "PositionUpdate.h" +#include "StringifiedEnum.h" + + +namespace ClientPackets { + void Stamp::Serialize(RakNet::BitStream& bitStream) const { + bitStream.Write(type); + bitStream.Write(value); + bitStream.Write(timestamp); + }; + + void ClientLUBitStream::Serialize(RakNet::BitStream& bitStream) const { + bitStream.Write(this->messageType); + bitStream.Write(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]); + bitStream.Write(events[2]); + bitStream.Write(events[3]); + bitStream.Write(events[4]); + bitStream.Write(events[5]); + bitStream.Write(events[6]); + bitStream.Write(events[7]); + bitStream.Write(version_major); + bitStream.Write(version_current); + bitStream.Write(version_minor); + bitStream.Write(userKey); + bitStream.Write(worldServerIP); + bitStream.Write(chatServerIP); + bitStream.Write(worldServerPort); + bitStream.Write(chatServerPort); + bitStream.Write(cdnKey); + bitStream.Write(cdnTicket); + bitStream.Write(language); + bitStream.Write(localization); + bitStream.Write(static_cast(justUpgradedFromF2P)); + bitStream.Write(static_cast(isF2P)); + bitStream.Write(membershipTimeLeft); + bitStream.Write(errorMessage.length()); + bitStream.Write(LUWString(errorMessage, static_cast(errorMessage.length()))); + bitStream.Write((sizeof(Stamp) * stamps.size()) + sizeof(uint32_t)); + for (const auto& stampData : stamps) stampData.Serialize(bitStream); + }; +} ChatMessage ClientPackets::HandleChatMessage(Packet* packet) { CINSTREAM_SKIP_HEADER; diff --git a/dNet/ClientPackets.h b/dNet/ClientPackets.h index a7d2941b5..6661d7a00 100644 --- a/dNet/ClientPackets.h +++ b/dNet/ClientPackets.h @@ -8,6 +8,8 @@ #include #include +#include "BitStreamUtils.h" +#include "MessageType/Client.h" class PositionUpdate; @@ -26,11 +28,132 @@ struct ChatModerationRequest { std::string message; }; + +enum class eLoginResponse : uint8_t { + GENERAL_FAILED = 0, + SUCCESS, + BANNED, + // Unused 3 + // Unused 4 + PERMISSIONS_NOT_HIGH_ENOUGH = 5, + INVALID_USER, + ACCOUNT_LOCKED, + WRONG_PASS, + ACCOUNT_ACTIVATION_PENDING, + ACCOUNT_DISABLED, + GAME_TIME_EXPIRED, + FREE_TRIAL_ENDED, + PLAY_SCHEDULE_TIME_UP, + ACCOUNT_NOT_ACTIVATED +}; + +enum class eStamps : uint32_t { + PASSPORT_AUTH_START, + PASSPORT_AUTH_BYPASS, + PASSPORT_AUTH_ERROR, + PASSPORT_AUTH_DB_SELECT_START, + PASSPORT_AUTH_DB_SELECT_FINISH, + PASSPORT_AUTH_DB_INSERT_START, + PASSPORT_AUTH_DB_INSERT_FINISH, + PASSPORT_AUTH_LEGOINT_COMMUNICATION_START, + PASSPORT_AUTH_LEGOINT_RECEIVED, + PASSPORT_AUTH_LEGOINT_THREAD_SPAWN, + PASSPORT_AUTH_LEGOINT_WEBSERVICE_START, + PASSPORT_AUTH_LEGOINT_WEBSERVICE_FINISH, + PASSPORT_AUTH_LEGOINT_LEGOCLUB_START, + PASSPORT_AUTH_LEGOINT_LEGOCLUB_FINISH, + PASSPORT_AUTH_LEGOINT_THREAD_FINISH, + PASSPORT_AUTH_LEGOINT_REPLY, + PASSPORT_AUTH_LEGOINT_ERROR, + PASSPORT_AUTH_LEGOINT_COMMUNICATION_END, + PASSPORT_AUTH_LEGOINT_DISCONNECT, + PASSPORT_AUTH_WORLD_COMMUNICATION_START, + PASSPORT_AUTH_CLIENT_OS, + PASSPORT_AUTH_WORLD_PACKET_RECEIVED, + PASSPORT_AUTH_IM_COMMUNICATION_START, + PASSPORT_AUTH_IM_LOGIN_START, + PASSPORT_AUTH_IM_LOGIN_ALREADY_LOGGED_IN, + PASSPORT_AUTH_IM_OTHER_LOGIN_REMOVED, + PASSPORT_AUTH_IM_LOGIN_QUEUED, + PASSPORT_AUTH_IM_LOGIN_RESPONSE, + PASSPORT_AUTH_IM_COMMUNICATION_END, + PASSPORT_AUTH_WORLD_SESSION_CONFIRM_TO_AUTH, + PASSPORT_AUTH_WORLD_COMMUNICATION_FINISH, + PASSPORT_AUTH_WORLD_DISCONNECT, + NO_LEGO_INTERFACE, + DB_ERROR, + GM_REQUIRED, + NO_LEGO_WEBSERVICE_XML, + LEGO_WEBSERVICE_TIMEOUT, + LEGO_WEBSERVICE_ERROR, + NO_WORLD_SERVER +}; + +enum class Language : uint32_t { + en_US, + pl_US, + de_DE, + en_GB, +}; + 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; + uint64_t timestamp; + + Stamp(eStamps type, uint32_t value, uint64_t timestamp = time(nullptr)) { + this->type = type; + this->value = value; + this->timestamp = timestamp; + } + + void Serialize(RakNet::BitStream& bitStream) const; + }; + + struct LoginResponse : public ClientLUBitStream { + eLoginResponse responseCode = eLoginResponse::GENERAL_FAILED; + std::vector events; + uint16_t version_major = 0; + uint16_t version_current = 0; + uint16_t version_minor = 0; + LUWString userKey; + LUString worldServerIP; + LUString chatServerIP = LUString(""); // unused + uint16_t worldServerPort = 0; + uint16_t chatServerPort = 0; // unused + LUString cdnKey = LUString(""); + LUString cdnTicket = LUString("00000000-0000-0000-0000-000000000000", 37); + Language language = Language::en_US; + LUString localization = LUString("US", 3); + bool justUpgradedFromF2P = false; // written as uint8_t + bool isF2P = false; // written as uint8_t + uint64_t membershipTimeLeft = 0; + std::string errorMessage; + std::vector stamps; + + LoginResponse() : ClientLUBitStream(MessageType::Client::LOGIN_RESPONSE) {} + void Serialize(RakNet::BitStream& bitStream) const override; + }; + + ChatMessage HandleChatMessage(Packet* packet); PositionUpdate HandleClientPositionUpdate(Packet* packet); ChatModerationRequest HandleChatModerationRequest(Packet* packet); int32_t SendTop5HelpIssues(Packet* packet); }; + #endif // CLIENTPACKETS_H diff --git a/dNet/CommonPackets.cpp b/dNet/CommonPackets.cpp new file mode 100644 index 000000000..30eac449e --- /dev/null +++ b/dNet/CommonPackets.cpp @@ -0,0 +1,100 @@ + +#include "CommonPackets.h" +#include "dServer.h" +#include "Logger.h" +#include "Game.h" +#include "dServer.h" +#include "dConfig.h" +#include "StringifiedEnum.h" +#include "GeneralUtils.h" + + +namespace CommonPackets { + std::map()>> g_Handlers = { + {MessageType::Server::VERSION_CONFIRM, []() { + return std::make_unique(); + }}, + {MessageType::Server::DISCONNECT_NOTIFY, []() { + return std::make_unique(); + }}, + {MessageType::Server::GENERAL_NOTIFY, []() { + return std::make_unique(); + }} + }; + + // Struct Functions + void CommonLUBitStream::Serialize(RakNet::BitStream& bitStream) const { + bitStream.Write(this->messageType); + bitStream.Write(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(netVersion); + bitStream.Write(861228100); + bitStream.Write(static_cast(serviceType)); + bitStream.Write(219818307120); + } + + bool VersionConfirm::Deserialize(RakNet::BitStream& bitStream) { + VALIDATE_READ(bitStream.Read(netVersion)); + uint32_t unknown = 0; + VALIDATE_READ(bitStream.Read(unknown)); + VALIDATE_READ(bitStream.Read(serviceType)); + uint16_t unknown2 = 0; + VALIDATE_READ(bitStream.Read(unknown2)); + VALIDATE_READ(bitStream.Read(processID)); + VALIDATE_READ(bitStream.Read(port)); + LUString unknownString; + VALIDATE_READ(bitStream.Read(unknownString)); + return true; + } + + void VersionConfirm::Handle() { + LOG_DEBUG("Client Data [Version: %i, Service: %s, Process: %u, Port: %u, Sysaddr Port: %u]", netVersion, StringifiedEnum::ToString(serviceType).data(), processID, port, sysAddr.port); + + VersionConfirm response; + auto& serverNetVersionString = Game::config->GetValue("client_net_version"); + const uint32_t serverNetVersion = GeneralUtils::TryParse(serverNetVersionString).value_or(171022); + response.netVersion = serverNetVersion; + response.serviceType = Game::server->GetServerType(); + response.Send(sysAddr); + } + + void DisconnectNotify::Serialize(RakNet::BitStream& bitStream) const { + CommonLUBitStream::Serialize(bitStream); + bitStream.Write(disconnectID); + } + + 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) { + CommonLUBitStream lubitstream; + if (!lubitstream.Deserialize(inStream)) return; + + 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(lubitstream.messageType).data()); + return; + } + LOG_DEBUG("Received Common Packet: %s", StringifiedEnum::ToString(lubitstream.messageType).data()); + request->Handle(); + } else { + LOG_DEBUG("Unhandled Common Packet with ID: %i", lubitstream.messageType); + } +} + diff --git a/dNet/CommonPackets.h b/dNet/CommonPackets.h new file mode 100644 index 000000000..da89f9fed --- /dev/null +++ b/dNet/CommonPackets.h @@ -0,0 +1,68 @@ +#include "dCommonVars.h" +#include "dNetCommon.h" +#include "BitStreamUtils.h" +#include "MessageType/Server.h" + +enum class eServerDisconnectIdentifiers : uint32_t { + UNKNOWN_SERVER_ERROR = 0, + WRONG_GAME_VERSION, + WRONG_SERVER_VERSION, + CONNECTION_ON_INVALID_PORT, + DUPLICATE_LOGIN, + SERVER_SHUTDOWN, + SERVER_MAP_LOAD_FAILURE, + INVALID_SESSION_KEY, + ACCOUNT_NOT_IN_PENDING_LIST, + CHARACTER_NOT_FOUND, + CHARACTER_CORRUPTED, + KICK, + SAVE_FAILURE, + FREE_TRIAL_EXPIRED, + PLAY_SCHEDULE_TIME_DONE +}; + +// Packet Struct Functions +namespace CommonPackets { + // Structs + struct CommonLUBitStream : public LUBitStream { + MessageType::Server messageType = MessageType::Server::VERSION_CONFIRM; + + 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() : CommonLUBitStream(MessageType::Server::VERSION_CONFIRM) {} + void Serialize(RakNet::BitStream& bitStream) const override; + bool Deserialize(RakNet::BitStream& bitStream) override; + void Handle() override; + }; + + struct DisconnectNotify : public CommonLUBitStream { + eServerDisconnectIdentifiers disconnectID = eServerDisconnectIdentifiers::UNKNOWN_SERVER_ERROR; + + DisconnectNotify() : CommonLUBitStream(MessageType::Server::DISCONNECT_NOTIFY) {} + void Serialize(RakNet::BitStream& bitStream) const override; + }; + + struct GeneralNotify : public CommonLUBitStream { + uint32_t notifyID = 0; // only one known value: 0, which is Duplicate account login + bool notifyUser = true; + + GeneralNotify() : CommonLUBitStream(MessageType::Server::GENERAL_NOTIFY) {} + void Serialize(RakNet::BitStream& bitStream) const override; + }; + + // Non Struct functions + void Handle(RakNet::BitStream& inStream, const SystemAddress& sysAddr); +} + diff --git a/dNet/WorldPackets.cpp b/dNet/WorldPackets.cpp index 1c9898a99..ce1236ba8 100644 --- a/dNet/WorldPackets.cpp +++ b/dNet/WorldPackets.cpp @@ -12,6 +12,20 @@ #include +namespace WorldPackets { + // Struct Functions + void WorldLUBitStream::Serialize(RakNet::BitStream& bitStream) const { + bitStream.Write(this->messageType); + bitStream.Write(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(openWeb); diff --git a/dNet/WorldPackets.h b/dNet/WorldPackets.h index 1a48f5dfb..f99c99203 100644 --- a/dNet/WorldPackets.h +++ b/dNet/WorldPackets.h @@ -4,6 +4,7 @@ #include "dCommonVars.h" #include #include +#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); diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index 0a8e0ab90..0fd07a108 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -197,12 +197,7 @@ void dServer::SendToMaster(RakNet::BitStream& bitStream) { mMasterPeer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, mMasterSystemAddress, false); } -void dServer::Disconnect(const SystemAddress& sysAddr, eServerDisconnectIdentifiers disconNotifyID) { - RakNet::BitStream bitStream; - BitStreamUtils::WriteHeader(bitStream, ServiceType::COMMON, MessageType::Server::DISCONNECT_NOTIFY); - bitStream.Write(disconNotifyID); - mPeer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, sysAddr, false); - +void dServer::Disconnect(const SystemAddress& sysAddr) { mPeer->CloseConnection(sysAddr, true); } diff --git a/dNet/dServer.h b/dNet/dServer.h index c1b96c1ab..8ac4ddeb2 100644 --- a/dNet/dServer.h +++ b/dNet/dServer.h @@ -43,7 +43,7 @@ class dServer { virtual void Send(RakNet::BitStream& bitStream, const SystemAddress& sysAddr, bool broadcast); void SendToMaster(RakNet::BitStream& bitStream); - void Disconnect(const SystemAddress& sysAddr, eServerDisconnectIdentifiers disconNotifyID); + void Disconnect(const SystemAddress& sysAddr); bool IsConnected(const SystemAddress& sysAddr); const std::string& GetIP() const { return mIP; } diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index cb7fedd5d..413bc8f7f 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -40,6 +40,7 @@ #include "dChatFilter.h" #include "ClientPackets.h" #include "CharacterComponent.h" +#include "CommonPackets.h" #include "EntityManager.h" #include "EntityInfo.h" @@ -62,7 +63,6 @@ #include "eBlueprintSaveResponseType.h" #include "Amf3.h" #include "NiPoint3.h" -#include "eServerDisconnectIdentifiers.h" #include "eObjectBits.h" #include "ServiceType.h" #include "MessageType/Server.h" @@ -78,7 +78,6 @@ #include "Server.h" #include "PositionUpdate.h" #include "PlayerManager.h" -#include "eLoginResponse.h" #include "MissionComponent.h" #include "SlashCommandHandler.h" #include "InventoryComponent.h" @@ -703,7 +702,10 @@ void HandleMasterPacket(Packet* packet) { //Verify it: if (userHash != it->second.hash) { LOG("SOMEONE IS TRYING TO HACK? SESSION KEY MISMATCH: ours: %s != master: %s", userHash.c_str(), it->second.hash.c_str()); - Game::server->Disconnect(it->second.sysAddr, eServerDisconnectIdentifiers::INVALID_SESSION_KEY); + CommonPackets::DisconnectNotify notification; + notification.disconnectID = eServerDisconnectIdentifiers::INVALID_SESSION_KEY; + notification.Send(it->second.sysAddr); + Game::server->Disconnect(it->second.sysAddr); return; } else { LOG("User %s authenticated with correct key.", username.GetAsString().c_str()); @@ -786,7 +788,10 @@ void HandleMasterPacket(Packet* packet) { //Check the key: if (sessionKey != std::atoi(user->GetSessionKey().c_str())) { LOG("But the session key is invalid!", username.string.c_str()); - Game::server->Disconnect(user->GetSystemAddress(), eServerDisconnectIdentifiers::INVALID_SESSION_KEY); + CommonPackets::DisconnectNotify notification; + notification.disconnectID = eServerDisconnectIdentifiers::INVALID_SESSION_KEY; + notification.Send(user->GetSystemAddress()); + Game::server->Disconnect(user->GetSystemAddress()); return; } break; @@ -854,15 +859,15 @@ void HandlePacket(Packet* packet) { LUBitStream luBitStream; luBitStream.ReadHeader(inStream); - if (luBitStream.connectionType == ServiceType::COMMON) { - if (static_cast(luBitStream.internalPacketID) == MessageType::Server::VERSION_CONFIRM) { - AuthPackets::HandleHandshake(Game::server, packet); - } + if (luBitStream.serviceType == ServiceType::COMMON) { + CommonPackets::Handle(inStream, packet->systemAddress); } - if (luBitStream.connectionType != ServiceType::WORLD) return; + if (luBitStream.serviceType != ServiceType::WORLD) return; + WorldPackets::WorldLUBitStream worldLUBitStream; + worldLUBitStream.Deserialize(inStream); - switch (static_cast(luBitStream.internalPacketID)) { + switch (static_cast(worldLUBitStream.messageType)) { case MessageType::World::VALIDATION: { CINSTREAM_SKIP_HEADER; LUWString username; @@ -879,7 +884,10 @@ void HandlePacket(Packet* packet) { auto accountInfo = Database::Get()->GetAccountInfo(username.GetAsString()); if (!accountInfo) { LOG("Client's account does not exist in the database, aborting connection."); - Game::server->Disconnect(packet->systemAddress, eServerDisconnectIdentifiers::CHARACTER_NOT_FOUND); + CommonPackets::DisconnectNotify notification; + notification.disconnectID = eServerDisconnectIdentifiers::CHARACTER_NOT_FOUND; + notification.Send(packet->systemAddress); + Game::server->Disconnect(packet->systemAddress); return; } @@ -888,13 +896,13 @@ void HandlePacket(Packet* packet) { if (accountInfo->maxGmLevel < eGameMasterLevel::DEVELOPER) { LOG("Client's database checksum does not match the server's, aborting connection."); - std::vector stamps; - // Using the LoginResponse here since the UI is still in the login screen state // and we have a way to send a message about the client mismatch. - AuthPackets::SendLoginResponse( - Game::server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, - Game::config->GetValue("cdclient_mismatch_message"), "", 0, "", stamps); + ClientPackets::LoginResponse response; + response.sysAddr = packet->systemAddress; + response.responseCode = eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH; + response.errorMessage= Game::config->GetValue("cdclient_mismatch_message"); + response.Send(packet->systemAddress); return; } else { AMFArrayValue args; @@ -1207,7 +1215,10 @@ void HandlePacket(Packet* packet) { } } else { LOG("Couldn't find character to log in with for user %s (%i)!", user->GetUsername().c_str(), user->GetAccountID()); - Game::server->Disconnect(packet->systemAddress, eServerDisconnectIdentifiers::CHARACTER_NOT_FOUND); + CommonPackets::DisconnectNotify notification; + notification.disconnectID = eServerDisconnectIdentifiers::CHARACTER_NOT_FOUND; + notification.Send(packet->systemAddress); + Game::server->Disconnect(packet->systemAddress); } } else { LOG("Couldn't get user for level load complete!"); @@ -1230,7 +1241,7 @@ void HandlePacket(Packet* packet) { } case MessageType::World::MAIL: { - Mail::HandleMail(inStream, packet->systemAddress, UserManager::Instance()->GetUser(packet->systemAddress)->GetLastUsedChar()->GetEntity()); + Mail::Handle(inStream, packet->systemAddress, UserManager::Instance()->GetUser(packet->systemAddress)->GetLastUsedChar()->GetEntity()); break; } @@ -1386,7 +1397,11 @@ void HandlePacket(Packet* packet) { if (user) { user->UserOutOfSync(); } else { - Game::server->Disconnect(packet->systemAddress, eServerDisconnectIdentifiers::KICK); + CommonPackets::DisconnectNotify notification; + notification.disconnectID = eServerDisconnectIdentifiers::KICK; + notification.Send(packet->systemAddress); + Game::server->Disconnect(packet->systemAddress); + } break; } @@ -1463,8 +1478,10 @@ void WorldShutdownProcess(uint32_t zoneId) { while (Game::server->GetReplicaManager()->GetParticipantCount() > 0) { const auto& player = Game::server->GetReplicaManager()->GetParticipantAtIndex(0); - - Game::server->Disconnect(player, eServerDisconnectIdentifiers::SERVER_SHUTDOWN); + CommonPackets::DisconnectNotify notification; + notification.disconnectID = eServerDisconnectIdentifiers::SERVER_SHUTDOWN; + notification.Send(player); + Game::server->Disconnect(player); } SendShutdownMessageToMaster(); }