diff --git a/dChatServer/ChatPacketHandler.cpp b/dChatServer/ChatPacketHandler.cpp index 878cc71c..faccf473 100644 --- a/dChatServer/ChatPacketHandler.cpp +++ b/dChatServer/ChatPacketHandler.cpp @@ -2,7 +2,7 @@ #include "PlayerContainer.h" #include "Database.h" #include -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "Game.h" #include "dServer.h" #include "GeneralUtils.h" @@ -75,11 +75,11 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) { //Now, we need to send the friendlist to the server they came from: CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(playerID); //portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GET_FRIENDS_LIST_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GET_FRIENDS_LIST_RESPONSE); bitStream.Write(0); bitStream.Write(1); //Length of packet -- just writing one as it doesn't matter, client skips it. bitStream.Write((uint16_t)friends.size()); @@ -103,25 +103,17 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) { inStream.Read(requestorPlayerID); uint32_t spacing{}; inStream.Read(spacing); - std::string playerName = ""; - uint16_t character; - bool noMoreLettersInName = false; - - for (uint32_t j = 0; j < 33; j++) { - inStream.Read(character); - if (character == '\0') noMoreLettersInName = true; - if (!noMoreLettersInName) playerName.push_back(static_cast(character)); - } + LUWString playerName(33); char isBestFriendRequest{}; inStream.Read(isBestFriendRequest); auto requestor = playerContainer.GetPlayerData(requestorPlayerID); - if (requestor->playerName == playerName) { + if (requestor->playerName == playerName.GetAsString()) { SendFriendResponse(requestor, requestor, eAddFriendResponseType::MYTHRAN); return; }; - std::unique_ptr requestee(playerContainer.GetPlayerData(playerName)); + std::unique_ptr requestee(playerContainer.GetPlayerData(playerName.GetAsString())); // Check if player is online first if (isBestFriendRequest && !requestee) { @@ -249,12 +241,14 @@ void ChatPacketHandler::HandleFriendResponse(Packet* packet) { LWOOBJID playerID; inStream.Read(playerID); - eAddFriendResponseCode clientResponseCode = static_cast(packet->data[0x14]); - std::string friendName = PacketUtils::ReadString(0x15, packet, true); + eAddFriendResponseCode clientResponseCode; + inStream.Read(clientResponseCode); + LUWString friendName(33); + inStream.Read(friendName); //Now to try and find both of these: auto requestor = playerContainer.GetPlayerData(playerID); - auto requestee = playerContainer.GetPlayerData(friendName); + auto requestee = playerContainer.GetPlayerData(friendName.GetAsString()); if (!requestor || !requestee) return; eAddFriendResponseType serverResponseCode{}; @@ -323,12 +317,13 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { CINSTREAM_SKIP_HEADER; LWOOBJID playerID; inStream.Read(playerID); - std::string friendName = PacketUtils::ReadString(0x14, packet, true); + LUWString friendName(33); + inStream.Read(friendName); //we'll have to query the db here to find the user, since you can delete them while they're offline. //First, we need to find their ID: std::unique_ptr stmt(Database::CreatePreppedStmt("SELECT id FROM charinfo WHERE name=? LIMIT 1;")); - stmt->setString(1, friendName.c_str()); + stmt->setString(1, friendName.GetAsString().c_str()); LWOOBJID friendID = 0; std::unique_ptr res(stmt->executeQuery()); @@ -358,7 +353,8 @@ void ChatPacketHandler::HandleRemoveFriend(Packet* packet) { break; } } - SendRemoveFriend(goonA, friendName, true); + auto friendString = friendName.GetAsString(); + SendRemoveFriend(goonA, friendString, true); } auto goonB = playerContainer.GetPlayerData(friendID); @@ -394,9 +390,10 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) { uint8_t channel = 0; inStream.Read(channel); - std::string message = PacketUtils::ReadString(0x66, packet, true, 512); + LUWString message(512); + inStream.Read(message); - Game::logger->Log("ChatPacketHandler", "Got a message from (%s) [%d]: %s", senderName.c_str(), channel, message.c_str()); + Game::logger->Log("ChatPacketHandler", "Got a message from (%s) [%d]: %s", senderName.c_str(), channel, message.GetAsString().c_str()); if (channel != 8) return; @@ -412,21 +409,21 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) { const auto otherName = std::string(otherMember->playerName.c_str()); CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(otherMember->playerID); - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); bitStream.Write(otherMember->playerID); bitStream.Write(8); bitStream.Write(69); - PacketUtils::WritePacketWString(senderName, 33, &bitStream); + bitStream.Write(LUWString(senderName)); bitStream.Write(sender->playerID); bitStream.Write(0); bitStream.Write(0); //not mythran nametag - PacketUtils::WritePacketWString(otherName, 33, &bitStream); + bitStream.Write(LUWString(otherName)); bitStream.Write(0); //not mythran for receiver bitStream.Write(0); //teams? - PacketUtils::WritePacketWString(message, 512, &bitStream); + bitStream.Write(message); SystemAddress sysAddr = otherMember->sysAddr; SEND_PACKET; @@ -434,13 +431,17 @@ void ChatPacketHandler::HandleChatMessage(Packet* packet) { } void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) { - LWOOBJID senderID = PacketUtils::ReadPacketS64(0x08, packet); - std::string receiverName = PacketUtils::ReadString(0x66, packet, true); - std::string message = PacketUtils::ReadString(0xAA, packet, true, 512); + CINSTREAM_SKIP_HEADER; + LWOOBJID senderID; + inStream.Read(senderID); + LUWString receiverName(33); + inStream.Read(receiverName); + LUWString message(512); + inStream.Read(message); //Get the bois: auto goonA = playerContainer.GetPlayerData(senderID); - auto goonB = playerContainer.GetPlayerData(receiverName); + auto goonB = playerContainer.GetPlayerData(receiverName.GetAsString()); if (!goonA || !goonB) return; if (playerContainer.GetIsMuted(goonA)) return; @@ -451,21 +452,21 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) { //To the sender: { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(goonA->playerID); - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); bitStream.Write(goonA->playerID); bitStream.Write(7); bitStream.Write(69); - PacketUtils::WritePacketWString(goonAName, 33, &bitStream); + bitStream.Write(LUWString(goonAName)); bitStream.Write(goonA->playerID); bitStream.Write(0); bitStream.Write(0); //not mythran nametag - PacketUtils::WritePacketWString(goonBName, 33, &bitStream); + bitStream.Write(LUWString(goonBName)); bitStream.Write(0); //not mythran for receiver bitStream.Write(0); //success - PacketUtils::WritePacketWString(message, 512, &bitStream); + bitStream.Write(LUWString(message.string, 512)); SystemAddress sysAddr = goonA->sysAddr; SEND_PACKET; @@ -474,21 +475,21 @@ void ChatPacketHandler::HandlePrivateChatMessage(Packet* packet) { //To the receiver: { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(goonB->playerID); - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::PRIVATE_CHAT_MESSAGE); bitStream.Write(goonA->playerID); bitStream.Write(7); bitStream.Write(69); - PacketUtils::WritePacketWString(goonAName, 33, &bitStream); + bitStream.Write(LUWString(goonAName)); bitStream.Write(goonA->playerID); bitStream.Write(0); bitStream.Write(0); //not mythran nametag - PacketUtils::WritePacketWString(goonBName, 33, &bitStream); + bitStream.Write(LUWString(goonBName)); bitStream.Write(0); //not mythran for receiver bitStream.Write(3); //new whisper - PacketUtils::WritePacketWString(message, 512, &bitStream); + bitStream.Write(LUWString(message.string, 512)); SystemAddress sysAddr = goonB->sysAddr; SEND_PACKET; @@ -499,7 +500,8 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) { CINSTREAM_SKIP_HEADER; LWOOBJID playerID; inStream.Read(playerID); - std::string invitedPlayer = PacketUtils::ReadString(0x14, packet, true); + LUWString invitedPlayer(33); + inStream.Read(invitedPlayer); auto* player = playerContainer.GetPlayerData(playerID); @@ -513,7 +515,7 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) { team = playerContainer.CreateTeam(playerID); } - auto* other = playerContainer.GetPlayerData(invitedPlayer); + auto* other = playerContainer.GetPlayerData(invitedPlayer.GetAsString()); if (other == nullptr) { return; @@ -532,7 +534,7 @@ void ChatPacketHandler::HandleTeamInvite(Packet* packet) { SendTeamInvite(other, player); - Game::logger->Log("ChatPacketHandler", "Got team invite: %llu -> %s", playerID, invitedPlayer.c_str()); + Game::logger->Log("ChatPacketHandler", "Got team invite: %llu -> %s", playerID, invitedPlayer.GetAsString().c_str()); } void ChatPacketHandler::HandleTeamInviteResponse(Packet* packet) { @@ -589,18 +591,18 @@ void ChatPacketHandler::HandleTeamKick(Packet* packet) { LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - std::string kickedPlayer = PacketUtils::ReadString(0x14, packet, true); + LUWString kickedPlayer(33); + inStream.Read(kickedPlayer); + Game::logger->Log("ChatPacketHandler", "(%llu) kicking (%s) from team", playerID, kickedPlayer.GetAsString().c_str()); - Game::logger->Log("ChatPacketHandler", "(%llu) kicking (%s) from team", playerID, kickedPlayer.c_str()); - - auto* kicked = playerContainer.GetPlayerData(kickedPlayer); + auto* kicked = playerContainer.GetPlayerData(kickedPlayer.GetAsString()); LWOOBJID kickedId = LWOOBJID_EMPTY; if (kicked != nullptr) { kickedId = kicked->playerID; } else { - kickedId = playerContainer.GetId(GeneralUtils::UTF8ToUTF16(kickedPlayer)); + kickedId = playerContainer.GetId(GeneralUtils::UTF8ToUTF16(kickedPlayer.GetAsString())); } if (kickedId == LWOOBJID_EMPTY) return; @@ -619,11 +621,12 @@ void ChatPacketHandler::HandleTeamPromote(Packet* packet) { LWOOBJID playerID = LWOOBJID_EMPTY; inStream.Read(playerID); - std::string promotedPlayer = PacketUtils::ReadString(0x14, packet, true); + LUWString promotedPlayer(33); + inStream.Read(promotedPlayer); - Game::logger->Log("ChatPacketHandler", "(%llu) promoting (%s) to team leader", playerID, promotedPlayer.c_str()); + Game::logger->Log("ChatPacketHandler", "(%llu) promoting (%s) to team leader", playerID, promotedPlayer.GetAsString().c_str()); - auto* promoted = playerContainer.GetPlayerData(promotedPlayer); + auto* promoted = playerContainer.GetPlayerData(promotedPlayer.GetAsString()); if (promoted == nullptr) return; @@ -709,13 +712,13 @@ void ChatPacketHandler::HandleTeamStatusRequest(Packet* packet) { void ChatPacketHandler::SendTeamInvite(PlayerData* receiver, PlayerData* sender) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TEAM_INVITE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TEAM_INVITE); - PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream); + bitStream.Write(LUWString(sender->playerName.c_str())); bitStream.Write(sender->playerID); SystemAddress sysAddr = receiver->sysAddr; @@ -724,7 +727,7 @@ void ChatPacketHandler::SendTeamInvite(PlayerData* receiver, PlayerData* sender) void ChatPacketHandler::SendTeamInviteConfirm(PlayerData* receiver, bool bLeaderIsFreeTrial, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, uint8_t ucResponseCode, std::u16string wsLeaderName) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -751,7 +754,7 @@ void ChatPacketHandler::SendTeamInviteConfirm(PlayerData* receiver, bool bLeader void ChatPacketHandler::SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderID, LWOZONEID i64LeaderZoneID, uint8_t ucLootFlag, uint8_t ucNumOfOtherPlayers, std::u16string wsLeaderName) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -776,7 +779,7 @@ void ChatPacketHandler::SendTeamStatus(PlayerData* receiver, LWOOBJID i64LeaderI void ChatPacketHandler::SendTeamSetLeader(PlayerData* receiver, LWOOBJID i64PlayerID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -793,7 +796,7 @@ void ChatPacketHandler::SendTeamSetLeader(PlayerData* receiver, LWOOBJID i64Play void ChatPacketHandler::SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTrial, bool bLocal, bool bNoLootOnDeath, LWOOBJID i64PlayerID, std::u16string wsPlayerName, LWOZONEID zoneID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -822,7 +825,7 @@ void ChatPacketHandler::SendTeamAddPlayer(PlayerData* receiver, bool bIsFreeTria void ChatPacketHandler::SendTeamRemovePlayer(PlayerData* receiver, bool bDisband, bool bIsKicked, bool bIsLeaving, bool bLocal, LWOOBJID i64LeaderID, LWOOBJID i64PlayerID, std::u16string wsPlayerName) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -848,7 +851,7 @@ void ChatPacketHandler::SendTeamRemovePlayer(PlayerData* receiver, bool bDisband void ChatPacketHandler::SendTeamSetOffWorldFlag(PlayerData* receiver, LWOOBJID i64PlayerID, LWOZONEID zoneID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: @@ -882,16 +885,16 @@ void ChatPacketHandler::SendFriendUpdate(PlayerData* friendData, PlayerData* pla [bool] - is FTP*/ CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(friendData->playerID); //portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::UPDATE_FRIEND_NOTIFY); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::UPDATE_FRIEND_NOTIFY); bitStream.Write(notifyType); std::string playerName = playerData->playerName.c_str(); - PacketUtils::WritePacketWString(playerName, 33, &bitStream); + bitStream.Write(LUWString(playerName)); bitStream.Write(playerData->zoneID.GetMapID()); bitStream.Write(playerData->zoneID.GetInstanceID()); @@ -921,12 +924,12 @@ void ChatPacketHandler::SendFriendRequest(PlayerData* receiver, PlayerData* send } CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_REQUEST); - PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_REQUEST); + bitStream.Write(LUWString(sender->playerName.c_str())); bitStream.Write(0); // This is a BFF flag however this is unused in live and does not have an implementation client side. SystemAddress sysAddr = receiver->sysAddr; @@ -937,16 +940,16 @@ void ChatPacketHandler::SendFriendResponse(PlayerData* receiver, PlayerData* sen if (!receiver || !sender) return; CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); // Portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::ADD_FRIEND_RESPONSE); bitStream.Write(responseCode); // For all requests besides accepted, write a flag that says whether or not we are already best friends with the receiver. bitStream.Write(responseCode != eAddFriendResponseType::ACCEPTED ? isBestFriendsAlready : sender->sysAddr != UNASSIGNED_SYSTEM_ADDRESS); // Then write the player name - PacketUtils::WritePacketWString(sender->playerName.c_str(), 33, &bitStream); + bitStream.Write(LUWString(sender->playerName.c_str())); // Then if this is an acceptance code, write the following extra info. if (responseCode == eAddFriendResponseType::ACCEPTED) { bitStream.Write(sender->playerID); @@ -962,13 +965,13 @@ void ChatPacketHandler::SendRemoveFriend(PlayerData* receiver, std::string& pers if (!receiver) return; CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); bitStream.Write(receiver->playerID); //portion that will get routed: - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::REMOVE_FRIEND_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::REMOVE_FRIEND_RESPONSE); bitStream.Write(isSuccessful); //isOnline - PacketUtils::WritePacketWString(personToRemove, 33, &bitStream); + bitStream.Write(LUWString(personToRemove)); SystemAddress sysAddr = receiver->sysAddr; SEND_PACKET; diff --git a/dChatServer/PlayerContainer.cpp b/dChatServer/PlayerContainer.cpp index 689ffd77..3ff90549 100644 --- a/dChatServer/PlayerContainer.cpp +++ b/dChatServer/PlayerContainer.cpp @@ -6,7 +6,7 @@ #include "dLogger.h" #include "ChatPacketHandler.h" #include "GeneralUtils.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "Database.h" #include "eConnectionType.h" #include "eChatInternalMessageType.h" @@ -146,7 +146,7 @@ void PlayerContainer::CreateTeamServer(Packet* packet) { void PlayerContainer::BroadcastMuteUpdate(LWOOBJID player, time_t time) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE); bitStream.Write(player); bitStream.Write(time); @@ -345,7 +345,7 @@ void PlayerContainer::TeamStatusUpdate(TeamData* team) { void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::TEAM_UPDATE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::TEAM_UPDATE); bitStream.Write(team->teamID); bitStream.Write(deleteTeam); diff --git a/dCommon/dEnums/dCommonVars.h b/dCommon/dEnums/dCommonVars.h index f67145da..7da54fb6 100644 --- a/dCommon/dEnums/dCommonVars.h +++ b/dCommon/dEnums/dCommonVars.h @@ -9,6 +9,7 @@ #include "BitStream.h" #include "eConnectionType.h" #include "eClientMessageType.h" +#include "BitstreamUtils.h" #pragma warning (disable:4251) //Disables SQL warnings @@ -32,7 +33,7 @@ constexpr uint32_t lowFrameDelta = FRAMES_TO_MS(lowFramerate); #define CBITSTREAM RakNet::BitStream bitStream; #define CINSTREAM RakNet::BitStream inStream(packet->data, packet->length, false); #define CINSTREAM_SKIP_HEADER CINSTREAM if (inStream.GetNumberOfUnreadBits() >= BYTES_TO_BITS(HEADER_SIZE)) inStream.IgnoreBytes(HEADER_SIZE); else inStream.IgnoreBits(inStream.GetNumberOfUnreadBits()); -#define CMSGHEADER PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); +#define CMSGHEADER BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); #define SEND_PACKET Game::server->Send(&bitStream, sysAddr, false); #define SEND_PACKET_BROADCAST Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true); diff --git a/dCommon/dEnums/eStamps.h b/dCommon/dEnums/eStamps.h new file mode 100644 index 00000000..475b4cb6 --- /dev/null +++ b/dCommon/dEnums/eStamps.h @@ -0,0 +1,48 @@ +#ifndef __ESTAMPS__H__ +#define __ESTAMPS__H__ + +#include + +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 +}; + +#endif //!__ESTAMPS__H__ diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 998541ad..5d4b4d34 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -3,7 +3,6 @@ #include "CDClientManager.h" #include "Game.h" #include "dLogger.h" -#include #include #include "CDDestructibleComponentTable.h" #include "CDClientDatabase.h" diff --git a/dGame/UserManager.cpp b/dGame/UserManager.cpp index 9e409019..648c21cf 100644 --- a/dGame/UserManager.cpp +++ b/dGame/UserManager.cpp @@ -11,7 +11,7 @@ #include #include "Character.h" #include -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "../dWorldServer/ObjectIDManager.h" #include "dLogger.h" #include "GeneralUtils.h" @@ -248,30 +248,44 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) { void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) { User* u = GetUser(sysAddr); if (!u) return; + CINSTREAM; + LUWString name(33); + inStream.Read(name); - std::string name = PacketUtils::ReadString(8, packet, true); - - uint32_t firstNameIndex = PacketUtils::ReadPacketU32(74, packet); - uint32_t middleNameIndex = PacketUtils::ReadPacketU32(78, packet); - uint32_t lastNameIndex = PacketUtils::ReadPacketU32(82, packet); + uint32_t firstNameIndex; + inStream.Read(firstNameIndex); + uint32_t middleNameIndex; + inStream.Read(middleNameIndex); + uint32_t lastNameIndex; + inStream.Read(lastNameIndex); std::string predefinedName = GetPredefinedName(firstNameIndex, middleNameIndex, lastNameIndex); - uint32_t shirtColor = PacketUtils::ReadPacketU32(95, packet); - uint32_t shirtStyle = PacketUtils::ReadPacketU32(99, packet); - uint32_t pantsColor = PacketUtils::ReadPacketU32(103, packet); - uint32_t hairStyle = PacketUtils::ReadPacketU32(107, packet); - uint32_t hairColor = PacketUtils::ReadPacketU32(111, packet); - uint32_t lh = PacketUtils::ReadPacketU32(115, packet); - uint32_t rh = PacketUtils::ReadPacketU32(119, packet); - uint32_t eyebrows = PacketUtils::ReadPacketU32(123, packet); - uint32_t eyes = PacketUtils::ReadPacketU32(127, packet); - uint32_t mouth = PacketUtils::ReadPacketU32(131, packet); + uint32_t shirtColor; + inStream.Read(shirtColor); + uint32_t shirtStyle; + inStream.Read(shirtStyle); + uint32_t pantsColor; + inStream.Read(pantsColor); + uint32_t hairStyle; + inStream.Read(hairStyle); + uint32_t hairColor; + inStream.Read(hairColor); + uint32_t lh; + inStream.Read(lh); + uint32_t rh; + inStream.Read(rh); + uint32_t eyebrows; + inStream.Read(eyebrows); + uint32_t eyes; + inStream.Read(eyes); + uint32_t mouth; + inStream.Read(mouth); LOT shirtLOT = FindCharShirtID(shirtColor, shirtStyle); LOT pantsLOT = FindCharPantsID(pantsColor); - if (name != "" && !UserManager::IsNameAvailable(name)) { - Game::logger->Log("UserManager", "AccountID: %i chose unavailable name: %s", u->GetAccountID(), name.c_str()); + if (name.GetAsString() != "" && !UserManager::IsNameAvailable(name.GetAsString())) { + Game::logger->Log("UserManager", "AccountID: %i chose unavailable name: %s", u->GetAccountID(), name.GetAsString().c_str()); WorldPackets::SendCharacterCreationResponse(sysAddr, eCharacterCreationResponse::CUSTOM_NAME_IN_USE); return; } @@ -282,10 +296,10 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) return; } - if (name == "") { + if (name.GetAsString() == "") { Game::logger->Log("UserManager", "AccountID: %i is creating a character with predefined name: %s", u->GetAccountID(), predefinedName.c_str()); } else { - Game::logger->Log("UserManager", "AccountID: %i is creating a character with name: %s (temporary: %s)", u->GetAccountID(), name.c_str(), predefinedName.c_str()); + Game::logger->Log("UserManager", "AccountID: %i is creating a character with name: %s (temporary: %s)", u->GetAccountID(), name.GetAsString().c_str(), predefinedName.c_str()); } //Now that the name is ok, we can get an objectID from Master: @@ -334,20 +348,20 @@ void UserManager::CreateCharacter(const SystemAddress& sysAddr, Packet* packet) xml3 << ""; //Check to see if our name was pre-approved: - bool nameOk = IsNamePreapproved(name); + bool nameOk = IsNamePreapproved(name.GetAsString()); if (!nameOk && u->GetMaxGMLevel() > eGameMasterLevel::FORUM_MODERATOR) nameOk = true; - if (name != "") { + if (name.GetAsString() != "") { sql::PreparedStatement* stmt = Database::CreatePreppedStmt("INSERT INTO `charinfo`(`id`, `account_id`, `name`, `pending_name`, `needs_rename`, `last_login`) VALUES (?,?,?,?,?,?)"); stmt->setUInt(1, objectID); stmt->setUInt(2, u->GetAccountID()); stmt->setString(3, predefinedName.c_str()); - stmt->setString(4, name.c_str()); + stmt->setString(4, name.GetAsString().c_str()); stmt->setBoolean(5, false); stmt->setUInt64(6, time(NULL)); if (nameOk) { - stmt->setString(3, name.c_str()); + stmt->setString(3, name.GetAsString().c_str()); stmt->setString(4, ""); } @@ -386,8 +400,9 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet) Game::logger->Log("UserManager", "Couldn't get user to delete character"); return; } - - LWOOBJID objectID = PacketUtils::ReadPacketS64(8, packet); + CINSTREAM_SKIP_HEADER; + LWOOBJID objectID; + inStream.Read(objectID); uint32_t charID = static_cast(objectID); Game::logger->Log("UserManager", "Received char delete req for ID: %llu (%u)", objectID, charID); @@ -423,7 +438,7 @@ void UserManager::DeleteCharacter(const SystemAddress& sysAddr, Packet* packet) stmt->execute(); delete stmt; CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); bitStream.Write(objectID); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } @@ -482,15 +497,17 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet) Game::logger->Log("UserManager", "Couldn't get user to delete character"); return; } - - LWOOBJID objectID = PacketUtils::ReadPacketS64(8, packet); + CINSTREAM_SKIP_HEADER; + LWOOBJID objectID; + inStream.Read(objectID); GeneralUtils::ClearBit(objectID, eObjectBits::CHARACTER); GeneralUtils::ClearBit(objectID, eObjectBits::PERSISTENT); uint32_t charID = static_cast(objectID); Game::logger->Log("UserManager", "Received char rename request for ID: %llu (%u)", objectID, charID); - std::string newName = PacketUtils::ReadString(16, packet, true); + LUWString newName(33); + inStream.Read(newName); Character* character = nullptr; @@ -505,32 +522,32 @@ void UserManager::RenameCharacter(const SystemAddress& sysAddr, Packet* packet) Game::logger->Log("UserManager", "User %i tried to rename a character that it does not own!", u->GetAccountID()); WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::UNKNOWN_ERROR); } else if (hasCharacter && character) { - if (newName == character->GetName()) { + if (newName.GetAsString() == character->GetName()) { WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::NAME_UNAVAILABLE); return; } - if (IsNameAvailable(newName)) { - if (IsNamePreapproved(newName)) { + if (IsNameAvailable(newName.GetAsString())) { + if (IsNamePreapproved(newName.GetAsString())) { sql::PreparedStatement* stmt = Database::CreatePreppedStmt("UPDATE charinfo SET name=?, pending_name='', needs_rename=0, last_login=? WHERE id=? LIMIT 1"); - stmt->setString(1, newName); + stmt->setString(1, newName.GetAsString()); stmt->setUInt64(2, time(NULL)); stmt->setUInt(3, character->GetID()); stmt->execute(); delete stmt; - Game::logger->Log("UserManager", "Character %s now known as %s", character->GetName().c_str(), newName.c_str()); + Game::logger->Log("UserManager", "Character %s now known as %s", character->GetName().c_str(), newName.GetAsString().c_str()); WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::SUCCESS); UserManager::RequestCharacterList(sysAddr); } else { sql::PreparedStatement* stmt = Database::CreatePreppedStmt("UPDATE charinfo SET pending_name=?, needs_rename=0, last_login=? WHERE id=? LIMIT 1"); - stmt->setString(1, newName); + stmt->setString(1, newName.GetAsString()); stmt->setUInt64(2, time(NULL)); stmt->setUInt(3, character->GetID()); stmt->execute(); delete stmt; - Game::logger->Log("UserManager", "Character %s has been renamed to %s and is pending approval by a moderator.", character->GetName().c_str(), newName.c_str()); + Game::logger->Log("UserManager", "Character %s has been renamed to %s and is pending approval by a moderator.", character->GetName().c_str(), newName.GetAsString().c_str()); WorldPackets::SendCharacterRenameResponse(sysAddr, eRenameResponse::SUCCESS); UserManager::RequestCharacterList(sysAddr); } diff --git a/dGame/dBehaviors/BehaviorContext.cpp b/dGame/dBehaviors/BehaviorContext.cpp index 43ba8457..2adbbdc3 100644 --- a/dGame/dBehaviors/BehaviorContext.cpp +++ b/dGame/dBehaviors/BehaviorContext.cpp @@ -6,7 +6,7 @@ #include "Game.h" #include "dLogger.h" #include "dServer.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include @@ -253,7 +253,7 @@ bool BehaviorContext::CalculateUpdate(const float deltaTime) { // Write message RakNet::BitStream message; - PacketUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); + BitstreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); message.Write(this->originator); echo.Serialize(&message); diff --git a/dGame/dComponents/RebuildComponent.cpp b/dGame/dComponents/RebuildComponent.cpp index 13854bd6..d60a4ef0 100644 --- a/dGame/dComponents/RebuildComponent.cpp +++ b/dGame/dComponents/RebuildComponent.cpp @@ -14,7 +14,6 @@ #include "eGameActivity.h" #include "dServer.h" -#include "PacketUtils.h" #include "Spawner.h" #include "MovingPlatformComponent.h" #include "Preconditions.h" diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index 94f5fb5d..f2108708 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -5,7 +5,6 @@ #include #include "Entity.h" -#include "PacketUtils.h" #include "CDClientManager.h" #include "GameMessages.h" diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.cpp b/dGame/dComponents/RocketLaunchpadControlComponent.cpp index 10908d9e..fc906499 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.cpp +++ b/dGame/dComponents/RocketLaunchpadControlComponent.cpp @@ -15,7 +15,7 @@ #include "PropertyEntranceComponent.h" #include "RocketLaunchLupComponent.h" #include "dServer.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "eObjectWorldState.h" #include "eConnectionType.h" #include "eMasterMessageType.h" @@ -137,7 +137,7 @@ LWOCLONEID RocketLaunchpadControlComponent::GetSelectedCloneId(LWOOBJID player) void RocketLaunchpadControlComponent::TellMasterToPrepZone(int zoneID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PREP_ZONE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PREP_ZONE); bitStream.Write(zoneID); Game::server->SendToMaster(&bitStream); } diff --git a/dGame/dComponents/ScriptedActivityComponent.cpp b/dGame/dComponents/ScriptedActivityComponent.cpp index 81b3e9a9..b440bfa4 100644 --- a/dGame/dComponents/ScriptedActivityComponent.cpp +++ b/dGame/dComponents/ScriptedActivityComponent.cpp @@ -11,7 +11,7 @@ #include "EntityManager.h" #include "ChatPackets.h" #include "Player.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "dServer.h" #include "GeneralUtils.h" #include "dZoneManager.h" @@ -516,7 +516,7 @@ void ActivityInstance::StartZone() { // only make a team if we have more than one participant if (participants.size() > 1) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::CREATE_TEAM); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::CREATE_TEAM); bitStream.Write(leader->GetObjectID()); bitStream.Write(m_Participants.size()); diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 5c1d221a..591f236f 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -15,7 +15,7 @@ #include "dServer.h" #include "EntityManager.h" #include "Game.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "BaseCombatAIComponent.h" #include "ScriptComponent.h" #include "BuffComponent.h" @@ -304,7 +304,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c // Write message RakNet::BitStream message; - PacketUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); + BitstreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); message.Write(this->m_Parent->GetObjectID()); start.Serialize(&message); @@ -437,7 +437,7 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) RakNet::BitStream message; - PacketUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); + BitstreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); message.Write(this->m_Parent->GetObjectID()); projectileImpact.Serialize(&message); diff --git a/dGame/dGameMessages/GameMessageHandler.cpp b/dGame/dGameMessages/GameMessageHandler.cpp index 83005b6f..b0a3089b 100644 --- a/dGame/dGameMessages/GameMessageHandler.cpp +++ b/dGame/dGameMessages/GameMessageHandler.cpp @@ -5,7 +5,7 @@ #include "GameMessageHandler.h" #include "MissionComponent.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "dServer.h" #include "../thirdparty/raknet/Source/RakNetworkFactory.h" #include @@ -314,7 +314,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System if (success) { //Broadcast our startSkill: RakNet::BitStream bitStreamLocal; - PacketUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); + BitstreamUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); bitStreamLocal.Write(entity->GetObjectID()); EchoStartSkill echoStartSkill; @@ -336,7 +336,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System case eGameMessageType::SYNC_SKILL: { RakNet::BitStream bitStreamLocal; - PacketUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); + BitstreamUtils::WriteHeader(bitStreamLocal, eConnectionType::CLIENT, eClientMessageType::GAME_MSG); bitStreamLocal.Write(entity->GetObjectID()); //bitStreamLocal.Write((unsigned short)eGameMessageType::ECHO_SYNC_SKILL); //bitStreamLocal.Write(inStream); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index c3358625..82ffed40 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -2,6 +2,7 @@ #include "User.h" #include "Entity.h" #include "PacketUtils.h" +#include "BitstreamUtils.h" #include "BitStream.h" #include "Game.h" #include "SlashCommandHandler.h" @@ -172,7 +173,7 @@ void GameMessages::SendPlayAnimation(Entity* entity, const std::u16string& anima bitStream.Write(eGameMessageType::PLAY_ANIMATION); bitStream.Write(animationIDLength); - PacketUtils::WriteWString(bitStream, animationName, animationIDLength); + bitStream.Write(animationName); bitStream.Write(bExpectAnimToExist); @@ -325,7 +326,7 @@ void GameMessages::SendPlayNDAudioEmitter(Entity* entity, const SystemAddress& s bitStream.Write(static_cast(audioGUID[k])); } - //PacketUtils::WriteString(bitStream, audioGUID, audioGUID.size()); + //BitstreamUtils::WriteString(bitStream, audioGUID, audioGUID.size()); //bitStream.Write(uint32_t(audioGUID.size())); //for (char character : audioGUID) { @@ -2179,7 +2180,7 @@ void GameMessages::HandleUnUseModel(RakNet::BitStream* inStream, Entity* entity, if (unknown) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); bitStream.Write(LWOOBJID_EMPTY); //always zero so that a check on the client passes bitStream.Write(eBlueprintSaveResponseType::PlacementFailed); // Sending a non-zero error code here prevents the client from deleting its in progress build for some reason? bitStream.Write(0); @@ -2431,7 +2432,7 @@ void GameMessages::HandleBBBLoadItemRequest(RakNet::BitStream* inStream, Entity* void GameMessages::SendBlueprintLoadItemResponse(const SystemAddress& sysAddr, bool success, LWOOBJID oldItemId, LWOOBJID newItemId) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_LOAD_RESPONSE_ITEMID); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_LOAD_RESPONSE_ITEMID); bitStream.Write(static_cast(success)); bitStream.Write(oldItemId); bitStream.Write(newItemId); @@ -2679,7 +2680,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent //Tell the client their model is saved: (this causes us to actually pop out of our current state): CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); bitStream.Write(localId); bitStream.Write(eBlueprintSaveResponseType::EverythingWorked); bitStream.Write(1); diff --git a/dGame/dUtilities/Mail.cpp b/dGame/dUtilities/Mail.cpp index d33af6dc..e7d65e8c 100644 --- a/dGame/dUtilities/Mail.cpp +++ b/dGame/dUtilities/Mail.cpp @@ -283,7 +283,7 @@ void Mail::HandleDataRequest(RakNet::BitStream* packet, const SystemAddress& sys sql::ResultSet* res = stmt->executeQuery(); RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); bitStream.Write(int(MailMessageID::MailData)); bitStream.Write(int(0)); @@ -406,7 +406,7 @@ void Mail::HandleNotificationRequest(const SystemAddress& sysAddr, uint32_t obje void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse response) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); bitStream.Write(int(MailMessageID::SendResponse)); bitStream.Write(int(response)); Game::server->Send(&bitStream, sysAddr, false); @@ -414,7 +414,7 @@ void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse respo void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); uint64_t messageType = 2; uint64_t s1 = 0; uint64_t s2 = 0; @@ -433,7 +433,7 @@ void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) { void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t mailID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); bitStream.Write(int(MailMessageID::AttachmentCollectConfirm)); bitStream.Write(int(0)); //unknown bitStream.Write(mailID); @@ -442,7 +442,7 @@ void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t ma void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOOBJID playerID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); bitStream.Write(int(MailMessageID::MailDeleteConfirm)); bitStream.Write(int(0)); //unknown bitStream.Write(mailID); @@ -456,7 +456,7 @@ void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOO void Mail::SendReadConfirm(const SystemAddress& sysAddr, uint64_t mailID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL); bitStream.Write(int(MailMessageID::MailReadConfirm)); bitStream.Write(int(0)); //unknown bitStream.Write(mailID); diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 03e3cc89..77a0b570 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -49,7 +49,7 @@ #include "dpWorld.h" #include "Item.h" #include "PropertyManagementComponent.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "Loot.h" #include "EntityInfo.h" #include "LUTriggers.h" @@ -761,7 +761,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "shutdownuniverse" && entity->GetGMLevel() == eGameMasterLevel::OPERATOR) { //Tell the master server that we're going to be shutting down whole "universe": CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN_UNIVERSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN_UNIVERSE); Game::server->SendToMaster(&bitStream); ChatPackets::SendSystemMessage(sysAddr, u"Sent universe shutdown notification to master."); @@ -1092,7 +1092,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //Notify chat about it CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::MUTE_UPDATE); bitStream.Write(characterId); bitStream.Write(expire); @@ -2013,7 +2013,7 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std:: //Notify chat about it CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ANNOUNCEMENT); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ANNOUNCEMENT); bitStream.Write(title.size()); for (auto character : title) { diff --git a/dMasterServer/InstanceManager.cpp b/dMasterServer/InstanceManager.cpp index 50f55b72..4d4058ad 100644 --- a/dMasterServer/InstanceManager.cpp +++ b/dMasterServer/InstanceManager.cpp @@ -8,7 +8,7 @@ #include "CDClientManager.h" #include "CDZoneTableTable.h" #include "MasterPackets.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "BinaryPathFinder.h" #include "eConnectionType.h" #include "eMasterMessageType.h" @@ -202,7 +202,7 @@ void InstanceManager::RequestAffirmation(Instance* instance, const PendingInstan CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::AFFIRM_TRANSFER_REQUEST); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::AFFIRM_TRANSFER_REQUEST); bitStream.Write(request.id); @@ -406,7 +406,7 @@ bool Instance::GetShutdownComplete() const { void Instance::Shutdown() { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN); Game::server->Send(&bitStream, this->m_SysAddr, false); diff --git a/dMasterServer/MasterServer.cpp b/dMasterServer/MasterServer.cpp index ce237eac..c2d63974 100644 --- a/dMasterServer/MasterServer.cpp +++ b/dMasterServer/MasterServer.cpp @@ -40,7 +40,7 @@ #include "InstanceManager.h" #include "MasterPackets.h" #include "ObjectIDManager.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "FdbToSqlite.h" namespace Game { @@ -561,13 +561,19 @@ void HandlePacket(Packet* packet) { uint32_t theirZoneID = 0; uint32_t theirInstanceID = 0; ServerType theirServerType; + uint32_t theirIPSize; std::string theirIP = ""; inStream.Read(theirPort); inStream.Read(theirZoneID); inStream.Read(theirInstanceID); inStream.Read(theirServerType); - theirIP = PacketUtils::ReadString(24, packet, false); //24 is the current offset + inStream.Read(theirIPSize); + char character; + while(theirIPSize-- > 0) { + inStream.Read(character); + theirIP.push_back(character); + } if (theirServerType == ServerType::World && !Game::im->IsPortInUse(theirPort)) { Instance* in = new Instance(theirIP, theirPort, theirZoneID, theirInstanceID, 0, 12, 12); @@ -608,23 +614,21 @@ void HandlePacket(Packet* packet) { } case eMasterMessageType::SET_SESSION_KEY: { - RakNet::BitStream inStream(packet->data, packet->length, false); - uint64_t header = inStream.Read(header); + CINSTREAM_SKIP_HEADER; uint32_t sessionKey = 0; - std::string username; - inStream.Read(sessionKey); - username = PacketUtils::ReadString(12, packet, false); + LUString username(33); + inStream.Read(username); for (auto it : activeSessions) { - if (it.second == username) { + if (it.second == username.string) { activeSessions.erase(it.first); CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::NEW_SESSION_ALERT); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::NEW_SESSION_ALERT); bitStream.Write(sessionKey); - bitStream.Write(username.size()); - for (auto character : username) { + bitStream.Write(username.string.size()); + for (auto character : username.string) { bitStream.Write(character); } SEND_PACKET_BROADCAST; @@ -633,22 +637,22 @@ void HandlePacket(Packet* packet) { } } - activeSessions.insert(std::make_pair(sessionKey, username)); - Game::logger->Log("MasterServer", "Got sessionKey %i for user %s", sessionKey, username.c_str()); + activeSessions.insert(std::make_pair(sessionKey, username.string)); + Game::logger->Log("MasterServer", "Got sessionKey %i for user %s", sessionKey, username.string.c_str()); break; } case eMasterMessageType::REQUEST_SESSION_KEY: { - RakNet::BitStream inStream(packet->data, packet->length, false); - uint64_t header = inStream.Read(header); - std::string username = PacketUtils::ReadString(8, packet, false); + CINSTREAM_SKIP_HEADER + LUWString username(33); + inStream.Read(username); for (auto key : activeSessions) { - if (key.second == username) { + if (key.second == username.GetAsString()) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SESSION_KEY_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SESSION_KEY_RESPONSE); bitStream.Write(key.first); - PacketUtils::WriteString(bitStream, key.second, 64); + bitStream.Write(LUString(key.second, 64)); Game::server->Send(&bitStream, packet->systemAddress, false); break; } @@ -892,7 +896,7 @@ void ShutdownSequence(int32_t signal) { { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN); Game::server->Send(&bitStream, UNASSIGNED_SYSTEM_ADDRESS, true); Game::logger->Log("MasterServer", "Triggered master shutdown"); } diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index 978540c1..c76d5415 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -1,5 +1,5 @@ #include "AuthPackets.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "dNetCommon.h" #include "dServer.h" @@ -19,6 +19,7 @@ #include #include +#include "PacketUtils.h" #include "Game.h" #include "dConfig.h" #include "eServerDisconnectIdentifiers.h" @@ -26,46 +27,136 @@ #include "eConnectionType.h" #include "eServerMessageType.h" #include "eMasterMessageType.h" +#include "eStamps.h" + +enum class ClientOS : uint8_t { + UNKNOWN, + WINDOWS, + MACOS +}; + +enum class LCID : uint16_t { + en_US = 0x0409, + de_DE = 0x0407, + en_GB = 0x0809 +}; + +enum class Language : uint32_t { + en_US, + pl_US, + de_DE, + en_GB, +}; + +void Stamp::Serialize(RakNet::BitStream* outBitStream){ + outBitStream->Write(type); + outBitStream->Write(value); + outBitStream->Write(timestamp); +}; void AuthPackets::HandleHandshake(dServer* server, Packet* packet) { - RakNet::BitStream inStream(packet->data, packet->length, false); - uint64_t header = inStream.Read(header); + CINSTREAM_SKIP_HEADER uint32_t clientVersion = 0; inStream.Read(clientVersion); - server->GetLogger()->Log("AuthPackets", "Received client version: %i", clientVersion); + uint32_t paddingZero; + inStream.Read(paddingZero); + if (paddingZero != 0) Game::logger->Log("AuthPackets::HandleHandShake", "WARNING: ZeroPadding is not Zero!"); + + ServiceId serviceId; + inStream.Read(serviceId); + if (serviceId != ServiceId::Client) Game::logger->Log("AuthPackets::HandleHandShake", "WARNING: Service ID is not a Client!"); + + uint32_t processID; + inStream.Read(processID); + + uint16_t port; + inStream.Read(port); + + LUWString paddingString(33); + inStream.Read(paddingString); + if (!paddingString.string.empty()) Game::logger->Log("AuthPackets::HandleHandShake", "WARNING: StringPadding is not empty!"); + + if (inStream.GetNumberOfUnreadBits() != 8) Game::logger->Log("AuthPackets::HandleHandShake", "WARNING: End padding is incorrect!"); + Game::logger->Log("AuthPackets::HandleHandShake", "Client Data [Version: %i, PaddingZero: %i, Service: %u, Process: %u, Port: %u, paddingString: %s, Sysaddr Port: %u]", clientVersion, paddingZero, serviceId, processID, port, paddingString.string.c_str(), 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 ServerType serverType) { - RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::VERSION_CONFIRM); - bitStream.Write(NET_VERSION); - bitStream.Write(uint32_t(0x93)); + RakNet::BitStream handshakeResponse; + BitstreamUtils::WriteHeader(handshakeResponse, eConnectionType::SERVER, eServerMessageType::VERSION_CONFIRM); + handshakeResponse.Write(NET_VERSION); + handshakeResponse.Write(0); // Unused/Unknown/Padding - if (serverType == ServerType::Auth) bitStream.Write(uint32_t(1)); //Conn: auth - else bitStream.Write(uint32_t(4)); //Conn: world + if (serverType == ServerType::Auth) handshakeResponse.Write(ServiceId::Auth); + else if (serverType == ServerType::World) handshakeResponse.Write(ServiceId::World); + else handshakeResponse.Write(ServiceId::General); - bitStream.Write(uint32_t(0)); //Server process ID - bitStream.Write(nextServerPort); - - server->Send(&bitStream, sysAddr, false); + server->Send(&handshakeResponse, sysAddr, false); } void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) { - std::string username = PacketUtils::ReadString(8, packet, true); - std::string password = PacketUtils::ReadString(0x4A, packet, true); - const char* szUsername = username.c_str(); + CINSTREAM_SKIP_HEADER; + + LUWString username(33); + inStream.Read(username); + std::string usernameString = GeneralUtils::UTF16ToWTF8(username.string); + + LUWString password(41); + inStream.Read(password); + + LCID locale_id; + inStream.Read(locale_id); + Game::logger->Log("AuthPackets", "Locale ID: %i", locale_id); + + ClientOS clientOS; + inStream.Read(clientOS); + std::string clientOSString = "Unknown"; + if (clientOS == ClientOS::WINDOWS) clientOSString = "Windows"; + else if (clientOS == ClientOS::MACOS) clientOSString = "MacOS"; + Game::logger->Log("AuthPackets", "Operating System: %s",clientOSString.c_str()); + + LUWString memoryStats(256); + inStream.Read(memoryStats); + Game::logger->Log("AuthPackets", "Memory Stats [%s]", memoryStats.GetAsString().c_str()); + + LUWString videoCard(128); + inStream.Read(videoCard); + Game::logger->Log("AuthPackets", "VideoCard Info: [%s]", 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); + Game::logger->Log("AuthPackets", "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); + Game::logger->Log("AuthPackets", "OS Info: [Size: %i, Major: %i, Minor %i, Buid#: %i, platformID: %i]", osVersionInfoSize, majorVersion, minorVersion, buildNumber, platformID); // Fetch account details - sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT password, banned, locked, play_key_id, gm_level FROM accounts WHERE name=? LIMIT 1;"); - stmt->setString(1, szUsername); + std::unique_ptr stmt(Database::CreatePreppedStmt("SELECT password, banned, locked, play_key_id, gm_level FROM accounts WHERE name=? LIMIT 1;")); + stmt->setString(1, usernameString.c_str()); - sql::ResultSet* res = stmt->executeQuery(); + std::unique_ptr res(stmt->executeQuery()); if (res->rowsCount() == 0) { server->GetLogger()->Log("AuthPackets", "No user found!"); - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::INVALID_USER, "", "", 2001, username); + AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::INVALID_USER, "", "", 2001, usernameString); return; } @@ -83,21 +174,25 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) { sqlGmLevel = res->getInt(5); } - delete stmt; - delete res; + int32_t bcryptState = ::bcrypt_checkpw(GeneralUtils::UTF16ToWTF8(password.string).c_str(), sqlPass.c_str()); + if (bcryptState != 0) { + AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::WRONG_PASS, "", "", 2001, usernameString); + server->GetLogger()->Log("AuthPackets", "Wrong password used"); + 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)) && sqlGmLevel == 0) { - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "The server is currently only open to developers.", "", 2001, username); + AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "The server is currently only open to developers.", "", 2001, usernameString); return; } if (Game::config->GetValue("dont_use_keys") != "1") { //Check to see if we have a play key: if (sqlPlayKey == 0 && sqlGmLevel == 0) { - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, username); - server->GetLogger()->Log("AuthPackets", "User %s tried to log in, but they don't have a play key.", username.c_str()); + AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, usernameString); + server->GetLogger()->Log("AuthPackets", "User %s tried to log in, but they don't have a play key.", usernameString.c_str()); return; } @@ -108,7 +203,7 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) { bool isKeyActive = false; if (keyRes->rowsCount() == 0 && sqlGmLevel == 0) { - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, username); + AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your account doesn't have a play key associated with it!", "", 2001, usernameString); return; } @@ -117,150 +212,133 @@ void AuthPackets::HandleLoginRequest(dServer* server, Packet* packet) { } if (!isKeyActive && sqlGmLevel == 0) { - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your play key has been disabled.", "", 2001, username); - server->GetLogger()->Log("AuthPackets", "User %s tried to log in, but their play key was disabled", username.c_str()); + AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::PERMISSIONS_NOT_HIGH_ENOUGH, "Your play key has been disabled.", "", 2001, usernameString); + server->GetLogger()->Log("AuthPackets", "User %s tried to log in, but their play key was disabled", usernameString.c_str()); return; } } if (sqlBanned) { - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::BANNED, "", "", 2001, username); return; + AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::BANNED, "", "", 2001, usernameString); + return; } if (sqlLocked) { - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::ACCOUNT_LOCKED, "", "", 2001, username); return; + AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::ACCOUNT_LOCKED, "", "", 2001, usernameString); + return; } - /* - * Updated hashing method: - * First attempt bcrypt. - * If that fails, fallback to old method and setup bcrypt for new login. - */ + auto system = packet->systemAddress; //Copy the sysAddr before the Packet gets destroyed from main - bool loginSuccess = true; - - int32_t bcryptState = ::bcrypt_checkpw(password.c_str(), sqlPass.c_str()); - - if (bcryptState != 0) { - // Fallback on old method - - std::string oldPassword = sha512(password + username); - - if (sqlPass != oldPassword) { - loginSuccess = false; - } else { - // Generate new hash for bcrypt - - char salt[BCRYPT_HASHSIZE]; - char hash[BCRYPT_HASHSIZE]; - - bcryptState = ::bcrypt_gensalt(12, salt); - - assert(bcryptState == 0); - - bcryptState = ::bcrypt_hashpw(password.c_str(), salt, hash); - - assert(bcryptState == 0); - - sql::PreparedStatement* accountUpdate = Database::CreatePreppedStmt("UPDATE accounts SET password = ? WHERE name = ? LIMIT 1;"); - - accountUpdate->setString(1, std::string(hash, BCRYPT_HASHSIZE).c_str()); - accountUpdate->setString(2, szUsername); - - accountUpdate->executeUpdate(); - } - } else { - // Login success with bcrypt + if (!server->GetIsConnectedToMaster()) { + AuthPackets::SendLoginResponse(server, system, eLoginResponse::GENERAL_FAILED, "Unable to Connect to Master Server", "", 0, usernameString); + Game::logger->Log("AuthPackets", "Unable to complete login of user %s due to no connection to Master", usernameString.c_str()); + return; } - if (!loginSuccess) { - AuthPackets::SendLoginResponse(server, packet->systemAddress, eLoginResponse::WRONG_PASS, "", "", 2001, username); - server->GetLogger()->Log("AuthPackets", "Wrong password used"); - } else { - SystemAddress system = packet->systemAddress; //Copy the sysAddr before the Packet gets destroyed from main - - if (!server->GetIsConnectedToMaster()) { - AuthPackets::SendLoginResponse(server, system, eLoginResponse::GENERAL_FAILED, "", "", 0, username); - return; - } - - ZoneInstanceManager::Instance()->RequestZoneTransfer(server, 0, 0, false, [system, server, username](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string zoneIP, uint16_t zonePort) { - AuthPackets::SendLoginResponse(server, system, eLoginResponse::SUCCESS, "", zoneIP, zonePort, username); - }); - } + ZoneInstanceManager::Instance()->RequestZoneTransfer(server, 0, 0, false, [system, server, usernameString](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string zoneIP, uint16_t zonePort) { + AuthPackets::SendLoginResponse(server, system, eLoginResponse::SUCCESS, "", zoneIP, zonePort, usernameString); + }); } void AuthPackets::SendLoginResponse(dServer* server, const SystemAddress& sysAddr, eLoginResponse responseCode, const std::string& errorMsg, const std::string& wServerIP, uint16_t wServerPort, std::string username) { - RakNet::BitStream packet; - PacketUtils::WriteHeader(packet, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE); + RakNet::BitStream loginResponse; + BitstreamUtils::WriteHeader(loginResponse, eConnectionType::CLIENT, eClientMessageType::LOGIN_RESPONSE); - packet.Write(static_cast(responseCode)); + loginResponse.Write(responseCode); - PacketUtils::WritePacketString("Talk_Like_A_Pirate", 33, &packet); + // Events + loginResponse.Write(LUString("Talk_Like_A_Pirate")); + loginResponse.Write(LUString("")); + loginResponse.Write(LUString("")); + loginResponse.Write(LUString("")); + loginResponse.Write(LUString("")); + loginResponse.Write(LUString("")); + loginResponse.Write(LUString("")); + loginResponse.Write(LUString("")); - // 7 unknown strings - perhaps other IP addresses? - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); - - packet.Write(static_cast(1)); // Version Major - packet.Write(static_cast(10)); // Version Current - packet.Write(static_cast(64)); // Version Minor + loginResponse.Write(static_cast(1)); // Version Major + loginResponse.Write(static_cast(10)); // Version Current + loginResponse.Write(static_cast(64)); // Version Minor // Writes the user key uint32_t sessionKey = GeneralUtils::GenerateRandomNumber(); std::string userHash = std::to_string(sessionKey); userHash = md5(userHash); - PacketUtils::WritePacketWString(userHash, 33, &packet); + loginResponse.Write(LUWString(userHash)); - // Write the Character and Chat IPs - PacketUtils::WritePacketString(wServerIP, 33, &packet); - PacketUtils::WritePacketString("", 33, &packet); + // World Server IP + loginResponse.Write(LUString(wServerIP)); + // Chat Server IP (unused) + loginResponse.Write(LUString("")); - // Write the Character and Chat Ports - packet.Write(static_cast(wServerPort)); - packet.Write(static_cast(0)); + // World Server Redirect port + loginResponse.Write(wServerPort); + // Char Server Redirect port (unused) + loginResponse.Write(static_cast(0)); - // Write another IP - PacketUtils::WritePacketString("", 33, &packet); + // CDN Key + loginResponse.Write(LUString("")); - // Write a GUID or something... - PacketUtils::WritePacketString("00000000-0000-0000-0000-000000000000", 37, &packet); + // CDN Ticket + loginResponse.Write(LUString("00000000-0000-0000-0000-000000000000", 37)); - packet.Write(static_cast(0)); // ??? + // Language + loginResponse.Write(Language::en_US); - // Write the localization - PacketUtils::WritePacketString("US", 3, &packet); + // Country Code + loginResponse.Write(LUString("US", 3)); - packet.Write(static_cast(false)); // User first logged in? - packet.Write(static_cast(false)); // User is F2P? - packet.Write(static_cast(0)); // ??? + + // Just upgraded from FTP + loginResponse.Write(static_cast(false)); + // Is FTP, static_cast(errorMsg.length())) + loginResponse.Write(static_cast(false)); + // Time remaining in FTP + loginResponse.Write(static_cast(0)); // Write custom error message - packet.Write(static_cast(errorMsg.length())); - PacketUtils::WritePacketWString(errorMsg, static_cast(errorMsg.length()), &packet); + loginResponse.Write(static_cast(errorMsg.length())); + loginResponse.Write(errorMsg); - // Here write auth logs - packet.Write(static_cast(20)); - for (uint32_t i = 0; i < 20; ++i) { - packet.Write(static_cast(8)); - packet.Write(static_cast(44)); - packet.Write(static_cast(14000)); - packet.Write(static_cast(0)); + // Stamps + std::vector stamps; + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_START, 0, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_COMMUNICATION_START, 207, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_RECEIVED, 13, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_THREAD_SPAWN, 0, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_WEBSERVICE_START, 0, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_WEBSERVICE_FINISH, 1, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_THREAD_FINISH, 1, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_REPLY, 0, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_LEGOINT_COMMUNICATION_END, 0, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_DB_INSERT_START, 0, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_DB_INSERT_FINISH, 1, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_CLIENT_OS, 0, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_WORLD_COMMUNICATION_START, 16087, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_WORLD_PACKET_RECEIVED, 0, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_IM_COMMUNICATION_START, 0, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_IM_LOGIN_START, 5926, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_IM_LOGIN_RESPONSE, 5926, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_IM_COMMUNICATION_END, 1, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_WORLD_SESSION_CONFIRM_TO_AUTH, 0, time(nullptr))); + stamps.push_back(Stamp(eStamps::PASSPORT_AUTH_WORLD_COMMUNICATION_FINISH, 16087, time(nullptr))); + + loginResponse.Write(static_cast((sizeof(Stamp) * stamps.size()) + sizeof(uint32_t))); + for (auto& stamp : stamps) { + stamp.Serialize(&loginResponse); } - - server->Send(&packet, sysAddr, false); + PacketUtils::SavePacket("loginresponse",(const char*)loginResponse.GetData(), loginResponse.GetNumberOfBytesUsed()); + Game::logger->Log("AuthPackets", "Sending Login Response..."); + server->Send(&loginResponse, sysAddr, false); //Inform the master server that we've created a session for this user: { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SET_SESSION_KEY); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SET_SESSION_KEY); bitStream.Write(sessionKey); - PacketUtils::WriteString(bitStream, username, 66); + bitStream.Write(LUString(username, 66)); + server->SendToMaster(&bitStream); server->GetLogger()->Log("AuthPackets", "Set sessionKey: %i for user %s", sessionKey, username.c_str()); diff --git a/dNet/AuthPackets.h b/dNet/AuthPackets.h index 0f004ca4..e98b88a7 100644 --- a/dNet/AuthPackets.h +++ b/dNet/AuthPackets.h @@ -7,8 +7,23 @@ enum class ServerType : uint32_t; enum class eLoginResponse : uint8_t; +enum class eStamps : uint32_t; class dServer; +struct Stamp { + eStamps type; + uint32_t value; + uint64_t timestamp; + + Stamp(eStamps type, uint32_t value, uint64_t timestamp){ + this->type = type; + this->value = value; + this->timestamp = timestamp; + } + + void Serialize(RakNet::BitStream* outBitStream); +}; + namespace AuthPackets { void HandleHandshake(dServer* server, Packet* packet); void SendHandshake(dServer* server, const SystemAddress& sysAddr, const std::string& nextServerIP, uint16_t nextServerPort, const ServerType serverType); diff --git a/dNet/BitstreamUtils.h b/dNet/BitstreamUtils.h new file mode 100644 index 00000000..b4849819 --- /dev/null +++ b/dNet/BitstreamUtils.h @@ -0,0 +1,127 @@ + +#ifndef __BITSTREAMUTILS__H__ +#define __BITSTREAMUTILS__H__ + +#include "GeneralUtils.h" +#include +#include +#include + +enum class eConnectionType : uint16_t; + +struct LUString { + std::string string; + uint32_t size; + + LUString(uint32_t size) { + this->size = size; + }; + LUString(std::string string, uint32_t size = 33) { + this->string = string; + this->size = size; + }; + std::u16string GetAsU16String() const { + return GeneralUtils::ASCIIToUTF16(this->string); + }; +}; + +struct LUWString { + std::u16string string; + uint32_t size; + + LUWString(uint32_t size) { + this->size = size; + }; + LUWString(std::u16string string, uint32_t size = 33) { + this->string = string; + this->size = size; + }; + LUWString(std::string string, uint32_t size = 33) { + this->string = GeneralUtils::ASCIIToUTF16(string); + this->size = size; + }; + std::string GetAsString() const { + return GeneralUtils::UTF16ToWTF8(this->string); + }; +}; + +namespace BitstreamUtils { + template + void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) { + bitStream.Write(MessageID(ID_USER_PACKET_ENUM)); + bitStream.Write(connectionType); + bitStream.Write(static_cast(internalPacketID)); + bitStream.Write(0); + } + +} + +namespace RakNet { + template <> + inline bool RakNet::BitStream::Read(LUString& value) { + bool noMoreLetters = false; + char character; + for (uint32_t j = 0; j < value.size; j++) { + if (!Read(character)) return false; + if (character == '\0') noMoreLetters = true; + if (!noMoreLetters) value.string.push_back(character); + } + return true; + } + + template <> + inline bool RakNet::BitStream::Read(LUWString& value) { + bool noMoreLetters = false; + char16_t character; + for (uint32_t j = 0; j < value.size; j++) { + if (!Read(character)) return false; + if (character == '\0') noMoreLetters = true; + if (!noMoreLetters) value.string.push_back(character); + } + return true; + } + + template <> + inline void RakNet::BitStream::Write(LUString value) { + uint32_t size = value.string.size(); + uint32_t emptySize = value.size - size; + + if (size > value.size) size = value.size; + + for (uint32_t i = 0; i < size; i++) { + this->Write(static_cast(value.string[i])); + } + + for (uint32_t i = 0; i < emptySize; i++) { + this->Write(static_cast(0)); + } + } + + template <> + inline void RakNet::BitStream::Write(LUWString value) { + uint32_t size = static_cast(value.string.length()); + uint32_t remSize = static_cast(value.size - size); + + if (size > value.size) size = value.size; + + for (uint32_t i = 0; i < size; ++i) { + this->Write(static_cast(value.string[i])); + } + + for (uint32_t j = 0; j < remSize; ++j) { + this->Write(static_cast(0)); + } + } + + template <> + inline void RakNet::BitStream::Write(std::string value) { + this->WriteBits(reinterpret_cast(value.data()), BYTES_TO_BITS(value.size())); + } + + template <> + inline void RakNet::BitStream::Write(std::u16string value) { + this->WriteBits(reinterpret_cast(value.data()), BYTES_TO_BITS(value.size()) * 2); + } +}; + +#endif //!__BITSTREAMUTILS__H__ diff --git a/dNet/ChatPackets.cpp b/dNet/ChatPackets.cpp index 41661523..2eef22f4 100644 --- a/dNet/ChatPackets.cpp +++ b/dNet/ChatPackets.cpp @@ -7,20 +7,20 @@ #include "RakNetTypes.h" #include "BitStream.h" #include "Game.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "dServer.h" #include "eConnectionType.h" #include "eChatMessageType.h" void ChatPackets::SendChatMessage(const SystemAddress& sysAddr, char chatChannel, const std::string& senderName, LWOOBJID playerObjectID, bool senderMythran, const std::u16string& message) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE); bitStream.Write(static_cast(0)); bitStream.Write(chatChannel); bitStream.Write(static_cast(message.size())); - PacketUtils::WriteWString(bitStream, senderName, 33); + bitStream.Write(LUWString(senderName)); bitStream.Write(playerObjectID); bitStream.Write(static_cast(0)); @@ -36,13 +36,13 @@ void ChatPackets::SendChatMessage(const SystemAddress& sysAddr, char chatChannel void ChatPackets::SendSystemMessage(const SystemAddress& sysAddr, const std::u16string& message, const bool broadcast) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, eChatMessageType::GENERAL_CHAT_MESSAGE); bitStream.Write(static_cast(0)); bitStream.Write(static_cast(4)); bitStream.Write(static_cast(message.size())); - PacketUtils::WriteWString(bitStream, "", 33); + bitStream.Write(LUWString("")); bitStream.Write(static_cast(0)); bitStream.Write(static_cast(0)); @@ -68,7 +68,7 @@ void ChatPackets::SendMessageFail(const SystemAddress& sysAddr) { //0x01 - "Upgrade to a full LEGO Universe Membership to chat with other players." CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SEND_CANNED_TEXT); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SEND_CANNED_TEXT); bitStream.Write(0); //response type, options above ^ //docs say there's a wstring here-- no idea what it's for, or if it's even needed so leaving it as is for now. SEND_PACKET; diff --git a/dNet/MasterPackets.cpp b/dNet/MasterPackets.cpp index 4233a37d..04695718 100644 --- a/dNet/MasterPackets.cpp +++ b/dNet/MasterPackets.cpp @@ -1,6 +1,6 @@ #include "MasterPackets.h" #include "BitStream.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "dCommonVars.h" #include "dServer.h" #include "eConnectionType.h" @@ -10,14 +10,14 @@ void MasterPackets::SendPersistentIDRequest(dServer* server, uint64_t requestID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID); bitStream.Write(requestID); server->SendToMaster(&bitStream); } void MasterPackets::SendPersistentIDResponse(dServer* server, const SystemAddress& sysAddr, uint64_t requestID, uint32_t objID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE); bitStream.Write(requestID); bitStream.Write(objID); @@ -27,7 +27,7 @@ void MasterPackets::SendPersistentIDResponse(dServer* server, const SystemAddres void MasterPackets::SendZoneTransferRequest(dServer* server, uint64_t requestID, bool mythranShift, uint32_t zoneID, uint32_t cloneID) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER); bitStream.Write(requestID); bitStream.Write(static_cast(mythranShift)); @@ -39,7 +39,7 @@ void MasterPackets::SendZoneTransferRequest(dServer* server, uint64_t requestID, void MasterPackets::SendZoneCreatePrivate(dServer* server, uint32_t zoneID, uint32_t cloneID, const std::string& password) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::CREATE_PRIVATE_ZONE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::CREATE_PRIVATE_ZONE); bitStream.Write(zoneID); bitStream.Write(cloneID); @@ -54,7 +54,7 @@ void MasterPackets::SendZoneCreatePrivate(dServer* server, uint32_t zoneID, uint void MasterPackets::SendZoneRequestPrivate(dServer* server, uint64_t requestID, bool mythranShift, const std::string& password) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PRIVATE_ZONE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_PRIVATE_ZONE); bitStream.Write(requestID); bitStream.Write(static_cast(mythranShift)); @@ -69,7 +69,7 @@ void MasterPackets::SendZoneRequestPrivate(dServer* server, uint64_t requestID, void MasterPackets::SendWorldReady(dServer* server, LWOMAPID zoneId, LWOINSTANCEID instanceId) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::WORLD_READY); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::WORLD_READY); bitStream.Write(zoneId); bitStream.Write(instanceId); @@ -79,7 +79,7 @@ void MasterPackets::SendWorldReady(dServer* server, LWOMAPID zoneId, LWOINSTANCE void MasterPackets::SendZoneTransferResponse(dServer* server, const SystemAddress& sysAddr, uint64_t requestID, bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, const std::string& serverIP, uint32_t serverPort) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE); bitStream.Write(requestID); bitStream.Write(static_cast(mythranShift)); @@ -87,7 +87,7 @@ void MasterPackets::SendZoneTransferResponse(dServer* server, const SystemAddres bitStream.Write(zoneInstance); bitStream.Write(zoneClone); bitStream.Write(static_cast(serverPort)); - PacketUtils::WriteString(bitStream, serverIP, static_cast(serverIP.size() + 1)); + bitStream.Write(LUString(serverIP, 255)); server->Send(&bitStream, sysAddr, false); } @@ -99,25 +99,26 @@ void MasterPackets::HandleServerInfo(Packet* packet) { uint32_t theirPort = 0; uint32_t theirZoneID = 0; uint32_t theirInstanceID = 0; - std::string theirIP = ""; + LUString theirIP(33); inStream.Read(theirPort); inStream.Read(theirZoneID); inStream.Read(theirInstanceID); - theirIP = PacketUtils::ReadString(inStream.GetReadOffset(), packet, false); //20 is the current offset + inStream.Read(theirIP); //TODO: Actually mark this server as an available server in the manager } void MasterPackets::SendServerInfo(dServer* server, Packet* packet) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SERVER_INFO); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SERVER_INFO); bitStream.Write(server->GetPort()); bitStream.Write(server->GetZoneID()); bitStream.Write(server->GetInstanceID()); bitStream.Write(server->GetServerType()); - PacketUtils::WriteString(bitStream, server->GetIP(), server->GetIP().size()); + bitStream.Write(server->GetIP().size()); + bitStream.Write(server->GetIP()); server->SendToMaster(&bitStream); } diff --git a/dNet/PacketUtils.cpp b/dNet/PacketUtils.cpp index 77b314d6..0f944482 100644 --- a/dNet/PacketUtils.cpp +++ b/dNet/PacketUtils.cpp @@ -1,139 +1,8 @@ #include "PacketUtils.h" -#include #include #include "dLogger.h" #include "Game.h" -uint16_t PacketUtils::ReadPacketU16(uint32_t startLoc, Packet* packet) { - if (startLoc + 2 > packet->length) return 0; - - std::vector t; - for (uint32_t i = startLoc; i < startLoc + 2; i++) t.push_back(packet->data[i]); - return *(uint16_t*)t.data(); -} - -uint32_t PacketUtils::ReadPacketU32(uint32_t startLoc, Packet* packet) { - if (startLoc + 4 > packet->length) return 0; - - std::vector t; - for (uint32_t i = startLoc; i < startLoc + 4; i++) { - t.push_back(packet->data[i]); - } - return *(uint32_t*)t.data(); -} - -uint64_t PacketUtils::ReadPacketU64(uint32_t startLoc, Packet* packet) { - if (startLoc + 8 > packet->length) return 0; - - std::vector t; - for (uint32_t i = startLoc; i < startLoc + 8; i++) t.push_back(packet->data[i]); - return *(uint64_t*)t.data(); -} - -int64_t PacketUtils::ReadPacketS64(uint32_t startLoc, Packet* packet) { - if (startLoc + 8 > packet->length) return 0; - - std::vector t; - for (size_t i = startLoc; i < startLoc + 8; i++) t.push_back(packet->data[i]); - return *(int64_t*)t.data(); -} - -std::string PacketUtils::ReadString(uint32_t startLoc, Packet* packet, bool wide, uint32_t maxLen) { - std::string readString = ""; - - if (wide) maxLen *= 2; - - if (packet->length > startLoc) { - uint32_t i = 0; - while (packet->data[startLoc + i] != '\0' && packet->length > (uint32_t)(startLoc + i) && maxLen > i) { - readString.push_back(packet->data[startLoc + i]); - - if (wide) { - i += 2; // Wide-char string - } else { - i++; // Regular string - } - } - } - - return readString; -} - -void PacketUtils::WritePacketString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream) { - uint32_t size = static_cast(string.size()); - uint32_t remSize = static_cast(maxSize - size); - - if (size > maxSize) size = maxSize; - - for (uint32_t i = 0; i < size; ++i) { - bitStream->Write(static_cast(string[i])); - } - - for (uint32_t j = 0; j < remSize; ++j) { - bitStream->Write(static_cast(0)); - } -} - -void PacketUtils::WriteString(RakNet::BitStream& bitStream, const std::string& s, uint32_t maxSize) { - uint32_t size = s.size(); - uint32_t emptySize = maxSize - size; - - if (size > maxSize) size = maxSize; - - for (uint32_t i = 0; i < size; i++) { - bitStream.Write((char)s[i]); - } - - for (uint32_t i = 0; i < emptySize; i++) { - bitStream.Write((char)0); - } -} - -void PacketUtils::WriteWString(RakNet::BitStream& bitStream, const std::string& string, uint32_t maxSize) { - uint32_t size = static_cast(string.length()); - uint32_t remSize = static_cast(maxSize - size); - - if (size > maxSize) size = maxSize; - - for (uint32_t i = 0; i < size; ++i) { - bitStream.Write(static_cast(string[i])); - } - - for (uint32_t j = 0; j < remSize; ++j) { - bitStream.Write(static_cast(0)); - } -} - -void PacketUtils::WriteWString(RakNet::BitStream& bitStream, const std::u16string& string, uint32_t maxSize) { - uint32_t size = static_cast(string.length()); - uint32_t remSize = static_cast(maxSize - size); - - if (size > maxSize) size = maxSize; - - for (uint32_t i = 0; i < size; ++i) { - bitStream.Write(static_cast(string[i])); - } - - for (uint32_t j = 0; j < remSize; ++j) { - bitStream.Write(static_cast(0)); - } -} - -void PacketUtils::WritePacketWString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream) { - uint32_t size = static_cast(string.length()); - uint32_t remSize = static_cast(maxSize - size); - - if (size > maxSize) size = maxSize; - - for (uint32_t i = 0; i < size; ++i) { - bitStream->Write(static_cast(string[i])); - } - - for (uint32_t j = 0; j < remSize; ++j) { - bitStream->Write(static_cast(0)); - } -} - //! Saves a packet to the filesystem void PacketUtils::SavePacket(const std::string& filename, const char* data, size_t length) { //If we don't log to the console, don't save the bin files either. This takes up a lot of time. diff --git a/dNet/PacketUtils.h b/dNet/PacketUtils.h index d07759a0..8cfb4458 100644 --- a/dNet/PacketUtils.h +++ b/dNet/PacketUtils.h @@ -1,33 +1,12 @@ #ifndef PACKETUTILS_H #define PACKETUTILS_H -#include -#include #include +#include +#include "RakNetTypes.h" -enum class eConnectionType : uint16_t; namespace PacketUtils { - template - void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) { - bitStream.Write(MessageID(ID_USER_PACKET_ENUM)); - bitStream.Write(connectionType); - bitStream.Write(static_cast(internalPacketID)); - bitStream.Write(0); - } - - uint16_t ReadPacketU16(uint32_t startLoc, Packet* packet); - uint32_t ReadPacketU32(uint32_t startLoc, Packet* packet); - uint64_t ReadPacketU64(uint32_t startLoc, Packet* packet); - int64_t ReadPacketS64(uint32_t startLoc, Packet* packet); - std::string ReadString(uint32_t startLoc, Packet* packet, bool wide, uint32_t maxLen = 33); - - void WritePacketString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream); - void WriteString(RakNet::BitStream& bitStream, const std::string& s, uint32_t maxSize); - void WriteWString(RakNet::BitStream& bitStream, const std::string& string, uint32_t maxSize); - void WriteWString(RakNet::BitStream& bitStream, const std::u16string& string, uint32_t maxSize); - void WritePacketWString(const std::string& string, uint32_t maxSize, RakNet::BitStream* bitStream); - void SavePacket(const std::string& filename, const char* data, size_t length); }; diff --git a/dNet/WorldPackets.cpp b/dNet/WorldPackets.cpp index 35c985eb..350661ca 100644 --- a/dNet/WorldPackets.cpp +++ b/dNet/WorldPackets.cpp @@ -1,7 +1,7 @@ #include "dCommonVars.h" #include "WorldPackets.h" #include "BitStream.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "GeneralUtils.h" #include "User.h" #include "Character.h" @@ -17,7 +17,7 @@ void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::LOAD_STATIC_ZONE); auto zone = Game::zoneManager->GetZone()->GetZoneID(); bitStream.Write(static_cast(zone.GetMapID())); @@ -41,7 +41,7 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) { if (!user) return; RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_LIST_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_LIST_RESPONSE); std::vector characters = user->GetCharacters(); bitStream.Write(static_cast(characters.size())); @@ -51,13 +51,13 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) { bitStream.Write(characters[i]->GetObjectID()); bitStream.Write(static_cast(0)); - PacketUtils::WriteWString(bitStream, characters[i]->GetName(), 33); - PacketUtils::WriteWString(bitStream, characters[i]->GetUnapprovedName(), 33); + bitStream.Write(LUWString(characters[i]->GetName())); + bitStream.Write(LUWString(characters[i]->GetUnapprovedName())); bitStream.Write(static_cast(characters[i]->GetNameRejected())); bitStream.Write(static_cast(false)); - PacketUtils::WriteString(bitStream, "", 10); + bitStream.Write(LUString("", 10)); bitStream.Write(characters[i]->GetShirtColor()); bitStream.Write(characters[i]->GetShirtStyle()); @@ -90,30 +90,30 @@ void WorldPackets::SendCharacterList(const SystemAddress& sysAddr, User* user) { void WorldPackets::SendCharacterCreationResponse(const SystemAddress& sysAddr, eCharacterCreationResponse response) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_CREATE_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_CREATE_RESPONSE); bitStream.Write(response); SEND_PACKET; } void WorldPackets::SendCharacterRenameResponse(const SystemAddress& sysAddr, eRenameResponse response) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_RENAME_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHARACTER_RENAME_RESPONSE); bitStream.Write(response); SEND_PACKET; } void WorldPackets::SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::DELETE_CHARACTER_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::DELETE_CHARACTER_RESPONSE); bitStream.Write(static_cast(response)); SEND_PACKET; } void WorldPackets::SendTransferToWorld(const SystemAddress& sysAddr, const std::string& serverIP, uint32_t serverPort, bool mythranShift) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TRANSFER_TO_WORLD); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::TRANSFER_TO_WORLD); - PacketUtils::WriteString(bitStream, serverIP, 33); + bitStream.Write(LUString(serverIP)); bitStream.Write(static_cast(serverPort)); bitStream.Write(static_cast(mythranShift)); @@ -122,14 +122,14 @@ void WorldPackets::SendTransferToWorld(const SystemAddress& sysAddr, const std:: void WorldPackets::SendServerState(const SystemAddress& sysAddr) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SERVER_STATES); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::SERVER_STATES); bitStream.Write(static_cast(1)); //If the server is receiving this request, it probably is ready anyway. SEND_PACKET; } void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, eGameMasterLevel gm) { RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CREATE_CHARACTER); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CREATE_CHARACTER); RakNet::BitStream data; data.Write(7); //LDF key count @@ -198,7 +198,7 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* ent void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::vector> unacceptedItems) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHAT_MODERATION_STRING); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::CHAT_MODERATION_STRING); bitStream.Write(unacceptedItems.empty()); // Is sentence ok? bitStream.Write(0x16); // Source ID, unknown @@ -206,7 +206,7 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool bitStream.Write(static_cast(requestID)); // request ID bitStream.Write(static_cast(0)); // chat mode - PacketUtils::WritePacketWString(receiver, 42, &bitStream); // receiver name + bitStream.Write(LUWString(receiver, 42)); // receiver name for (auto it : unacceptedItems) { bitStream.Write(it.first); // start index @@ -222,7 +222,7 @@ void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool void WorldPackets::SendGMLevelChange(const SystemAddress& sysAddr, bool success, eGameMasterLevel highestLevel, eGameMasterLevel prevLevel, eGameMasterLevel newLevel) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAKE_GM_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAKE_GM_RESPONSE); bitStream.Write(success); bitStream.Write(static_cast(highestLevel)); diff --git a/dNet/ZoneInstanceManager.cpp b/dNet/ZoneInstanceManager.cpp index b57bb634..75cb334d 100644 --- a/dNet/ZoneInstanceManager.cpp +++ b/dNet/ZoneInstanceManager.cpp @@ -3,7 +3,7 @@ // Custom Classes #include "MasterPackets.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "dServer.h" // C++ @@ -26,19 +26,29 @@ void ZoneInstanceManager::RequestZoneTransfer(dServer* server, uint32_t zoneID, //! Handles a zone transfer response void ZoneInstanceManager::HandleRequestZoneTransferResponse(uint64_t requestID, Packet* packet) { - - bool mythranShift = static_cast(packet->data[16]); - uint32_t zoneID = PacketUtils::ReadPacketU32(17, packet); - uint32_t zoneInstance = PacketUtils::ReadPacketU32(21, packet); - uint32_t zoneClone = PacketUtils::ReadPacketU32(25, packet); - uint16_t serverPort = PacketUtils::ReadPacketU16(29, packet); - std::string serverIP = PacketUtils::ReadString(31, packet, false); + CINSTREAM_SKIP_HEADER; + uint64_t requestIDAgain; + inStream.Read(requestIDAgain); + bool mythranShift; + uint8_t tmp; + inStream.Read(tmp); + mythranShift = tmp > 0; + uint32_t zoneID; + inStream.Read(zoneID); + uint32_t zoneInstance; + inStream.Read(zoneInstance); + uint32_t zoneClone; + inStream.Read(zoneClone); + uint16_t serverPort; + inStream.Read(serverPort); + LUString serverIP(255); + inStream.Read(serverIP); for (uint32_t i = 0; i < this->requests.size(); ++i) { if (this->requests[i]->requestID == requestID) { // Call the request callback - this->requests[i]->callback(mythranShift, zoneID, zoneInstance, zoneClone, serverIP, serverPort); + this->requests[i]->callback(mythranShift, zoneID, zoneInstance, zoneClone, serverIP.string, serverPort); delete this->requests[i]; this->requests.erase(this->requests.begin() + i); diff --git a/dNet/dServer.cpp b/dNet/dServer.cpp index 610f06a5..6e9c539d 100644 --- a/dNet/dServer.cpp +++ b/dNet/dServer.cpp @@ -10,7 +10,7 @@ #include "eServerMessageType.h" #include "eMasterMessageType.h" -#include "PacketUtils.h" +#include "BitstreamUtils.h" #include "MasterPackets.h" #include "ZoneInstanceManager.h" @@ -123,7 +123,9 @@ Packet* dServer::ReceiveFromMaster() { if (static_cast(packet->data[1]) == eConnectionType::MASTER) { switch (static_cast(packet->data[3])) { case eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE: { - uint64_t requestID = PacketUtils::ReadPacketU64(8, packet); + CINSTREAM_SKIP_HEADER; + uint64_t requestID; + inStream.Read(requestID); ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(requestID, packet); break; } @@ -167,8 +169,9 @@ void dServer::SendToMaster(RakNet::BitStream* bitStream) { } void dServer::Disconnect(const SystemAddress& sysAddr, eServerDisconnectIdentifiers disconNotifyID) { + Game::logger->Log("dServer", "Disconnecting reason: %i", disconNotifyID); RakNet::BitStream bitStream; - PacketUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::DISCONNECT_NOTIFY); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::SERVER, eServerMessageType::DISCONNECT_NOTIFY); bitStream.Write(disconNotifyID); mPeer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE_ORDERED, 0, sysAddr, false); diff --git a/dNet/dServer.h b/dNet/dServer.h index 797647b6..648b86fc 100644 --- a/dNet/dServer.h +++ b/dNet/dServer.h @@ -15,6 +15,14 @@ enum class ServerType : uint32_t { World }; +enum class ServiceId : uint32_t{ + General = 0, + Auth = 1, + Chat = 2, + World = 4, + Client = 5, +}; + class dServer { public: // Default constructor should only used for testing! diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index f07c17e3..1807d214 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -256,56 +256,57 @@ int main(int argc, char** argv) { Game::entityManager = new EntityManager(); Game::zoneManager = new dZoneManager(); + //Load our level: if (zoneID != 0) { dpWorld::Instance().Initialize(zoneID); Game::zoneManager->Initialize(LWOZONEID(zoneID, instanceID, cloneID)); g_CloneID = cloneID; - - // pre calculate the FDB checksum - if (Game::config->GetValue("check_fdb") == "1") { - std::ifstream fileStream; - - static const std::vector aliases = { - "CDServers.fdb", - "cdserver.fdb", - "CDClient.fdb", - "cdclient.fdb", - }; - - for (const auto& file : aliases) { - fileStream.open(Game::assetManager->GetResPath() / file, std::ios::binary | std::ios::in); - if (fileStream.is_open()) { - break; - } - } - - const int32_t bufferSize = 1024; - MD5* md5 = new MD5(); - - char fileStreamBuffer[1024] = {}; - - while (!fileStream.eof()) { - memset(fileStreamBuffer, 0, bufferSize); - fileStream.read(fileStreamBuffer, bufferSize); - md5->update(fileStreamBuffer, fileStream.gcount()); - } - - fileStream.close(); - - const char* nullTerminateBuffer = "\0"; - md5->update(nullTerminateBuffer, 1); // null terminate the data - md5->finalize(); - databaseChecksum = md5->hexdigest(); - - delete md5; - - Game::logger->Log("WorldServer", "FDB Checksum calculated as: %s", databaseChecksum.c_str()); - } } else { Game::entityManager->Initialize(); } + // pre calculate the FDB checksum + if (Game::config->GetValue("check_fdb") == "1") { + std::ifstream fileStream; + + static const std::vector aliases = { + "CDServers.fdb", + "cdserver.fdb", + "CDClient.fdb", + "cdclient.fdb", + }; + + for (const auto& file : aliases) { + fileStream.open(Game::assetManager->GetResPath() / file, std::ios::binary | std::ios::in); + if (fileStream.is_open()) { + break; + } + } + + const int32_t bufferSize = 1024; + MD5* md5 = new MD5(); + + char fileStreamBuffer[1024] = {}; + + while (!fileStream.eof()) { + memset(fileStreamBuffer, 0, bufferSize); + fileStream.read(fileStreamBuffer, bufferSize); + md5->update(fileStreamBuffer, fileStream.gcount()); + } + + fileStream.close(); + + const char* nullTerminateBuffer = "\0"; + md5->update(nullTerminateBuffer, 1); // null terminate the data + md5->finalize(); + databaseChecksum = md5->hexdigest(); + + delete md5; + + Game::logger->Log("WorldServer", "FDB Checksum calculated as: %s", databaseChecksum.c_str()); + } + uint32_t currentFrameDelta = highFrameDelta; // These values are adjust them selves to the current framerate should it update. uint32_t logFlushTime = 15 * currentFramerate; // 15 seconds in frames @@ -707,7 +708,7 @@ void HandlePacket(Packet* packet) { { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); bitStream.Write(user->GetLoggedInChar()); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } @@ -719,7 +720,7 @@ void HandlePacket(Packet* packet) { } CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_REMOVED); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_REMOVED); bitStream.Write((LWOMAPID)Game::server->GetZoneID()); bitStream.Write((LWOINSTANCEID)instanceID); Game::server->SendToMaster(&bitStream); @@ -735,14 +736,19 @@ void HandlePacket(Packet* packet) { if (static_cast(packet->data[1]) == eConnectionType::MASTER) { switch (static_cast(packet->data[3])) { case eMasterMessageType::REQUEST_PERSISTENT_ID_RESPONSE: { - uint64_t requestID = PacketUtils::ReadPacketU64(8, packet); - uint32_t objectID = PacketUtils::ReadPacketU32(16, packet); + CINSTREAM_SKIP_HEADER; + uint64_t requestID; + inStream.Read(requestID); + uint32_t objectID; + inStream.Read(objectID); ObjectIDManager::Instance()->HandleRequestPersistentIDResponse(requestID, objectID); break; } case eMasterMessageType::REQUEST_ZONE_TRANSFER_RESPONSE: { - uint64_t requestID = PacketUtils::ReadPacketU64(8, packet); + CINSTREAM_SKIP_HEADER; + uint64_t requestID; + inStream.Read(requestID); ZoneInstanceManager::Instance()->HandleRequestZoneTransferResponse(requestID, packet); break; } @@ -752,13 +758,13 @@ void HandlePacket(Packet* packet) { RakNet::BitStream inStream(packet->data, packet->length, false); uint64_t header = inStream.Read(header); uint32_t sessionKey = 0; - std::string username; + LUString username(64); inStream.Read(sessionKey); - username = PacketUtils::ReadString(12, packet, false); + inStream.Read(username); //Find them: - auto it = m_PendingUsers.find(username); + auto it = m_PendingUsers.find(username.string); if (it == m_PendingUsers.end()) return; //Convert our key: @@ -771,12 +777,12 @@ void HandlePacket(Packet* packet) { Game::server->Disconnect(it->second.sysAddr, eServerDisconnectIdentifiers::INVALID_SESSION_KEY); return; } else { - Game::logger->Log("WorldServer", "User %s authenticated with correct key.", username.c_str()); + Game::logger->Log("WorldServer", "User %s authenticated with correct key.", username.string.c_str()); UserManager::Instance()->DeleteUser(packet->systemAddress); //Create our user and send them in: - UserManager::Instance()->CreateUser(it->second.sysAddr, username, userHash); + UserManager::Instance()->CreateUser(it->second.sysAddr, username.string, userHash); auto zone = Game::zoneManager->GetZone(); if (zone) { @@ -799,12 +805,12 @@ void HandlePacket(Packet* packet) { UserManager::Instance()->RequestCharacterList(it->second.sysAddr); } - m_PendingUsers.erase(username); + m_PendingUsers.erase(username.string); //Notify master: { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_ADDED); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PLAYER_ADDED); bitStream.Write((LWOMAPID)Game::server->GetZoneID()); bitStream.Write((LWOINSTANCEID)instanceID); Game::server->SendToMaster(&bitStream); @@ -814,13 +820,14 @@ void HandlePacket(Packet* packet) { break; } case eMasterMessageType::AFFIRM_TRANSFER_REQUEST: { - const uint64_t requestID = PacketUtils::ReadPacketU64(8, packet); - + CINSTREAM_SKIP_HEADER; + uint64_t requestID; + inStream.Read(requestID); Game::logger->Log("MasterServer", "Got affirmation request of transfer %llu", requestID); CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::AFFIRM_TRANSFER_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::AFFIRM_TRANSFER_RESPONSE); bitStream.Write(requestID); Game::server->SendToMaster(&bitStream); @@ -875,18 +882,19 @@ void HandlePacket(Packet* packet) { switch (static_cast(packet->data[3])) { case eWorldMessageType::VALIDATION: { - std::string username = PacketUtils::ReadString(0x08, packet, true); - std::string sessionKey = PacketUtils::ReadString(74, packet, true); - std::string clientDatabaseChecksum = PacketUtils::ReadString(packet->length - 33, packet, false); - - // sometimes client puts a null terminator at the end of the checksum and sometimes doesn't, weird - clientDatabaseChecksum = clientDatabaseChecksum.substr(0, 32); + CINSTREAM_SKIP_HEADER; + LUWString username(33); + inStream.Read(username); + LUWString sessionKey(33); + inStream.Read(sessionKey); + LUString clientDatabaseChecksum(32); + inStream.Read(clientDatabaseChecksum); // If the check is turned on, validate the client's database checksum. if (Game::config->GetValue("check_fdb") == "1" && !databaseChecksum.empty()) { uint32_t gmLevel = 0; auto* stmt = Database::CreatePreppedStmt("SELECT gm_level FROM accounts WHERE name=? LIMIT 1;"); - stmt->setString(1, username.c_str()); + stmt->setString(1, username.GetAsString().c_str()); auto* res = stmt->executeQuery(); while (res->next()) { @@ -897,24 +905,24 @@ void HandlePacket(Packet* packet) { delete res; // Developers may skip this check - if (gmLevel < 8 && clientDatabaseChecksum != databaseChecksum) { + if (clientDatabaseChecksum.string != databaseChecksum) { Game::logger->Log("WorldServer", "Client's database checksum does not match the server's, aborting connection."); Game::server->Disconnect(packet->systemAddress, eServerDisconnectIdentifiers::WRONG_GAME_VERSION); return; - } + } else Game::logger->Log("WorldServer", "checksum was good"); } //Request the session info from Master: CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_SESSION_KEY); - PacketUtils::WriteString(bitStream, username, 64); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::REQUEST_SESSION_KEY); + bitStream.Write(username); Game::server->SendToMaster(&bitStream); //Insert info into our pending list tempSessionInfo info; info.sysAddr = SystemAddress(packet->systemAddress); - info.hash = sessionKey; - m_PendingUsers.insert(std::make_pair(username, info)); + info.hash = sessionKey.GetAsString(); + m_PendingUsers.insert(std::make_pair(username.GetAsString(), info)); break; } @@ -980,7 +988,7 @@ void HandlePacket(Packet* packet) { // This means we swapped characters and we need to remove the previous player from the container. if (static_cast(lastCharacter) != playerID) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_REMOVED_NOTIFICATION); bitStream.Write(lastCharacter); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } @@ -1129,7 +1137,7 @@ void HandlePacket(Packet* packet) { GeneralUtils::SetBit(blueprintID, eObjectBits::PERSISTENT); CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::BLUEPRINT_SAVE_RESPONSE); bitStream.Write(LWOOBJID_EMPTY); //always zero so that a check on the client passes bitStream.Write(eBlueprintSaveResponseType::EverythingWorked); bitStream.Write(1); @@ -1170,7 +1178,7 @@ void HandlePacket(Packet* packet) { //RakNet::RakString playerName(player->GetCharacter()->GetName().c_str()); CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_ADDED_NOTIFICATION); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::PLAYER_ADDED_NOTIFICATION); bitStream.Write(player->GetObjectID()); bitStream.Write(playerName.size()); for (size_t i = 0; i < playerName.size(); i++) { @@ -1221,7 +1229,7 @@ void HandlePacket(Packet* packet) { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::CHAT, packet->data[14]); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::CHAT, packet->data[14]); //We need to insert the player's objectID so the chat server can find who originated this request: LWOOBJID objectID = 0; @@ -1347,6 +1355,6 @@ void FinalizeShutdown() { void SendShutdownMessageToMaster() { CBITSTREAM; - PacketUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN_RESPONSE); + BitstreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::SHUTDOWN_RESPONSE); Game::server->SendToMaster(&bitStream); } diff --git a/tests/dCommonTests/CMakeLists.txt b/tests/dCommonTests/CMakeLists.txt index a345863d..006102fa 100644 --- a/tests/dCommonTests/CMakeLists.txt +++ b/tests/dCommonTests/CMakeLists.txt @@ -5,6 +5,8 @@ set(DCOMMONTEST_SOURCES "TestLDFFormat.cpp" "TestNiPoint3.cpp" "TestEncoding.cpp" + "TestLUString.cpp" + "TestLUWString.cpp" "dCommonDependencies.cpp" ) diff --git a/tests/dCommonTests/TestLUString.cpp b/tests/dCommonTests/TestLUString.cpp new file mode 100644 index 00000000..3abec985 --- /dev/null +++ b/tests/dCommonTests/TestLUString.cpp @@ -0,0 +1,121 @@ +#include + +#include "dCommonVars.h" + +TEST(LUString33Test, SerializeWriteTestOld) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 33; i++) testString += "a"; + for (const auto& c : testString) bitStream.Write(c); + std::string result; + char c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeWriteTestOldPartial) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 15; i++) testString += "a"; + for (const auto& c : testString) bitStream.Write(c); + for (int i = 0; i < 18; i++) bitStream.Write(0); + std::string result; + char c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeWriteTestNew) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 33; i++) testString += "a"; + bitStream.Write(LUString(testString, 33)); + std::string result; + char c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeWriteTestNewPartial) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 15; i++) testString += "a"; + bitStream.Write(LUString(testString, 33)); + std::string result; + char c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeReadTestOld) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 33; i++) testString += "a"; + for (const auto& c : testString) bitStream.Write(c); + std::string result; + char c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeReadTestOldPartial) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 15; i++) testString += "a"; + for (const auto& c : testString) bitStream.Write(c); + for (int i = 0; i < 18; i++) bitStream.Write(0); + std::string result; + char c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUString33Test, SerializeReadTestNew) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 33; i++) testString += "a"; + bitStream.Write(LUString(testString, 33)); + LUString result(33); + ASSERT_EQ(result.size, 33); + ASSERT_TRUE(bitStream.Read(result)); + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result.string, testString); +} + +TEST(LUString33Test, SerializeReadTestNewPartial) { + CBITSTREAM; + std::string testString; + for (int i = 0; i < 15; i++) testString += "a"; + bitStream.Write(LUString(testString, 33)); + LUString result(33); + ASSERT_EQ(result.size, 33); + ASSERT_TRUE(bitStream.Read(result)); + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result.string, testString); +} diff --git a/tests/dCommonTests/TestLUWString.cpp b/tests/dCommonTests/TestLUWString.cpp new file mode 100644 index 00000000..a16dd911 --- /dev/null +++ b/tests/dCommonTests/TestLUWString.cpp @@ -0,0 +1,121 @@ +#include + +#include "dCommonVars.h" + +TEST(LUWString33Test, SerializeWriteTestOld) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 33; i++) testString += u'ü'; + for (const auto& c : testString) bitStream.Write(c); + std::u16string result; + char16_t c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeWriteTestOldPartial) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 15; i++) testString += u'ü'; + for (const auto& c : testString) bitStream.Write(c); + for (int i = 0; i < 18; i++) bitStream.Write(0); + std::u16string result; + char16_t c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeWriteTestNew) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 33; i++) testString += u'ü'; + bitStream.Write(LUWString(testString, 33)); + std::u16string result; + char16_t c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeWriteTestNewPartial) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 15; i++) testString += u'ü'; + bitStream.Write(LUWString(testString, 33)); + std::u16string result; + char16_t c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeReadTestOld) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 33; i++) testString += u'ü'; + for (const auto& c : testString) bitStream.Write(c); + std::u16string result; + char16_t c; + while (bitStream.Read(c)) result += c; + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeReadTestOldPartial) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 15; i++) testString += u'ü'; + for (const auto& c : testString) bitStream.Write(c); + for (int i = 0; i < 18; i++) bitStream.Write(0); + std::u16string result; + char16_t c; + int nulls = 18; + while (bitStream.Read(c)){ + if (c == 0) { + nulls--; + continue; + } + result += c; + } + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(nulls, 0); + ASSERT_EQ(result, testString); +} + +TEST(LUWString33Test, SerializeReadTestNew) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 33; i++) testString += u'ü'; + bitStream.Write(LUWString(testString, 33)); + LUWString result(33); + ASSERT_EQ(result.size, 33); + ASSERT_TRUE(bitStream.Read(result)); + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result.string, testString); +} + +TEST(LUWString33Test, SerializeReadTestNewPartial) { + CBITSTREAM; + std::u16string testString; + for (int i = 0; i < 15; i++) testString += u'ü'; + bitStream.Write(LUWString(testString, 33)); + LUWString result(33); + ASSERT_EQ(result.size, 33); + ASSERT_TRUE(bitStream.Read(result)); + ASSERT_EQ(bitStream.GetNumberOfUnreadBits(), 0); + ASSERT_EQ(result.string, testString); +}