Any idea how to write this in c++? Regarding Steam Workshop setup

I have been following various tutorials and whatnot to sort of frankenstein my own setup for uploading objects to Steam Workshop.

I have the below code in my game instance h file:

UCLASS()
class DUNGEON3D_API UDungeonGameInstance : public UGameInstance
{
	GENERATED_BODY()
	
public:

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GameInstance|SteamWorkshop")
		FString CommunityFileUrl = "steam://url/CommunityFilePage/";
	UFUNCTION()
		virtual void CreateSteamWorkshopItem();
private:

	void onItemCreated(CreateItemResult_t* pCallback, bool bIOFailure);
	void onItemSubmitted(SubmitItemUpdateResult_t* pCallback, bool bIOFailure);

	CCallResult<UDungeonGameInstance, CreateItemResult_t> m_CreateItemResult;
	CCallResult<UDungeonGameInstance, SubmitItemUpdateResult_t> m_SubmitItemUpdateResult;

};

And my cpp file below:

void UDungeonGameInstance::CreateSteamWorkshopItem()
{
    SteamAPICall_t hSteamAPICall = SteamUGC()->CreateItem(SteamUtils()->GetAppID(), k_EWorkshopFileTypeCommunity);
    m_CreateItemResult.Set(hSteamAPICall, this, &UDungeonGameInstance::onItemCreated);
}

void UDungeonGameInstance::onItemCreated(CreateItemResult_t* pCallback, bool bIOFailure)
{
    if (pCallback->m_eResult == k_EResultOK && !bIOFailure)
    {
        UE_LOG(LogTemp, Warning, TEXT("Item created!"));

        if (pCallback->m_bUserNeedsToAcceptWorkshopLegalAgreement)
        {
            char* fileurl;
            fileurl = (TCHAR_TO_UTF8(*CommunityFileUrl));
            SteamFriends()->ActivateGameOverlayToWebPage(fileurl);
        }

        UGCUpdateHandle_t handle = SteamUGC()->StartItemUpdate(SteamUtils()->GetAppID(), pCallback->m_nPublishedFileId);

        SteamUGC()->SetItemTitle(handle, "D3D test");
        SteamUGC()->SetItemDescription(handle, "Description test");
        SteamUGC()->SetItemUpdateLanguage(handle, "None");
        SteamUGC()->SetItemMetadata(handle, "Test metadata");
        SteamUGC()->SetItemVisibility(handle, k_ERemoteStoragePublishedFileVisibilityPublic);

        SteamParamStringArray_t* pTags = new SteamParamStringArray_t();
        pTags->m_ppStrings = new const char* [1];
        pTags->m_ppStrings[0] = "stage";
        pTags->m_nNumStrings = 1;
        SteamUGC()->SetItemTags(handle, pTags);
        SteamUGC()->AddItemKeyValueTag(handle, "test_key", "test_value");
        std::string mod_directory = "/Mods";
        SteamUGC()->SetItemContent(handle, mod_directory.c_str());
        std::string preview_image = "Mods/preview.png";
        SteamUGC()->SetItemPreview(handle, preview_image.c_str());

        std::string pchChangeNote = "D3D changelog test.";

        SteamAPICall_t submit_item_call = SteamUGC()->SubmitItemUpdate(handle, pchChangeNote.c_str());
        m_SubmitItemUpdateResult.Set(submit_item_call, this, &UDungeonGameInstance::onItemSubmitted);
    }
    else
    {
        UE_LOG(LogTemp, Warning, TEXT("Failed to create item!"));
        return;
    }
}

void UDungeonGameInstance::onItemSubmitted(SubmitItemUpdateResult_t* pCallback, bool bIOFailure)
{
    if (pCallback->m_eResult == k_EResultOK && !bIOFailure)
    {
        UE_LOG(LogTemp, Warning, TEXT("Updated item submitted!"));
    }
    return;
}

I THINK it should work, but I am missing a vital line that I can’t figure out how to translate properly to c++. I am assuming I need to set a delegate, but my various attempts so far have failed and I just need some guidance on the delegate itself and how to write this out. This is the part I need to add:

this.OnCreateItemResultCallResult = CallResult<CreateItemResult_t>.Create(this.OnCreateItemResult);

Basically I need to add a ‘Call result handler’ for CreateItemResult_t. Again, it looks like it’s basically a delegate to me. I’ve made a few delegates here and there over the last couple of months of really diving into c++, and I’m fairly comfortable with them, but I am unable to write this thing correctly regardless of all my attempts. I would very much appreciate some help.

For reference:

https://partner.steamgames.com/doc/features/workshop/implementation

Would super appreciate some insight!

I think your setup looks ok but you need to trigger the callbacks.
Steam recommends doing it at >10hz so it’s probably ok to do it in Tick :

void UDungeonGameInstance::Tick(float dt)
{
    Super::Tick(dt);
    SteamAPI_RunCallbacks();
}

Shouldn’t that happen automatically (assuming the engine is configured to use OSSSteam)? https://github.com/EpicGames/UnrealEngine/blob/a3cb3d8fdec1fc32f071ae7d22250f33f80b21c4/Engine/Plugins/Online/OnlineSubsystemSteam/Source/Private/OnlineAsyncTaskManagerSteam.cpp#L20

Oh I’m a dummy, that’s what I was missing, haha! Now it works, thank you.

I needed to actually tell it to run the callbacks, for whatever reason it wasn’t doing it automatically. But adding that, now it works!

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