diff --git a/Source/AdvancedSessions/Classes/FindSessionsCallbackProxyAdvanced.h b/Source/AdvancedSessions/Classes/FindSessionsCallbackProxyAdvanced.h index 6b09526..4d12ca8 100644 --- a/Source/AdvancedSessions/Classes/FindSessionsCallbackProxyAdvanced.h +++ b/Source/AdvancedSessions/Classes/FindSessionsCallbackProxyAdvanced.h @@ -51,6 +51,10 @@ private: // Internal callback when the session search completes, calls out to the public success/failure callbacks void OnCompleted(bool bSuccess); + bool bRunSecondSearch; + + TArray SessionSearchResults; + private: // The player controller triggering things TWeakObjectPtr PlayerControllerWeakPtr; @@ -63,6 +67,7 @@ private: // Object to track search results TSharedPtr SearchObject; + TSharedPtr SearchObjectDedicated; // Whether or not to search LAN bool bUseLAN; diff --git a/Source/AdvancedSessions/Classes/SteamFuncs/AdvancedSteamWorkshopLibrary.h b/Source/AdvancedSessions/Classes/SteamFuncs/AdvancedSteamWorkshopLibrary.h index e317380..635d223 100644 --- a/Source/AdvancedSessions/Classes/SteamFuncs/AdvancedSteamWorkshopLibrary.h +++ b/Source/AdvancedSessions/Classes/SteamFuncs/AdvancedSteamWorkshopLibrary.h @@ -7,6 +7,30 @@ #include "OnlineSubsystem.h" #include "OnlineSessionInterface.h" +// @todo Steam: Steam headers trigger secure-C-runtime warnings in Visual C++. Rather than mess with _CRT_SECURE_NO_WARNINGS, we'll just +// disable the warnings locally. Remove when this is fixed in the SDK +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) +#endif + +#if PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX + +#pragma push_macro("ARRAY_COUNT") +#undef ARRAY_COUNT + +#include + +#pragma pop_macro("ARRAY_COUNT") + +#endif + +// @todo Steam: See above +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + #include "AdvancedSteamWorkshopLibrary.generated.h" @@ -37,6 +61,224 @@ public: }; +// General result codes - Copying steams version over +// Check these to future proof +UENUM(BlueprintType) +enum class FBPSteamResult : uint8 +{ + k_EResultOK = 1, // success + k_EResultFail = 2, // generic failure + k_EResultNoConnection = 3, // no/failed network connection + // k_EResultNoConnectionRetry = 4, // OBSOLETE - removed + k_EResultInvalidPassword = 5, // password/ticket is invalid + k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere + k_EResultInvalidProtocolVer = 7, // protocol version is incorrect + k_EResultInvalidParam = 8, // a parameter is incorrect + k_EResultFileNotFound = 9, // file was not found + k_EResultBusy = 10, // called method busy - action not taken + k_EResultInvalidState = 11, // called object was in an invalid state + k_EResultInvalidName = 12, // name is invalid + k_EResultInvalidEmail = 13, // email is invalid + k_EResultDuplicateName = 14, // name is not unique + k_EResultAccessDenied = 15, // access is denied + k_EResultTimeout = 16, // operation timed out + k_EResultBanned = 17, // VAC2 banned + k_EResultAccountNotFound = 18, // account not found + k_EResultInvalidSteamID = 19, // steamID is invalid + k_EResultServiceUnavailable = 20, // The requested service is currently unavailable + k_EResultNotLoggedOn = 21, // The user is not logged on + k_EResultPending = 22, // Request is pending (may be in process, or waiting on third party) + k_EResultEncryptionFailure = 23, // Encryption or Decryption failed + k_EResultInsufficientPrivilege = 24, // Insufficient privilege + k_EResultLimitExceeded = 25, // Too much of a good thing + k_EResultRevoked = 26, // Access has been revoked (used for revoked guest passes) + k_EResultExpired = 27, // License/Guest pass the user is trying to access is expired + k_EResultAlreadyRedeemed = 28, // Guest pass has already been redeemed by account, cannot be acked again + k_EResultDuplicateRequest = 29, // The request is a duplicate and the action has already occurred in the past, ignored this time + k_EResultAlreadyOwned = 30, // All the games in this guest pass redemption request are already owned by the user + k_EResultIPNotFound = 31, // IP address not found + k_EResultPersistFailed = 32, // failed to write change to the data store + k_EResultLockingFailed = 33, // failed to acquire access lock for this operation + k_EResultLogonSessionReplaced = 34, + k_EResultConnectFailed = 35, + k_EResultHandshakeFailed = 36, + k_EResultIOFailure = 37, + k_EResultRemoteDisconnect = 38, + k_EResultShoppingCartNotFound = 39, // failed to find the shopping cart requested + k_EResultBlocked = 40, // a user didn't allow it + k_EResultIgnored = 41, // target is ignoring sender + k_EResultNoMatch = 42, // nothing matching the request found + k_EResultAccountDisabled = 43, + k_EResultServiceReadOnly = 44, // this service is not accepting content changes right now + k_EResultAccountNotFeatured = 45, // account doesn't have value, so this feature isn't available + k_EResultAdministratorOK = 46, // allowed to take this action, but only because requester is admin + k_EResultContentVersion = 47, // A Version mismatch in content transmitted within the Steam protocol. + k_EResultTryAnotherCM = 48, // The current CM can't service the user making a request, user should try another. + k_EResultPasswordRequiredToKickSession = 49,// You are already logged in elsewhere, this cached credential login has failed. + k_EResultAlreadyLoggedInElsewhere = 50, // You are already logged in elsewhere, you must wait + k_EResultSuspended = 51, // Long running operation (content download) suspended/paused + k_EResultCancelled = 52, // Operation canceled (typically by user: content download) + k_EResultDataCorruption = 53, // Operation canceled because data is ill formed or unrecoverable + k_EResultDiskFull = 54, // Operation canceled - not enough disk space. + k_EResultRemoteCallFailed = 55, // an remote call or IPC call failed + k_EResultPasswordUnset = 56, // Password could not be verified as it's unset server side + k_EResultExternalAccountUnlinked = 57, // External account (PSN, Facebook...) is not linked to a Steam account + k_EResultPSNTicketInvalid = 58, // PSN ticket was invalid + k_EResultExternalAccountAlreadyLinked = 59, // External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first + k_EResultRemoteFileConflict = 60, // The sync cannot resume due to a conflict between the local and remote files + k_EResultIllegalPassword = 61, // The requested new password is not legal + k_EResultSameAsPreviousValue = 62, // new value is the same as the old one ( secret question and answer ) + k_EResultAccountLogonDenied = 63, // account login denied due to 2nd factor authentication failure + k_EResultCannotUseOldPassword = 64, // The requested new password is not legal + k_EResultInvalidLoginAuthCode = 65, // account login denied due to auth code invalid + k_EResultAccountLogonDeniedNoMail = 66, // account login denied due to 2nd factor auth failure - and no mail has been sent + k_EResultHardwareNotCapableOfIPT = 67, // + k_EResultIPTInitError = 68, // + k_EResultParentalControlRestricted = 69, // operation failed due to parental control restrictions for current user + k_EResultFacebookQueryError = 70, // Facebook query returned an error + k_EResultExpiredLoginAuthCode = 71, // account login denied due to auth code expired + k_EResultIPLoginRestrictionFailed = 72, + k_EResultAccountLockedDown = 73, + k_EResultAccountLogonDeniedVerifiedEmailRequired = 74, + k_EResultNoMatchingURL = 75, + k_EResultBadResponse = 76, // parse failure, missing field, etc. + k_EResultRequirePasswordReEntry = 77, // The user cannot complete the action until they re-enter their password + k_EResultValueOutOfRange = 78, // the value entered is outside the acceptable range + k_EResultUnexpectedError = 79, // something happened that we didn't expect to ever happen + k_EResultDisabled = 80, // The requested service has been configured to be unavailable + k_EResultInvalidCEGSubmission = 81, // The set of files submitted to the CEG server are not valid ! + k_EResultRestrictedDevice = 82, // The device being used is not allowed to perform this action + k_EResultRegionLocked = 83, // The action could not be complete because it is region restricted + k_EResultRateLimitExceeded = 84, // Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent + k_EResultAccountLoginDeniedNeedTwoFactor = 85, // Need two-factor code to login + k_EResultItemDeleted = 86, // The thing we're trying to access has been deleted + k_EResultAccountLoginDeniedThrottle = 87, // login attempt failed, try to throttle response to possible attacker + k_EResultTwoFactorCodeMismatch = 88, // two factor code mismatch + k_EResultTwoFactorActivationCodeMismatch = 89, // activation code for two-factor didn't match + k_EResultAccountAssociatedToMultiplePartners = 90, // account has been associated with multiple partners + k_EResultNotModified = 91, // data not modified +}; + +// Check these to future proof +UENUM(BlueprintType) +enum class FBPWorkshopFileType : uint8 +{ + k_EWorkshopFileTypeCommunity = 0, + k_EWorkshopFileTypeMicrotransaction = 1, + k_EWorkshopFileTypeCollection = 2, + k_EWorkshopFileTypeArt = 3, + k_EWorkshopFileTypeVideo = 4, + k_EWorkshopFileTypeScreenshot = 5, + k_EWorkshopFileTypeGame = 6, + k_EWorkshopFileTypeSoftware = 7, + k_EWorkshopFileTypeConcept = 8, + k_EWorkshopFileTypeWebGuide = 9, + k_EWorkshopFileTypeIntegratedGuide = 10, + k_EWorkshopFileTypeMerch = 11, + k_EWorkshopFileTypeControllerBinding = 12, + k_EWorkshopFileTypeSteamworksAccessInvite = 13, + k_EWorkshopFileTypeSteamVideo = 14, + + // Update k_EWorkshopFileTypeMax if you add values. + k_EWorkshopFileTypeMax = 15 +}; + +// WorkshopItemDetails Struct +USTRUCT(BlueprintType) +struct FBPSteamWorkshopItemDetails +{ + GENERATED_USTRUCT_BODY() + +public: + FBPSteamWorkshopItemDetails() + { + + } + + FBPSteamWorkshopItemDetails(SteamUGCDetails_t &hUGCDetails) + { + ResultOfRequest = (FBPSteamResult)hUGCDetails.m_eResult; + FileType = (FBPWorkshopFileType)hUGCDetails.m_eFileType; + CreatorAppID = (int32)hUGCDetails.m_nCreatorAppID; + ConsumerAppID = (int32)hUGCDetails.m_nConsumerAppID; + Title = FString(hUGCDetails.m_rgchTitle, k_cchPublishedDocumentTitleMax); + Description = FString(hUGCDetails.m_rgchDescription, k_cchPublishedDocumentDescriptionMax); + ItemUrl = FString(hUGCDetails.m_rgchURL, k_cchPublishedFileURLMax); + VotesUp = (int32)hUGCDetails.m_unVotesUp; + VotesDown = (int32)hUGCDetails.m_unVotesDown; + CalculatedScore = hUGCDetails.m_flScore; + bBanned = hUGCDetails.m_bBanned; + bAcceptedForUse = hUGCDetails.m_bAcceptedForUse; + bTagsTruncated = hUGCDetails.m_bTagsTruncated; + } + + // Result of obtaining the details + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FBPSteamResult ResultOfRequest; + + // Type of file + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FBPWorkshopFileType FileType; + + // These two are listed as baked to an int, but is stored as a uint, think its safe to keep int + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + int32 CreatorAppID; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + int32 ConsumerAppID; + + // Title of item + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FString Title; + + // Description of item + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FString Description; + + //Url for a video of website + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + FString ItemUrl; + + // Votes will be unlikely to go above signed limited + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + int32 VotesUp; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + int32 VotesDown; + + // Calculated score + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + float CalculatedScore; + + // whether the file was banned + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + bool bBanned; + + // developer has specifically flagged this item as accepted in the Workshop + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + bool bAcceptedForUse; + + // whether the list of tags was too long to be returned in the provided buffer + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop") + bool bTagsTruncated; + + /* + PublishedFileId_t m_nPublishedFileId; + uint64 m_ulSteamIDOwner; // Steam ID of the user who created this content. + uint32 m_rtimeCreated; // time when the published file was created + uint32 m_rtimeUpdated; // time when the published file was last updated + uint32 m_rtimeAddedToUserList; // time when the user added the published file to their list (not always applicable) + ERemoteStoragePublishedFileVisibility m_eVisibility; // visibility + char m_rgchTags[k_cchTagListMax]; // comma separated list of all tags associated with this file + // file/url information + UGCHandle_t m_hFile; // The handle of the primary file + UGCHandle_t m_hPreviewFile; // The handle of the preview file + char m_pchFileName[k_cchFilenameMax]; // The cloud filename of the primary file + int32 m_nFileSize; // Size of the primary file + int32 m_nPreviewFileSize; // Size of the preview file + uint32 m_unNumChildren; // if m_eFileType == k_EWorkshopFileTypeCollection, then this number will be the number of children contained within the collection + */ + +}; + UCLASS() class UAdvancedSteamWorkshopLibrary : public UBlueprintFunctionLibrary { diff --git a/Source/AdvancedSessions/Classes/SteamFuncs/SteamWSRequestUGCDetailsCallbackProxy.h b/Source/AdvancedSessions/Classes/SteamFuncs/SteamWSRequestUGCDetailsCallbackProxy.h index b0a0339..bdbe618 100644 --- a/Source/AdvancedSessions/Classes/SteamFuncs/SteamWSRequestUGCDetailsCallbackProxy.h +++ b/Source/AdvancedSessions/Classes/SteamFuncs/SteamWSRequestUGCDetailsCallbackProxy.h @@ -28,6 +28,9 @@ #include "SteamWSRequestUGCDetailsCallbackProxy.generated.h" + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintWorkshopDetailsDelegate, const FBPSteamWorkshopItemDetails&, WorkShopDetails); + UCLASS(MinimalAPI) class USteamWSRequestUGCDetailsCallbackProxy : public UOnlineBlueprintCallProxyBase { @@ -35,11 +38,11 @@ class USteamWSRequestUGCDetailsCallbackProxy : public UOnlineBlueprintCallProxyB // Called when there is a successful results return UPROPERTY(BlueprintAssignable) - FEmptyOnlineDelegate OnSuccess; + FBlueprintWorkshopDetailsDelegate OnSuccess; // Called when there is an unsuccessful results return UPROPERTY(BlueprintAssignable) - FEmptyOnlineDelegate OnFailure; + FBlueprintWorkshopDetailsDelegate OnFailure; // Ends the current session UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedSteamWorkshop") diff --git a/Source/AdvancedSessions/Private/FindSessionsCallbackProxyAdvanced.cpp b/Source/AdvancedSessions/Private/FindSessionsCallbackProxyAdvanced.cpp index d4e68fd..302bbdb 100644 --- a/Source/AdvancedSessions/Private/FindSessionsCallbackProxyAdvanced.cpp +++ b/Source/AdvancedSessions/Private/FindSessionsCallbackProxyAdvanced.cpp @@ -12,6 +12,7 @@ UFindSessionsCallbackProxyAdvanced::UFindSessionsCallbackProxyAdvanced(const FOb , Delegate(FOnFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)) , bUseLAN(false) { + bRunSecondSearch = false; } UFindSessionsCallbackProxyAdvanced* UFindSessionsCallbackProxyAdvanced::FindSessionsAdvanced(UObject* WorldContextObject, class APlayerController* PlayerController, int MaxResults, bool bUseLAN, EBPServerPresenceSearchType ServerTypeToSearch, const TArray &Filters, bool bEmptyServersOnly, bool bNonEmptyServersOnly, bool bSecureServersOnly, int MinSlotsAvailable) @@ -40,6 +41,9 @@ void UFindSessionsCallbackProxyAdvanced::Activate() auto Sessions = Helper.OnlineSub->GetSessionInterface(); if (Sessions.IsValid()) { + // Re-initialize here, otherwise I think there might be issues with people re-calling search for some reason before it is destroyed + bRunSecondSearch = false; + DelegateHandle = Sessions->AddOnFindSessionsCompleteDelegate_Handle(Delegate); SearchObject = MakeShareable(new FOnlineSessionSearch); @@ -81,6 +85,18 @@ void UFindSessionsCallbackProxyAdvanced::Activate() if (MinSlotsAvailable != 0) tem.Set(SEARCH_MINSLOTSAVAILABLE, MinSlotsAvailable, EOnlineComparisonOp::GreaterThanEquals); + + + // Filter results + if (SearchSettings.Num() > 0) + { + for (int i = 0; i < SearchSettings.Num(); i++) + { + // Function that was added to make directly adding a FVariant possible + tem.HardSet(SearchSettings[i].PropertyKeyPair.Key, SearchSettings[i].PropertyKeyPair.Data, SearchSettings[i].ComparisonOp); + } + } + switch (ServerSearchType) { @@ -99,28 +115,26 @@ void UFindSessionsCallbackProxyAdvanced::Activate() case EBPServerPresenceSearchType::AllServers: default: { - // tem.Set(SEARCH_DEDICATED_ONLY, false, EOnlineComparisonOp::Equals); - // tem.Set(SEARCH_PRESENCE, false, EOnlineComparisonOp::Equals); + bRunSecondSearch = true; + + SearchObjectDedicated = MakeShareable(new FOnlineSessionSearch); + SearchObjectDedicated->MaxSearchResults = MaxResults; + SearchObjectDedicated->bIsLanQuery = bUseLAN; + + FOnlineSearchSettingsEx DedicatedOnly = tem; + tem.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals); + + DedicatedOnly.Set(SEARCH_DEDICATED_ONLY, true, EOnlineComparisonOp::Equals); + SearchObjectDedicated->QuerySettings = DedicatedOnly; } break; - - } - - // Filter results - if (SearchSettings.Num() > 0) - { - for (int i = 0; i < SearchSettings.Num(); i++) - { - // Function that was added to make directly adding a FVariant possible - tem.HardSet(SearchSettings[i].PropertyKeyPair.Key, SearchSettings[i].PropertyKeyPair.Data, SearchSettings[i].ComparisonOp); - } } // Copy the derived temp variable over to it's base class SearchObject->QuerySettings = tem; Sessions->FindSessions(*Helper.UserID, SearchObject.ToSharedRef()); - + // OnQueryCompleted will get called, nothing more to do now return; } @@ -131,8 +145,7 @@ void UFindSessionsCallbackProxyAdvanced::Activate() } // Fail immediately - TArray Results; - OnFailure.Broadcast(Results); + OnFailure.Broadcast(SessionSearchResults); } void UFindSessionsCallbackProxyAdvanced::OnCompleted(bool bSuccess) @@ -140,7 +153,7 @@ void UFindSessionsCallbackProxyAdvanced::OnCompleted(bool bSuccess) FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("FindSessionsCallback"), GEngine->GetWorldFromContextObject(WorldContextObject)); Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); - if (Helper.IsValid()) + if (!bRunSecondSearch && Helper.IsValid()) { auto Sessions = Helper.OnlineSub->GetSessionInterface(); if (Sessions.IsValid()) @@ -149,51 +162,43 @@ void UFindSessionsCallbackProxyAdvanced::OnCompleted(bool bSuccess) } } - TArray Results; - if (bSuccess && SearchObject.IsValid()) { // Just log the results for now, will need to add a blueprint-compatible search result struct for (auto& Result : SearchObject->SearchResults) { - /* bool bAddResult = true; + FString ResultText = FString::Printf(TEXT("Found a session. Ping is %d"), Result.PingInMs); - // Filter results - if (SearchSettings.Num() > 0) - { - FOnlineSessionSetting * setting; - for (int i = 0; i < SearchSettings.Num(); i++) - { - setting = Result.Session.SessionSettings.Settings.Find(SearchSettings[i].PropertyKeyPair.Key); + FFrame::KismetExecutionMessage(*ResultText, ELogVerbosity::Log); - // Couldn't find this key - if (!setting) - continue; - - if (!CompareVariants(setting->Data, SearchSettings[i].PropertyKeyPair.Data, SearchSettings[i].ComparisonOp)) - { - bAddResult = false; - break; - } - } - }*/ - - //if (bAddResult) - //{ - FString ResultText = FString::Printf(TEXT("Found a session. Ping is %d"), Result.PingInMs); - - FFrame::KismetExecutionMessage(*ResultText, ELogVerbosity::Log); - - FBlueprintSessionResult BPResult; - BPResult.OnlineResult = Result; - Results.Add(BPResult); - //} + FBlueprintSessionResult BPResult; + BPResult.OnlineResult = Result; + SessionSearchResults.Add(BPResult); + } + if (!bRunSecondSearch) + { + OnSuccess.Broadcast(SessionSearchResults); + return; } - OnSuccess.Broadcast(Results); } else { - OnFailure.Broadcast(Results); + if (!bRunSecondSearch) + { + // Need to account for only one of the searches failing + if(SessionSearchResults.Num() > 0) + OnSuccess.Broadcast(SessionSearchResults); + else + OnFailure.Broadcast(SessionSearchResults); + return; + } + } + + if (bRunSecondSearch && ServerSearchType == EBPServerPresenceSearchType::AllServers) + { + bRunSecondSearch = false; + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + Sessions->FindSessions(*Helper.UserID, SearchObjectDedicated.ToSharedRef()); } } diff --git a/Source/AdvancedSessions/Private/SteamFuncs/AdvancedSteamWorkshopLibrary.cpp b/Source/AdvancedSessions/Private/SteamFuncs/AdvancedSteamWorkshopLibrary.cpp index 7856800..cb59c47 100644 --- a/Source/AdvancedSessions/Private/SteamFuncs/AdvancedSteamWorkshopLibrary.cpp +++ b/Source/AdvancedSessions/Private/SteamFuncs/AdvancedSteamWorkshopLibrary.cpp @@ -1,32 +1,6 @@ // Fill out your copyright notice in the Description page of Project Settings. #include "OnlineSubSystemHeader.h" #include "SteamFuncs/AdvancedSteamWorkshopLibrary.h" - - -// This is taken directly from UE4 - OnlineSubsystemSteamPrivatePCH.h as a fix for the array_count macro -// @todo Steam: Steam headers trigger secure-C-runtime warnings in Visual C++. Rather than mess with _CRT_SECURE_NO_WARNINGS, we'll just -// disable the warnings locally. Remove when this is fixed in the SDK -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4996) -#endif - -#if PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX - -#pragma push_macro("ARRAY_COUNT") -#undef ARRAY_COUNT - -#include - -#pragma pop_macro("ARRAY_COUNT") - -#endif - -// @todo Steam: See above -#ifdef _MSC_VER -#pragma warning(pop) -#endif - //General Log DEFINE_LOG_CATEGORY(AdvancedSteamWorkshopLog); diff --git a/Source/AdvancedSessions/Private/SteamFuncs/SteamWSRequestUGCDetailsCallbackProxy.cpp b/Source/AdvancedSessions/Private/SteamFuncs/SteamWSRequestUGCDetailsCallbackProxy.cpp index 511833e..e3c7035 100644 --- a/Source/AdvancedSessions/Private/SteamFuncs/SteamWSRequestUGCDetailsCallbackProxy.cpp +++ b/Source/AdvancedSessions/Private/SteamFuncs/SteamWSRequestUGCDetailsCallbackProxy.cpp @@ -9,6 +9,7 @@ USteamWSRequestUGCDetailsCallbackProxy::USteamWSRequestUGCDetailsCallbackProxy(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { + NumSecondsBeforeTimeout = 4.0f; } @@ -31,59 +32,23 @@ void USteamWSRequestUGCDetailsCallbackProxy::Activate() return; } #endif - OnFailure.Broadcast(); + OnFailure.Broadcast(FBPSteamWorkshopItemDetails()); } void USteamWSRequestUGCDetailsCallbackProxy::OnUGCRequestUGCDetails(SteamUGCRequestUGCDetailsResult_t *pResult, bool bIOFailure) { #if PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX - if (bIOFailure) + if (bIOFailure || !pResult) { - OnFailure.Broadcast(); + OnFailure.Broadcast(FBPSteamWorkshopItemDetails()); return; } - SteamUGCDetails_t hUGCDetails = pResult->m_details; - GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Green, hUGCDetails.m_rgchTitle); - GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Green, hUGCDetails.m_rgchDescription); - - OnSuccess.Broadcast(); + OnSuccess.Broadcast(FBPSteamWorkshopItemDetails(pResult->m_details)); return; #endif - OnFailure.Broadcast(); - /* - PublishedFileId_t m_nPublishedFileId; - EResult m_eResult; // The result of the operation. - EWorkshopFileType m_eFileType; // Type of the file - AppId_t m_nCreatorAppID; // ID of the app that created this file. - AppId_t m_nConsumerAppID; // ID of the app that will consume this file. - char m_rgchTitle[k_cchPublishedDocumentTitleMax]; // title of document - char m_rgchDescription[k_cchPublishedDocumentDescriptionMax]; // description of document - uint64 m_ulSteamIDOwner; // Steam ID of the user who created this content. - uint32 m_rtimeCreated; // time when the published file was created - uint32 m_rtimeUpdated; // time when the published file was last updated - uint32 m_rtimeAddedToUserList; // time when the user added the published file to their list (not always applicable) - ERemoteStoragePublishedFileVisibility m_eVisibility; // visibility - bool m_bBanned; // whether the file was banned - bool m_bAcceptedForUse; // developer has specifically flagged this item as accepted in the Workshop - bool m_bTagsTruncated; // whether the list of tags was too long to be returned in the provided buffer - char m_rgchTags[k_cchTagListMax]; // comma separated list of all tags associated with this file - // file/url information - UGCHandle_t m_hFile; // The handle of the primary file - UGCHandle_t m_hPreviewFile; // The handle of the preview file - char m_pchFileName[k_cchFilenameMax]; // The cloud filename of the primary file - int32 m_nFileSize; // Size of the primary file - int32 m_nPreviewFileSize; // Size of the preview file - char m_rgchURL[k_cchPublishedFileURLMax]; // URL (for a video or a website) - // voting information - uint32 m_unVotesUp; // number of votes up - uint32 m_unVotesDown; // number of votes down - float m_flScore; // calculated score - uint32 m_unNumChildren; // if m_eFileType == k_EWorkshopFileTypeCollection, then this number will be the number of children contained within the collection - - - */ + OnFailure.Broadcast(FBPSteamWorkshopItemDetails()); }