fix: properly check friend list limits (#1300)

* fix: properly check friend list limits
added a config for friend list limit for the brave that want to mod the client to sanely go over 50
moved the best friend limit config to chatconfig.ini where it should be
cleanup loading these configs options a bit

Tested that the BFF limit works and that the new friend limit works as well

* fix typo

* fix member variable naming
This commit is contained in:
Aaron Kimbrell 2023-11-17 18:44:48 -06:00 committed by GitHub
parent 7bbe5ffc39
commit b68823b4cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 43 additions and 27 deletions

View File

@ -96,9 +96,6 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
} }
void ChatPacketHandler::HandleFriendRequest(Packet* packet) { void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
auto maxNumberOfBestFriendsAsString = Game::config->GetValue("max_number_of_best_friends");
// If this config option doesn't exist, default to 5 which is what live used.
auto maxNumberOfBestFriends = maxNumberOfBestFriendsAsString != "" ? std::stoi(maxNumberOfBestFriendsAsString) : 5U;
CINSTREAM_SKIP_HEADER; CINSTREAM_SKIP_HEADER;
LWOOBJID requestorPlayerID; LWOOBJID requestorPlayerID;
inStream.Read(requestorPlayerID); inStream.Read(requestorPlayerID);
@ -204,11 +201,12 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
// Only do updates if there was a change in the bff status. // Only do updates if there was a change in the bff status.
if (oldBestFriendStatus != bestFriendStatus) { if (oldBestFriendStatus != bestFriendStatus) {
if (requestee->countOfBestFriends >= maxNumberOfBestFriends || requestor->countOfBestFriends >= maxNumberOfBestFriends) { auto maxBestFriends = playerContainer.GetMaxNumberOfBestFriends();
if (requestee->countOfBestFriends >= maxNumberOfBestFriends) { if (requestee->countOfBestFriends >= maxBestFriends || requestor->countOfBestFriends >= maxBestFriends) {
if (requestee->countOfBestFriends >= maxBestFriends) {
SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::THEIRFRIENDLISTFULL, false); SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::THEIRFRIENDLISTFULL, false);
} }
if (requestor->countOfBestFriends >= maxNumberOfBestFriends) { if (requestor->countOfBestFriends >= maxBestFriends) {
SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::YOURFRIENDSLISTFULL, false); SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::YOURFRIENDSLISTFULL, false);
} }
} else { } else {
@ -242,8 +240,15 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
if (requestor->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::WAITINGAPPROVAL, true, true); if (requestor->sysAddr != UNASSIGNED_SYSTEM_ADDRESS) SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::WAITINGAPPROVAL, true, true);
} }
} else { } else {
// Do not send this if we are requesting to be a best friend. auto maxFriends = playerContainer.GetMaxNumberOfFriends();
SendFriendRequest(requestee.get(), requestor); if (requestee->friends.size() >= maxFriends) {
SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::THEIRFRIENDLISTFULL, false);
} else if (requestor->friends.size() >= maxFriends) {
SendFriendResponse(requestor, requestee.get(), eAddFriendResponseType::YOURFRIENDSLISTFULL, false);
} else {
// Do not send this if we are requesting to be a best friend.
SendFriendRequest(requestee.get(), requestor);
}
} }
// If the player is actually a player and not a ghost one defined above, release it from being deleted. // If the player is actually a player and not a ghost one defined above, release it from being deleted.

View File

@ -14,10 +14,12 @@
#include "dConfig.h" #include "dConfig.h"
PlayerContainer::PlayerContainer() { PlayerContainer::PlayerContainer() {
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_best_friends"), m_MaxNumberOfBestFriends);
GeneralUtils::TryParse<uint32_t>(Game::config->GetValue("max_number_of_friends"), m_MaxNumberOfFriends);
} }
PlayerContainer::~PlayerContainer() { PlayerContainer::~PlayerContainer() {
mPlayers.clear(); m_Players.clear();
} }
TeamData::TeamData() { TeamData::TeamData() {
@ -41,9 +43,9 @@ void PlayerContainer::InsertPlayer(Packet* packet) {
inStream.Read(data->muteExpire); inStream.Read(data->muteExpire);
data->sysAddr = packet->systemAddress; data->sysAddr = packet->systemAddress;
mNames[data->playerID] = GeneralUtils::UTF8ToUTF16(data->playerName); m_Names[data->playerID] = GeneralUtils::UTF8ToUTF16(data->playerName);
mPlayers.insert(std::make_pair(data->playerID, data)); m_Players.insert(std::make_pair(data->playerID, data));
LOG("Added user: %s (%llu), zone: %i", data->playerName.c_str(), data->playerID, data->zoneID.GetMapID()); LOG("Added user: %s (%llu), zone: %i", data->playerName.c_str(), data->playerID, data->zoneID.GetMapID());
auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);"); auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);");
@ -88,7 +90,7 @@ void PlayerContainer::RemovePlayer(Packet* packet) {
} }
LOG("Removed user: %llu", playerID); LOG("Removed user: %llu", playerID);
mPlayers.erase(playerID); m_Players.erase(playerID);
auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);"); auto* insertLog = Database::CreatePreppedStmt("INSERT INTO activity_log (character_id, activity, time, map_id) VALUES (?, ?, ?, ?);");
@ -191,7 +193,7 @@ TeamData* PlayerContainer::CreateLocalTeam(std::vector<LWOOBJID> members) {
TeamData* PlayerContainer::CreateTeam(LWOOBJID leader, bool local) { TeamData* PlayerContainer::CreateTeam(LWOOBJID leader, bool local) {
auto* team = new TeamData(); auto* team = new TeamData();
team->teamID = ++mTeamIDCounter; team->teamID = ++m_TeamIDCounter;
team->leaderID = leader; team->leaderID = leader;
team->local = local; team->local = local;
@ -376,15 +378,15 @@ void PlayerContainer::UpdateTeamsOnWorld(TeamData* team, bool deleteTeam) {
} }
std::u16string PlayerContainer::GetName(LWOOBJID playerID) { std::u16string PlayerContainer::GetName(LWOOBJID playerID) {
const auto& pair = mNames.find(playerID); const auto& pair = m_Names.find(playerID);
if (pair == mNames.end()) return u""; if (pair == m_Names.end()) return u"";
return pair->second; return pair->second;
} }
LWOOBJID PlayerContainer::GetId(const std::u16string& playerName) { LWOOBJID PlayerContainer::GetId(const std::u16string& playerName) {
for (const auto& pair : mNames) { for (const auto& pair : m_Names) {
if (pair.second == playerName) { if (pair.second == playerName) {
return pair.first; return pair.first;
} }

View File

@ -39,13 +39,13 @@ public:
void BroadcastMuteUpdate(LWOOBJID player, time_t time); void BroadcastMuteUpdate(LWOOBJID player, time_t time);
PlayerData* GetPlayerData(const LWOOBJID& playerID) { PlayerData* GetPlayerData(const LWOOBJID& playerID) {
auto it = mPlayers.find(playerID); auto it = m_Players.find(playerID);
if (it != mPlayers.end()) return it->second; if (it != m_Players.end()) return it->second;
return nullptr; return nullptr;
} }
PlayerData* GetPlayerData(const std::string& playerName) { PlayerData* GetPlayerData(const std::string& playerName) {
for (auto player : mPlayers) { for (auto player : m_Players) {
if (player.second) { if (player.second) {
std::string pn = player.second->playerName.c_str(); std::string pn = player.second->playerName.c_str();
if (pn == playerName) return player.second; if (pn == playerName) return player.second;
@ -67,13 +67,17 @@ public:
std::u16string GetName(LWOOBJID playerID); std::u16string GetName(LWOOBJID playerID);
LWOOBJID GetId(const std::u16string& playerName); LWOOBJID GetId(const std::u16string& playerName);
bool GetIsMuted(PlayerData* data); bool GetIsMuted(PlayerData* data);
uint32_t GetMaxNumberOfBestFriends() { return m_MaxNumberOfBestFriends; }
uint32_t GetMaxNumberOfFriends() { return m_MaxNumberOfFriends; }
std::map<LWOOBJID, PlayerData*>& GetAllPlayerData() { return mPlayers; } std::map<LWOOBJID, PlayerData*>& GetAllPlayerData() { return m_Players; }
private: private:
LWOOBJID mTeamIDCounter = 0; LWOOBJID m_TeamIDCounter = 0;
std::map<LWOOBJID, PlayerData*> mPlayers; std::map<LWOOBJID, PlayerData*> m_Players;
std::vector<TeamData*> mTeams; std::vector<TeamData*> mTeams;
std::unordered_map<LWOOBJID, std::u16string> mNames; std::unordered_map<LWOOBJID, std::u16string> m_Names;
uint32_t m_MaxNumberOfBestFriends = 5;
uint32_t m_MaxNumberOfFriends = 50;
}; };

View File

@ -1,2 +1,11 @@
# Port number # Port number
port=2005 port=2005
# If you would like to increase the maximum number of best friends a player can have on the server
# Change the value below to what you would like this to be (5 is live accurate)
max_number_of_best_friends=5
# If you would like to increase the maximum number of friends a player can have on the server
# Change the value below to what you would like this to be (50 is live accurate)
# going over 50 will be allowed in some secnarios, but proper handling will require client modding
max_number_of_friends=50

View File

@ -40,10 +40,6 @@ classic_survival_scoring=0
# If this value is 1, pets will consume imagination as they did in live. if 0 they will not consume imagination at all. # If this value is 1, pets will consume imagination as they did in live. if 0 they will not consume imagination at all.
pets_take_imagination=1 pets_take_imagination=1
# If you would like to increase the maximum number of best friends a player can have on the server
# Change the value below to what you would like this to be (5 is live accurate)
max_number_of_best_friends=5
# Disables loot drops # Disables loot drops
disable_drops=0 disable_drops=0