bool UPartyBeaconState::RemovePlayer(const FUniqueNetIdRepl& PlayerId)
{
	bool bWasRemoved = false;

	for (int32 ResIdx = 0; ResIdx < Reservations.Num() && !bWasRemoved; ResIdx++)
	{
		FPartyReservation& Reservation = Reservations[ResIdx];

		if (Reservation.PartyLeader == PlayerId)
		{
			UE_LOG(LogBeacon, Display, TEXT("Party leader has left the party"), *PlayerId.ToString());

			// Maintain existing members of party reservation that lost its leader
			for (int32 PlayerIdx = 0; PlayerIdx < Reservation.PartyMembers.Num(); PlayerIdx++)
			{
				FPlayerReservation& PlayerEntry = Reservation.PartyMembers[PlayerIdx];
				if (PlayerEntry.UniqueId != Reservation.PartyLeader && PlayerEntry.UniqueId.IsValid())
				{
					// Promote to party leader (for now)
					Reservation.PartyLeader = PlayerEntry.UniqueId;
					break;
				}
			}
		}

		// find the player in an existing reservation slot
		for (int32 PlayerIdx = 0; PlayerIdx < Reservation.PartyMembers.Num(); PlayerIdx++)
		{
			FPlayerReservation& PlayerEntry = Reservation.PartyMembers[PlayerIdx];
			if (PlayerEntry.UniqueId == PlayerId)
			{
				// player removed
				Reservation.PartyMembers.RemoveAtSwap(PlayerIdx--);
				bWasRemoved = true;

				// free up a consumed entry
				NumConsumedReservations--;
			}
		}

		// remove the entire party reservation slot if no more party members
		if (Reservation.PartyMembers.Num() == 0)
		{
			Reservations.RemoveAtSwap(ResIdx--);
		}
	}

	if (bWasRemoved)
	{
		// Reshuffle existing teams so that beacon can accommodate biggest open slots
		BestFitTeamAssignmentJiggle();
	}

	return bWasRemoved;
}
void UPartyBeaconState::RegisterAuthTicket(const FUniqueNetIdRepl& InPartyMemberId, const FString& InAuthTicket)
{
	if (InPartyMemberId.IsValid() && !InAuthTicket.IsEmpty())
	{
		bool bFoundReservation = false;

		for (int32 ResIdx = 0; ResIdx < Reservations.Num() && !bFoundReservation; ResIdx++)
		{
			FPartyReservation& ReservationEntry = Reservations[ResIdx];

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

			if (PlayerRes)
			{
				UE_LOG(LogBeacon, Display, TEXT("Updating auth ticket for member %s."), *InPartyMemberId.ToString());
				if (!PlayerRes->ValidationStr.IsEmpty() && PlayerRes->ValidationStr != InAuthTicket)
				{
					UE_LOG(LogBeacon, Display, TEXT("Auth ticket changing for member %s."), *InPartyMemberId.ToString());
				}

				PlayerRes->ValidationStr = InAuthTicket;
				bFoundReservation = true;
				break;
			}
		}

		if (!bFoundReservation)
		{
			UE_LOG(LogBeacon, Warning, TEXT("Found no reservation for player %s, while registering auth ticket."), *InPartyMemberId.ToString());
		}
	}
}
void TestUniqueIdRepl(UWorld* InWorld)
{
#if !UE_BUILD_SHIPPING
	bool bSuccess = true;

	TSharedPtr<const FUniqueNetId> UserId = UOnlineEngineInterface::Get()->GetUniquePlayerId(InWorld, 0);

	FUniqueNetIdRepl EmptyIdIn;
	if (EmptyIdIn.IsValid())
	{
		UE_LOG(LogNet, Warning, TEXT("EmptyId is valid."), *EmptyIdIn->ToString());
		bSuccess = false;
	}

	FUniqueNetIdRepl ValidIdIn(UserId);
	if (!ValidIdIn.IsValid() || UserId != ValidIdIn.GetUniqueNetId() || *UserId != *ValidIdIn)
	{
		UE_LOG(LogNet, Warning, TEXT("UserId input %s != UserId output %s"), *UserId->ToString(), *ValidIdIn->ToString());
		bSuccess = false;
	}

	if (bSuccess)
	{
		TArray<uint8> Buffer;
		for (int32 i = 0; i < 2; i++)
		{
			Buffer.Empty();
			FMemoryWriter TestWriteUniqueId(Buffer);

			if (i == 0)
			{
				// Normal serialize
				TestWriteUniqueId << EmptyIdIn;
				TestWriteUniqueId << ValidIdIn;
			}
			else
			{
				// Net serialize
				bool bOutSuccess = false;
				EmptyIdIn.NetSerialize(TestWriteUniqueId, NULL, bOutSuccess);
				ValidIdIn.NetSerialize(TestWriteUniqueId, NULL, bOutSuccess);
			}

			FMemoryReader TestReadUniqueId(Buffer);

			FUniqueNetIdRepl EmptyIdOut;
			TestReadUniqueId << EmptyIdOut;
			if (EmptyIdOut.GetUniqueNetId().IsValid())
			{
				UE_LOG(LogNet, Warning, TEXT("EmptyId %s should have been invalid"), *EmptyIdOut->ToString());
				bSuccess = false;
			}

			FUniqueNetIdRepl ValidIdOut;
			TestReadUniqueId << ValidIdOut;
			if (*UserId != *ValidIdOut.GetUniqueNetId())
			{
				UE_LOG(LogNet, Warning, TEXT("UserId input %s != UserId output %s"), *ValidIdIn->ToString(), *ValidIdOut->ToString());
				bSuccess = false;
			}
		}
	}

	if (bSuccess)
	{
		FString OutString;
		TSharedRef<FJsonValue> JsonValue = ValidIdIn.ToJson();
		bSuccess = JsonValue->TryGetString(OutString);
		if (bSuccess)
		{
			FUniqueNetIdRepl NewIdOut;
			NewIdOut.FromJson(OutString);
			bSuccess = NewIdOut.IsValid();
		}
	}


	if (!bSuccess)
	{
		UE_LOG(LogNet, Warning, TEXT("TestUniqueIdRepl test failure!"));
	}
#endif
}
void APartyBeaconHost::RemovePartyReservation(const FUniqueNetIdRepl& PartyLeader)
{
	const int32 ExistingReservationIdx = GetExistingReservation(PartyLeader);
	if (ExistingReservationIdx != INDEX_NONE)
	{
		NumConsumedReservations -= Reservations[ExistingReservationIdx].PartyMembers.Num();
		Reservations.RemoveAtSwap(ExistingReservationIdx);

		CancelationReceived.ExecuteIfBound(*PartyLeader);
		ReservationChanged.ExecuteIfBound();
	}
	else
	{
		UE_LOG(LogBeacon, Warning, TEXT("Failed to find reservation to cancel for leader %s:"), *PartyLeader->ToString());
	}
}
void TestUniqueIdRepl(UWorld* InWorld)
{
	bool bSuccess = true;

	IOnlineIdentityPtr IdentityPtr = Online::GetIdentityInterface(InWorld);
	if (IdentityPtr.IsValid())
	{
		TSharedPtr<FUniqueNetId> UserId = IdentityPtr->GetUniquePlayerId(0);

		FUniqueNetIdRepl EmptyIdIn;
		if (EmptyIdIn.IsValid())
		{
			UE_LOG(LogNet, Warning, TEXT("EmptyId is valid."), *EmptyIdIn->ToString());
			bSuccess = false;
		}

		FUniqueNetIdRepl ValidIdIn(UserId);
		if (!ValidIdIn.IsValid() || UserId != ValidIdIn.GetUniqueNetId())
		{
			UE_LOG(LogNet, Warning, TEXT("UserId input %s != UserId output %s"), *UserId->ToString(), *ValidIdIn->ToString());
			bSuccess = false;
		}

		if (bSuccess)
		{
			TArray<uint8> Buffer;
			for (int32 i=0; i<2; i++)
			{
				Buffer.Empty();
				FMemoryWriter TestWriteUniqueId(Buffer);

				if (i == 0)
				{
					// Normal serialize
					TestWriteUniqueId << EmptyIdIn;
					TestWriteUniqueId << ValidIdIn;
				}
				else
				{
					// Net serialize
					bool bSuccess = false;
					EmptyIdIn.NetSerialize(TestWriteUniqueId, NULL, bSuccess);
					ValidIdIn.NetSerialize(TestWriteUniqueId, NULL, bSuccess);
				}

				FMemoryReader TestReadUniqueId(Buffer);

				FUniqueNetIdRepl EmptyIdOut;
				TestReadUniqueId << EmptyIdOut;
				if (EmptyIdOut.GetUniqueNetId().IsValid())
				{
					UE_LOG(LogNet, Warning, TEXT("EmptyId %s should have been invalid"), *EmptyIdOut->ToString());
					bSuccess = false;
				}

				FUniqueNetIdRepl ValidIdOut;
				TestReadUniqueId << ValidIdOut;
				if (*UserId != *ValidIdOut.GetUniqueNetId())
				{
					UE_LOG(LogNet, Warning, TEXT("UserId input %s != UserId output %s"), *ValidIdIn->ToString(), *ValidIdOut->ToString());
					bSuccess = false;
				}
			}
		}
	}

	if (!bSuccess)
	{
		UE_LOG(LogNet, Warning, TEXT("TestUniqueIdRepl test failure!"));
	}
}
Example #6
0
void APartyBeaconHost::RemovePartyReservation(const FUniqueNetIdRepl& PartyLeader)
{
	if (State && State->RemoveReservation(PartyLeader))
	{
		CancelationReceived.ExecuteIfBound(*PartyLeader);
		ReservationChanged.ExecuteIfBound();
	}
	else
	{
		UE_LOG(LogBeacon, Warning, TEXT("Failed to find reservation to cancel for leader %s:"), *PartyLeader->ToString());
	}
}
Example #7
0
void APartyBeaconHost::RemovePartyReservation(const FUniqueNetIdRepl& PartyLeader)
{
    if (State && State->RemoveReservation(PartyLeader))
    {
        CancelationReceived.ExecuteIfBound(*PartyLeader);

        SendReservationUpdates();
        NotifyReservationEventNextFrame(ReservationChanged);
    }
    else
    {
        UE_LOG(LogBeacon, Warning, TEXT("Failed to find reservation to cancel for leader %s:"), PartyLeader.IsValid() ? *PartyLeader->ToString() : TEXT("INVALID") );
    }
}
void APartyBeaconHost::DumpReservations() const
{
	FUniqueNetIdRepl NetId;
	FPlayerReservation PlayerRes;

	UE_LOG(LogBeacon, Display, TEXT("Debug info for Beacon: %s"), *BeaconName);
	UE_LOG(LogBeacon, Display, TEXT("Session that reservations are for: %s"), *SessionName.ToString());
	UE_LOG(LogBeacon, Display, TEXT("Number of teams: %d"), NumTeams);
	UE_LOG(LogBeacon, Display, TEXT("Number players per team: %d"), NumPlayersPerTeam);
	UE_LOG(LogBeacon, Display, TEXT("Number total reservations: %d"), MaxReservations);
	UE_LOG(LogBeacon, Display, TEXT("Number consumed reservations: %d"), NumConsumedReservations);
	UE_LOG(LogBeacon, Display, TEXT("Number of party reservations: %d"), Reservations.Num());

	// Log each party that has a reservation
	for (int32 PartyIndex = 0; PartyIndex < Reservations.Num(); PartyIndex++)
	{
		NetId = Reservations[PartyIndex].PartyLeader;
		UE_LOG(LogBeacon, Display, TEXT("  Party leader: %s"), *NetId->ToString());
		UE_LOG(LogBeacon, Display, TEXT("  Party team: %d"), Reservations[PartyIndex].TeamNum);
		UE_LOG(LogBeacon, Display, TEXT("  Party size: %d"), Reservations[PartyIndex].PartyMembers.Num());
		// Log each member of the party
		for (int32 MemberIndex = 0; MemberIndex < Reservations[PartyIndex].PartyMembers.Num(); MemberIndex++)
		{
			PlayerRes = Reservations[PartyIndex].PartyMembers[MemberIndex];
			UE_LOG(LogBeacon, Display, TEXT("  Party member: %s"), *PlayerRes.UniqueId->ToString());
		}
	}
	UE_LOG(LogBeacon, Display, TEXT(""));
}
void UPartyBeaconState::UpdatePartyLeader(const FUniqueNetIdRepl& InPartyMemberId, const FUniqueNetIdRepl& NewPartyLeaderId)
{
	if (InPartyMemberId.IsValid() && NewPartyLeaderId.IsValid())
	{
		bool bFoundReservation = false;

		for (int32 ResIdx = 0; ResIdx < Reservations.Num() && !bFoundReservation; ResIdx++)
		{
			FPartyReservation& ReservationEntry = Reservations[ResIdx];

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

			if (PlayerRes)
			{
				UE_LOG(LogBeacon, Display, TEXT("Updating party leader to %s from member %s."), *NewPartyLeaderId.ToString(), *InPartyMemberId.ToString());
				ReservationEntry.PartyLeader = NewPartyLeaderId;
				bFoundReservation = true;
				break;
			}
		}

		if (!bFoundReservation)
		{
			UE_LOG(LogBeacon, Warning, TEXT("Found no reservation for player %s, while updating party leader."), *InPartyMemberId.ToString());
		}
	}
}
bool UPartyBeaconState::GetPartyLeader(const FUniqueNetIdRepl& InPartyMemberId, FUniqueNetIdRepl& OutPartyLeaderId) const
{
	bool bFoundReservation = false;

	if (InPartyMemberId.IsValid())
	{
		for (int32 ResIdx = 0; ResIdx < Reservations.Num() && !bFoundReservation; ResIdx++)
		{
			const FPartyReservation& ReservationEntry = Reservations[ResIdx];

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

			if (PlayerRes)
			{
				UE_LOG(LogBeacon, Display, TEXT("Found party leader for member %s."), *InPartyMemberId.ToString());
				OutPartyLeaderId = ReservationEntry.PartyLeader;
				bFoundReservation = true;
				break;
			}
		}

		if (!bFoundReservation)
		{
			UE_LOG(LogBeacon, Warning, TEXT("Found no reservation for player %s, while looking for party leader."), *InPartyMemberId.ToString());
		}
	}

	return bFoundReservation;
}
void APartyBeaconHost::ProcessCancelReservationRequest(APartyBeaconClient* Client, const FUniqueNetIdRepl& PartyLeader)
{
	UE_LOG(LogBeacon, Verbose, TEXT("ProcessCancelReservationRequest %s PartyLeader: %s from (%s)"), 
		Client ? *Client->GetName() : TEXT("NULL"), 
		PartyLeader.IsValid() ? *PartyLeader->ToString() : TEXT("INVALID"),
		Client ? *Client->GetNetConnection()->LowLevelDescribe() : TEXT("NULL"));

	if (Client)
	{
		RemovePartyReservation(PartyLeader);
	}
}