From 4627168871d70914a48f8c36305f40a787fbbde7 Mon Sep 17 00:00:00 2001 From: Aronwk Date: Sun, 18 May 2025 23:36:05 -0500 Subject: [PATCH] fixes --- dCommon/dEnums/eChatMode.h | 11 ++++++ dNet/ClientPackets.cpp | 36 +++++++++---------- dNet/ClientPackets.h | 4 +-- dNet/WorldPackets.cpp | 56 ++++++++++++++++++++++++++++- dNet/WorldPackets.h | 3 +- dWorldServer/WorldServer.cpp | 70 +++--------------------------------- 6 files changed, 93 insertions(+), 87 deletions(-) create mode 100644 dCommon/dEnums/eChatMode.h diff --git a/dCommon/dEnums/eChatMode.h b/dCommon/dEnums/eChatMode.h new file mode 100644 index 00000000..22469d58 --- /dev/null +++ b/dCommon/dEnums/eChatMode.h @@ -0,0 +1,11 @@ +#ifndef __ECHATMODE__H__ +#define __ECHATMODE__H__ +#include + +enum class eChatMode : uint8_t { + RESTRICTED = 0, + UNRESTRICTED = 1 + +}; + +#endif //!__ECHATMODE__H__ diff --git a/dNet/ClientPackets.cpp b/dNet/ClientPackets.cpp index 1a4a6c94..6e2241b9 100644 --- a/dNet/ClientPackets.cpp +++ b/dNet/ClientPackets.cpp @@ -46,28 +46,26 @@ namespace ClientPackets { RakNet::BitStream data; - data.Write(7); //LDF key count + data.Write(7); // LDF key count LDFData(u"objid", objid).WriteToPacket(data); - LDFData(u"template", templateID).WriteToPacket(data);; - LDFData(u"name", name).WriteToPacket(data);; - LDFData(u"gmlevel", static_cast(gmLevel)).WriteToPacket(data);; - LDFData(u"chatmode", static_cast(chatMode)).WriteToPacket(data);; - LDFData(u"xmlData", xmlData).WriteToPacket(data);; - LDFData(u"reputation", reputation).WriteToPacket(data);; - //Compress the data before sending: + LDFData(u"template", templateID).WriteToPacket(data); + LDFData(u"name", name).WriteToPacket(data); + LDFData(u"gmlevel", static_cast(gmLevel)).WriteToPacket(data); + LDFData(u"chatmode", static_cast(chatMode)).WriteToPacket(data); + LDFData(u"xmlData", xmlData).WriteToPacket(data); + LDFData(u"reputation", reputation).WriteToPacket(data); + + // Compress the data before sending: const uint32_t reservedSize = ZCompression::GetMaxCompressedLength(data.GetNumberOfBytesUsed()); uint8_t* compressedData = new uint8_t[reservedSize]; - if (!compressedData) { - throw std::runtime_error("Failed to allocate memory for compressed data"); - } + if (!compressedData) throw std::runtime_error("Failed to allocate memory for compressed data"); size_t size = ZCompression::Compress(data.GetData(), data.GetNumberOfBytesUsed(), compressedData, reservedSize); - assert(size <= reservedSize); - bitStream.Write(size + 9); //size of data + header bytes (8) - bitStream.Write(1); //compressed boolean, true + bitStream.Write(size + 9); // size of data + header bytes (8) + bitStream.Write(1); // compressed boolean, true bitStream.Write(data.GetNumberOfBytesUsed()); bitStream.Write(size); @@ -91,14 +89,16 @@ namespace ClientPackets { bitStream.Write(LUWString(receiver, 42)); + // Write the rejected words + // There has to be 64 items written so we need to pad the rest with 0s + int toWrite = 64; for (auto it : rejectedWords) { + if (toWrite <= 0) return; bitStream.Write(it.first); // start index bitStream.Write(it.second); // length + toWrite--; } - - // Pad out the rest of the packet - // The client expects 64 items, so we need to write 64 - rejectedWords.size() empty items - for (int i = rejectedWords.size(); 64 > i; i++) { + for (toWrite; toWrite <= 0; toWrite--) { bitStream.Write(0); } diff --git a/dNet/ClientPackets.h b/dNet/ClientPackets.h index 30455cf0..a0506ff9 100644 --- a/dNet/ClientPackets.h +++ b/dNet/ClientPackets.h @@ -74,12 +74,12 @@ namespace ClientPackets { }; struct CreateCharacter : public LUBitStream { - LWOOBJID objid = 0; + LWOOBJID objid = LWOOBJID_EMPTY; LOT templateID = 1; std::u16string name; eGameMasterLevel gmLevel = eGameMasterLevel::CIVILIAN; int32_t chatMode = 0; - std::string xmlData; + std::string_view xmlData; int64_t reputation = 0; CreateCharacter() : LUBitStream(eConnectionType::CLIENT, MessageType::Client::CREATE_CHARACTER) {}; diff --git a/dNet/WorldPackets.cpp b/dNet/WorldPackets.cpp index 6a7c36b1..8fe34659 100644 --- a/dNet/WorldPackets.cpp +++ b/dNet/WorldPackets.cpp @@ -9,6 +9,8 @@ #include "Character.h" #include "dChatFilter.h" #include "ChatPackets.h" +#include "ClientPackets.h" +#include "Database.h" namespace WorldPackets { @@ -160,7 +162,7 @@ namespace WorldPackets { } bool StringCheck::Deserialize(RakNet::BitStream& bitStream) { - VALIDATE_READ(bitStream.Read(chatLevel)); + VALIDATE_READ(bitStream.Read(chatMode)); VALIDATE_READ(bitStream.Read(requestID)); for (uint32_t i = 0; i < 42; ++i) { @@ -187,6 +189,58 @@ namespace WorldPackets { } void StringCheck::Handle() { + auto* entity = Game::entityManager->GetEntity(objectID); + if (!entity) { + LOG("Unable to get player to handle string check request"); + return; + } + auto* character = entity->GetCharacter(); + if (!character) { + LOG("Unable to get character to handle string check request"); + return; + } + auto* user = character->GetParentUser(); + if (!user) { + LOG("Unable to get user to handle string check request"); + return; + } + + // Check if the player has restricted chat access + if (character->HasPermission(ePermissionMap::RestrictedChatAccess)) { + ChatPackets::SendSystemMessage( + entity->GetSystemAddress(), + u"This character has restricted chat access." + ); + return; + } + + bool isBestFriend = false; + if (chatMode == eChatMode::UNRESTRICTED) { + // Check if the receiver is a best friend + LWOOBJID idOfReceiver = LWOOBJID_EMPTY; + { + auto characterIdFetch = Database::Get()->GetCharacterInfo(receiver); + if (characterIdFetch) idOfReceiver = characterIdFetch->id; + } + const auto& bffMap = user->GetIsBestFriendMap(); + if (bffMap.find(receiver) == bffMap.end() && idOfReceiver != LWOOBJID_EMPTY) { + auto bffInfo = Database::Get()->GetBestFriendStatus(entity->GetObjectID(), idOfReceiver); + if (bffInfo) isBestFriend = bffInfo->bestFriendStatus == 3; + if (isBestFriend) user->UpdateBestFriendValue(receiver, true); + } else if (bffMap.find(receiver) != bffMap.end()) { + isBestFriend = true; + } + } + + const auto segments = Game::chatFilter->IsSentenceOkay(message, entity->GetGMLevel(), !(isBestFriend && chatMode == eChatMode::UNRESTRICTED)); + bool bAllClean = segments.empty(); + if (user->GetIsMuted()) bAllClean = false; + + user->SetLastChatMessageApproved(bAllClean); + ClientPackets::ChatModerationString response; + response.receiver = receiver; + response.rejectedWords = segments; + response.Send(entity->GetSystemAddress()); } } diff --git a/dNet/WorldPackets.h b/dNet/WorldPackets.h index 71ece127..a91f61f8 100644 --- a/dNet/WorldPackets.h +++ b/dNet/WorldPackets.h @@ -4,6 +4,7 @@ #include "dCommonVars.h" #include "BitStreamUtils.h" #include "MessageType/World.h" +#include "eChatMode.h" class Entity; enum class eLanguageCodeID : int32_t { @@ -62,7 +63,7 @@ namespace WorldPackets { }; struct StringCheck : public LUBitStream { - uint8_t chatLevel = 0; + eChatMode chatMode = eChatMode::RESTRICTED; uint8_t requestID = 0; std::string receiver; std::string message; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index ff7b5bbd..d14cb54f 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -1043,7 +1043,7 @@ void HandlePacket(Packet* packet) { createCharacter.name = username; createCharacter.gmLevel = c->GetGMLevel(); createCharacter.xmlData = c->GetXMLData(); - createCharacter.reputation = player->GetComponent()->GetReputation(); + createCharacter.reputation = characterComponent->GetReputation(); createCharacter.Send(packet->systemAddress); ClientPackets::ServerState serverState; @@ -1230,7 +1230,8 @@ void HandlePacket(Packet* packet) { LOG("Unable to get user to parse position update"); return; } - positionUpdate.objectID = user->GetLastUsedChar()->GetObjectID(); + positionUpdate.objectID = user->GetLastUsedChar()->GetObjectID(); + positionUpdate.Handle(); break; } @@ -1277,75 +1278,14 @@ void HandlePacket(Packet* packet) { WorldPackets::StringCheck request; request.Deserialize(inStream); - // TODO: Find a good home for the logic in this case. - User* user = UserManager::Instance()->GetUser(packet->systemAddress); - if (!user) { - LOG("Unable to get user to parse chat moderation request"); - return; - } - auto* entity = PlayerManager::GetPlayer(packet->systemAddress); - if (entity == nullptr) { LOG("Unable to get player to parse chat moderation request"); return; } - // Check if the player has restricted chat access - auto* character = entity->GetCharacter(); - - if (character->HasPermission(ePermissionMap::RestrictedChatAccess)) { - // Send a message to the player - ChatPackets::SendSystemMessage( - packet->systemAddress, - u"This character has restricted chat access." - ); - - return; - } - - bool isBestFriend = false; - - if (request.chatLevel == 1) { - // Private chat - LWOOBJID idOfReceiver = LWOOBJID_EMPTY; - - { - auto characterIdFetch = Database::Get()->GetCharacterInfo(request.receiver); - - if (characterIdFetch) { - idOfReceiver = characterIdFetch->id; - } - } - const auto& bffMap = user->GetIsBestFriendMap(); - if (bffMap.find(request.receiver) == bffMap.end() && idOfReceiver != LWOOBJID_EMPTY) { - auto bffInfo = Database::Get()->GetBestFriendStatus(entity->GetObjectID(), idOfReceiver); - - if (bffInfo) { - isBestFriend = bffInfo->bestFriendStatus == 3; - } - - if (isBestFriend) { - user->UpdateBestFriendValue(request.receiver, true); - } - } else if (bffMap.find(request.receiver) != bffMap.end()) { - isBestFriend = true; - } - } - - const auto segments = Game::chatFilter->IsSentenceOkay(request.message, entity->GetGMLevel(), !(isBestFriend && request.chatLevel == 1)); - - bool bAllClean = segments.empty(); - - if (user->GetIsMuted()) { - bAllClean = false; - } - - user->SetLastChatMessageApproved(bAllClean); - ClientPackets::ChatModerationString response; - response.receiver = request.receiver; - response.rejectedWords = segments; - response.Send(packet->systemAddress); + request.objectID = entity->GetObjectID(); + request.Handle(); break; }