Core/Dungeon Finder: Some cosmetic changes

- Drop pointer use in updateData struct
- Variable renaming
- Use of guid instead of group/player in rolecheck update

--HG--
branch : trunk
This commit is contained in:
Spp
2010-12-23 06:06:19 +01:00
parent cfa26522ad
commit 1f238d1700
3 changed files with 71 additions and 83 deletions
+60 -73
View File
@@ -201,31 +201,27 @@ void LFGMgr::Update(uint32 diff)
time_t currTime = time(NULL); time_t currTime = time(NULL);
// Remove obsolete role checks // Remove obsolete role checks
LfgJoinResultData joinData;
joinData.result = LFG_JOIN_FAILED;
joinData.state = LFG_ROLECHECK_MISSING_ROLE;
for (LfgRoleCheckMap::iterator it = m_RoleChecks.begin(); it != m_RoleChecks.end();) for (LfgRoleCheckMap::iterator it = m_RoleChecks.begin(); it != m_RoleChecks.end();)
{ {
LfgRoleCheckMap::iterator itRoleCheck = it++; LfgRoleCheckMap::iterator itRoleCheck = it++;
LfgRoleCheck* pRoleCheck = itRoleCheck->second; LfgRoleCheck* roleCheck = itRoleCheck->second;
if (currTime < pRoleCheck->cancelTime) if (currTime < roleCheck->cancelTime)
continue; continue;
pRoleCheck->state = LFG_ROLECHECK_MISSING_ROLE; roleCheck->state = LFG_ROLECHECK_MISSING_ROLE;
for (LfgRolesMap::const_iterator itRoles = pRoleCheck->roles.begin(); itRoles != pRoleCheck->roles.end(); ++itRoles) for (LfgRolesMap::const_iterator itRoles = roleCheck->roles.begin(); itRoles != roleCheck->roles.end(); ++itRoles)
{ {
uint64 guid = itRoles->first; uint64 guid = itRoles->first;
ClearState(guid); ClearState(guid);
if (Player* plr = sObjectMgr->GetPlayer(guid)) if (Player* plr = sObjectMgr->GetPlayer(guid))
{ {
plr->GetSession()->SendLfgRoleCheckUpdate(pRoleCheck); plr->GetSession()->SendLfgRoleCheckUpdate(roleCheck);
if (itRoles->first == pRoleCheck->leader) if (itRoles->first == roleCheck->leader)
plr->GetSession()->SendLfgJoinResult(joinData); plr->GetSession()->SendLfgJoinResult(LfgJoinResultData(LFG_JOIN_FAILED, LFG_ROLECHECK_MISSING_ROLE));
} }
} }
delete pRoleCheck; delete roleCheck;
m_RoleChecks.erase(itRoleCheck); m_RoleChecks.erase(itRoleCheck);
} }
@@ -283,16 +279,14 @@ void LFGMgr::Update(uint32 diff)
if (Player* plr = sObjectMgr->GetPlayer(itPlayers->first)) if (Player* plr = sObjectMgr->GetPlayer(itPlayers->first))
{ {
Group *grp = plr->GetGroup(); Group *grp = plr->GetGroup();
LfgDungeonSet dungeons = GetSelectedDungeons(guid);
LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, &dungeons, GetComment(guid));
if (grp) if (grp)
{ {
uint64 gguid = grp->GetGUID(); uint64 gguid = grp->GetGUID();
SetState(gguid, LFG_STATE_PROPOSAL); SetState(gguid, LFG_STATE_PROPOSAL);
plr->GetSession()->SendLfgUpdateParty(updateData); plr->GetSession()->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, GetSelectedDungeons(guid), GetComment(guid)));
} }
else else
plr->GetSession()->SendLfgUpdatePlayer(updateData); plr->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, GetSelectedDungeons(guid), GetComment(guid)));
plr->GetSession()->SendLfgUpdateProposal(m_lfgProposalId, pProposal); plr->GetSession()->SendLfgUpdateProposal(m_lfgProposalId, pProposal);
} }
} }
@@ -519,7 +513,7 @@ void LFGMgr::Join(Player* plr, uint8 roles, const LfgDungeonSet& selectedDungeon
LfgDungeonSet playerDungeons = GetSelectedDungeons(guid); LfgDungeonSet playerDungeons = GetSelectedDungeons(guid);
if (playerDungeons == dungeons) // Joining the same dungeons -- Send OK if (playerDungeons == dungeons) // Joining the same dungeons -- Send OK
{ {
LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, &dungeons, comment); LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, dungeons, comment);
plr->GetSession()->SendLfgJoinResult(joinData); // Default value of joinData.result = LFG_JOIN_OK plr->GetSession()->SendLfgJoinResult(joinData); // Default value of joinData.result = LFG_JOIN_OK
if (grp) if (grp)
{ {
@@ -641,13 +635,13 @@ void LFGMgr::Join(Player* plr, uint8 roles, const LfgDungeonSet& selectedDungeon
if (grp) // Begin rolecheck if (grp) // Begin rolecheck
{ {
// Create new rolecheck // Create new rolecheck
LfgRoleCheck* pRoleCheck = new LfgRoleCheck(); LfgRoleCheck* roleCheck = new LfgRoleCheck();
pRoleCheck->cancelTime = time_t(time(NULL)) + LFG_TIME_ROLECHECK; roleCheck->cancelTime = time_t(time(NULL)) + LFG_TIME_ROLECHECK;
pRoleCheck->state = LFG_ROLECHECK_INITIALITING; roleCheck->state = LFG_ROLECHECK_INITIALITING;
pRoleCheck->leader = plr->GetGUID(); roleCheck->leader = guid;
pRoleCheck->dungeons = dungeons; roleCheck->dungeons = dungeons;
pRoleCheck->rDungeonId = rDungeonId; roleCheck->rDungeonId = rDungeonId;
m_RoleChecks[grp->GetGUID()] = pRoleCheck; m_RoleChecks[gguid] = roleCheck;
if (rDungeonId) if (rDungeonId)
{ {
@@ -655,10 +649,9 @@ void LFGMgr::Join(Player* plr, uint8 roles, const LfgDungeonSet& selectedDungeon
dungeons.insert(rDungeonId); dungeons.insert(rDungeonId);
} }
SetRoles(guid, roles);
SetState(gguid, LFG_STATE_ROLECHECK); SetState(gguid, LFG_STATE_ROLECHECK);
// Send update to player // Send update to player
LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_JOIN_PROPOSAL, &dungeons, comment); LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_JOIN_PROPOSAL, dungeons, comment);
for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{ {
if (Player* plrg = itr->getSource()) if (Player* plrg = itr->getSource())
@@ -668,11 +661,11 @@ void LFGMgr::Join(Player* plr, uint8 roles, const LfgDungeonSet& selectedDungeon
SetState(pguid, LFG_STATE_ROLECHECK); SetState(pguid, LFG_STATE_ROLECHECK);
if (!isContinue) if (!isContinue)
SetSelectedDungeons(pguid, dungeons); SetSelectedDungeons(pguid, dungeons);
pRoleCheck->roles[pguid] = 0; roleCheck->roles[pguid] = 0;
} }
} }
// Update leader role // Update leader role
UpdateRoleCheck(grp, plr, true); UpdateRoleCheck(gguid, guid, roles);
} }
else // Add player to queue else // Add player to queue
{ {
@@ -691,7 +684,7 @@ void LFGMgr::Join(Player* plr, uint8 roles, const LfgDungeonSet& selectedDungeon
// Send update to player // Send update to player
plr->GetSession()->SendLfgJoinResult(joinData); plr->GetSession()->SendLfgJoinResult(joinData);
plr->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_JOIN_PROPOSAL, &dungeons, comment)); plr->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_JOIN_PROPOSAL, dungeons, comment));
SetState(gguid, LFG_STATE_QUEUED); SetState(gguid, LFG_STATE_QUEUED);
SetRoles(guid, roles); SetRoles(guid, roles);
if (!isContinue) if (!isContinue)
@@ -750,7 +743,7 @@ void LFGMgr::Leave(Player* plr, Group* grp /* = NULL*/)
break; break;
case LFG_STATE_ROLECHECK: case LFG_STATE_ROLECHECK:
if (grp) if (grp)
UpdateRoleCheck(grp); // No player to update role = LFG_ROLECHECK_ABORTED UpdateRoleCheck(guid); // No player to update role = LFG_ROLECHECK_ABORTED
break; break;
case LFG_STATE_PROPOSAL: case LFG_STATE_PROPOSAL:
{ {
@@ -1049,74 +1042,72 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal)
/** /**
Update the Role check info with the player selected role. Update the Role check info with the player selected role.
@param[in] grp Group to update rolecheck @param[in] grp Group guid to update rolecheck
@param[in] plr Player to update role (NULL = Rolecheck Failed) @param[in] guid Player guid (0 = rolecheck failed)
@param[in] newRoleCheck Determines if its a new rolecheck (Default false) @param[in] roles Player selected roles
*/ */
void LFGMgr::UpdateRoleCheck(Group* grp, Player* plr /* = NULL*/, bool newRoleCheck /* = false */) void LFGMgr::UpdateRoleCheck(uint64& gguid, uint64 guid /* = 0 */, uint8 roles /* = ROLE_NONE */)
{ {
if (!grp) if (!gguid)
return; return;
LfgRolesMap check_roles; LfgRolesMap check_roles;
LfgRoleCheckMap::iterator itRoleCheck = m_RoleChecks.find(grp->GetGUID()); LfgRoleCheckMap::iterator itRoleCheck = m_RoleChecks.find(gguid);
if (itRoleCheck == m_RoleChecks.end()) if (itRoleCheck == m_RoleChecks.end())
return; return;
uint64 guid = plr ? plr->GetGUID() : 0; LfgRoleCheck* roleCheck = itRoleCheck->second;
uint8 roles = guid ? GetRoles(guid) : 0; bool sendRoleChosen = roleCheck->state != LFG_ROLECHECK_DEFAULT && guid;
LfgRoleCheck* pRoleCheck = itRoleCheck->second;
if (!guid) if (!guid)
pRoleCheck->state = LFG_ROLECHECK_ABORTED; roleCheck->state = LFG_ROLECHECK_ABORTED;
else if (roles < ROLE_TANK) // Player selected no role. else if (roles < ROLE_TANK) // Player selected no role.
pRoleCheck->state = LFG_ROLECHECK_NO_ROLE; roleCheck->state = LFG_ROLECHECK_NO_ROLE;
else else
{ {
pRoleCheck->roles[guid] = roles; roleCheck->roles[guid] = roles;
// Check if all players have selected a role // Check if all players have selected a role
LfgRolesMap::const_iterator itRoles = pRoleCheck->roles.begin(); LfgRolesMap::const_iterator itRoles = roleCheck->roles.begin();
while (itRoles != pRoleCheck->roles.end() && itRoles->second != ROLE_NONE) while (itRoles != roleCheck->roles.end() && itRoles->second != ROLE_NONE)
++itRoles; ++itRoles;
if (itRoles == pRoleCheck->roles.end()) if (itRoles == roleCheck->roles.end())
{ {
// use temporal var to check roles, CheckGroupRoles modifies the roles // use temporal var to check roles, CheckGroupRoles modifies the roles
check_roles = pRoleCheck->roles; check_roles = roleCheck->roles;
pRoleCheck->state = CheckGroupRoles(check_roles) ? LFG_ROLECHECK_FINISHED : LFG_ROLECHECK_WRONG_ROLES; roleCheck->state = CheckGroupRoles(check_roles) ? LFG_ROLECHECK_FINISHED : LFG_ROLECHECK_WRONG_ROLES;
} }
} }
uint8 team = 0; uint8 team = 0;
LfgDungeonSet dungeons; LfgDungeonSet dungeons;
if (pRoleCheck->rDungeonId) if (roleCheck->rDungeonId)
dungeons.insert(pRoleCheck->rDungeonId); dungeons.insert(roleCheck->rDungeonId);
else else
dungeons = pRoleCheck->dungeons; dungeons = roleCheck->dungeons;
LfgJoinResultData joinData = LfgJoinResultData(LFG_JOIN_FAILED, pRoleCheck->state); LfgJoinResultData joinData = LfgJoinResultData(LFG_JOIN_FAILED, roleCheck->state);
for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) for (LfgRolesMap::const_iterator it = roleCheck->roles.begin(); it != roleCheck->roles.end(); ++it)
{ {
Player* plrg = itr->getSource(); uint64 pguid = it->first;
if (!plrg) Player* plrg = sObjectMgr->GetPlayer(pguid);
continue;
uint64 pguid = plrg->GetGUID();
team = uint8(plrg->GetTeam()); team = uint8(plrg->GetTeam());
WorldSession* session = plrg->GetSession(); WorldSession* session = plrg->GetSession();
if (!newRoleCheck && plr) if (!sendRoleChosen)
session->SendLfgRoleChosen(guid, roles); session->SendLfgRoleChosen(guid, roles);
session->SendLfgRoleCheckUpdate(pRoleCheck); session->SendLfgRoleCheckUpdate(roleCheck);
switch(pRoleCheck->state) switch(roleCheck->state)
{ {
case LFG_ROLECHECK_INITIALITING: case LFG_ROLECHECK_INITIALITING:
continue; continue;
case LFG_ROLECHECK_FINISHED: case LFG_ROLECHECK_FINISHED:
SetState(pguid, LFG_STATE_QUEUED); SetState(pguid, LFG_STATE_QUEUED);
session->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, &dungeons, GetComment(pguid))); session->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, dungeons, GetComment(pguid)));
break; break;
default: default:
if (grp->GetLeaderGUID() == pguid) if (roleCheck->leader == pguid)
session->SendLfgJoinResult(joinData); session->SendLfgJoinResult(joinData);
session->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_ROLECHECK_FAILED)); session->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_ROLECHECK_FAILED));
ClearState(pguid); ClearState(pguid);
@@ -1124,15 +1115,13 @@ void LFGMgr::UpdateRoleCheck(Group* grp, Player* plr /* = NULL*/, bool newRoleCh
} }
} }
uint64 gguid = grp->GetGUID(); if (roleCheck->state == LFG_ROLECHECK_FINISHED)
if (pRoleCheck->state == LFG_ROLECHECK_FINISHED)
{ {
SetState(gguid, LFG_STATE_QUEUED); SetState(gguid, LFG_STATE_QUEUED);
LfgQueueInfo* pqInfo = new LfgQueueInfo(); LfgQueueInfo* pqInfo = new LfgQueueInfo();
pqInfo->joinTime = time_t(time(NULL)); pqInfo->joinTime = time_t(time(NULL));
pqInfo->roles = pRoleCheck->roles; pqInfo->roles = roleCheck->roles;
pqInfo->dungeons = pRoleCheck->dungeons; pqInfo->dungeons = roleCheck->dungeons;
// Set queue roles needed - As we are using check_roles will not have more that 1 tank, 1 healer, 3 dps // Set queue roles needed - As we are using check_roles will not have more that 1 tank, 1 healer, 3 dps
for (LfgRolesMap::const_iterator it = check_roles.begin(); it != check_roles.end(); ++it) for (LfgRolesMap::const_iterator it = check_roles.begin(); it != check_roles.end(); ++it)
@@ -1150,11 +1139,11 @@ void LFGMgr::UpdateRoleCheck(Group* grp, Player* plr /* = NULL*/, bool newRoleCh
AddToQueue(gguid, team); AddToQueue(gguid, team);
} }
if (pRoleCheck->state != LFG_ROLECHECK_INITIALITING) if (roleCheck->state != LFG_ROLECHECK_INITIALITING)
{ {
if (pRoleCheck->state != LFG_ROLECHECK_FINISHED) if (roleCheck->state != LFG_ROLECHECK_FINISHED)
RestoreState(gguid); RestoreState(gguid);
delete pRoleCheck; delete roleCheck;
m_RoleChecks.erase(itRoleCheck); m_RoleChecks.erase(itRoleCheck);
} }
} }
@@ -1545,17 +1534,15 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t
} }
else else
{ {
LfgDungeonSet dungeons = GetSelectedDungeons(guid);
LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, &dungeons, GetComment(guid));
sLog.outDebug("LFGMgr::RemoveProposal: Readding [" UI64FMTD "] to queue.", guid); sLog.outDebug("LFGMgr::RemoveProposal: Readding [" UI64FMTD "] to queue.", guid);
SetState(guid, LFG_STATE_QUEUED); SetState(guid, LFG_STATE_QUEUED);
if (grp) if (grp)
{ {
SetState(gguid, LFG_STATE_QUEUED); SetState(gguid, LFG_STATE_QUEUED);
plr->GetSession()->SendLfgUpdateParty(updateData); plr->GetSession()->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, GetSelectedDungeons(guid), GetComment(guid)));
} }
else else
plr->GetSession()->SendLfgUpdatePlayer(updateData); plr->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, GetSelectedDungeons(guid), GetComment(guid)));
} }
} }
+4 -3
View File
@@ -157,11 +157,12 @@ struct LfgJoinResultData
// Data needed by SMSG_LFG_UPDATE_PARTY and SMSG_LFG_UPDATE_PLAYER // Data needed by SMSG_LFG_UPDATE_PARTY and SMSG_LFG_UPDATE_PLAYER
struct LfgUpdateData struct LfgUpdateData
{ {
LfgUpdateData(LfgUpdateType _type = LFG_UPDATETYPE_DEFAULT, LfgDungeonSet* _dungeons = NULL, std::string _comment = ""): LfgUpdateData(LfgUpdateType _type = LFG_UPDATETYPE_DEFAULT): updateType(_type), comment("") {}
LfgUpdateData(LfgUpdateType _type, const LfgDungeonSet& _dungeons, std::string _comment):
updateType(_type), dungeons(_dungeons), comment(_comment) {} updateType(_type), dungeons(_dungeons), comment(_comment) {}
LfgUpdateType updateType; LfgUpdateType updateType;
LfgDungeonSet* dungeons; LfgDungeonSet dungeons;
std::string comment; std::string comment;
}; };
@@ -272,7 +273,7 @@ class LFGMgr
void Leave(Player* plr, Group* grp = NULL); void Leave(Player* plr, Group* grp = NULL);
// Role Check // Role Check
void UpdateRoleCheck(Group* grp, Player* plr = NULL, bool newRoleCheck = false); void UpdateRoleCheck(uint64& gguid, uint64 guid = 0, uint8 roles = ROLE_NONE);
// Proposals // Proposals
void UpdateProposal(uint32 proposalId, const uint64& guid, bool accept); void UpdateProposal(uint32 proposalId, const uint64& guid, bool accept);
@@ -115,9 +115,9 @@ void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recv_data)
sLog.outDebug("CMSG_LFG_SET_ROLES [" UI64FMTD "] Not in group", guid); sLog.outDebug("CMSG_LFG_SET_ROLES [" UI64FMTD "] Not in group", guid);
return; return;
} }
sLog.outDebug("CMSG_LFG_SET_ROLES [" UI64FMTD "] Roles: %u", guid, roles); uint64 gguid = grp->GetGUID();
sLFGMgr->SetRoles(guid, roles); sLog.outDebug("CMSG_LFG_SET_ROLES: Group [" UI64FMTD "], Player [" UI64FMTD "], Roles: %u", gguid, guid, roles);
sLFGMgr->UpdateRoleCheck(grp, GetPlayer()); sLFGMgr->UpdateRoleCheck(gguid, guid, roles);
} }
void WorldSession::HandleLfgSetCommentOpcode(WorldPacket& recv_data) void WorldSession::HandleLfgSetCommentOpcode(WorldPacket& recv_data)
@@ -300,7 +300,7 @@ void WorldSession::SendLfgUpdatePlayer(const LfgUpdateData& updateData)
} }
uint64 guid = GetPlayer()->GetGUID(); uint64 guid = GetPlayer()->GetGUID();
uint8 size = updateData.dungeons ? uint8(updateData.dungeons->size()) : 0; uint8 size = uint8(updateData.dungeons.size());
sLog.outDebug("SMSG_LFG_UPDATE_PLAYER [" UI64FMTD "] updatetype: %u", guid, updateData.updateType); sLog.outDebug("SMSG_LFG_UPDATE_PLAYER [" UI64FMTD "] updatetype: %u", guid, updateData.updateType);
WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + size * 4 + updateData.comment.length())); WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
@@ -314,7 +314,7 @@ void WorldSession::SendLfgUpdatePlayer(const LfgUpdateData& updateData)
data << uint8(size); data << uint8(size);
if (size) if (size)
for (LfgDungeonSet::const_iterator it = updateData.dungeons->begin(); it != updateData.dungeons->end(); ++it) for (LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
data << uint32(*it); data << uint32(*it);
data << updateData.comment; data << updateData.comment;
} }
@@ -350,7 +350,7 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData)
} }
uint64 guid = GetPlayer()->GetGUID(); uint64 guid = GetPlayer()->GetGUID();
uint8 size = updateData.dungeons ? uint8(updateData.dungeons->size()) : 0; uint8 size = uint8(updateData.dungeons.size());
sLog.outDebug("SMSG_LFG_UPDATE_PARTY [" UI64FMTD "] updatetype: %u", guid, updateData.updateType); sLog.outDebug("SMSG_LFG_UPDATE_PARTY [" UI64FMTD "] updatetype: %u", guid, updateData.updateType);
WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + size * 4 + updateData.comment.length())); WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (extrainfo ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
@@ -367,7 +367,7 @@ void WorldSession::SendLfgUpdateParty(const LfgUpdateData& updateData)
data << uint8(size); data << uint8(size);
if (size) if (size)
for (LfgDungeonSet::const_iterator it = updateData.dungeons->begin(); it != updateData.dungeons->end(); ++it) for (LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
data << uint32(*it); data << uint32(*it);
data << updateData.comment; data << updateData.comment;
} }