コード例 #1
0
EPartyReservationResult::Type APartyBeaconHost::AddPartyReservation(const FPartyReservation& ReservationRequest)
{
	EPartyReservationResult::Type Result = EPartyReservationResult::GeneralError;

	int32 IncomingPartySize = ReservationRequest.PartyMembers.Num();
	if (NumConsumedReservations + IncomingPartySize <= MaxReservations)
	{
		const int32 ExistingReservationIdx = GetExistingReservation(ReservationRequest.PartyLeader);
		if (ExistingReservationIdx == INDEX_NONE)
		{
			bool bContinue = true;
			if (ValidatePlayers.IsBound())
			{
				bContinue = ValidatePlayers.Execute(ReservationRequest.PartyMembers);
			}

			if (bContinue)
			{
				NumConsumedReservations += IncomingPartySize;

				Reservations.Add(ReservationRequest);

				// Keep track of newly added players
				for (int32 Count = 0; Count < ReservationRequest.PartyMembers.Num(); Count++)
				{
					NewPlayerAdded(ReservationRequest.PartyMembers[Count]);
				}

				ReservationChanged.ExecuteIfBound();
				if (NumConsumedReservations == MaxReservations)
				{
					ReservationsFull.ExecuteIfBound();
				}

				Result = EPartyReservationResult::ReservationAccepted;
			}
			else
			{
				Result = EPartyReservationResult::ReservationDenied_Banned;
			}
		}
		else
		{
			Result = EPartyReservationResult::ReservationDuplicate;
		}
	}
	else
	{
		Result = EPartyReservationResult::PartyLimitReached;
	}

	return Result;
}
コード例 #2
0
EPartyReservationResult::Type APartyBeaconHost::AddPartyReservation(const FPartyReservation& ReservationRequest)
{
    EPartyReservationResult::Type Result = EPartyReservationResult::GeneralError;

    if (!State || GetBeaconState() == EBeaconState::DenyRequests)
    {
        return EPartyReservationResult::ReservationDenied;
    }

    if (ReservationRequest.IsValid())
    {
        if (State->DoesReservationFit(ReservationRequest))
        {
            bool bContinue = true;
            if (ValidatePlayers.IsBound())
            {
                bContinue = ValidatePlayers.Execute(ReservationRequest.PartyMembers);
            }

            if (bContinue)
            {
                const int32 ExistingReservationIdx = State->GetExistingReservation(ReservationRequest.PartyLeader);
                if (ExistingReservationIdx != INDEX_NONE)
                {
                    TArray<FPartyReservation>& Reservations = State->GetReservations();
                    FPartyReservation& ExistingReservation = Reservations[ExistingReservationIdx];
                    if (ReservationRequest.PartyMembers.Num() == ExistingReservation.PartyMembers.Num())
                    {
                        // Verify the reservations are the same
                        int32 NumMatchingReservations = 0;
                        for (const FPlayerReservation& NewPlayerRes : ReservationRequest.PartyMembers)
                        {
                            FPlayerReservation* PlayerRes = ExistingReservation.PartyMembers.FindByPredicate(
                                                                [NewPlayerRes](const FPlayerReservation& ExistingPlayerRes)
                            {
                                return NewPlayerRes.UniqueId == ExistingPlayerRes.UniqueId;
                            });

                            if (PlayerRes)
                            {
                                NumMatchingReservations++;
                            }
                        }

                        if (NumMatchingReservations == ExistingReservation.PartyMembers.Num())
                        {
                            for (const FPlayerReservation& NewPlayerRes : ReservationRequest.PartyMembers)
                            {
                                FPlayerReservation* PlayerRes = ExistingReservation.PartyMembers.FindByPredicate(
                                                                    [NewPlayerRes](const FPlayerReservation& ExistingPlayerRes)
                                {
                                    return NewPlayerRes.UniqueId == ExistingPlayerRes.UniqueId;
                                });

                                if (PlayerRes)
                                {
                                    // Update the validation auth strings because they may have changed with a new login
                                    PlayerRes->ValidationStr = NewPlayerRes.ValidationStr;
                                }
                            }

                            SendReservationUpdates();

                            // Clean up the game entities for these duplicate players
                            DuplicateReservation.ExecuteIfBound(ReservationRequest);

                            // Add all players back into the pending join list
                            for (int32 Count = 0; Count < ReservationRequest.PartyMembers.Num(); Count++)
                            {
                                NewPlayerAdded(ReservationRequest.PartyMembers[Count]);
                            }

                            Result = EPartyReservationResult::ReservationDuplicate;
                        }
                        else
                        {
                            // Existing reservation doesn't match incoming duplicate reservation
                            Result = EPartyReservationResult::IncorrectPlayerCount;
                        }
                    }
                    else
                    {
                        // Existing reservation doesn't match incoming duplicate reservation
                        Result = EPartyReservationResult::IncorrectPlayerCount;
                    }
                }
                else
                {
                    if (State->AreTeamsAvailable(ReservationRequest))
                    {
                        if (State->AddReservation(ReservationRequest))
                        {
                            // Keep track of newly added players
                            for (const FPlayerReservation& PartyMember : ReservationRequest.PartyMembers)
                            {
                                NewPlayerAdded(PartyMember);
                            }

                            SendReservationUpdates();

                            NotifyReservationEventNextFrame(ReservationChanged);
                            if (State->IsBeaconFull())
                            {
                                NotifyReservationEventNextFrame(ReservationsFull);
                            }

                            Result = EPartyReservationResult::ReservationAccepted;
                        }
                        else
                        {
                            Result = EPartyReservationResult::IncorrectPlayerCount;
                        }
                    }
                    else
                    {
                        // New reservation doesn't fit with existing players
                        Result = EPartyReservationResult::PartyLimitReached;
                    }
                }
            }
            else
            {
                Result = EPartyReservationResult::ReservationDenied_Banned;
            }
        }
        else
        {
            Result = EPartyReservationResult::IncorrectPlayerCount;
        }
    }
    else
    {
        Result = EPartyReservationResult::IncorrectPlayerCount;
    }

    return Result;
}
コード例 #3
0
EPartyReservationResult::Type APartyBeaconHost::AddPartyReservation(const FPartyReservation& ReservationRequest)
{
	EPartyReservationResult::Type Result = EPartyReservationResult::GeneralError;

	if (!State || GetBeaconState() == EBeaconState::DenyRequests)
	{
		return EPartyReservationResult::ReservationDenied;
	}

	if (State->DoesReservationFit(ReservationRequest))
	{
		bool bContinue = true;
		if (ValidatePlayers.IsBound())
		{
			bContinue = ValidatePlayers.Execute(ReservationRequest.PartyMembers);
		}

		if (bContinue)
		{
			const int32 ExistingReservationIdx = State->GetExistingReservation(ReservationRequest.PartyLeader);
			if (ExistingReservationIdx != INDEX_NONE)
			{
				const TArray<FPartyReservation>& Reservations = State->GetReservations();
				const FPartyReservation& ExistingReservation = Reservations[ExistingReservationIdx];
				if (ReservationRequest.PartyMembers.Num() == ExistingReservation.PartyMembers.Num())
				{
					// Clean up the game entities for these duplicate players
					DuplicateReservation.ExecuteIfBound(ReservationRequest);

					// Add all players back into the pending join list
					for (int32 Count = 0; Count < ReservationRequest.PartyMembers.Num(); Count++)
					{
						NewPlayerAdded(ReservationRequest.PartyMembers[Count]);
					}

					Result = EPartyReservationResult::ReservationDuplicate;
				}
				else
				{
					Result = EPartyReservationResult::IncorrectPlayerCount;
				}
			}
			else
			{
				if (State->AreTeamsAvailable(ReservationRequest))
				{
					if (State->AddReservation(ReservationRequest))
					{
						// Keep track of newly added players
						for (const FPlayerReservation& PartyMember : ReservationRequest.PartyMembers)
						{
							NewPlayerAdded(PartyMember);
						}

						ReservationChanged.ExecuteIfBound();
						if (State->IsBeaconFull())
						{
							ReservationsFull.ExecuteIfBound();
						}

						Result = EPartyReservationResult::ReservationAccepted;
					}
					else
					{
						Result = EPartyReservationResult::IncorrectPlayerCount;
					}
				}
				else
				{
					Result = EPartyReservationResult::PartyLimitReached;
				}
			}
		}
		else
		{
			Result = EPartyReservationResult::ReservationDenied_Banned;
		}
	}
	else
	{
		Result = EPartyReservationResult::IncorrectPlayerCount;
	}

	return Result;
}
コード例 #4
0
EPartyReservationResult::Type APartyBeaconHost::UpdatePartyReservation(const FPartyReservation& ReservationUpdateRequest)
{
	EPartyReservationResult::Type Result = EPartyReservationResult::GeneralError;

	if (!State || GetBeaconState() == EBeaconState::DenyRequests)
	{
		return EPartyReservationResult::ReservationDenied;
	}

	if (ReservationUpdateRequest.IsValid())
	{
		if (!State->IsBeaconFull())
		{
			const int32 ExistingReservationIdx = State->GetExistingReservation(ReservationUpdateRequest.PartyLeader);
			if (ExistingReservationIdx != INDEX_NONE)
			{
				// Count the number of available slots for the existing reservation's team
				TArray<FPartyReservation>& Reservations = State->GetReservations();
				FPartyReservation& ExistingReservation = Reservations[ExistingReservationIdx];
				const int32 NumTeamMembers = GetNumPlayersOnTeam(ExistingReservation.TeamNum);
				const int32 NumAvailableSlotsOnTeam = FMath::Max<int32>(0, GetMaxPlayersPerTeam() - NumTeamMembers);

				// Read the list of new players and remove the ones that have existing reservation entries
				TArray<FPlayerReservation> NewPlayers;
				for (int32 PlayerIdx = 0; PlayerIdx < ReservationUpdateRequest.PartyMembers.Num(); PlayerIdx++)
				{
					const FPlayerReservation& NewPlayerRes = ReservationUpdateRequest.PartyMembers[PlayerIdx];

					FPlayerReservation* PlayerRes = ExistingReservation.PartyMembers.FindByPredicate(
						[NewPlayerRes](const FPlayerReservation& ExistingPlayerRes)
					{
						return NewPlayerRes.UniqueId == ExistingPlayerRes.UniqueId;
					});

					if (!PlayerRes)
					{
						// player reservation doesn't exist so add it as a new player
						NewPlayers.Add(NewPlayerRes);
					}
					else
					{
						// duplicate entry for this player
						UE_LOG(LogBeacon, Log, TEXT("Skipping player %s"),
							*NewPlayerRes.UniqueId.ToString());
					}
				}

				// Validate that adding the new party members to this reservation entry still fits within the team size
				if (NewPlayers.Num() <= NumAvailableSlotsOnTeam)
				{
					if (NewPlayers.Num() > 0)
					{
						// Copy new player entries into existing reservation
						for (int32 PlayerIdx = 0; PlayerIdx < NewPlayers.Num(); PlayerIdx++)
						{
							const FPlayerReservation& PlayerRes = NewPlayers[PlayerIdx];
							ExistingReservation.PartyMembers.Add(PlayerRes);
							// Keep track of newly added players
							NewPlayerAdded(PlayerRes);
						}

						// Update the reservation count before sending the response
						State->NumConsumedReservations += NewPlayers.Num();

						// Tell any UI and/or clients that there has been a change in the reservation state
						SendReservationUpdates();

						// Tell the owner that we've received a reservation so the UI can be updated
						NotifyReservationEventNextFrame(ReservationChanged);
						if (State->IsBeaconFull())
						{
							// If we've hit our limit, fire the delegate so the host can do the
							// next step in getting parties together
							NotifyReservationEventNextFrame(ReservationsFull);
						}

						Result = EPartyReservationResult::ReservationAccepted;
					}
					else
					{
						// Duplicate entries (or zero) so existing reservation not updated
						Result = EPartyReservationResult::ReservationDuplicate;
					}
				}
				else
				{
					// Send an invalid party size response
					Result = EPartyReservationResult::IncorrectPlayerCount;
				}
			}
			else
			{
				// Send a not found reservation response
				Result = EPartyReservationResult::ReservationNotFound;
			}
		}
		else
		{
			// Send a session full response
			Result = EPartyReservationResult::PartyLimitReached;
		}
	}
	else
	{
		// Invalid reservation
		Result = EPartyReservationResult::ReservationInvalid;
	}	

	return Result;
}