mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-10-09 17:08:06 +00:00

* feat: convert character ids to 64 bits remove all usages of the PERSISTENT bit with regards to storing of playerIDs on the server. the bit does not exist and was a phantom in the first place. Tested that a full playthrough of ag, ns and gf was still doable. slash commands work, ugc works, friends works, ignore list works, properties work and have names, teaming works. migrating an old mysql database works . need to test an old sqlite database * fix sqlite migration * remove nd specific column migration
170 lines
5.7 KiB
C++
170 lines
5.7 KiB
C++
#include "ChatIgnoreList.h"
|
|
#include "PlayerContainer.h"
|
|
#include "MessageType/Chat.h"
|
|
#include "BitStreamUtils.h"
|
|
#include "Game.h"
|
|
#include "Logger.h"
|
|
#include "eObjectBits.h"
|
|
|
|
#include "Database.h"
|
|
|
|
// A note to future readers, The client handles all the actual ignoring logic:
|
|
// not allowing teams, rejecting DMs, friends requets etc.
|
|
// The only thing not auto-handled is instance activities force joining the team on the server.
|
|
|
|
void WriteOutgoingReplyHeader(RakNet::BitStream& bitStream, const LWOOBJID& receivingPlayer, const MessageType::Client type) {
|
|
BitStreamUtils::WriteHeader(bitStream, ServiceType::CHAT, MessageType::Chat::WORLD_ROUTE_PACKET);
|
|
bitStream.Write(receivingPlayer);
|
|
|
|
//portion that will get routed:
|
|
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, type);
|
|
}
|
|
|
|
void ChatIgnoreList::GetIgnoreList(Packet* packet) {
|
|
CINSTREAM_SKIP_HEADER;
|
|
LWOOBJID playerId;
|
|
inStream.Read(playerId);
|
|
|
|
auto& receiver = Game::playerContainer.GetPlayerDataMutable(playerId);
|
|
if (!receiver) {
|
|
LOG("Tried to get ignore list, but player %llu not found in container", playerId);
|
|
return;
|
|
}
|
|
|
|
if (!receiver.ignoredPlayers.empty()) {
|
|
LOG_DEBUG("Player %llu already has an ignore list, but is requesting it again.", playerId);
|
|
} else {
|
|
auto ignoreList = Database::Get()->GetIgnoreList(playerId);
|
|
if (ignoreList.empty()) {
|
|
LOG_DEBUG("Player %llu has no ignores", playerId);
|
|
return;
|
|
}
|
|
|
|
for (auto& ignoredPlayer : ignoreList) {
|
|
receiver.ignoredPlayers.emplace_back(ignoredPlayer.name, ignoredPlayer.id);
|
|
GeneralUtils::SetBit(receiver.ignoredPlayers.back().playerId, eObjectBits::CHARACTER);
|
|
}
|
|
}
|
|
|
|
CBITSTREAM;
|
|
WriteOutgoingReplyHeader(bitStream, receiver.playerID, MessageType::Client::GET_IGNORE_LIST_RESPONSE);
|
|
|
|
bitStream.Write<uint8_t>(false); // Is Free Trial, but we don't care about that
|
|
bitStream.Write<uint16_t>(0); // literally spacing due to struct alignment
|
|
|
|
bitStream.Write<uint16_t>(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);
|
|
}
|
|
|
|
void ChatIgnoreList::AddIgnore(Packet* packet) {
|
|
CINSTREAM_SKIP_HEADER;
|
|
LWOOBJID playerId;
|
|
inStream.Read(playerId);
|
|
|
|
auto& receiver = Game::playerContainer.GetPlayerDataMutable(playerId);
|
|
if (!receiver) {
|
|
LOG("Tried to get ignore list, but player %llu not found in container", playerId);
|
|
return;
|
|
}
|
|
|
|
constexpr int32_t MAX_IGNORES = 32;
|
|
if (receiver.ignoredPlayers.size() > MAX_IGNORES) {
|
|
LOG_DEBUG("Player %llu has too many ignores", playerId);
|
|
return;
|
|
}
|
|
|
|
inStream.IgnoreBytes(4); // ignore some garbage zeros idk
|
|
|
|
LUWString toIgnoreName;
|
|
inStream.Read(toIgnoreName);
|
|
std::string toIgnoreStr = toIgnoreName.GetAsString();
|
|
|
|
CBITSTREAM;
|
|
WriteOutgoingReplyHeader(bitStream, receiver.playerID, MessageType::Client::ADD_IGNORE_RESPONSE);
|
|
|
|
// 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(ChatIgnoreList::AddResponse::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(ChatIgnoreList::AddResponse::ALREADY_IGNORED);
|
|
} else {
|
|
// Get the playerId falling back to query if not online
|
|
const auto& playerData = Game::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());
|
|
} else {
|
|
ignoredPlayerId = player->id;
|
|
}
|
|
} else {
|
|
ignoredPlayerId = playerData.playerID;
|
|
}
|
|
|
|
if (ignoredPlayerId != LWOOBJID_EMPTY) {
|
|
Database::Get()->AddIgnore(playerId, ignoredPlayerId);
|
|
GeneralUtils::SetBit(ignoredPlayerId, eObjectBits::CHARACTER);
|
|
|
|
receiver.ignoredPlayers.emplace_back(toIgnoreStr, ignoredPlayerId);
|
|
LOG_DEBUG("Player %llu is ignoring %s", playerId, toIgnoreStr.c_str());
|
|
|
|
bitStream.Write(ChatIgnoreList::AddResponse::SUCCESS);
|
|
} else {
|
|
bitStream.Write(ChatIgnoreList::AddResponse::PLAYER_NOT_FOUND);
|
|
}
|
|
}
|
|
|
|
LUWString playerNameSend(toIgnoreStr, 33);
|
|
bitStream.Write(playerNameSend);
|
|
bitStream.Write(ignoredPlayerId);
|
|
|
|
Game::server->Send(bitStream, packet->systemAddress, false);
|
|
}
|
|
|
|
void ChatIgnoreList::RemoveIgnore(Packet* packet) {
|
|
CINSTREAM_SKIP_HEADER;
|
|
LWOOBJID playerId;
|
|
inStream.Read(playerId);
|
|
|
|
auto& receiver = Game::playerContainer.GetPlayerDataMutable(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 removedIgnoreName;
|
|
inStream.Read(removedIgnoreName);
|
|
std::string removedIgnoreStr = removedIgnoreName.GetAsString();
|
|
|
|
auto toRemove = std::remove(receiver.ignoredPlayers.begin(), receiver.ignoredPlayers.end(), removedIgnoreStr);
|
|
if (toRemove == receiver.ignoredPlayers.end()) {
|
|
LOG_DEBUG("Player %llu is not ignoring %s", playerId, removedIgnoreStr.c_str());
|
|
return;
|
|
}
|
|
|
|
Database::Get()->RemoveIgnore(playerId, toRemove->playerId);
|
|
receiver.ignoredPlayers.erase(toRemove, receiver.ignoredPlayers.end());
|
|
|
|
CBITSTREAM;
|
|
WriteOutgoingReplyHeader(bitStream, receiver.playerID, MessageType::Client::REMOVE_IGNORE_RESPONSE);
|
|
|
|
bitStream.Write<int8_t>(0);
|
|
LUWString playerNameSend(removedIgnoreStr, 33);
|
|
bitStream.Write(playerNameSend);
|
|
|
|
Game::server->Send(bitStream, packet->systemAddress, false);
|
|
}
|