Process character lockout results in db methods

This commit is contained in:
hg 2020-06-10 22:29:52 -04:00
parent f287e9318e
commit 59d10a9db3
4 changed files with 55 additions and 38 deletions

View File

@ -9726,16 +9726,10 @@ bool Client::HasExpeditionLockout(
void Client::LoadAllExpeditionLockouts()
{
auto results = ExpeditionDatabase::LoadCharacterLockouts(CharacterID());
if (results.Success())
auto lockouts = ExpeditionDatabase::LoadCharacterLockouts(CharacterID());
for (const auto& lockout : lockouts)
{
for (auto row = results.begin(); row != results.end(); ++row)
{
auto expire_time = strtoull(row[0], nullptr, 10);
auto original_duration = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
ExpeditionLockoutTimer lockout{ row[2], row[3], expire_time, original_duration };
AddExpeditionLockout(lockout, false, false);
}
AddExpeditionLockout(lockout, false, false);
}
SendExpeditionLockoutTimers();
}

View File

@ -94,33 +94,51 @@ MySQLRequestResult ExpeditionDatabase::LoadAllExpeditions()
return database.QueryDatabase(query);
}
MySQLRequestResult ExpeditionDatabase::LoadCharacterLockouts(uint32_t character_id)
std::vector<ExpeditionLockoutTimer> ExpeditionDatabase::LoadCharacterLockouts(uint32_t character_id)
{
LogExpeditionsDetail("Loading character [{}] lockouts", character_id);
std::vector<ExpeditionLockoutTimer> lockouts;
auto query = fmt::format(SQL(
SELECT
UNIX_TIMESTAMP(expire_time),
duration,
expedition_name,
event_name
event_name,
UNIX_TIMESTAMP(expire_time),
duration
FROM expedition_character_lockouts
WHERE character_id = {} AND is_pending = FALSE AND expire_time > NOW();
), character_id);
return database.QueryDatabase(query);
auto results = database.QueryDatabase(query);
if (results.Success())
{
for (auto row = results.begin(); row != results.end(); ++row)
{
lockouts.emplace_back(ExpeditionLockoutTimer{
row[0], // expedition_name
row[1], // event_name
strtoull(row[2], nullptr, 10), // expire_time
static_cast<uint32_t>(strtoul(row[3], nullptr, 10)) // duration
});
}
}
return lockouts;
}
MySQLRequestResult ExpeditionDatabase::LoadCharacterLockouts(
std::vector<ExpeditionLockoutTimer> ExpeditionDatabase::LoadCharacterLockouts(
uint32_t character_id, const std::string& expedition_name)
{
LogExpeditionsDetail("Loading character [{}] lockouts for [{}]", character_id, expedition_name);
std::vector<ExpeditionLockoutTimer> lockouts;
auto query = fmt::format(SQL(
SELECT
event_name,
UNIX_TIMESTAMP(expire_time),
duration,
event_name
duration
FROM expedition_character_lockouts
WHERE
character_id = {}
@ -129,7 +147,21 @@ MySQLRequestResult ExpeditionDatabase::LoadCharacterLockouts(
AND expedition_name = '{}';
), character_id, expedition_name);
return database.QueryDatabase(query);
auto results = database.QueryDatabase(query);
if (results.Success())
{
for (auto row = results.begin(); row != results.end(); ++row)
{
lockouts.emplace_back(ExpeditionLockoutTimer{
expedition_name,
row[0], // event_name
strtoull(row[1], nullptr, 10), // expire_time
static_cast<uint32_t>(strtoul(row[2], nullptr, 10)) // duration
});
}
}
return lockouts;
}
std::unordered_map<uint32_t, std::unordered_map<std::string, ExpeditionLockoutTimer>>

View File

@ -41,10 +41,10 @@ namespace ExpeditionDatabase
std::string LoadExpeditionsSelectQuery();
MySQLRequestResult LoadExpedition(uint32_t expedition_id);
MySQLRequestResult LoadAllExpeditions();
MySQLRequestResult LoadCharacterLockouts(uint32_t character_id);
MySQLRequestResult LoadCharacterLockouts(uint32_t character_id, const std::string& expedition_name);
MySQLRequestResult LoadMembersForCreateRequest(
const std::vector<std::string>& character_names, const std::string& expedition_name);
std::vector<ExpeditionLockoutTimer> LoadCharacterLockouts(uint32_t character_id);
std::vector<ExpeditionLockoutTimer> LoadCharacterLockouts(uint32_t character_id, const std::string& expedition_name);
std::unordered_map<uint32_t, std::unordered_map<std::string, ExpeditionLockoutTimer>>
LoadMultipleExpeditionLockouts(const std::vector<uint32_t>& expedition_ids);
void DeleteAllCharacterLockouts(uint32_t character_id);

View File

@ -116,7 +116,6 @@ bool ExpeditionRequest::CanGroupRequest(Group* group)
m_leader_name = m_leader ? m_leader->GetName() : GetGroupLeaderName(group->GetID()); // group->GetLeaderName();
m_leader_id = m_leader ? m_leader->CharacterID() : database.GetCharacterID(m_leader_name.c_str());
uint32_t count = 0;
std::vector<std::string> member_names;
for (int i = 0; i < MAX_GROUP_MEMBERS; ++i)
{
@ -163,20 +162,13 @@ bool ExpeditionRequest::ValidateMembers(const std::vector<std::string>& member_n
bool ExpeditionRequest::LoadLeaderLockouts()
{
// leader's lockouts are used to check member conflicts and later stored in expedition
auto results = ExpeditionDatabase::LoadCharacterLockouts(m_leader_id, m_expedition_name);
if (!results.Success())
{
LogExpeditions("Failed to load leader id [{}] lockouts ([{}])", m_leader_id, m_leader_name);
return false;
}
auto lockouts = ExpeditionDatabase::LoadCharacterLockouts(m_leader_id, m_expedition_name);
auto leeway_seconds = static_cast<uint32_t>(RuleI(Expedition, RequestExpiredLockoutLeewaySeconds));
for (auto row = results.begin(); row != results.end(); ++row)
for (auto& lockout : lockouts)
{
uint64_t expire_time = strtoull(row[0], nullptr, 10);
uint32_t duration = strtoul(row[1], nullptr, 10);
ExpeditionLockoutTimer lockout{m_expedition_name, row[2], expire_time, duration, true};
lockout.SetInherited(true);
// client window hides timers with less than 60s remaining, optionally count them as expired
if (lockout.GetSecondsRemaining() <= leeway_seconds)
@ -188,10 +180,10 @@ bool ExpeditionRequest::LoadLeaderLockouts()
}
else
{
m_lockouts.emplace(row[2], lockout);
m_lockouts.emplace(lockout.GetEventName(), lockout);
// on live if leader has a replay lockout it never bothers checking for event conflicts
if (m_check_event_lockouts && m_has_replay_timer && strcmp(row[2], DZ_REPLAY_TIMER_NAME) == 0)
if (m_check_event_lockouts && m_has_replay_timer && lockout.IsReplayTimer())
{
m_check_event_lockouts = false;
}
@ -256,10 +248,9 @@ bool ExpeditionRequest::CheckMembersForConflicts(const std::vector<std::string>&
if (row[3] && row[4] && row[5])
{
auto expire_time = strtoull(row[3], nullptr, 10);
auto original_duration = strtoul(row[4], nullptr, 10);
std::string event_name(row[5]);
auto duration = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
ExpeditionLockoutTimer lockout(m_expedition_name, event_name, expire_time, original_duration);
ExpeditionLockoutTimer lockout{m_expedition_name, row[5], expire_time, duration};
// client window hides timers with less than 60s remaining, optionally count them as expired
if (lockout.GetSecondsRemaining() <= leeway_seconds)
@ -272,14 +263,14 @@ bool ExpeditionRequest::CheckMembersForConflicts(const std::vector<std::string>&
else
{
// replay timer conflict messages always show up before event conflicts
if (/*m_has_replay_timer && */event_name == DZ_REPLAY_TIMER_NAME)
if (/*m_has_replay_timer && */lockout.IsReplayTimer())
{
has_conflicts = true;
SendLeaderMemberReplayLockout(character_name, lockout, is_solo);
}
else if (m_check_event_lockouts && character_id != m_leader_id)
{
if (m_lockouts.find(event_name) == m_lockouts.end())
if (m_lockouts.find(lockout.GetEventName()) == m_lockouts.end())
{
// leader doesn't have this lockout. queue instead of messaging
// now so message comes after any replay lockout messages