From df3515f4742b9271899fad2329e5624e6acb7b40 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 18 Nov 2023 03:55:12 -0800 Subject: [PATCH] IgnoreList: Add and Populate fully working --- dChatServer/CMakeLists.txt | 1 + dChatServer/ChatIgnoreList.cpp | 121 +++++++++++++++++++++++++++++++++ dChatServer/ChatIgnoreList.h | 11 +++ dChatServer/ChatServer.cpp | 7 +- dChatServer/PlayerContainer.h | 14 ++++ 5 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 dChatServer/ChatIgnoreList.cpp create mode 100644 dChatServer/ChatIgnoreList.h diff --git a/dChatServer/CMakeLists.txt b/dChatServer/CMakeLists.txt index 9a47803d..34d58a3a 100644 --- a/dChatServer/CMakeLists.txt +++ b/dChatServer/CMakeLists.txt @@ -1,4 +1,5 @@ set(DCHATSERVER_SOURCES + "ChatIgnoreList.cpp" "ChatPacketHandler.cpp" "PlayerContainer.cpp" ) diff --git a/dChatServer/ChatIgnoreList.cpp b/dChatServer/ChatIgnoreList.cpp new file mode 100644 index 00000000..a84c3cda --- /dev/null +++ b/dChatServer/ChatIgnoreList.cpp @@ -0,0 +1,121 @@ +#include "ChatIgnoreList.h" +#include "PlayerContainer.h" +#include "eChatInternalMessageType.h" +#include "BitStreamUtils.h" +#include "PacketUtils.h" +#include "Game.h" +#include "Logger.h" +#include "eObjectBits.h" + +#include "Database.h" + +extern PlayerContainer playerContainer; + +enum IgnoreReponse : uint8_t { + AddIgnoreResponse = 32, + GetIgnoreListResponse = 34, +}; + +void ChatIgnoreList::GetIgnoreList(Packet* packet) { + LOG_DEBUG("Getting ignore list"); + + CINSTREAM_SKIP_HEADER; + LWOOBJID playerId; + inStream.Read(playerId); + + auto* receiver = playerContainer.GetPlayerData(playerId); + if (!receiver) { + LOG("Tried to get ignore list, but player %llu not found in container", playerId); + return; + } + + CBITSTREAM; + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + bitStream.Write(receiver->playerID); + + //portion that will get routed: + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, IgnoreReponse::GetIgnoreListResponse); + bitStream.Write(false); // Probably is Is Free Trial, but we don't care about that + bitStream.Write(0); // literally spacing due to struct alignment + bitStream.Write(receiver->ignoredPlayers.size()); + for (const auto& ignoredPlayer : receiver->ignoredPlayers) { + bitStream.Write(ignoredPlayer.playerId); + bitStream.Write(LUWString(ignoredPlayer.playerName, 36)); + } + Game::server->Send(&bitStream, packet->systemAddress, false); +} + +// Remove from ignore list and response +// Not much else to do with editing the list, maybe more messages are needed for refreshes or something +// but you can only add or remove from the list, and you only request the list on world start so pretty small file +// After the above all work, move to implement the actual ignore functionality in the chat server +enum class IgnoreResponse : uint8_t { + SUCCESS, + ALREADY_IGNORED, + PLAYER_NOT_FOUND, + GENERAL_ERROR, +}; + +void ChatIgnoreList::AddIgnore(Packet* packet) { + LOG_DEBUG("Adding ignore"); + + CINSTREAM_SKIP_HEADER; + LWOOBJID playerId; + inStream.Read(playerId); + + auto* receiver = playerContainer.GetPlayerData(playerId); + if (!receiver) { + LOG("Tried to get ignore list, but player %llu not found in container", playerId); + return; + } + inStream.IgnoreBytes(4); // ignore some garbage zeros idk + + LUWString toIgnoreName(33); + inStream.Read(toIgnoreName); + std::string toIgnoreStr = toIgnoreName.GetAsString(); + + CBITSTREAM; + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CHAT_INTERNAL, eChatInternalMessageType::ROUTE_TO_PLAYER); + bitStream.Write(receiver->playerID); + + //portion that will get routed: + BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, IgnoreReponse::AddIgnoreResponse); + + // Check if the player exists + LWOOBJID ignoredPlayerId = LWOOBJID_EMPTY; + if (toIgnoreStr == receiver->playerName || toIgnoreStr.find("[GM]") == 0) { + LOG_DEBUG("Player %llu tried to ignore themselves", playerId); + + bitStream.Write(IgnoreResponse::GENERAL_ERROR); + } else if (std::count(receiver->ignoredPlayers.begin(), receiver->ignoredPlayers.end(), toIgnoreStr) > 0) { + LOG_DEBUG("Player %llu is already ignoring %s", playerId, toIgnoreStr.c_str()); + + bitStream.Write(IgnoreResponse::ALREADY_IGNORED); + } else { + auto* playerData = playerContainer.GetPlayerData(toIgnoreStr); + if (!playerData) { + // Fall back to query + auto player = Database::Get()->GetCharacterInfo(toIgnoreStr); + if (!player || player->name != toIgnoreStr) { + LOG_DEBUG("Player %s not found", toIgnoreStr.c_str()); + + bitStream.Write(IgnoreResponse::PLAYER_NOT_FOUND); + } else { + ignoredPlayerId = player->id; + GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::CHARACTER); + GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::PERSISTENT); + + receiver->ignoredPlayers.push_back(IgnoreData{ ignoredPlayerId, toIgnoreStr }); + LOG_DEBUG("Player %llu is ignoring %s", playerId, toIgnoreStr.c_str()); + + bitStream.Write(IgnoreResponse::SUCCESS); + } + } + } + + LUWString playerNameSend(toIgnoreStr, 33); + bitStream.Write(playerNameSend); + bitStream.Write(ignoredPlayerId); + + Game::server->Send(&bitStream, packet->systemAddress, false); +} diff --git a/dChatServer/ChatIgnoreList.h b/dChatServer/ChatIgnoreList.h new file mode 100644 index 00000000..48170369 --- /dev/null +++ b/dChatServer/ChatIgnoreList.h @@ -0,0 +1,11 @@ +#ifndef __CHATIGNORELIST__H__ +#define __CHATIGNORELIST__H__ + +struct Packet; + +namespace ChatIgnoreList { + void GetIgnoreList(Packet* packet); + void AddIgnore(Packet* packet); +}; + +#endif //!__CHATIGNORELIST__H__ diff --git a/dChatServer/ChatServer.cpp b/dChatServer/ChatServer.cpp index b41ad4ec..6671b047 100644 --- a/dChatServer/ChatServer.cpp +++ b/dChatServer/ChatServer.cpp @@ -19,6 +19,7 @@ #include "eChatMessageType.h" #include "eChatInternalMessageType.h" #include "eWorldMessageType.h" +#include "ChatIgnoreList.h" #include "Game.h" @@ -234,7 +235,11 @@ void HandlePacket(Packet* packet) { break; case eChatMessageType::GET_IGNORE_LIST: - LOG("Asked for ignore list, but is unimplemented right now."); + ChatIgnoreList::GetIgnoreList(packet); + break; + + case eChatMessageType::ADD_IGNORE: + ChatIgnoreList::AddIgnore(packet); break; case eChatMessageType::TEAM_GET_STATUS: diff --git a/dChatServer/PlayerContainer.h b/dChatServer/PlayerContainer.h index d055ed95..51bff6c1 100644 --- a/dChatServer/PlayerContainer.h +++ b/dChatServer/PlayerContainer.h @@ -7,12 +7,26 @@ #include "dServer.h" #include +struct IgnoreData { + inline bool operator==(const std::string& other) const noexcept { + return playerName == other; + } + + inline bool operator==(const LWOOBJID& other) const noexcept { + return playerId == other; + } + + LWOOBJID playerId; + std::string playerName; +}; + struct PlayerData { LWOOBJID playerID; std::string playerName; SystemAddress sysAddr; LWOZONEID zoneID; std::vector friends; + std::vector ignoredPlayers; time_t muteExpire; uint8_t countOfBestFriends = 0; };