From f91d4ec4eabf7160883a57de8c1624f193b86863 Mon Sep 17 00:00:00 2001 From: mordentral Date: Thu, 14 Jan 2016 13:20:40 -0500 Subject: [PATCH] steam avatar support --- .../AdvancedSessions.Build.cs | 7 +- .../Classes/AdvancedFriendsLibrary.h | 12 +++ .../Private/AdvancedFriendsLibrary.cpp | 85 +++++++++++++++++++ .../Private/OnlineSubSystemHeader.h | 9 +- 4 files changed, 108 insertions(+), 5 deletions(-) diff --git a/Source/AdvancedSessions/AdvancedSessions.Build.cs b/Source/AdvancedSessions/AdvancedSessions.Build.cs index 7e2fed6..ab364a0 100644 --- a/Source/AdvancedSessions/AdvancedSessions.Build.cs +++ b/Source/AdvancedSessions/AdvancedSessions.Build.cs @@ -5,10 +5,9 @@ public class AdvancedSessions : ModuleRules { public AdvancedSessions(TargetInfo Target) { - PrivateIncludePaths.AddRange(new string[] { "AdvancedSessions/Private" }); + PrivateIncludePaths.AddRange(new string[] { "AdvancedSessions/Private"/*, "OnlineSubsystemSteam/Private"*/ }); PublicIncludePaths.AddRange(new string[] { "AdvancedSessions/Public" }); - - PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "OnlineSubsystem","CoreUObject", "OnlineSubsystemUtils", "Networking", "Sockets" }); - PrivateDependencyModuleNames.AddRange(new string[] { "OnlineSubsystem", "Sockets", "Networking"}); + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "OnlineSubsystem","CoreUObject", "OnlineSubsystemUtils", "Networking", "Sockets", "Steamworks"/*, "OnlineSubsystemSteam"*/ }); + PrivateDependencyModuleNames.AddRange(new string[] { "OnlineSubsystem", "Sockets", "Networking"/*, "Steamworks", "OnlineSubsystemSteam"*/ }); } } \ No newline at end of file diff --git a/Source/AdvancedSessions/Classes/AdvancedFriendsLibrary.h b/Source/AdvancedSessions/Classes/AdvancedFriendsLibrary.h index f834b2e..09b1f6e 100644 --- a/Source/AdvancedSessions/Classes/AdvancedFriendsLibrary.h +++ b/Source/AdvancedSessions/Classes/AdvancedFriendsLibrary.h @@ -20,6 +20,14 @@ //General Advanced Sessions Log DECLARE_LOG_CATEGORY_EXTERN(AdvancedFriendsLog, Log, All); +UENUM(Blueprintable) +enum SteamAvatarSize +{ + SteamAvatar_Small = 1, + SteamAvatar_Medium = 2, + SteamAvatar_Large = 3 +}; + UCLASS() class UAdvancedFriendsLibrary : public UBlueprintFunctionLibrary @@ -53,4 +61,8 @@ public: UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|FriendsList") static void IsAFriend(APlayerController *PlayerController, const FBPUniqueNetId UniqueNetId, bool &IsFriend); + // Get a texture of a valid friends avatar, STEAM ONLY + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI") + static UTexture2D * GetSteamFriendAvatar(APlayerController *PlayerController, const FBPUniqueNetId UniqueNetId, SteamAvatarSize AvatarSize = SteamAvatarSize::SteamAvatar_Medium); + }; diff --git a/Source/AdvancedSessions/Private/AdvancedFriendsLibrary.cpp b/Source/AdvancedSessions/Private/AdvancedFriendsLibrary.cpp index 1ed58ba..ad7b1e8 100644 --- a/Source/AdvancedSessions/Private/AdvancedFriendsLibrary.cpp +++ b/Source/AdvancedSessions/Private/AdvancedFriendsLibrary.cpp @@ -1,10 +1,95 @@ // Fill out your copyright notice in the Description page of Project Settings. #include "OnlineSubSystemHeader.h" #include "AdvancedFriendsLibrary.h" +#include //General Log DEFINE_LOG_CATEGORY(AdvancedFriendsLog); + +UTexture2D * UAdvancedFriendsLibrary::GetSteamFriendAvatar(APlayerController *PlayerController, const FBPUniqueNetId UniqueNetId, SteamAvatarSize AvatarSize) +{ + if (!PlayerController) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("IsAFriend Had a bad Player Controller!")); + return nullptr; + } + + if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("IsAFriend Had a bad UniqueNetId!")); + return nullptr; + } + + uint32 Width = 0; + uint32 Height = 0; + + if (SteamAPI_Init()) + { + //Getting the PictureID from the SteamAPI and getting the Size with the ID + + uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes()); + int Picture = 0; + + switch(AvatarSize) + { + case SteamAvatarSize::SteamAvatar_Small: Picture = SteamFriends()->GetSmallFriendAvatar(id); break; + case SteamAvatarSize::SteamAvatar_Medium: Picture = SteamFriends()->GetMediumFriendAvatar(id); break; + case SteamAvatarSize::SteamAvatar_Large: Picture = SteamFriends()->GetLargeFriendAvatar(id); break; + default: break; + } + + SteamUtils()->GetImageSize(Picture, &Width, &Height); + + // STOLEN FROM ANSWERHUB :p + + if (Width > 0 && Height > 0) + { + //Creating the buffer "oAvatarRGBA" and then filling it with the RGBA Stream from the Steam Avatar + BYTE *oAvatarRGBA = new BYTE[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)); + + //Swap R and B channels because for some reason the games whack + for (uint32 i = 0; i < (Width * Height * 4); i += 4) + { + uint8 Temp = oAvatarRGBA[i + 0]; + oAvatarRGBA[i + 0] = oAvatarRGBA[i + 2]; + oAvatarRGBA[i + 2] = Temp; + } + UTexture2D* Avatar = UTexture2D::CreateTransient(Width, Height, PF_B8G8R8A8); + + //MAGIC! + 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!! + delete[] oAvatarRGBA; + + //Setting some Parameters for the Texture and finally returning it + Avatar->PlatformData->NumSlices = 1; + Avatar->NeverStream = true; + //Avatar->CompressionSettings = TC_EditorIcon; + + Avatar->UpdateResource(); + + return Avatar; + } + else + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("Bad Height / Width with steam avatar!")); + } + + return nullptr; + } + + UE_LOG(AdvancedFriendsLog, Warning, TEXT("STEAM Couldn't be verified as initialized")); + return nullptr; +} + void UAdvancedFriendsLibrary::SendSessionInviteToFriends(APlayerController *PlayerController, const TArray &Friends, TEnumAsByte &Result) { if (!PlayerController) diff --git a/Source/AdvancedSessions/Private/OnlineSubSystemHeader.h b/Source/AdvancedSessions/Private/OnlineSubSystemHeader.h index a0e48d1..fd8b29b 100644 --- a/Source/AdvancedSessions/Private/OnlineSubSystemHeader.h +++ b/Source/AdvancedSessions/Private/OnlineSubSystemHeader.h @@ -11,4 +11,11 @@ #include "OnlineSubsystemUtilsModule.h" #include "ModuleManager.h" #include "OnlineSubsystemUtilsClasses.h" -#include "BlueprintDataDefinitions.h" \ No newline at end of file +#include "BlueprintDataDefinitions.h" + +// Found this in the steam controller, seems like a nice thought since steam is throwing errors +// Disable crazy warnings that claim that standard C library is "deprecated". +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) +#endif