Get player avatar using online subsystem, and not using Steam API

Hi, I tried to google this out and search these forums, but could not find the answer. So I apologize in advance if this was already answered.

I want to download player avatar, but I don’t want to use Advanced and Steam sessions plugins for that. I want to use IOnlineSubsystem. I tried couple of interfaces, and sweaped throught their methods, but just could not find the way to do it.

I need it to download and display my avatar, and other player’s avatar when there is a multiplayer game. I currently use GetSteamFriendAvatar, and it works fine, but, as I mentioned above, I want to use IOnlineSubsystem.

Thanks in advance

But what avatar do you want to get? Where players would that avatar?

Player’s avatar, picture, or however you want to call it :). Then one you set on your profile on Steam.

Here it is on the Steam
image

Here it is in my game
image

Yep, that’s what I meant. How do you want to get a Steam avatar without using Steam subsystem?

Same way I get Steam friends list. Using IOnlineSubsystem. I can also get tons of other stuff for which I don’t need Steam API.

	IOnlineFriends* FriendsPointer = OnlineSubsystem->GetFriendsInterface().Get();

	if (FriendsPointer)
	{
		TArray<TShaderRef<FOnlineFriend>> ListOfFriends;
		FriendsPointer->ReadFriendsList(
			0,
			"",
			FOnReadFriendsListComplete::CreateUObject(this, &UEosHelper::FriendListDownloadComplete)
		);
	}

I just wanna know how to get avatar using IOnlineSubsystem :slight_smile:

1 Like

Hmm, that’s interesting. I have no idea how it gets a list of Steam friends without connecting to Steam. I’ll stick around to see if someone provides some more information.

1 Like

Actually, I just don’t want to use Steam API. I am using Steam Subsystem and my game is connected to steam. I just want to ditch out Steam Online Sessions and Advanced sessions plugin and use IOnlineSubsystem. Because it should cover all online subystems, and not just Steam. So, if my game goes to some other platform, I should not write all the code specifically for that platform.

Bumping this up. Anyone? :slight_smile:

Hey @Bojann, great question, and I’m also shocked the documentation isn’t better for this.
From what I’ve gathered, instead of using the Friends Interface, you would connect to the IdentityInterface which I believe has access to the user profile settings.

I hope this can help,
-Zen

Hello @ZenLeviathan, I apologize for late answer. And thanks for replying. Unfortunately I was unlucky with this one. Closest thing I could get to is FUserOnlineAccount, as that is the only logical thing from IOnlineIdentity that I can get. But it does not have profile picture access.
Maybe I should use OnlineAccount.Get()->GetUserAttribute(), but I could not google out the list of attributes, and I’m not sure what I could do with the string that it returns back.

If you have any other ideas, I’m willing to try them out :slight_smile:

Ever found a solution to this?

Nope, what I did is implement separate player avatar download logic for GOG and Steam using code from SteamOnlineSessions. If you need the code, let me know.

Yeah if you wouldn’t mind.

Ah, sorry for late reply. I need to turn back notifications from this forum :slight_smile:

Steam:
First request user info and wait for it to finish

	if (SteamAPI_Init())
	{
		const uint64 Int64Id = FCString::Atoi64(*UniqueNetId);
		SteamFriends()->RequestUserInformation(Int64Id, false);
	}

Then download avatar

UTexture2D* USteamHelper::GetSteamFriendAvatar(const uint64 UniqueNetId, PlayerAvatarSize PlayerAvatarSize)
{
	UTexture2D** CachedTexture = TextureCacheMap.Find(UniqueNetId);
	if (CachedTexture != nullptr)
	{
		return *CachedTexture;
	}
	
	uint32 Width = 0;
	uint32 Height = 0;

	if (SteamAPI_Init())
	{
		//Getting the PictureID from the SteamAPI and getting the Size with the ID
		//virtual bool RequestUserInformation( CSteamID steamIDUser, bool bRequireNameOnly ) = 0;
		
		int Picture = 0;
		
		switch(PlayerAvatarSize)
		{
		case PlayerAvatarSize::PlayerAvatar_Small: Picture = SteamFriends()->GetSmallFriendAvatar(UniqueNetId); break;
		case PlayerAvatarSize::PlayerAvatar_Medium: Picture = SteamFriends()->GetMediumFriendAvatar(UniqueNetId); break;
		case PlayerAvatarSize::PlayerAvatar_Large: Picture = SteamFriends()->GetLargeFriendAvatar(UniqueNetId); break;
		default: break;
		}

		if (Picture == -1)
		{
			return NULL;
		}

		SteamUtils()->GetImageSize(Picture, &Width, &Height);

		if (Width > 0 && Height > 0)
		{
			//Creating the buffer "oAvatarRGBA" and then filling it with the RGBA Stream from the Steam Avatar
			uint8 *oAvatarRGBA = new uint8[Width * Height * 4];


			//Filling the buffer with the RGBA Stream from the Steam Avatar and creating a UTextur2D to parse the RGBA Steam in
			SteamUtils()->GetImageRGBA(Picture, (uint8*)oAvatarRGBA, 4 * Height * Width * sizeof(char));
			
			UTexture2D* Avatar = UTexture2D::CreateTransient(Width, Height, PF_R8G8B8A8);
			// Switched to a Memcpy instead of byte by byte transer
			uint8* MipData = (uint8*)Avatar->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
			FMemory::Memcpy(MipData, (void*)oAvatarRGBA, Height * Width * 4);
			Avatar->PlatformData->Mips[0].BulkData.Unlock();

			// Original implementation was missing this!!
			// the hell man......
			delete[] oAvatarRGBA;

			//Setting some Parameters for the Texture and finally returning it
			Avatar->PlatformData->SetNumSlices(1);
			Avatar->NeverStream = true;
			//Avatar->CompressionSettings = TC_EditorIcon;

			Avatar->UpdateResource();

			TextureCacheMap.Add(UniqueNetId, Avatar);
			return Avatar;
		}
		else
		{
			UE_LOG(LogTemp, Warning, TEXT("Bad Height / Width with steam avatar!"));
		}
		
		return nullptr;
	}
	return nullptr;
}

GOG

First request user info and wait for it to finish

galaxy::api::Friends()->RequestUserInformation(MyGalaxyID, PlayerAvatarType, GogUserInfoListener);

Then download avatar

UTexture2D* UGogHelper::GetGogFriendAvatar(uint64 UserId, galaxy::api::AvatarType AvatarType)
{
	UTexture2D** CachedTexture = TextureCacheMap.Find(UserId);
	if (CachedTexture != nullptr)
	{
		return *CachedTexture;
	}
	
	uint32 Width;
	uint32 Height;

	switch (AvatarType)
	{
	case galaxy::api::AVATAR_TYPE_SMALL:
		{
			Width = 32;
			Height = 32;
		}
		break;
	case galaxy::api::AVATAR_TYPE_MEDIUM:
		{
			Width = 64;
			Height = 64;
		}
		break;
	case galaxy::api::AVATAR_TYPE_LARGE:
		{
			Width = 184;
			Height = 184;
		}
		break;
	default:
		{
			Width = 0;
			Height = 0;
		}
	}

	if (Width > 0 && Height > 0)
	{
		const galaxy::api::GalaxyID UserGalaxyId = galaxy::api::GalaxyID::FromRealID(
			galaxy::api::GalaxyID::ID_TYPE_USER, UserId);

		//Creating the buffer "oAvatarRGBA" and then filling it with the RGBA Stream from the Steam Avatar
		uint8* oAvatarRGBA = new uint8[Width * Height * 4];


		//Filling the buffer with the RGBA Stream from the Steam Avatar and creating a UTexture2D to parse the RGBA Steam in		
		galaxy::api::Friends()->GetFriendAvatarImageRGBA(UserGalaxyId, AvatarType, oAvatarRGBA,
		                                                 4 * Width * Height * sizeof(char));


		UTexture2D* Avatar = UTexture2D::CreateTransient(Width, Height, PF_R8G8B8A8);
		// Switched to a Memcpy instead of byte by byte transfer
		uint8* MipData = (uint8*)Avatar->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
		FMemory::Memcpy(MipData, (void*)oAvatarRGBA, Height * Width * 4);
		Avatar->PlatformData->Mips[0].BulkData.Unlock();

		delete[] oAvatarRGBA;

		//Setting some Parameters for the Texture and finally returning it
		Avatar->PlatformData->SetNumSlices(1);
		Avatar->NeverStream = true;

		Avatar->UpdateResource();
		TextureCacheMap.Add(UserId, Avatar);
		return Avatar;
	}
	UE_LOG(LogTemp, Warning, TEXT("Bad Height / Width with GOG avatar!"));
	return nullptr;
}
2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.