Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions Code/client/Services/Generic/PartyService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ void PartyService::CreateInvite(const uint32_t aPlayerId) const noexcept

void PartyService::AcceptInvite(const uint32_t aInviterId) const noexcept
{
if (!m_invitations.contains(aInviterId))
const auto itor = m_invitations.find(aInviterId);
if (!m_transport.IsConnected() || m_inParty || itor == m_invitations.end() || itor->second <= m_transport.GetClock().GetCurrentTick())
return;

PartyAcceptInviteRequest request;
Expand Down Expand Up @@ -92,7 +93,7 @@ void PartyService::OnUpdate(const UpdateEvent& acEvent) noexcept
auto itor = std::begin(m_invitations);
while (itor != std::end(m_invitations))
{
if (itor->second < cCurrentTick)
if (itor->second <= cCurrentTick)
itor = m_invitations.erase(itor);
else
++itor;
Expand Down Expand Up @@ -140,12 +141,17 @@ void PartyService::OnPartyInfo(const NotifyPartyInfo& acPartyInfo) noexcept

void PartyService::OnPartyInvite(const NotifyPartyInvite& acPartyInvite) noexcept
{
const auto cCurrentTick = m_transport.GetClock().GetCurrentTick();
if (m_inParty || acPartyInvite.ExpiryTick <= cCurrentTick)
return;

spdlog::debug("[PartyService]: Got party invite from {}", acPartyInvite.InviterId);

m_invitations[acPartyInvite.InviterId] = acPartyInvite.ExpiryTick;

auto pArguments = CefListValue::Create();
pArguments->SetInt(0, acPartyInvite.InviterId);
pArguments->SetDouble(1, static_cast<double>(acPartyInvite.ExpiryTick - cCurrentTick));
m_world.GetOverlayService().GetOverlayApp()->ExecuteAsync("partyInviteReceived", pArguments);
}

Expand All @@ -157,6 +163,7 @@ void PartyService::OnPartyJoined(const NotifyPartyJoined& acPartyJoined) noexcep
m_isLeader = acPartyJoined.IsLeader;
m_leaderPlayerId = acPartyJoined.LeaderPlayerId;
m_partyMembers = acPartyJoined.PlayerIds;
m_invitations.clear();

m_world.GetDispatcher().trigger(PartyJoinedEvent(m_isLeader));
}
Expand All @@ -176,4 +183,5 @@ void PartyService::DestroyParty() noexcept
m_isLeader = false;
m_leaderPlayerId = -1;
m_partyMembers.clear();
m_invitations.clear();
}
25 changes: 24 additions & 1 deletion Code/server/Components/PartyComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,29 @@ struct PartyComponent
{
PartyComponent() {}

void ExpireInvitations(uint64_t aCurrentTick) noexcept
{
auto itor = Invitations.begin();
while (itor != Invitations.end())
{
if (itor->second <= aCurrentTick)
itor = Invitations.erase(itor);
else
++itor;
}
}

bool TryConsumeInvitation(uint32_t aInviterId, uint64_t aCurrentTick) noexcept
{
const auto itor = Invitations.find(aInviterId);
if (itor == Invitations.end())
return false;

const bool isValid = itor->second > aCurrentTick;
Invitations.erase(itor);
return isValid;
}

std::optional<uint32_t> JoinedPartyId;
TiltedPhoques::Map<Player*, uint64_t> Invitations;
TiltedPhoques::Map<uint32_t, uint64_t> Invitations;
};
46 changes: 25 additions & 21 deletions Code/server/Services/PartyService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,22 +79,9 @@ void PartyService::OnUpdate(const UpdateEvent& acEvent) noexcept
// Only expire once every 10 seconds
m_nextInvitationExpire = cCurrentTick + 10000;

auto view = m_world.view<PartyComponent>();
for (auto entity : view)
for (Player* pPlayer : m_world.GetPlayerManager())
{
auto& partyComponent = view.get<PartyComponent>(entity);
auto itor = std::begin(partyComponent.Invitations);
while (itor != std::end(partyComponent.Invitations))
{
if (itor->second < cCurrentTick)
{
itor = partyComponent.Invitations.erase(itor);
}
else
{
++itor;
}
}
pPlayer->GetParty().ExpireInvitations(cCurrentTick);
}
}

Expand Down Expand Up @@ -158,6 +145,9 @@ void PartyService::OnPartyChangeLeader(const PacketEvent<PartyChangeLeaderReques
{
if (pPlayer->GetId() == pNewLeader->GetId())
{
if (party.LeaderPlayerId != pNewLeader->GetId())
RevokeInvitations(party.LeaderPlayerId);

party.LeaderPlayerId = pPlayer->GetId();
spdlog::debug("[PartyService]: Changed party leader to {}, updating party members.", party.LeaderPlayerId);
BroadcastPartyInfo(*inviterPartyComponent.JoinedPartyId);
Expand Down Expand Up @@ -271,7 +261,7 @@ void PartyService::OnPartyInvite(const PacketEvent<PartyInviteRequest>& acPacket

// Expire in 60 seconds
const auto cExpiryTick = GameServer::Get()->GetTick() + 60000;
inviteePartyComponent.Invitations[pInviter] = cExpiryTick;
inviteePartyComponent.Invitations[pInviter->GetId()] = cExpiryTick;

NotifyPartyInvite notification;
notification.InviterId = pInviter->GetId();
Expand All @@ -297,11 +287,6 @@ void PartyService::OnPartyAcceptInvite(const PacketEvent<PartyAcceptInviteReques
auto& inviterPartyComponent = pInviter->GetParty();
auto& selfPartyComponent = pSelf->GetParty();

// Check if we have this invitation so people don't invite themselves
if (selfPartyComponent.Invitations.count(pInviter) == 0)
return;

spdlog::debug("[PartyService]: Invite found, processing.");
if (!inviterPartyComponent.JoinedPartyId) // Ensure inviter is in a party otherwise break
{
spdlog::debug("[PartyService]: Inviter not in party. Cancelling.");
Expand All @@ -324,6 +309,13 @@ void PartyService::OnPartyAcceptInvite(const PacketEvent<PartyAcceptInviteReques
return;
}

// Acceptance must check the deadline even between periodic cleanup passes.
if (!selfPartyComponent.TryConsumeInvitation(pInviter->GetId(), GameServer::Get()->GetTick()))
{
spdlog::debug("[PartyService]: Invitation missing or expired, cancelling.");
return;
}

party.Members.push_back(pSelf);
selfPartyComponent.JoinedPartyId = partyId;

Expand All @@ -347,6 +339,8 @@ void PartyService::OnPlayerLeave(const PlayerLeaveEvent& acEvent) noexcept
void PartyService::RemovePlayerFromParty(Player* apPlayer) noexcept
{
auto* pPartyComponent = &apPlayer->GetParty();
pPartyComponent->Invitations.clear();
RevokeInvitations(apPlayer->GetId());
spdlog::debug("[PartyService]: Removing player from party.");

if (pPartyComponent->JoinedPartyId)
Expand Down Expand Up @@ -381,6 +375,14 @@ void PartyService::RemovePlayerFromParty(Player* apPlayer) noexcept
}
}

void PartyService::RevokeInvitations(uint32_t aInviterId) noexcept
{
for (Player* pPlayer : m_world.GetPlayerManager())
{
pPlayer->GetParty().Invitations.erase(aInviterId);
}
}

void PartyService::BroadcastPlayerList(Player* apPlayer) const noexcept
{
auto pIgnoredPlayer = apPlayer;
Expand Down Expand Up @@ -431,6 +433,8 @@ void PartyService::BroadcastPartyInfo(uint32_t aPartyId) const noexcept

void PartyService::SendPartyJoinedEvent(Party& aParty, Player* aPlayer) noexcept
{
aPlayer->GetParty().Invitations.clear();

NotifyPartyJoined joinedMessage;
joinedMessage.LeaderPlayerId = aParty.LeaderPlayerId;
joinedMessage.IsLeader = aParty.LeaderPlayerId == aPlayer->GetId();
Expand Down
1 change: 1 addition & 0 deletions Code/server/Services/PartyService.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct PartyService
void OnPartyChangeLeader(const PacketEvent<PartyChangeLeaderRequest>& acPacket) noexcept;
void OnPartyKick(const PacketEvent<PartyKickRequest>& acPacket) noexcept;
void RemovePlayerFromParty(Player* apPlayer) noexcept;
void RevokeInvitations(uint32_t aInviterId) noexcept;

void BroadcastPlayerList(Player* apPlayer = nullptr) const noexcept;
void BroadcastPartyInfo(uint32_t aPartyId) const noexcept;
Expand Down
Loading
Loading