bool FOnlineLeaderboardsNull::WriteLeaderboards(const FName& SessionName, const FUniqueNetId& Player, FOnlineLeaderboardWrite& WriteObject)
{
    bool bWasSuccessful = true;

    int32 NumLeaderboards = WriteObject.LeaderboardNames.Num();
    for (int32 LeaderboardIdx = 0; LeaderboardIdx < NumLeaderboards; ++LeaderboardIdx)
    {
        // Will create or retrieve the leaderboards, triggering async calls as appropriate
        FLeaderboardNull* Leaderboard = FindOrCreateLeaderboard(WriteObject.LeaderboardNames[LeaderboardIdx], WriteObject.SortMethod, WriteObject.DisplayFormat);
        check(Leaderboard);

        FOnlineStatsRow* PlayerRow = Leaderboard->FindOrCreatePlayerRecord(Player);
        check(PlayerRow);

        for (FStatPropertyArray::TConstIterator It(WriteObject.Properties); It; ++It)
        {
            const FName& StatName = It.Key();
            const FVariantData& Stat = It.Value();
            FVariantData* ExistingStat = PlayerRow->Columns.Find(StatName);
            if (ExistingStat)
            {
                //@TODO: Add support for other types (variant doesn't define an ordering operator)
                bool bJustAssign = true;

                if ((ExistingStat->GetType() == Stat.GetType()) && (Stat.GetType() == EOnlineKeyValuePairDataType::Int32))
                {
                    int32 NewValue;
                    int32 OldValue;
                    Stat.GetValue(NewValue);
                    ExistingStat->GetValue(OldValue);

                    switch (WriteObject.SortMethod)
                    {
                    case ELeaderboardSort::Ascending:
                        bJustAssign = NewValue < OldValue;
                        break;
                    case ELeaderboardSort::Descending:
                        bJustAssign = NewValue > OldValue;
                        break;
                    default:
                        bJustAssign = true;
                    }
                }

                if (bJustAssign)
                {
                    *ExistingStat = Stat;
                }
            }
            else
            {
                PlayerRow->Columns.Add(StatName, Stat);
            }
        }
    }

    // Write has no delegates as of now
    return bWasSuccessful;
}
/**
 * Increments a stat of type int32 by the value specified. Does nothing
 * if the stat is not of the right type.
 *
 * @param StatName the stat to increment
 * @param IncBy the value to increment by
 */
void FOnlineStats::IncrementIntStat(const FName& StatName, int32 IncBy)
{
	FVariantData* Stat = FindStatByName(StatName);
	if (Stat != NULL && Stat->GetType() == EOnlineKeyValuePairDataType::Int32)
	{
		// Set the value
		Stat->Increment<int32, EOnlineKeyValuePairDataType::Int32>(IncBy);
	}
	else
	{
		FVariantData NewValue(IncBy);
		Properties.Add(StatName, NewValue);
	}
}
/**
 * Decrements a stat of type float by the value specified. Does nothing
 * if the stat is not of the right type.
 *
 * @param StatName the stat to decrement
 * @param DecBy the value to decrement by
 */
void FOnlineStats::DecrementFloatStat(const FName& StatName, float DecBy)
{
	FVariantData* Stat = FindStatByName(StatName);
	if (Stat != NULL && Stat->GetType() == EOnlineKeyValuePairDataType::Float)
	{
		// Set the value
		Stat->Decrement<float, EOnlineKeyValuePairDataType::Float>(DecBy);
	}
	else
	{
		FVariantData NewValue(-DecBy);
		Properties.Add(StatName, NewValue);
	}
}
void AMessageSubsystemTestActor::LoginCallback(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& Error)
{
	UE_LOG(LogTemp, Log, TEXT("%s"), (_identity->GetLoginStatus(0) == ELoginStatus::LoggedIn) ? TEXT("true") : TEXT("false"));

	TArray<TSharedRef<const FUniqueNetId>> ids;
	ids.Add(UserId.AsShared());

	FOnlineMessagePayload payload = FOnlineMessagePayload();
	FVariantData data = FVariantData();
	data.SetValue(true);
	payload.SetAttribute("test", data);

	_message->SendMessage(0, ids, TEXT("testMessage"), payload);
}
/**
 * Sets a stat of type float to the value specified. Does nothing
 * if the stat is not of the right type.
 *
 * @param StatName the stat to change the value of
 * @param Value the new value to assign to the stat
 */
void FOnlineStats::SetFloatStat(const FName& StatName, float Value)
{
	FVariantData* Stat = FindStatByName(StatName);
	if (Stat != NULL)
	{
		if (Stat->GetType() == EOnlineKeyValuePairDataType::Float)
		{
			// Set the value
			Stat->SetValue(Value);
		}
	}
	else
	{
		FVariantData NewValue(Value);
		Properties.Add(StatName, NewValue);
	}
}
Exemplo n.º 6
0
	void AddPresenceAttributes(const FUniqueNetId& UserId, TArray<FAnalyticsEventAttribute>& Attributes) const
	{
		IOnlinePresencePtr OnlinePresence = Online::GetPresenceInterface(TEXT("MCP"));
		if (OnlinePresence.IsValid())
		{
			TSharedPtr<FOnlineUserPresence> Presence;
			OnlinePresence->GetCachedPresence(UserId, Presence);
			if (Presence.IsValid())
			{
				FVariantData* ClientIdData = Presence->Status.Properties.Find(DefaultClientIdKey);
				if (ClientIdData != nullptr)
				{
					Attributes.Add(FAnalyticsEventAttribute(TEXT("ClientId"), ClientIdData->ToString()));
				}
				Attributes.Add(FAnalyticsEventAttribute(TEXT("Status"), Presence->Status.StatusStr));
			}
		}
	}
/** Simple test cases for key value pair code */
void TestKeyValuePairs()
{
	bool bSuccess = true;

	TArray<uint8> TestData;
	TestData.Add((uint8)200);

 	typedef FOnlineKeyValuePairs<FName, FVariantData> TestDataType;
	TestDataType TestKeyValuePairs;
 
 	// Test Templates
 	TestKeyValuePairs.Add(TEXT("INTValue"), FVariantData(512)); 
 	TestKeyValuePairs.Add(TEXT("FLOATValue"), FVariantData(512.0f)); 
 	TestKeyValuePairs.Add(TEXT("QWORDValue"), FVariantData((uint64)512)); 
 	TestKeyValuePairs.Add(TEXT("DOUBLEValue"), FVariantData(512000.0)); 
 	TestKeyValuePairs.Add(TEXT("STRINGValue"), FVariantData(TEXT("This Is A Test!"))); 
 	TestKeyValuePairs.Add(TEXT("BLOBValue"), FVariantData(TestData)); 

	UE_LOG(LogOnline, Display, TEXT("ConstIterator"));
	for (TestDataType::TConstIterator It(TestKeyValuePairs); It; ++It)
	{
		UE_LOG(LogOnline, Display, TEXT("%s = %s"), *It.Key().ToString(), *It.Value().ToString());
	}

	UE_LOG(LogOnline, Display, TEXT("Iterator"));
	for (TestDataType::TIterator It(TestKeyValuePairs); It; ++It)
	{
		UE_LOG(LogOnline, Display, TEXT("Iterator %s = %s"), *It.Key().ToString(), *It.Value().ToString());
	}

	UE_LOG(LogOnline, Display, TEXT("Finding all elements"));
	if (TestKeyValuePairs.Find(TEXT("INTValue")) == NULL)
	{
		bSuccess = false;
	}
	if (TestKeyValuePairs.Find(TEXT("FLOATValue")) == NULL)
	{
		bSuccess = false;
	}
	if (TestKeyValuePairs.Find(TEXT("QWORDValue")) == NULL)
	{
		bSuccess = false;
	}
	if (TestKeyValuePairs.Find(TEXT("DOUBLEValue")) == NULL)
	{
		bSuccess = false;
	}
	if (TestKeyValuePairs.Find(TEXT("STRINGValue")) == NULL)
	{
		bSuccess = false;
	}
	if (TestKeyValuePairs.Find(TEXT("BLOBValue")) == NULL)
	{
		bSuccess = false;
	}

	if (!bSuccess)
	{
		UE_LOG(LogOnline, Display, TEXT("Not all elements found!"));
	}

	TestKeyValuePairs.Remove(TEXT("INTValue"));
	TestKeyValuePairs.Remove(TEXT("BLOBValue"));

	UE_LOG(LogOnline, Display, TEXT("Iterator AFTER removing int32 and Blob elements"));
	for (TestDataType::TIterator It(TestKeyValuePairs); It; ++It)
	{
		UE_LOG(LogOnline, Display, TEXT("Iterator %s = %s"), *It.Key().ToString(), *It.Value().ToString());
	}

	TestKeyValuePairs.Empty();
	UE_LOG(LogOnline, Display, TEXT("Iterator AFTER emptying structure"));
	for (TestDataType::TIterator It(TestKeyValuePairs); It; ++It)
	{
		UE_LOG(LogOnline, Display, TEXT("Iterator %s = %s"), *It.Key().ToString(), *It.Value().ToString());
	}

	bSuccess = TestKeyValuePairs.Num() == 0 ? true : false;

	// Test basic variant data type functionality
	FVariantData OrigKeyValuePair;
	FVariantData CopyValue;

	{
		// Test int32
		int32 OutValue = 0;
		int32 TestValue = 5;
		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);   
		
		CopyValue = OrigKeyValuePair; 
		UE_LOG(LogOnline, Display, TEXT("int32 Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());

		OrigKeyValuePair.Increment<int32,EOnlineKeyValuePairDataType::Int32>((int32)1);
		UE_LOG(LogOnline, Display, TEXT("+1 Now is %s"), *OrigKeyValuePair.ToString());

		OrigKeyValuePair.Decrement<int32,EOnlineKeyValuePairDataType::Int32>((int32)1);
		UE_LOG(LogOnline, Display, TEXT("-1 Now is %s"), *OrigKeyValuePair.ToString());

		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue); 
		bSuccess = bSuccess && OrigKeyValuePair.FromString(TEXT("5"));
		UE_LOG(LogOnline, Display, TEXT("int32 Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());
	}

	{
		// Test float
		float OutValue = 0.0f;
		float TestValue = 5.0f;
		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);

		CopyValue = OrigKeyValuePair; 
		UE_LOG(LogOnline, Display, TEXT("float Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());

		OrigKeyValuePair.Increment<float,EOnlineKeyValuePairDataType::Float>(1.0f);
		UE_LOG(LogOnline, Display, TEXT("+1 Now is %s"), *OrigKeyValuePair.ToString());

		OrigKeyValuePair.Decrement<float,EOnlineKeyValuePairDataType::Float>(1.0f);
		UE_LOG(LogOnline, Display, TEXT("-1 Now is %s"), *OrigKeyValuePair.ToString());

		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue); 
		bSuccess = bSuccess && OrigKeyValuePair.FromString(TEXT("5.0"));
		UE_LOG(LogOnline, Display, TEXT("float Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());
	}

	{
		// Test double
		double OutValue = 0.0;
		double TestValue = 5.0;
		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);

		CopyValue = OrigKeyValuePair; 
		UE_LOG(LogOnline, Display, TEXT("double Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());

		OrigKeyValuePair.Increment<double,EOnlineKeyValuePairDataType::Double>(1.0);
		UE_LOG(LogOnline, Display, TEXT("+1 Now is %s"), *OrigKeyValuePair.ToString());

		OrigKeyValuePair.Decrement<double,EOnlineKeyValuePairDataType::Double>(1.0);
		UE_LOG(LogOnline, Display, TEXT("-1 Now is %s"), *OrigKeyValuePair.ToString());

		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue); 
		bSuccess = bSuccess && OrigKeyValuePair.FromString(TEXT("5.0"));
		UE_LOG(LogOnline, Display, TEXT("double Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());
	}

	{
		// Test uint64
		uint64 OutValue = 0;
		uint64 TestValue = 524288;
		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);

		CopyValue = OrigKeyValuePair; 
		UE_LOG(LogOnline, Display, TEXT("uint64 Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString()); 

		OrigKeyValuePair.Increment<uint64,EOnlineKeyValuePairDataType::Int64>(1.0);
		UE_LOG(LogOnline, Display, TEXT("+1 Now is %s"), *OrigKeyValuePair.ToString());

		OrigKeyValuePair.Decrement<uint64,EOnlineKeyValuePairDataType::Int64>(1.0);
		UE_LOG(LogOnline, Display, TEXT("-1 Now is %s"), *OrigKeyValuePair.ToString());

		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue);
		bSuccess = bSuccess && OrigKeyValuePair.FromString(TEXT("524288"));
		UE_LOG(LogOnline, Display, TEXT("uint64 Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());
	}

	{
		// Test String
		FString OutValue;
		FString TestValue(TEXT("This is a test!"));
		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);

		CopyValue = OrigKeyValuePair; 
		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue);
		UE_LOG(LogOnline, Display, TEXT("STRING Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString()); 
	}

	{
		// Test Blob
		TArray<uint8> OutValue;
		TArray<uint8> TestValue;
		for (int32 i=0; i<512; i++)
		{
			TestValue.Add(FMath::Rand() % 255);
		}

		OrigKeyValuePair.SetValue(TestValue);
		OrigKeyValuePair.GetValue(OutValue);
		bSuccess = bSuccess && (OutValue == TestValue);

		CopyValue = OrigKeyValuePair; 
		bSuccess = bSuccess && (OrigKeyValuePair == CopyValue); 
		UE_LOG(LogOnline, Display, TEXT("BLOB Test %s == %s"), *OrigKeyValuePair.ToString(), *CopyValue.ToString());
	}

	UE_LOG(LogOnline, Warning, TEXT("KeyValuePairTest: %s!"), bSuccess ? TEXT("PASSED") : TEXT("FAILED"));
}
bool UFindSessionsCallbackProxyAdvanced::CompareVariants(const FVariantData &A, const FVariantData &B, EOnlineComparisonOpRedux::Type Comparator)
{
	if (A.GetType() != B.GetType())
		return false;

	switch (A.GetType())
	{
	case EOnlineKeyValuePairDataType::Bool:
	{
		bool bA, bB;
		A.GetValue(bA);
		B.GetValue(bB);
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		default:
			return false;break;
		}
	}
	case EOnlineKeyValuePairDataType::Double:
	{
		double bA, bB;
		A.GetValue(bA);
		B.GetValue(bB);
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		case EOnlineComparisonOpRedux::GreaterThanEquals:
			return (bA == bB || bA > bB); break;
		case EOnlineComparisonOpRedux::LessThanEquals:
			return (bA == bB || bA < bB); break;
		case EOnlineComparisonOpRedux::GreaterThan:
			return bA > bB; break;
		case EOnlineComparisonOpRedux::LessThan:
			return bA < bB; break;
		default:
			return false; break;
		}
	}
	case EOnlineKeyValuePairDataType::Float:
	{
		float tbA, tbB;
		double bA, bB;
		A.GetValue(tbA);
		B.GetValue(tbB);
		bA = (double)tbA;
		bB = (double)tbB;
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		case EOnlineComparisonOpRedux::GreaterThanEquals:
			return (bA == bB || bA > bB); break;
		case EOnlineComparisonOpRedux::LessThanEquals:
			return (bA == bB || bA < bB); break;
		case EOnlineComparisonOpRedux::GreaterThan:
			return bA > bB; break;
		case EOnlineComparisonOpRedux::LessThan:
			return bA < bB; break;
		default:
			return false; break;
		}
	}
	case EOnlineKeyValuePairDataType::Int32:
	{
		int32 bA, bB;
		A.GetValue(bA);
		B.GetValue(bB);
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		case EOnlineComparisonOpRedux::GreaterThanEquals:
			return (bA == bB || bA > bB); break;
		case EOnlineComparisonOpRedux::LessThanEquals:
			return (bA == bB || bA < bB); break;
		case EOnlineComparisonOpRedux::GreaterThan:
			return bA > bB; break;
		case EOnlineComparisonOpRedux::LessThan:
			return bA < bB; break;
		default:
			return false; break;
		}
	}
	case EOnlineKeyValuePairDataType::Int64:
	{
		uint64 bA, bB;
		A.GetValue(bA);
		B.GetValue(bB);
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		case EOnlineComparisonOpRedux::GreaterThanEquals:
			return (bA == bB || bA > bB); break;
		case EOnlineComparisonOpRedux::LessThanEquals:
			return (bA == bB || bA < bB); break;
		case EOnlineComparisonOpRedux::GreaterThan:
			return bA > bB; break;
		case EOnlineComparisonOpRedux::LessThan:
			return bA < bB; break;
		default:
			return false; break;
		}
	}

	case EOnlineKeyValuePairDataType::String:
	{
		FString bA, bB;
		A.GetValue(bA);
		B.GetValue(bB);
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		default:
			return false; break;
		}
	}

	case EOnlineKeyValuePairDataType::Empty:
	case EOnlineKeyValuePairDataType::Blob:
	default:
		return false; break;
	}



}
void FFriendsMessageManager::OnReadMessageComplete(int32 LocalPlayer, bool bWasSuccessful, const FUniqueMessageId& MessageId, const FString& ErrorStr)
{
	if ( bWasSuccessful )
	{
		TSharedPtr<FOnlineMessage> TempMessage = OnlineSubMcp->GetMessageInterface()->GetMessage( 0, MessageId );
		FOnlineMessagePayload Payload = TempMessage->Payload;
		FVariantData TestValue;
		Payload.GetAttribute(TEXT("STRINGValue"), TestValue);
		FVariantData SenderName;
 		Payload.GetAttribute(TEXT("SenderID"), SenderName );

		FString DisplayMessage = SenderName.ToString();

		FVariantData GameInvite;
 		if ( Payload.GetAttribute(TEXT("GameInvite"), GameInvite ) )
		{
			TSharedPtr< FUniqueNetId > NetID = FFriendsAndChatManager::Get()->FindUserID( DisplayMessage);
			if ( NetID.IsValid() )
			{
				DisplayMessage += TEXT ( " invited you to play" );
				TSharedPtr< FFriendsAndChatMessage > NotificationMessage = MakeShareable( new FFriendsAndChatMessage( DisplayMessage, NetID.ToSharedRef() ) );
				NotificationMessage->SetMessageType( EFriendsRequestType::JoinGame );
				NotificationMessage->SetRequesterName( SenderName.ToString() );
				NotificationMessage->SetSelfHandle( true );

				// auto accept - for game launch
				if ( bCanJoinGame && GameLaunchMessageID != TEXT("") && GameLaunchMessageID == MessageId.ToString() )
				{
					NotificationMessage->SetAutoAccept();
				}
				else if ( !bCanJoinGame )
				{
					// Send message ID
					NotificationMessage->SetLaunchGameID( MessageId.ToString() );
				}

				FriendsListNotificationDelegate->Broadcast( NotificationMessage.ToSharedRef() );

				// Chache, and don't delete game invites if the app cannot directly join a game
				if ( bCanJoinGame == false && LatentMessage.IsEmpty() )
				{
					for ( int32 Index = 0; Index < MessagesToDelete.Num(); Index++ )
					{
						if ( *MessagesToDelete[Index] == MessageId )
						{
							LatentMessage = MessageId.ToString();
							MessagesToDelete.RemoveAt( Index );
							break;
						}
					}
				}
			}
		}
		else
		{
			DisplayMessage += TEXT ( " says:\n" );
			DisplayMessage += TestValue.ToString();
			TSharedPtr< FFriendsAndChatMessage > ChatMessage = MakeShareable( new FFriendsAndChatMessage( DisplayMessage ) );
			ChatMessage->SetSelfHandle( false );
			ChatMessages.Add( ChatMessage );
			OChatListUpdatedDelegate.Broadcast();
		}

		MessagesToRead.RemoveAt(0);
	}

	SetState( EFriendsMessageManagerState::Idle );
}