Use replay timer uuid to allow re-invite

Instead of allowing all previous members to bypass a replay timer
conflict, only allow if expedition uuid of the lockout matches

This fixes an exploit for expeditions that add delayed replay timers.
Members could be part of an expedition on creation and then quit to form
another expedition. They could then always be re-invited to the original
expedition even with a conflicting replay timer lockout.
This commit is contained in:
hg 2020-06-13 19:44:27 -04:00
parent fa21d835d9
commit da2a6205ed
2 changed files with 34 additions and 33 deletions

View File

@ -691,17 +691,18 @@ bool Expedition::ProcessAddConflicts(Client* leader_client, Client* add_client,
has_conflict = true;
}
// client with a replay lockout is allowed only if they were a previous member
auto member_iter = m_member_id_history.find(add_client->CharacterID());
bool was_member = (member_iter != m_member_id_history.end());
if (!was_member)
// check any extra event lockouts for this expedition that the client has and expedition doesn't
auto client_lockouts = add_client->GetExpeditionLockouts(m_expedition_name);
for (const auto& client_lockout : client_lockouts)
{
auto replay_lockout = add_client->GetExpeditionLockout(m_expedition_name, DZ_REPLAY_TIMER_NAME);
if (replay_lockout)
if (client_lockout.IsReplayTimer())
{
// client with a replay lockout is allowed only if the replay timer was from this expedition
if (client_lockout.GetExpeditionUUID() != GetUUID())
{
has_conflict = true;
auto time_remaining = replay_lockout->GetDaysHoursMinutesRemaining();
auto time_remaining = client_lockout.GetDaysHoursMinutesRemaining();
SendLeaderMessage(leader_client, Chat::Red, DZADD_REPLAY_TIMER, {
add_client->GetName(),
time_remaining.days,
@ -710,13 +711,10 @@ bool Expedition::ProcessAddConflicts(Client* leader_client, Client* add_client,
});
}
}
// check any extra event lockouts for this expedition that the client has and expedition doesn't
auto client_lockouts = add_client->GetExpeditionLockouts(m_expedition_name);
for (const auto& client_lockout : client_lockouts)
else
{
bool is_missing_lockout = (m_lockouts.find(client_lockout.GetEventName()) == m_lockouts.end());
if (!client_lockout.IsReplayTimer() && is_missing_lockout)
if (is_missing_lockout)
{
has_conflict = true;
@ -731,6 +729,7 @@ bool Expedition::ProcessAddConflicts(Client* leader_client, Client* add_client,
});
}
}
}
// swapping ignores the max player count check since it's a 1:1 change
if (!swapping && GetMemberCount() >= m_max_players)

View File

@ -227,7 +227,9 @@ ExpeditionDatabase::LoadMultipleExpeditionLockouts(
MySQLRequestResult ExpeditionDatabase::LoadMembersForCreateRequest(
const std::vector<std::string>& character_names, const std::string& expedition_name)
{
LogExpeditionsDetail("Loading multiple characters data for [{}] request", expedition_name);
LogExpeditionsDetail(
"Loading data of [{}] characters for [{}] request", character_names.size(), expedition_name
);
std::string in_character_names_query;
for (const auto& character_name : character_names)