浏览代码

Implemented ISteamUGC API.

woollybah 5 年之前
父节点
当前提交
cc8febfb36
共有 4 个文件被更改,包括 2209 次插入4 次删除
  1. 2 0
      .gitignore
  2. 119 1
      steamsdk.mod/common.bmx
  3. 747 0
      steamsdk.mod/glue/glue.cpp
  4. 1341 3
      steamsdk.mod/steamsdk.bmx

+ 2 - 0
.gitignore

@@ -1,2 +1,4 @@
 *.bak
 .bmx
+*.i
+*.i2

+ 119 - 1
steamsdk.mod/common.bmx

@@ -43,6 +43,7 @@ Extern
 	Function bmx_SteamAPI_ISteamClient_GetISteamUtils:Byte Ptr(inst:Byte Ptr, pipe:UInt, version:String)
 	Function bmx_SteamAPI_ISteamClient_ConnectToGlobalUser:Int(inst:Byte Ptr, pipe:UInt)
 	Function bmx_SteamAPI_ISteamClient_GetISteamUserStats:Byte Ptr(inst:Byte Ptr, user:Int, pipe:UInt, version:String)
+	Function bmx_SteamAPI_ISteamClient_GetISteamUGC:Byte Ptr(inst:Byte Ptr, user:Int, pipe:UInt, version:String)
 
 	Function bmx_steamsdk_register_steamuutils:Byte Ptr(inst:Byte Ptr, obj:Object)
 	Function bmx_steamsdk_unregister_steamutils(callbackPtr:Byte Ptr)
@@ -109,8 +110,106 @@ Extern
 	Function bmx_SteamAPI_ISteamUserStats_UpdateAvgRateStat:Int(inst:Byte Ptr, name:String, countThisSession:Float, sessionLength:Double)
 	Function bmx_SteamAPI_ISteamUserStats_UploadLeaderboardScore(callback:Byte Ptr, leaderboardHandle:ULong, uploadScoreMethod:ELeaderboardUploadScoreMethod, score:Int, scoreDetails:Int Ptr, count:Int)
 
+	Function bmx_steamsdk_register_steamugc:Byte Ptr(inst:Byte Ptr, obj:Object)
+	Function bmx_steamsdk_unregister_steamugc(callbackPtr:Byte Ptr)
+	
+	Function bmx_SteamAPI_ISteamUGC_AddAppDependency(callback:Byte Ptr, publishedFileID:ULong, appID:UInt)
+	Function bmx_SteamAPI_ISteamUGC_AddDependency(callback:Byte Ptr, publishedFileId:ULong, childPublishedFileId:ULong)
+	Function bmx_SteamAPI_ISteamUGC_AddExcludedTag:Int(inst:Byte Ptr, queryHandle:ULong, tagName:String)
+	Function bmx_SteamAPI_ISteamUGC_AddItemKeyValueTag:Int(inst:Byte Ptr, queryHandle:ULong, key:String, value:String)
+	Function bmx_SteamAPI_ISteamUGC_AddItemPreviewFile:Int(inst:Byte Ptr, queryHandle:ULong, previewFile:String, previewType:EItemPreviewType)
+	Function bmx_SteamAPI_ISteamUGC_AddItemPreviewVideo:Int(inst:Byte Ptr, queryHandle:ULong, videoID:String)
+	Function bmx_SteamAPI_ISteamUGC_AddItemToFavorites(callback:Byte Ptr, appId:UInt, publishedFileID:ULong)
+	Function bmx_SteamAPI_ISteamUGC_AddRequiredKeyValueTag:Int(inst:Byte Ptr, queryHandle:ULong, key:String, value:String)
+	Function bmx_SteamAPI_ISteamUGC_AddRequiredTag:Int(inst:Byte Ptr, queryHandle:ULong, tagName:String)
+	Function bmx_SteamAPI_ISteamUGC_InitWorkshopForGameServer:Int(inst:Byte Ptr, workshopDepotID:ULong, folder:String)
+	Function bmx_SteamAPI_ISteamUGC_CreateItem(callback:Byte Ptr, consumerAppId:UInt, FileType:EWorkshopFileType)
+	Function bmx_SteamAPI_ISteamUGC_CreateQueryAllUGCRequest:ULong(inst:Byte Ptr, queryType:EUGCQuery, matchingeMatchingUGCTypeFileType:EUGCMatchingUGCType, creatorAppID:UInt, consumerAppID:UInt, page:UInt)
+	Function bmx_SteamAPI_ISteamUGC_CreateQueryUGCDetailsRequest:ULong(inst:Byte Ptr, publishedFileIDs:ULong Ptr, numPublishedFileIDs:Int)
+	Function bmx_SteamAPI_ISteamUGC_CreateQueryUserUGCRequest:ULong(inst:Byte Ptr, accountID:UInt, listType:EUserUGCList, matchingUGCType:EUGCMatchingUGCType, sortOrder:EUserUGCListSortOrder, creatorAppID:UInt, consumerAppID:UInt, page:UInt)
+	Function bmx_SteamAPI_ISteamUGC_DeleteItem(callback:Byte Ptr, publishedFileID:ULong)
+	Function bmx_SteamAPI_ISteamUGC_DownloadItem:Int(inst:Byte Ptr, publishedFileID:ULong, highPriority:Int)
+	Function bmx_SteamAPI_ISteamUGC_GetAppDependencies(callback:Byte Ptr, publishedFileID:ULong)
+	Function bmx_SteamAPI_ISteamUGC_GetItemDownloadInfo:Int(inst:Byte Ptr, publishedFileID:ULong, bytesDownloaded:ULong Var, bytesTotal:ULong Var)
+	Function bmx_SteamAPI_ISteamUGC_GetItemInstallInfo:Int(inst:Byte Ptr, publishedFileID:ULong, sizeOnDisk:ULong Var, folder:String Var, timestamp:UInt Var)
+	Function bmx_SteamAPI_ISteamUGC_GetItemState:EItemState(inst:Byte Ptr, publishedFileID:ULong)
+	Function bmx_SteamAPI_ISteamUGC_GetItemUpdateProgress:EItemUpdateStatus(inst:Byte Ptr, queryHandle:ULong, bytesProcessed:ULong Var, bytesTotal:ULong Var)
+	Function bmx_SteamAPI_ISteamUGC_GetNumSubscribedItems:UInt(inst:Byte Ptr)
+	Function bmx_SteamAPI_ISteamUGC_GetQueryUGCAdditionalPreview:Int(inst:Byte Ptr, queryHandle:ULong, index:UInt, previewIndex:UInt, URLOrVideoID:String Var, originalFileName:String Var, previewType:EItemPreviewType Var)
+	Function bmx_SteamAPI_ISteamUGC_GetQueryUGCChildren:Int(inst:Byte Ptr, queryHandle:ULong, index:UInt, publishedFileIDs:ULong Ptr, maxEntries:UInt)
+	Function bmx_SteamAPI_ISteamUGC_GetQueryUGCKeyValueTag:Int(inst:Byte Ptr, queryHandle:ULong, index:UInt, keyValueTagIndex:UInt, key:String Var, value:String Var)
+	Function bmx_SteamAPI_ISteamUGC_GetQueryUGCMetadata:Int(inst:Byte Ptr, queryHandle:ULong, index:UInt, metadata:String Var)
+	Function bmx_SteamAPI_ISteamUGC_GetQueryUGCNumAdditionalPreviews:UInt(inst:Byte Ptr, queryHandle:ULong, index:UInt)
+	Function bmx_SteamAPI_ISteamUGC_GetQueryUGCNumKeyValueTags:UInt(inst:Byte Ptr, queryHandle:ULong, index:UInt)
+	Function bmx_SteamAPI_ISteamUGC_GetQueryUGCPreviewURL:Int(inst:Byte Ptr, queryHandle:ULong, index:UInt, URL:String Var)
+	Function bmx_SteamAPI_ISteamUGC_GetQueryUGCStatistic:Int(inst:Byte Ptr, queryHandle:ULong, index:UInt, statType:EItemStatistic, statValue:ULong Var)
+	Function bmx_SteamAPI_ISteamUGC_GetSubscribedItems:UInt(inst:Byte Ptr, publishedFileIDs:ULong Ptr, maxEntries:UInt)
+	Function bmx_SteamAPI_ISteamUGC_GetUserItemVote(callback:Byte Ptr, publishedFileID:ULong)
+	Function bmx_SteamAPI_ISteamUGC_ReleaseQueryUGCRequest:Int(inst:Byte Ptr, queryHandle:ULong)
+	Function bmx_SteamAPI_ISteamUGC_RemoveAppDependency(callback:Byte Ptr, publishedFileID:ULong, appID:UInt)
+	Function bmx_SteamAPI_ISteamUGC_RemoveDependency(callback:Byte Ptr, parentPublishedFileID:ULong, childPublishedFileID:ULong)
+	Function bmx_SteamAPI_ISteamUGC_RemoveItemFromFavorites(callback:Byte Ptr, appId:UInt, publishedFileID:ULong)
+	Function bmx_SteamAPI_ISteamUGC_RemoveItemKeyValueTags:Int(inst:Byte Ptr, queryHandle:ULong, key:String)
+	Function bmx_SteamAPI_ISteamUGC_RemoveItemPreview:Int(inst:Byte Ptr, queryHandle:ULong, index:UInt)
+	Function bmx_SteamAPI_ISteamUGC_SendQueryUGCRequest(callback:Byte Ptr, queryHandle:ULong)
+	Function bmx_SteamAPI_ISteamUGC_SetAllowCachedResponse:Int(inst:Byte Ptr, queryHandle:ULong, maxAgeSeconds:UInt)
+	Function bmx_SteamAPI_ISteamUGC_SetCloudFileNameFilter:Int(inst:Byte Ptr, queryHandle:ULong, matchCloudFileName:String)
+	Function bmx_SteamAPI_ISteamUGC_SetItemContent:Int(inst:Byte Ptr, updateHandle:ULong, contentFolder:String)
+	Function bmx_SteamAPI_ISteamUGC_SetItemDescription:Int(inst:Byte Ptr, updateHandle:ULong, description:String)
+	Function bmx_SteamAPI_ISteamUGC_SetItemMetadata:Int(inst:Byte Ptr, updateHandle:ULong, metaData:String)
+	Function bmx_SteamAPI_ISteamUGC_SetItemPreview:Int(inst:Byte Ptr, updateHandle:ULong, previewFile:String)
+	Function bmx_SteamAPI_ISteamUGC_SetItemTags:Int(inst:Byte Ptr, updateHandle:ULong, tags:String[])
+	Function bmx_SteamAPI_ISteamUGC_SetItemTitle:Int(inst:Byte Ptr, updateHandle:ULong, title:String)
+	Function bmx_SteamAPI_ISteamUGC_SetItemUpdateLanguage:Int(inst:Byte Ptr, updateHandle:ULong, language:String)
+	Function bmx_SteamAPI_ISteamUGC_SetItemVisibility:Int(inst:Byte Ptr, updateHandle:ULong, visibility:ERemoteStoragePublishedFileVisibility)
+	Function bmx_SteamAPI_ISteamUGC_SetLanguage:Int(inst:Byte Ptr, queryHandle:ULong, language:String)
+	Function bmx_SteamAPI_ISteamUGC_SetMatchAnyTag:Int(inst:Byte Ptr, queryHandle:ULong, matchAnyTag:Int)
+	Function bmx_SteamAPI_ISteamUGC_SetRankedByTrendDays:Int(inst:Byte Ptr, queryHandle:ULong, days:UInt)
+	Function bmx_SteamAPI_ISteamUGC_SetReturnAdditionalPreviews:Int(inst:Byte Ptr, queryHandle:ULong, returnAdditionalPreviews:Int)
+	Function bmx_SteamAPI_ISteamUGC_SetReturnChildren:Int(inst:Byte Ptr, queryHandle:ULong, returnChildren:Int)
+	Function bmx_SteamAPI_ISteamUGC_SetReturnKeyValueTags:Int(inst:Byte Ptr, queryHandle:ULong, returnKeyValueTags:Int)
+	Function bmx_SteamAPI_ISteamUGC_SetReturnLongDescription:Int(inst:Byte Ptr, queryHandle:ULong, returnLongDescription:Int)
+	Function bmx_SteamAPI_ISteamUGC_SetReturnMetadata:Int(inst:Byte Ptr, queryHandle:ULong, returnMetadata:Int)
+	Function bmx_SteamAPI_ISteamUGC_SetReturnOnlyIDs:Int(inst:Byte Ptr, queryHandle:ULong, returnOnlyIDs:Int)
+	Function bmx_SteamAPI_ISteamUGC_SetReturnPlaytimeStats:Int(inst:Byte Ptr, queryHandle:ULong, days:UInt)
+	Function bmx_SteamAPI_ISteamUGC_SetReturnTotalOnly:Int(inst:Byte Ptr, queryHandle:ULong, returnTotalOnly:Int)
+	Function bmx_SteamAPI_ISteamUGC_SetSearchText:Int(inst:Byte Ptr, queryHandle:ULong, searchText:String)
+	Function bmx_SteamAPI_ISteamUGC_SetUserItemVote(callback:Byte Ptr, publishedFileID:ULong, voteUp:Int)
+	Function bmx_SteamAPI_ISteamUGC_StartItemUpdate:ULong(inst:Byte Ptr, consumerAppId:UInt, publishedFileID:ULong)
+	Function bmx_SteamAPI_ISteamUGC_StartPlaytimeTracking(callback:Byte Ptr, publishedFileIDs:ULong Ptr, numPublishedFileIDs:UInt)
+	Function bmx_SteamAPI_ISteamUGC_StopPlaytimeTracking(callback:Byte Ptr, publishedFileIDs:ULong Ptr, numPublishedFileIDs:UInt)
+	Function bmx_SteamAPI_ISteamUGC_StopPlaytimeTrackingForAllItems(callback:Byte Ptr)
+	Function bmx_SteamAPI_ISteamUGC_SubmitItemUpdate(callback:Byte Ptr, updateHandle:ULong, changeNote:String)
+	Function bmx_SteamAPI_ISteamUGC_SubscribeItem(callback:Byte Ptr, publishedFileID:ULong)
+	Function bmx_SteamAPI_ISteamUGC_SuspendDownloads(inst:Byte Ptr, suspend:Int)
+	Function bmx_SteamAPI_ISteamUGC_UnsubscribeItem(callback:Byte Ptr, publishedFileID:ULong)
+	Function bmx_SteamAPI_ISteamUGC_UpdateItemPreviewFile:Int(inst:Byte Ptr, updateHandle:ULong, index:UInt, previewFile:String)
+	Function bmx_SteamAPI_ISteamUGC_UpdateItemPreviewVideo:Int(inst:Byte Ptr, updateHandle:ULong, index:UInt, videoID:String)
+	
 End Extern
 
+Rem
+bbdoc: Used to specify an invalid query handle.
+about: This is frequently returned if a call fails.
+End Rem
+Const k_UGCQueryHandleInvalid:ULong = $ffffffffffffffff:ULong
+Rem
+bbdoc: Used to specify an invalid item update handle.
+about: This is frequently returned if a call fails.
+End Rem
+Const k_UGCUpdateHandleInvalid:ULong = $ffffffffffffffff:ULong
+Rem
+bbdoc: The maximum size in bytes that a Workshop item description can be.
+End Rem
+Const k_cchPublishedDocumentDescriptionMax:UInt = 8000
+Rem
+bbdoc: The maximum amount of bytes you can set with #SetItemMetadata.
+End Rem
+Const k_cchDeveloperMetadataMax:UInt = 5000
+Rem
+bbdoc: The maximum size in bytes that a Workshop item title can be.
+End Rem
+Const k_cchPublishedDocumentTitleMax:UInt = 128 + 1
 
 ' // GENERATED
 
@@ -731,12 +830,18 @@ Enum ERemoteStoragePlatform Flags
 	k_ERemoteStoragePlatformAll = -1
 End Enum
 
+Rem
+bbdoc: Possible visibility states that a Workshop item can be in.
+End Rem
 Enum ERemoteStoragePublishedFileVisibility
 	k_ERemoteStoragePublishedFileVisibilityPublic = 0
 	k_ERemoteStoragePublishedFileVisibilityFriendsOnly = 1
 	k_ERemoteStoragePublishedFileVisibilityPrivate = 2
 End Enum
 
+Rem
+bbdoc: The way that a shared file will be shared with the community.
+End Rem
 Enum EWorkshopFileType
 	k_EWorkshopFileTypeFirst = 0
 	k_EWorkshopFileTypeCommunity = 0
@@ -1591,6 +1696,9 @@ Enum ESteamControllerLEDFlag
 	k_ESteamControllerLEDFlag_RestoreUserDefault = 1
 End Enum
 
+Rem
+bbdoc: Specifies the types of UGC to obtain from a call to #CreateQueryUserUGCRequest or #CreateQueryAllUGCRequest.
+End Rem
 Enum EUGCMatchingUGCType
 	k_EUGCMatchingUGCType_Items = 0
 	k_EUGCMatchingUGCType_Items_Mtx = 1
@@ -1608,6 +1716,9 @@ Enum EUGCMatchingUGCType
 	k_EUGCMatchingUGCType_All = -1
 End Enum
 
+Rem
+bbdoc: Used with #CreateQueryUserUGCRequest to obtain different lists of published UGC for a user.
+End Rem
 Enum EUserUGCList
 	k_EUserUGCList_Published = 0
 	k_EUserUGCList_VotedOn = 1
@@ -1630,6 +1741,9 @@ Enum EUserUGCListSortOrder
 	k_EUserUGCListSortOrder_ForModeration = 6
 End Enum
 
+Rem
+bbdoc: Used with #CreateQueryAllUGCRequest to specify the sorting and filtering for queries across all available UGC.
+End Rem
 Enum EUGCQuery
 	k_EUGCQuery_RankedByVote = 0
 	k_EUGCQuery_RankedByPublicationDate = 1
@@ -1661,7 +1775,7 @@ Enum EItemUpdateStatus
 	k_EItemUpdateStatusCommittingChanges = 5
 End Enum
 
-Enum EItemState
+Enum EItemState Flags
 	k_EItemStateNone = 0
 	k_EItemStateSubscribed = 1
 	k_EItemStateLegacyItem = 2
@@ -1687,6 +1801,10 @@ Enum EItemStatistic
 	k_EItemStatistic_NumPlaytimeSessionsDuringTimePeriod = 12
 End Enum
 
+Rem
+bbdoc: Flags that specify the type of preview an item has. 
+about: Set with #AddItemPreviewFile, and received with #GetQueryUGCAdditionalPreview.
+End Rem
 Enum EItemPreviewType
 	k_EItemPreviewType_Image = 0
 	k_EItemPreviewType_YouTubeVideo = 1

+ 747 - 0
steamsdk.mod/glue/glue.cpp

@@ -31,6 +31,11 @@
 
 class MaxUtils;
 class MaxUserStats;
+class MaxUGC;
+
+#define BUFFER_SIZE 2048
+#define VALUE_SIZE 16384
+#define METADATA_SIZE 5000
 
 extern "C" {
 
@@ -51,6 +56,24 @@ extern "C" {
 	void steam_steamsdk_TSteamUserStats__OnUserAchievementIconFetched(BBObject * maxHandle, uint64 gameID, BBString * achievementName, int achieved, int iconHandle);
 	void steam_steamsdk_TSteamUserStats__OnUserAchievementStored(BBObject * maxHandle, uint64 gameID, int groupAchievement, BBString * achievementName, uint32 curProgress, uint32 maxProgress);
 
+	void steam_steamsdk_TSteamUGC__OnAddAppDependency(BBObject * maxHandle, EResult result, uint64 publishedFileId, uint32 appID);
+	void steam_steamsdk_TSteamUGC__OnAddDependency(BBObject * maxHandle, EResult result, uint64 publishedFileId, uint64 childPublishedFileId);
+	void steam_steamsdk_TSteamUGC__OnUserFavoriteItemsListChanged(BBObject * maxHandle, uint64 publishedFileId, EResult result, int wasAddRequest);
+	void steam_steamsdk_TSteamUGC__OnCreateItem(BBObject * maxHandle, EResult result, uint64 publishedFileId, int userNeedsToAcceptWorkshopLegalAgreement);
+	void steam_steamsdk_TSteamUGC__OnDeleteItem(BBObject * maxHandle, EResult result, uint64 publishedFileId);
+	void steam_steamsdk_TSteamUGC__OnDownloadItem(BBObject * maxHandle, EResult result, uint32 appID, uint64 publishedFileId);
+	void steam_steamsdk_TSteamUGC__OnGetUserItemVote(BBObject * maxHandle, uint64 publishedFileId, EResult result, int votedUp, int votedDown, int voteSkipped);
+	void steam_steamsdk_TSteamUGC__OnRemoveAppDependency(BBObject * maxHandle, EResult result, uint64 publishedFileId, uint32 appID);
+	void steam_steamsdk_TSteamUGC__OnRemoveUGCDependency(BBObject * maxHandle, EResult result, uint64 publishedFileId, uint64 childPublishedFileId);
+	void steam_steamsdk_TSteamUGC__OnSteamUGCQueryCompleted(BBObject * maxHandle, uint64 handle, EResult result, uint32 numResultsReturned, uint32 totalMatchingResults, int cachedData);
+	void steam_steamsdk_TSteamUGC__OnSetUserItemVote(BBObject * maxHandle, uint64 publishedFileId, EResult result, int voteUp);
+	void steam_steamsdk_TSteamUGC__OnStartPlaytimeTracking(BBObject * maxHandle, EResult result);
+	void steam_steamsdk_TSteamUGC__OnStopPlaytimeTracking(BBObject * maxHandle, EResult result);
+	void steam_steamsdk_TSteamUGC__OnGetAppDependencies(BBObject * maxHandle, EResult result, uint64 publishedFileId, uint32 * appID, int numAppDependencies, int totalNumAppDependencies);
+	void steam_steamsdk_TSteamUGC__OnSubmitItemUpdate(BBObject * maxHandle, EResult result, int userNeedsToAcceptWorkshopLegalAgreement);
+	void steam_steamsdk_TSteamUGC__OnRemoteStorageSubscribePublishedFile(BBObject * maxHandle, EResult result, uint64 publishedFileId);
+	void steam_steamsdk_TSteamUGC__OnRemoteStorageUnsubscribePublishedFile(BBObject * maxHandle, EResult result, uint64 publishedFileId);
+
 	int bmx_SteamAPI_Init();
 	void bmx_SteamAPI_Shutdown();
 	void bmx_SteamAPI_startBackgroundTimer();
@@ -67,6 +90,8 @@ extern "C" {
 	void * bmx_SteamAPI_ISteamClient_GetISteamUtils(intptr_t instancePtr, HSteamPipe pipe, BBString * version);
 	HSteamUser bmx_SteamAPI_ISteamClient_ConnectToGlobalUser(intptr_t instancePtr, HSteamPipe pipe);
 	void * bmx_SteamAPI_ISteamClient_GetISteamUserStats(intptr_t instancePtr, HSteamUser user, HSteamPipe pipe, BBString * version);
+	void * bmx_SteamAPI_ISteamClient_GetISteamUGC(intptr_t instancePtr, HSteamUser user, HSteamPipe pipe, BBString * version);
+
 
 	uint32 bmx_SteamAPI_ISteamUtils_GetSecondsSinceAppActive(intptr_t instancePtr);
 	uint32 bmx_SteamAPI_ISteamUtils_GetSecondsSinceComputerActive(intptr_t instancePtr);
@@ -132,6 +157,82 @@ extern "C" {
 	int bmx_SteamAPI_ISteamUserStats_StoreStats(intptr_t instancePtr);
 	int bmx_SteamAPI_ISteamUserStats_UpdateAvgRateStat(intptr_t instancePtr, BBString * name, float countThisSession, double sessionLength);
 	void bmx_SteamAPI_ISteamUserStats_UploadLeaderboardScore(MaxUserStats * userStats, uint64 leaderboardHandle, ELeaderboardUploadScoreMethod uploadScoreMethod, int score, int * scoreDetails, int count);
+
+	void * bmx_steamsdk_register_steamugc(intptr_t instancePtr, BBObject * obj);
+	void bmx_steamsdk_unregister_steamugc(void * callbackPtr);
+	
+	void bmx_SteamAPI_ISteamUGC_AddAppDependency(MaxUGC * ugc, uint64 publishedFileID, uint32 appID);
+	void bmx_SteamAPI_ISteamUGC_AddDependency(MaxUGC * ugc, uint64 publishedFileId, uint64 childPublishedFileId);
+	int bmx_SteamAPI_ISteamUGC_AddExcludedTag(intptr_t instancePtr, uint64 queryHandle, BBString * tagName);
+	int bmx_SteamAPI_ISteamUGC_AddItemKeyValueTag(intptr_t instancePtr, uint64 queryHandle, BBString * key, BBString * value);
+	int bmx_SteamAPI_ISteamUGC_AddItemPreviewFile(intptr_t instancePtr, uint64 queryHandle, BBString * previewFile, EItemPreviewType previewType);
+	int bmx_SteamAPI_ISteamUGC_AddItemPreviewVideo(intptr_t instancePtr, uint64 queryHandle, BBString * videoID);
+	void bmx_SteamAPI_ISteamUGC_AddItemToFavorites(MaxUGC * ugc, uint32 appId, uint64 publishedFileID);
+	int bmx_SteamAPI_ISteamUGC_AddRequiredKeyValueTag(intptr_t instancePtr, uint64 queryHandle, BBString * key, BBString * value);
+	int bmx_SteamAPI_ISteamUGC_AddRequiredTag(intptr_t instancePtr, uint64 queryHandle, BBString * tagName);
+	int bmx_SteamAPI_ISteamUGC_InitWorkshopForGameServer(intptr_t instancePtr, uint64 workshopDepotID, BBString * folder);
+	void bmx_SteamAPI_ISteamUGC_CreateItem(MaxUGC * ugc, uint32 consumerAppId, EWorkshopFileType fileType);
+	uint64 bmx_SteamAPI_ISteamUGC_CreateQueryAllUGCRequest(intptr_t instancePtr, EUGCQuery queryType, EUGCMatchingUGCType matchingeMatchingUGCTypeFileType, uint32 creatorAppID, uint32 consumerAppID, uint32 page);
+	uint64 bmx_SteamAPI_ISteamUGC_CreateQueryUGCDetailsRequest(intptr_t instancePtr, uint64 * publishedFileIDs, int numPublishedFileIDs);
+	uint64 bmx_SteamAPI_ISteamUGC_CreateQueryUserUGCRequest(intptr_t instancePtr, uint32 accountID, EUserUGCList listType, EUGCMatchingUGCType matchingUGCType, EUserUGCListSortOrder sortOrder, uint32 creatorAppID, uint32 consumerAppID, uint32 page);
+	void bmx_SteamAPI_ISteamUGC_DeleteItem(MaxUGC * ugc, uint64 publishedFileID);
+	int bmx_SteamAPI_ISteamUGC_DownloadItem(intptr_t instancePtr, uint64 publishedFileID, int highPriority);
+	void bmx_SteamAPI_ISteamUGC_GetAppDependencies(MaxUGC * ugc, uint64 publishedFileID);
+	int bmx_SteamAPI_ISteamUGC_GetItemDownloadInfo(intptr_t instancePtr, uint64 publishedFileID, uint64 * bytesDownloaded, uint64 * bytesTotal);
+	int bmx_SteamAPI_ISteamUGC_GetItemInstallInfo(intptr_t instancePtr, uint64 publishedFileID, uint64 * sizeOnDisk, BBString ** folder, uint32 * timestamp);
+	uint32 bmx_SteamAPI_ISteamUGC_GetItemState(intptr_t instancePtr, uint64 publishedFileID);
+	EItemUpdateStatus bmx_SteamAPI_ISteamUGC_GetItemUpdateProgress(intptr_t instancePtr, uint64 queryHandle, uint64 * bytesProcessed, uint64 * bytesTotal);
+	uint32 bmx_SteamAPI_ISteamUGC_GetNumSubscribedItems(intptr_t instancePtr);
+	int bmx_SteamAPI_ISteamUGC_GetQueryUGCAdditionalPreview(intptr_t instancePtr, uint64 queryHandle, uint32 index, uint32 previewIndex, BBString ** URLOrVideoID, BBString ** originalFileName, EItemPreviewType * previewType);
+	int bmx_SteamAPI_ISteamUGC_GetQueryUGCChildren(intptr_t instancePtr, uint64 queryHandle, uint32 index, uint64 * publishedFileIDs, uint32 maxEntries);
+	int bmx_SteamAPI_ISteamUGC_GetQueryUGCKeyValueTag(intptr_t instancePtr, uint64 queryHandle, uint32 index, uint32 keyValueTagIndex, BBString ** key, BBString ** value);
+	int bmx_SteamAPI_ISteamUGC_GetQueryUGCMetadata(intptr_t instancePtr, uint64 queryHandle, uint32 index, BBString ** metadata);
+	uint32 bmx_SteamAPI_ISteamUGC_GetQueryUGCNumAdditionalPreviews(intptr_t instancePtr, uint64 queryHandle, uint32 index);
+	uint32 bmx_SteamAPI_ISteamUGC_GetQueryUGCNumKeyValueTags(intptr_t instancePtr, uint64 queryHandle, uint32 index);
+	int bmx_SteamAPI_ISteamUGC_GetQueryUGCPreviewURL(intptr_t instancePtr, uint64 queryHandle, uint32 index, BBString ** URL);
+	int bmx_SteamAPI_ISteamUGC_GetQueryUGCStatistic(intptr_t instancePtr, uint64 queryHandle, uint32 index, EItemStatistic statType, uint64 * statValue);
+	uint32 bmx_SteamAPI_ISteamUGC_GetSubscribedItems(intptr_t instancePtr, uint64 * publishedFileIDs, uint32 maxEntries);
+	void bmx_SteamAPI_ISteamUGC_GetUserItemVote(MaxUGC * ugc, uint64 publishedFileID);
+	int bmx_SteamAPI_ISteamUGC_ReleaseQueryUGCRequest(intptr_t instancePtr, uint64 queryHandle);
+	void bmx_SteamAPI_ISteamUGC_RemoveAppDependency(MaxUGC * ugc, uint64 publishedFileID, uint32 appID);
+	void bmx_SteamAPI_ISteamUGC_RemoveDependency(MaxUGC * ugc, uint64 parentPublishedFileID, uint64 childPublishedFileID);
+	void bmx_SteamAPI_ISteamUGC_RemoveItemFromFavorites(MaxUGC * ugc, uint32 appId, uint64 publishedFileID);
+	int bmx_SteamAPI_ISteamUGC_RemoveItemKeyValueTags(intptr_t instancePtr, uint64 queryHandle, BBString * key);
+	int bmx_SteamAPI_ISteamUGC_RemoveItemPreview(intptr_t instancePtr, uint64 queryHandle, uint32 index);
+	void bmx_SteamAPI_ISteamUGC_SendQueryUGCRequest(MaxUGC * ugc, uint64 queryHandle);
+	int bmx_SteamAPI_ISteamUGC_SetAllowCachedResponse(intptr_t instancePtr, uint64 queryHandle, uint32 maxAgeSeconds);
+	int bmx_SteamAPI_ISteamUGC_SetCloudFileNameFilter(intptr_t instancePtr, uint64 queryHandle, BBString * matchCloudFileName);
+	int bmx_SteamAPI_ISteamUGC_SetItemContent(intptr_t instancePtr, uint64 updateHandle, BBString * contentFolder);
+	int bmx_SteamAPI_ISteamUGC_SetItemDescription(intptr_t instancePtr, uint64 updateHandle, BBString * description);
+	int bmx_SteamAPI_ISteamUGC_SetItemMetadata(intptr_t instancePtr, uint64 updateHandle, BBString * metaData);
+	int bmx_SteamAPI_ISteamUGC_SetItemPreview(intptr_t instancePtr, uint64 updateHandle, BBString * previewFile);
+	int bmx_SteamAPI_ISteamUGC_SetItemTags(intptr_t instancePtr, uint64 updateHandle, BBArray * tags);
+	int bmx_SteamAPI_ISteamUGC_SetItemTitle(intptr_t instancePtr, uint64 updateHandle, BBString * title);
+	int bmx_SteamAPI_ISteamUGC_SetItemUpdateLanguage(intptr_t instancePtr, uint64 updateHandle, BBString * language);
+	int bmx_SteamAPI_ISteamUGC_SetItemVisibility(intptr_t instancePtr, uint64 updateHandle, ERemoteStoragePublishedFileVisibility visibility);
+	int bmx_SteamAPI_ISteamUGC_SetLanguage(intptr_t instancePtr, uint64 queryHandle, BBString * language);
+	int bmx_SteamAPI_ISteamUGC_SetMatchAnyTag(intptr_t instancePtr, uint64 queryHandle, int matchAnyTag);
+	int bmx_SteamAPI_ISteamUGC_SetRankedByTrendDays(intptr_t instancePtr, uint64 queryHandle, uint32 days);
+	int bmx_SteamAPI_ISteamUGC_SetReturnAdditionalPreviews(intptr_t instancePtr, uint64 queryHandle, int returnAdditionalPreviews);
+	int bmx_SteamAPI_ISteamUGC_SetReturnChildren(intptr_t instancePtr, uint64 queryHandle, int returnChildren);
+	int bmx_SteamAPI_ISteamUGC_SetReturnKeyValueTags(intptr_t instancePtr, uint64 queryHandle, int returnKeyValueTags);
+	int bmx_SteamAPI_ISteamUGC_SetReturnLongDescription(intptr_t instancePtr, uint64 queryHandle, int returnLongDescription);
+	int bmx_SteamAPI_ISteamUGC_SetReturnMetadata(intptr_t instancePtr, uint64 queryHandle, int returnMetadata);
+	int bmx_SteamAPI_ISteamUGC_SetReturnOnlyIDs(intptr_t instancePtr, uint64 queryHandle, int returnOnlyIDs);
+	int bmx_SteamAPI_ISteamUGC_SetReturnPlaytimeStats(intptr_t instancePtr, uint64 queryHandle, uint32 days);
+	int bmx_SteamAPI_ISteamUGC_SetReturnTotalOnly(intptr_t instancePtr, uint64 queryHandle, int returnTotalOnly);
+	int bmx_SteamAPI_ISteamUGC_SetSearchText(intptr_t instancePtr, uint64 queryHandle, BBString * searchText);
+	void bmx_SteamAPI_ISteamUGC_SetUserItemVote(MaxUGC * ugc, uint64 publishedFileID, int voteUp);
+	uint64 bmx_SteamAPI_ISteamUGC_StartItemUpdate(intptr_t instancePtr, uint32 consumerAppId, uint64 publishedFileID);
+	void bmx_SteamAPI_ISteamUGC_StartPlaytimeTracking(MaxUGC * ugc, uint64 * publishedFileIDs, uint32 numPublishedFileIDs);
+	void bmx_SteamAPI_ISteamUGC_StopPlaytimeTracking(MaxUGC * ugc, uint64 * publishedFileIDs, uint32 numPublishedFileIDs);
+	void bmx_SteamAPI_ISteamUGC_StopPlaytimeTrackingForAllItems(MaxUGC * ugc);
+	void bmx_SteamAPI_ISteamUGC_SubmitItemUpdate(MaxUGC * ugc, uint64 updateHandle, BBString * changeNote);
+	void bmx_SteamAPI_ISteamUGC_SubscribeItem(MaxUGC * ugc, uint64 publishedFileID);
+	void bmx_SteamAPI_ISteamUGC_SuspendDownloads(intptr_t instancePtr, int suspend);
+	void bmx_SteamAPI_ISteamUGC_UnsubscribeItem(MaxUGC * ugc, uint64 publishedFileID);
+	int bmx_SteamAPI_ISteamUGC_UpdateItemPreviewFile(intptr_t instancePtr, uint64 updateHandle, uint32 index, BBString * previewFile);
+	int bmx_SteamAPI_ISteamUGC_UpdateItemPreviewVideo(intptr_t instancePtr, uint64 updateHandle, uint32 index, BBString * videoID);
 }
 
 
@@ -220,6 +321,13 @@ void * bmx_SteamAPI_ISteamClient_GetISteamUserStats(intptr_t instancePtr, HSteam
 	return inst;
 }
 
+void * bmx_SteamAPI_ISteamClient_GetISteamUGC(intptr_t instancePtr, HSteamUser user, HSteamPipe pipe, BBString * version) {
+	char * v = bbStringToUTF8String(version);
+	void * inst = SteamAPI_ISteamClient_GetISteamUGC(instancePtr, user, pipe, v);
+	bbMemFree(v);
+	return inst;
+}
+
 // ISteamUtils --------------------------------------------
 
 class MaxUtils
@@ -786,3 +894,642 @@ int bmx_SteamAPI_ISteamUserStats_UpdateAvgRateStat(intptr_t instancePtr, BBStrin
 void bmx_SteamAPI_ISteamUserStats_UploadLeaderboardScore(MaxUserStats * userStats, uint64 leaderboardHandle, ELeaderboardUploadScoreMethod uploadScoreMethod, int score, int * scoreDetails, int count) {
 	userStats->UploadLeaderboardScore(leaderboardHandle, uploadScoreMethod, score, scoreDetails, count);
 }
+
+// ISteamUGC --------------------------------------------
+
+class MaxUGC
+{
+private:
+	intptr_t instancePtr;
+	BBObject * maxHandle;
+
+	CCallResult< MaxUGC, AddAppDependencyResult_t > m_AddAppDependencyCallResult;
+	CCallResult< MaxUGC, AddUGCDependencyResult_t > m_AddDependencyCallResult;
+	CCallResult< MaxUGC, UserFavoriteItemsListChanged_t > m_UserFavoriteItemsListChangedCallResult;
+	CCallResult< MaxUGC, CreateItemResult_t > m_CreateItemCallResult;
+	CCallResult< MaxUGC, DeleteItemResult_t > m_DeleteItemCallResult;
+	CCallResult< MaxUGC, GetUserItemVoteResult_t > m_GetUserItemVoteCallResult;
+	CCallResult< MaxUGC, RemoveAppDependencyResult_t > m_RemoveAppDependencyCallResult;
+	CCallResult< MaxUGC, RemoveUGCDependencyResult_t > m_RemoveUGCDependencyCallResult;
+	CCallResult< MaxUGC, SteamUGCQueryCompleted_t > m_SteamUGCQueryCompletedCallResult;
+	CCallResult< MaxUGC, SetUserItemVoteResult_t > m_SetUserItemVoteCallResult;
+	CCallResult< MaxUGC, StartPlaytimeTrackingResult_t > m_StartPlaytimeTrackingCallResult;
+	CCallResult< MaxUGC, StopPlaytimeTrackingResult_t > m_StopPlaytimeTrackingCallResult;
+	CCallResult< MaxUGC, GetAppDependenciesResult_t > m_GetAppDependenciesCallResult;
+	CCallResult< MaxUGC, SubmitItemUpdateResult_t > m_SubmitItemUpdateCallResult;
+	CCallResult< MaxUGC, RemoteStorageSubscribePublishedFileResult_t > m_RemoteStorageSubscribePublishedFileCallResult;
+	CCallResult< MaxUGC, RemoteStorageUnsubscribePublishedFileResult_t > m_RemoteStorageUnsubscribePublishedFileCallResult;
+
+public:
+	STEAM_CALLBACK( MaxUGC, OnDownloadItem, DownloadItemResult_t, m_CallbackDownloadItem );
+
+	MaxUGC(intptr_t instancePtr, BBObject * handle);
+	~MaxUGC();
+
+	// calls
+	void AddAppDependency(uint64 publishedFileID, uint32 appID);
+	void AddDependency(uint64 parentPublishedFileID, uint64 childPublishedFileID);
+	void AddItemToFavorites(uint32 appId, uint64 publishedFileID);
+	void CreateItem(uint32 consumerAppId, EWorkshopFileType fileType);
+	void DeleteItem(uint64 publishedFileID);
+	void GetUserItemVote(uint64 publishedFileID);
+	void RemoveAppDependency(uint64 publishedFileID, uint32 appID);
+	void RemoveDependency(uint64 parentPublishedFileID, uint64 childPublishedFileID);
+	void RemoveItemFromFavorites(uint32 appId, uint64 publishedFileID);
+	void SendQueryUGCRequest(uint64 queryHandle);
+	void SetUserItemVote(uint64 publishedFileID, bool voteUp);
+	void StartPlaytimeTracking(uint64 * publishedFileIDs, uint32 numPublishedFileIDs);
+	void StopPlaytimeTracking(uint64 * publishedFileID, uint32 numPublishedFileIDs);
+	void StopPlaytimeTrackingForAllItems();
+	void GetAppDependencies(uint64 publishedFileID);
+	void SubmitItemUpdate(uint64 updateHandle, const char * changeNote);
+	void SubscribeItem(uint64 publishedFileID);
+	void UnsubscribeItem(uint64 publishedFileID);
+
+	// Callbacks
+	void OnAddAppDependency(AddAppDependencyResult_t * result, bool failure);
+	void OnAddDependency(AddUGCDependencyResult_t * result, bool failure);
+	void OnUserFavoriteItemsListChanged(UserFavoriteItemsListChanged_t * result, bool failure);
+	void OnCreateItem(CreateItemResult_t * result, bool failure);
+	void OnDeleteItem(DeleteItemResult_t * result, bool failure);
+	void OnGetUserItemVote(GetUserItemVoteResult_t * result, bool failure);
+	void OnRemoveAppDependency(RemoveAppDependencyResult_t * result, bool failure);
+	void OnRemoveUGCDependency(RemoveUGCDependencyResult_t * result, bool failure);
+	void OnSteamUGCQueryCompleted(SteamUGCQueryCompleted_t * result, bool failure);
+	void OnSetUserItemVote(SetUserItemVoteResult_t * result, bool failure);
+	void OnStartPlaytimeTracking(StartPlaytimeTrackingResult_t * result, bool failure);
+	void OnStopPlaytimeTracking(StopPlaytimeTrackingResult_t * result, bool failure);
+	void OnGetAppDependencies(GetAppDependenciesResult_t * result, bool failure);
+	void OnSubmitItemUpdate(SubmitItemUpdateResult_t * result, bool failure);
+	void OnRemoteStorageSubscribePublishedFile(RemoteStorageSubscribePublishedFileResult_t * result, bool failure);
+	void OnRemoteStorageUnsubscribePublishedFile(RemoteStorageUnsubscribePublishedFileResult_t * result, bool failure);
+};
+
+
+MaxUGC::MaxUGC(intptr_t instancePtr, BBObject * handle) :
+	instancePtr(instancePtr), maxHandle(handle),
+	m_CallbackDownloadItem( this, &MaxUGC::OnDownloadItem )
+{
+}
+
+void MaxUGC::OnDownloadItem(DownloadItemResult_t * result) {
+	steam_steamsdk_TSteamUGC__OnDownloadItem(maxHandle, result->m_eResult, result->m_unAppID, result->m_nPublishedFileId);
+}
+
+void MaxUGC::AddAppDependency(uint64 publishedFileID, uint32 appID) {
+	SteamAPICall_t apiCall = SteamUGC()->AddAppDependency(publishedFileID, appID);
+	m_AddAppDependencyCallResult.Set(apiCall, this, &MaxUGC::OnAddAppDependency);
+}
+
+void MaxUGC::AddDependency(uint64 parentPublishedFileID, uint64 childPublishedFileID) {
+	SteamAPICall_t apiCall = SteamUGC()->AddDependency(parentPublishedFileID, childPublishedFileID);
+	m_AddDependencyCallResult.Set(apiCall, this, &MaxUGC::OnAddDependency);
+}
+
+void MaxUGC::AddItemToFavorites(uint32 appId, uint64 publishedFileID) {
+	SteamAPICall_t apiCall = SteamUGC()->AddItemToFavorites(appId, publishedFileID);
+	m_UserFavoriteItemsListChangedCallResult.Set(apiCall, this, &MaxUGC::OnUserFavoriteItemsListChanged);
+}
+
+void MaxUGC::CreateItem(uint32 consumerAppId, EWorkshopFileType fileType) {
+	SteamAPICall_t apiCall = SteamUGC()->CreateItem(consumerAppId, fileType);
+	m_CreateItemCallResult.Set(apiCall, this, &MaxUGC::OnCreateItem);
+}
+
+void MaxUGC::DeleteItem(uint64 publishedFileID) {
+	SteamAPICall_t apiCall = SteamUGC()->DeleteItem(publishedFileID);
+	m_DeleteItemCallResult.Set(apiCall, this, &MaxUGC::OnDeleteItem);
+}
+
+void MaxUGC::GetUserItemVote(uint64 publishedFileID) {
+	SteamAPICall_t apiCall = SteamUGC()->GetUserItemVote(publishedFileID);
+	m_GetUserItemVoteCallResult.Set(apiCall, this, &MaxUGC::OnGetUserItemVote);
+}
+
+void MaxUGC::RemoveAppDependency(uint64 publishedFileID, uint32 appID) {
+	SteamAPICall_t apiCall = SteamUGC()->RemoveAppDependency(publishedFileID, appID);
+	m_RemoveAppDependencyCallResult.Set(apiCall, this, &MaxUGC::OnRemoveAppDependency);
+}
+
+void MaxUGC::RemoveDependency(uint64 parentPublishedFileID, uint64 childPublishedFileID) {
+	SteamAPICall_t apiCall = SteamUGC()->RemoveDependency(parentPublishedFileID, childPublishedFileID);
+	m_RemoveUGCDependencyCallResult.Set(apiCall, this, &MaxUGC::OnRemoveUGCDependency);
+}
+
+void MaxUGC::RemoveItemFromFavorites(uint32 appId, uint64 publishedFileID) {
+	SteamAPICall_t apiCall = SteamUGC()->RemoveItemFromFavorites(appId, publishedFileID);
+	m_UserFavoriteItemsListChangedCallResult.Set(apiCall, this, &MaxUGC::OnUserFavoriteItemsListChanged);
+}
+
+void MaxUGC::SendQueryUGCRequest(uint64 queryHandle) {
+	SteamAPICall_t apiCall = SteamUGC()->SendQueryUGCRequest(queryHandle);
+	m_SteamUGCQueryCompletedCallResult.Set(apiCall, this, &MaxUGC::OnSteamUGCQueryCompleted);
+}
+
+void MaxUGC::SetUserItemVote(uint64 publishedFileID, bool voteUp) {
+	SteamAPICall_t apiCall = SteamUGC()->SetUserItemVote(publishedFileID, voteUp);
+	m_SetUserItemVoteCallResult.Set(apiCall, this, &MaxUGC::OnSetUserItemVote);
+}
+
+void MaxUGC::StartPlaytimeTracking(uint64 * publishedFileIDs, uint32 numPublishedFileIDs) {
+	SteamAPICall_t apiCall = SteamUGC()->StartPlaytimeTracking(publishedFileIDs, numPublishedFileIDs);
+	m_StartPlaytimeTrackingCallResult.Set(apiCall, this, &MaxUGC::OnStartPlaytimeTracking);
+}
+
+void MaxUGC::StopPlaytimeTracking(uint64 * publishedFileID, uint32 numPublishedFileIDs) {
+	SteamAPICall_t apiCall = SteamUGC()->StopPlaytimeTracking(publishedFileID, numPublishedFileIDs);
+	m_StopPlaytimeTrackingCallResult.Set(apiCall, this, &MaxUGC::OnStopPlaytimeTracking);
+}
+
+void MaxUGC::StopPlaytimeTrackingForAllItems() {
+	SteamAPICall_t apiCall = SteamUGC()->StopPlaytimeTrackingForAllItems();
+	m_StopPlaytimeTrackingCallResult.Set(apiCall, this, &MaxUGC::OnStopPlaytimeTracking);
+}
+
+void MaxUGC::GetAppDependencies(uint64 publishedFileID) {
+	SteamAPICall_t apiCall = SteamUGC()->GetAppDependencies(publishedFileID);
+	m_GetAppDependenciesCallResult.Set(apiCall, this, &MaxUGC::OnGetAppDependencies);
+}
+
+void MaxUGC::SubmitItemUpdate(uint64 updateHandle, const char * changeNote) {
+	SteamAPICall_t apiCall = SteamUGC()->SubmitItemUpdate(updateHandle, changeNote);
+	m_SubmitItemUpdateCallResult.Set(apiCall, this, &MaxUGC::OnSubmitItemUpdate);
+}
+
+void MaxUGC::SubscribeItem(uint64 publishedFileID) {
+	SteamAPICall_t apiCall = SteamUGC()->SubscribeItem(publishedFileID);
+	m_RemoteStorageSubscribePublishedFileCallResult.Set(apiCall, this, &MaxUGC::OnRemoteStorageSubscribePublishedFile);
+}
+
+void MaxUGC::UnsubscribeItem(uint64 publishedFileID) {
+	SteamAPICall_t apiCall = SteamUGC()->UnsubscribeItem(publishedFileID);
+	m_RemoteStorageUnsubscribePublishedFileCallResult.Set(apiCall, this, &MaxUGC::OnRemoteStorageUnsubscribePublishedFile);
+}
+
+
+void MaxUGC::OnAddAppDependency(AddAppDependencyResult_t *result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnAddAppDependency(maxHandle, result->m_eResult, result->m_nPublishedFileId, result->m_nAppID);
+}
+
+void MaxUGC::OnAddDependency(AddUGCDependencyResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnAddDependency(maxHandle, result->m_eResult, result->m_nPublishedFileId, result->m_nChildPublishedFileId);
+}
+
+void MaxUGC::OnUserFavoriteItemsListChanged(UserFavoriteItemsListChanged_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnUserFavoriteItemsListChanged(maxHandle, result->m_nPublishedFileId, result->m_eResult, static_cast<int>(result->m_bWasAddRequest));
+}
+
+void MaxUGC::OnCreateItem(CreateItemResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnCreateItem(maxHandle, result->m_eResult, result->m_nPublishedFileId, static_cast<int>(result->m_bUserNeedsToAcceptWorkshopLegalAgreement));
+}
+
+void MaxUGC::OnDeleteItem(DeleteItemResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnDeleteItem(maxHandle, result->m_eResult, result->m_nPublishedFileId);
+}
+
+void MaxUGC::OnGetUserItemVote(GetUserItemVoteResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnGetUserItemVote(maxHandle, result->m_nPublishedFileId, result->m_eResult, static_cast<int>(result->m_bVotedUp), static_cast<int>(result->m_bVotedDown), static_cast<int>(result->m_bVoteSkipped));
+}
+
+void MaxUGC::OnRemoveAppDependency(RemoveAppDependencyResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnRemoveAppDependency(maxHandle, result->m_eResult, result->m_nPublishedFileId, result->m_nAppID);
+}
+
+void MaxUGC::OnRemoveUGCDependency(RemoveUGCDependencyResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnRemoveUGCDependency(maxHandle, result->m_eResult, result->m_nPublishedFileId, result->m_nChildPublishedFileId);
+}
+
+void MaxUGC::OnSteamUGCQueryCompleted(SteamUGCQueryCompleted_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnSteamUGCQueryCompleted(maxHandle, result->m_handle, result->m_eResult, result->m_unNumResultsReturned, result->m_unTotalMatchingResults, static_cast<int>(result->m_bCachedData));
+}
+
+void MaxUGC::OnSetUserItemVote(SetUserItemVoteResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnSetUserItemVote(maxHandle, result->m_nPublishedFileId, result->m_eResult, static_cast<int>(result->m_bVoteUp));
+}
+
+void MaxUGC::OnStartPlaytimeTracking(StartPlaytimeTrackingResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnStartPlaytimeTracking(maxHandle, result->m_eResult);
+}
+
+void MaxUGC::OnStopPlaytimeTracking(StopPlaytimeTrackingResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnStopPlaytimeTracking(maxHandle, result->m_eResult);
+}
+
+void MaxUGC::OnGetAppDependencies(GetAppDependenciesResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnGetAppDependencies(maxHandle, result->m_eResult, result->m_nPublishedFileId, result->m_rgAppIDs, result->m_nNumAppDependencies, result->m_nTotalNumAppDependencies);
+}
+
+void MaxUGC::OnSubmitItemUpdate(SubmitItemUpdateResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnSubmitItemUpdate(maxHandle, result->m_eResult, static_cast<int>(result->m_bUserNeedsToAcceptWorkshopLegalAgreement));
+}
+
+void MaxUGC::OnRemoteStorageSubscribePublishedFile(RemoteStorageSubscribePublishedFileResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnRemoteStorageSubscribePublishedFile(maxHandle, result->m_eResult, result->m_nPublishedFileId);
+}
+
+void MaxUGC::OnRemoteStorageUnsubscribePublishedFile(RemoteStorageUnsubscribePublishedFileResult_t * result, bool failure) {
+	steam_steamsdk_TSteamUGC__OnRemoteStorageUnsubscribePublishedFile(maxHandle, result->m_eResult, result->m_nPublishedFileId);
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+void * bmx_steamsdk_register_steamugc(intptr_t instancePtr, BBObject * obj) {
+	return new MaxUGC(instancePtr, obj);
+}
+
+void bmx_steamsdk_unregister_steamugc(void * callbackPtr) {
+	delete(callbackPtr);
+}
+
+void bmx_SteamAPI_ISteamUGC_AddAppDependency(MaxUGC * ugc, uint64 publishedFileID, uint32 appID) {
+	ugc->AddAppDependency(publishedFileID, appID);
+}
+
+void bmx_SteamAPI_ISteamUGC_AddDependency(MaxUGC * ugc, uint64 publishedFileId, uint64 childPublishedFileId) {
+	ugc->AddDependency(publishedFileId, childPublishedFileId);
+}
+
+int bmx_SteamAPI_ISteamUGC_AddExcludedTag(intptr_t instancePtr, uint64 queryHandle, BBString * tagName) {
+	char * t = bbStringToUTF8String(tagName);
+	bool res = SteamAPI_ISteamUGC_AddExcludedTag(instancePtr, queryHandle, t);
+	bbMemFree(t);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_AddItemKeyValueTag(intptr_t instancePtr, uint64 queryHandle, BBString * key, BBString * value) {
+	char * k = bbStringToUTF8String(key);
+	char * v = bbStringToUTF8String(value);
+	bool res = SteamAPI_ISteamUGC_AddItemKeyValueTag(instancePtr, queryHandle, k, v);
+	bbMemFree(v);
+	bbMemFree(k);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_AddItemPreviewFile(intptr_t instancePtr, uint64 queryHandle, BBString * previewFile, EItemPreviewType previewType) {
+	char * p = bbStringToUTF8String(previewFile);
+	bool res = SteamAPI_ISteamUGC_AddItemPreviewFile(instancePtr, queryHandle, p, previewType);
+	bbMemFree(p);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_AddItemPreviewVideo(intptr_t instancePtr, uint64 queryHandle, BBString * videoID) {
+	char * v = bbStringToUTF8String(videoID);
+	bool res = SteamAPI_ISteamUGC_AddItemPreviewVideo(instancePtr, queryHandle, v);
+	bbMemFree(v);
+	return res;
+}
+
+void bmx_SteamAPI_ISteamUGC_AddItemToFavorites(MaxUGC * ugc, uint32 appId, uint64 publishedFileID) {
+	ugc->AddItemToFavorites(appId, publishedFileID);
+}
+
+int bmx_SteamAPI_ISteamUGC_AddRequiredKeyValueTag(intptr_t instancePtr, uint64 queryHandle, BBString * key, BBString * value) {
+	char * k = bbStringToUTF8String(key);
+	char * v = bbStringToUTF8String(value);
+	bool res = SteamAPI_ISteamUGC_AddRequiredKeyValueTag(instancePtr, queryHandle, k, v);
+	bbMemFree(v);
+	bbMemFree(k);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_AddRequiredTag(intptr_t instancePtr, uint64 queryHandle, BBString * tagName) {
+	char * t = bbStringToUTF8String(tagName);
+	bool res = SteamAPI_ISteamUGC_AddRequiredTag(instancePtr, queryHandle, t);
+	bbMemFree(t);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_InitWorkshopForGameServer(intptr_t instancePtr, uint64 workshopDepotID, BBString * folder) {
+	char * f = bbStringToUTF8String(folder);
+	bool res = SteamAPI_ISteamUGC_BInitWorkshopForGameServer(instancePtr, workshopDepotID, f);
+	bbMemFree(f);
+	return res;
+}
+
+void bmx_SteamAPI_ISteamUGC_CreateItem(MaxUGC * ugc, uint32 consumerAppId, EWorkshopFileType fileType) {
+	ugc->CreateItem(consumerAppId, fileType);
+}
+
+uint64 bmx_SteamAPI_ISteamUGC_CreateQueryAllUGCRequest(intptr_t instancePtr, EUGCQuery queryType, EUGCMatchingUGCType matchingeMatchingUGCTypeFileType, uint32 creatorAppID, uint32 consumerAppID, uint32 page) {
+	return SteamAPI_ISteamUGC_CreateQueryAllUGCRequest(instancePtr, queryType, matchingeMatchingUGCTypeFileType, creatorAppID, consumerAppID, page);
+}
+
+uint64 bmx_SteamAPI_ISteamUGC_CreateQueryUGCDetailsRequest(intptr_t instancePtr, uint64 * publishedFileIDs, int numPublishedFileIDs) {
+	return SteamAPI_ISteamUGC_CreateQueryUGCDetailsRequest(instancePtr, publishedFileIDs, numPublishedFileIDs);
+}
+
+uint64 bmx_SteamAPI_ISteamUGC_CreateQueryUserUGCRequest(intptr_t instancePtr, uint32 accountID, EUserUGCList listType, EUGCMatchingUGCType matchingUGCType, EUserUGCListSortOrder sortOrder, uint32 creatorAppID, uint32 consumerAppID, uint32 page) {
+	return SteamAPI_ISteamUGC_CreateQueryUserUGCRequest(instancePtr, accountID, listType, matchingUGCType, sortOrder, creatorAppID, consumerAppID, page);
+}
+
+void bmx_SteamAPI_ISteamUGC_DeleteItem(MaxUGC * ugc, uint64 publishedFileID) {
+	ugc->DeleteItem(publishedFileID);
+}
+
+int bmx_SteamAPI_ISteamUGC_DownloadItem(intptr_t instancePtr, uint64 publishedFileID, int highPriority) {
+	return SteamAPI_ISteamUGC_DownloadItem(instancePtr, publishedFileID, highPriority);
+}
+
+void bmx_SteamAPI_ISteamUGC_GetAppDependencies(MaxUGC * ugc, uint64 publishedFileID) {
+	ugc->GetAppDependencies(publishedFileID);
+}
+
+int bmx_SteamAPI_ISteamUGC_GetItemDownloadInfo(intptr_t instancePtr, uint64 publishedFileID, uint64 * bytesDownloaded, uint64 * bytesTotal) {
+	return SteamAPI_ISteamUGC_GetItemDownloadInfo(instancePtr, publishedFileID, bytesDownloaded, bytesTotal);
+}
+
+int bmx_SteamAPI_ISteamUGC_GetItemInstallInfo(intptr_t instancePtr, uint64 publishedFileID, uint64 * sizeOnDisk, BBString ** folder, uint32 * timestamp) {
+	char fbuf[BUFFER_SIZE];
+	bool res = SteamAPI_ISteamUGC_GetItemInstallInfo(instancePtr, publishedFileID, sizeOnDisk, fbuf, BUFFER_SIZE, timestamp);
+	*folder = bbStringFromUTF8String(fbuf);
+	return res;
+}
+
+uint32 bmx_SteamAPI_ISteamUGC_GetItemState(intptr_t instancePtr, uint64 publishedFileID) {
+	return SteamAPI_ISteamUGC_GetItemState(instancePtr, publishedFileID);
+}
+
+EItemUpdateStatus bmx_SteamAPI_ISteamUGC_GetItemUpdateProgress(intptr_t instancePtr, uint64 queryHandle, uint64 * bytesProcessed, uint64 * bytesTotal) {
+	return SteamAPI_ISteamUGC_GetItemUpdateProgress(instancePtr, queryHandle, bytesProcessed, bytesTotal);
+}
+
+uint32 bmx_SteamAPI_ISteamUGC_GetNumSubscribedItems(intptr_t instancePtr) {
+	return SteamAPI_ISteamUGC_GetNumSubscribedItems(instancePtr);
+}
+
+int bmx_SteamAPI_ISteamUGC_GetQueryUGCAdditionalPreview(intptr_t instancePtr, uint64 queryHandle, uint32 index, uint32 previewIndex, BBString ** URLOrVideoID, BBString ** originalFileName, EItemPreviewType * previewType) {
+	char urlbuf[BUFFER_SIZE];
+	char filebuf[BUFFER_SIZE];
+	bool res = SteamAPI_ISteamUGC_GetQueryUGCAdditionalPreview(instancePtr, queryHandle, index, previewIndex, urlbuf, BUFFER_SIZE, filebuf, BUFFER_SIZE, previewType);
+	*URLOrVideoID = bbStringFromUTF8String(urlbuf);
+	*originalFileName = bbStringFromUTF8String(filebuf);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_GetQueryUGCChildren(intptr_t instancePtr, uint64 queryHandle, uint32 index, uint64 * publishedFileIDs, uint32 maxEntries) {
+	return SteamAPI_ISteamUGC_GetQueryUGCChildren(instancePtr, queryHandle, index, publishedFileIDs, maxEntries);
+}
+
+int bmx_SteamAPI_ISteamUGC_GetQueryUGCKeyValueTag(intptr_t instancePtr, uint64 queryHandle, uint32 index, uint32 keyValueTagIndex, BBString ** key, BBString ** value) {
+	char keybuf[BUFFER_SIZE];
+	char valuebuf[VALUE_SIZE];
+	bool res = SteamAPI_ISteamUGC_GetQueryUGCKeyValueTag(instancePtr, queryHandle, index, keyValueTagIndex, keybuf, BUFFER_SIZE, valuebuf, VALUE_SIZE);
+	*key = bbStringFromUTF8String(keybuf);
+	*value = bbStringFromUTF8String(valuebuf);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_GetQueryUGCMetadata(intptr_t instancePtr, uint64 queryHandle, uint32 index, BBString ** metadata) {
+	char metabuf[METADATA_SIZE];
+	bool res = SteamAPI_ISteamUGC_GetQueryUGCMetadata(instancePtr, queryHandle, index, metabuf, METADATA_SIZE);
+	*metadata = bbStringFromUTF8String(metabuf);
+	return res;
+}
+
+uint32 bmx_SteamAPI_ISteamUGC_GetQueryUGCNumAdditionalPreviews(intptr_t instancePtr, uint64 queryHandle, uint32 index) {
+	return SteamAPI_ISteamUGC_GetQueryUGCNumAdditionalPreviews(instancePtr, queryHandle, index);
+}
+
+uint32 bmx_SteamAPI_ISteamUGC_GetQueryUGCNumKeyValueTags(intptr_t instancePtr, uint64 queryHandle, uint32 index) {
+	return SteamAPI_ISteamUGC_GetQueryUGCNumKeyValueTags(instancePtr, queryHandle, index);
+}
+
+int bmx_SteamAPI_ISteamUGC_GetQueryUGCPreviewURL(intptr_t instancePtr, uint64 queryHandle, uint32 index, BBString ** URL) {
+	char urlbuf[BUFFER_SIZE];
+	bool res = SteamAPI_ISteamUGC_GetQueryUGCPreviewURL(instancePtr, queryHandle, index, urlbuf, BUFFER_SIZE);
+	*URL = bbStringFromUTF8String(urlbuf);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_GetQueryUGCStatistic(intptr_t instancePtr, uint64 queryHandle, uint32 index, EItemStatistic statType, uint64 * statValue) {
+	return SteamAPI_ISteamUGC_GetQueryUGCStatistic(instancePtr, queryHandle, index, statType, statValue);
+}
+
+uint32 bmx_SteamAPI_ISteamUGC_GetSubscribedItems(intptr_t instancePtr, uint64 * publishedFileIDs, uint32 maxEntries) {
+	return SteamAPI_ISteamUGC_GetSubscribedItems(instancePtr, publishedFileIDs, maxEntries);
+}
+
+void bmx_SteamAPI_ISteamUGC_GetUserItemVote(MaxUGC * ugc, uint64 publishedFileID) {
+	ugc->GetUserItemVote(publishedFileID);
+}
+
+int bmx_SteamAPI_ISteamUGC_ReleaseQueryUGCRequest(intptr_t instancePtr, uint64 queryHandle) {
+	return SteamAPI_ISteamUGC_ReleaseQueryUGCRequest(instancePtr, queryHandle);
+}
+
+void bmx_SteamAPI_ISteamUGC_RemoveAppDependency(MaxUGC * ugc, uint64 publishedFileID, uint32 appID) {
+	ugc->RemoveAppDependency(publishedFileID, appID);
+}
+
+void bmx_SteamAPI_ISteamUGC_RemoveDependency(MaxUGC * ugc, uint64 parentPublishedFileID, uint64 childPublishedFileID) {
+	ugc->RemoveDependency(parentPublishedFileID, childPublishedFileID);
+}
+
+void bmx_SteamAPI_ISteamUGC_RemoveItemFromFavorites(MaxUGC * ugc, uint32 appId, uint64 publishedFileID) {
+	ugc->RemoveItemFromFavorites(appId, publishedFileID);
+}
+
+int bmx_SteamAPI_ISteamUGC_RemoveItemKeyValueTags(intptr_t instancePtr, uint64 queryHandle, BBString * key) {
+	char * k = bbStringToUTF8String(key);
+	bool res = SteamAPI_ISteamUGC_RemoveItemKeyValueTags(instancePtr, queryHandle, k);
+	bbMemFree(k);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_RemoveItemPreview(intptr_t instancePtr, uint64 queryHandle, uint32 index) {
+	return SteamAPI_ISteamUGC_RemoveItemPreview(instancePtr, queryHandle, index);
+}
+
+void bmx_SteamAPI_ISteamUGC_SendQueryUGCRequest(MaxUGC * ugc, uint64 queryHandle) {
+	ugc->SendQueryUGCRequest(queryHandle);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetAllowCachedResponse(intptr_t instancePtr, uint64 queryHandle, uint32 maxAgeSeconds) {
+	return SteamAPI_ISteamUGC_SetAllowCachedResponse(instancePtr, queryHandle, maxAgeSeconds);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetCloudFileNameFilter(intptr_t instancePtr, uint64 queryHandle, BBString * matchCloudFileName) {
+	char * n = bbStringToUTF8String(matchCloudFileName);
+	bool res = SteamAPI_ISteamUGC_SetCloudFileNameFilter(instancePtr, queryHandle, n);
+	bbMemFree(n);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_SetItemContent(intptr_t instancePtr, uint64 updateHandle, BBString * contentFolder) {
+	char * c = bbStringToUTF8String(contentFolder);
+	bool res = SteamAPI_ISteamUGC_SetItemContent(instancePtr, updateHandle, c);
+	bbMemFree(c);
+	return res;	
+}
+
+int bmx_SteamAPI_ISteamUGC_SetItemDescription(intptr_t instancePtr, uint64 updateHandle, BBString * description) {
+	char * d = bbStringToUTF8String(description);
+	bool res = SteamAPI_ISteamUGC_SetItemDescription(instancePtr, updateHandle, d);
+	bbMemFree(d);
+	return res;		
+}
+
+int bmx_SteamAPI_ISteamUGC_SetItemMetadata(intptr_t instancePtr, uint64 updateHandle, BBString * metaData) {
+	char * m = bbStringToUTF8String(metaData);
+	bool res = SteamAPI_ISteamUGC_SetItemMetadata(instancePtr, updateHandle, m);
+	bbMemFree(m);
+	return res;		
+}
+
+int bmx_SteamAPI_ISteamUGC_SetItemPreview(intptr_t instancePtr, uint64 updateHandle, BBString * previewFile) {
+	char * p = bbStringToUTF8String(previewFile);
+	bool res = SteamAPI_ISteamUGC_SetItemPreview(instancePtr, updateHandle, p);
+	bbMemFree(p);
+	return res;		
+}
+
+int bmx_SteamAPI_ISteamUGC_SetItemTags(intptr_t instancePtr, uint64 updateHandle, BBArray * tags) {
+	int n = tags->scales[0];
+	BBString **s=(BBString**)BBARRAYDATA(tags, tags->dims);
+
+	SteamParamStringArray_t array = { 0 };
+	array.m_nNumStrings = n;
+	array.m_ppStrings = (const char**)malloc(sizeof(char*) * n);
+
+	for (int i = 0; i < n; i++) {
+		array.m_ppStrings[i] = bbStringToUTF8String(s[i]);
+	}
+
+	bool res = SteamAPI_ISteamUGC_SetItemTags(instancePtr, updateHandle, &array);
+
+	for (int i = 0; i < n; i++) {
+		bbMemFree((char*)array.m_ppStrings[i]);
+	}
+
+	free(array.m_ppStrings);
+	return res;
+}
+
+int bmx_SteamAPI_ISteamUGC_SetItemTitle(intptr_t instancePtr, uint64 updateHandle, BBString * title) {
+	char * t = bbStringToUTF8String(title);
+	bool res = SteamAPI_ISteamUGC_SetItemTitle(instancePtr, updateHandle, t);
+	bbMemFree(t);
+	return res;		
+}
+
+int bmx_SteamAPI_ISteamUGC_SetItemUpdateLanguage(intptr_t instancePtr, uint64 updateHandle, BBString * language) {
+	char * t = bbStringToUTF8String(language);
+	bool res = SteamAPI_ISteamUGC_SetItemUpdateLanguage(instancePtr, updateHandle, t);
+	bbMemFree(t);
+	return res;		
+}
+
+int bmx_SteamAPI_ISteamUGC_SetItemVisibility(intptr_t instancePtr, uint64 updateHandle, ERemoteStoragePublishedFileVisibility visibility) {
+	return SteamAPI_ISteamUGC_SetItemVisibility(instancePtr, updateHandle, visibility);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetLanguage(intptr_t instancePtr, uint64 queryHandle, BBString * language) {
+	char * t = bbStringToUTF8String(language);
+	bool res = SteamAPI_ISteamUGC_SetLanguage(instancePtr, queryHandle, t);
+	bbMemFree(t);
+	return res;		
+}
+
+int bmx_SteamAPI_ISteamUGC_SetMatchAnyTag(intptr_t instancePtr, uint64 queryHandle, int matchAnyTag) {
+	return SteamAPI_ISteamUGC_SetMatchAnyTag(instancePtr, queryHandle, matchAnyTag);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetRankedByTrendDays(intptr_t instancePtr, uint64 queryHandle, uint32 days) {
+	return SteamAPI_ISteamUGC_SetRankedByTrendDays(instancePtr, queryHandle, days);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetReturnAdditionalPreviews(intptr_t instancePtr, uint64 queryHandle, int returnAdditionalPreviews) {
+	return SteamAPI_ISteamUGC_SetReturnAdditionalPreviews(instancePtr, queryHandle, returnAdditionalPreviews);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetReturnChildren(intptr_t instancePtr, uint64 queryHandle, int returnChildren) {
+	return SteamAPI_ISteamUGC_SetReturnChildren(instancePtr, queryHandle, returnChildren);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetReturnKeyValueTags(intptr_t instancePtr, uint64 queryHandle, int returnKeyValueTags) {
+	return SteamAPI_ISteamUGC_SetReturnKeyValueTags(instancePtr, queryHandle, returnKeyValueTags);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetReturnLongDescription(intptr_t instancePtr, uint64 queryHandle, int returnLongDescription) {
+	return SteamAPI_ISteamUGC_SetReturnLongDescription(instancePtr, queryHandle, returnLongDescription);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetReturnMetadata(intptr_t instancePtr, uint64 queryHandle, int returnMetadata) {
+	return SteamAPI_ISteamUGC_SetReturnMetadata(instancePtr, queryHandle, returnMetadata);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetReturnOnlyIDs(intptr_t instancePtr, uint64 queryHandle, int returnOnlyIDs) {
+	return SteamAPI_ISteamUGC_SetReturnOnlyIDs(instancePtr, queryHandle, returnOnlyIDs);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetReturnPlaytimeStats(intptr_t instancePtr, uint64 queryHandle, uint32 days) {
+	return SteamAPI_ISteamUGC_SetReturnPlaytimeStats(instancePtr, queryHandle, days);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetReturnTotalOnly(intptr_t instancePtr, uint64 queryHandle, int returnTotalOnly) {
+	return SteamAPI_ISteamUGC_SetReturnTotalOnly(instancePtr, queryHandle, returnTotalOnly);
+}
+
+int bmx_SteamAPI_ISteamUGC_SetSearchText(intptr_t instancePtr, uint64 queryHandle, BBString * searchText) {
+	char * s = bbStringToUTF8String(searchText);
+	bool res = SteamAPI_ISteamUGC_SetSearchText(instancePtr, queryHandle, s);
+	bbMemFree(s);
+	return res;		
+}
+
+void bmx_SteamAPI_ISteamUGC_SetUserItemVote(MaxUGC * ugc, uint64 publishedFileID, int voteUp) {
+	ugc->SetUserItemVote(publishedFileID, voteUp);
+}
+
+uint64 bmx_SteamAPI_ISteamUGC_StartItemUpdate(intptr_t instancePtr, uint32 consumerAppId, uint64 publishedFileID) {
+	return SteamAPI_ISteamUGC_StartItemUpdate(instancePtr, consumerAppId, publishedFileID);
+}
+
+void bmx_SteamAPI_ISteamUGC_StartPlaytimeTracking(MaxUGC * ugc, uint64 * publishedFileIDs, uint32 numPublishedFileIDs) {
+	ugc->StartPlaytimeTracking(publishedFileIDs, numPublishedFileIDs);
+}
+
+void bmx_SteamAPI_ISteamUGC_StopPlaytimeTracking(MaxUGC * ugc, uint64 * publishedFileIDs, uint32 numPublishedFileIDs) {
+	ugc->StopPlaytimeTracking(publishedFileIDs, numPublishedFileIDs);
+}
+
+void bmx_SteamAPI_ISteamUGC_StopPlaytimeTrackingForAllItems(MaxUGC * ugc) {
+	ugc->StopPlaytimeTrackingForAllItems();
+}
+
+void bmx_SteamAPI_ISteamUGC_SubmitItemUpdate(MaxUGC * ugc, uint64 updateHandle, BBString * changeNote) {
+	char * c = NULL;
+	if (changeNote != &bbEmptyString) {
+		c = bbStringToUTF8String(changeNote);
+	}
+	ugc->SubmitItemUpdate(updateHandle, c);
+	if (c) {
+		bbMemFree(c);
+	}
+}
+
+void bmx_SteamAPI_ISteamUGC_SubscribeItem(MaxUGC * ugc, uint64 publishedFileID) {
+	ugc->SubscribeItem(publishedFileID);
+}
+
+void bmx_SteamAPI_ISteamUGC_SuspendDownloads(intptr_t instancePtr, int suspend) {
+	SteamAPI_ISteamUGC_SuspendDownloads(instancePtr, suspend);
+}
+
+void bmx_SteamAPI_ISteamUGC_UnsubscribeItem(MaxUGC * ugc, uint64 publishedFileID) {
+	ugc->UnsubscribeItem(publishedFileID);
+}
+
+int bmx_SteamAPI_ISteamUGC_UpdateItemPreviewFile(intptr_t instancePtr, uint64 updateHandle, uint32 index, BBString * previewFile) {
+	char * f = bbStringToUTF8String(previewFile);
+	bool res = SteamAPI_ISteamUGC_UpdateItemPreviewFile(instancePtr, updateHandle, index, f);
+	bbMemFree(f);
+	return res;		
+}
+
+int bmx_SteamAPI_ISteamUGC_UpdateItemPreviewVideo(intptr_t instancePtr, uint64 updateHandle, uint32 index, BBString * videoID) {
+	char * v = bbStringToUTF8String(videoID);
+	bool res = SteamAPI_ISteamUGC_UpdateItemPreviewVideo(instancePtr, updateHandle, index, v);
+	bbMemFree(v);
+	return res;		
+}

+ 1341 - 3
steamsdk.mod/steamsdk.bmx

@@ -19,7 +19,7 @@
 SuperStrict
 
 Rem
-bbdoc: 
+bbdoc: Steam SDK
 End Rem
 Module steam.steamsdk
 
@@ -83,7 +83,7 @@ Function SteamInit:Int(autoRunCallbacks:Int = True)
 End Function
 
 Rem
-bbdoc: 
+bbdoc: Shuts down Steam.
 End Rem
 Function SteamShutdown()
 	If _autoRunCallbacks Then
@@ -110,7 +110,7 @@ Type TSteamAPI Abstract
 End Type
 
 Rem
-bbdoc: 
+bbdoc: Provides an interface to a steam instance.
 End Rem
 Type TSteamClient Extends TSteamAPI
 
@@ -137,6 +137,13 @@ Type TSteamClient Extends TSteamAPI
 	Method GetISteamUserStats:TSteamUserStats()
 		Return TSteamUserStats._create(bmx_SteamAPI_ISteamClient_GetISteamUserStats(instancePtr, _user, _steamPipe, TSteamUserStats.STEAMUSERSTATS_INTERFACE_VERSION))
 	End Method
+
+	Rem
+	bbdoc: Returns a new instance of #TSteamUGC.
+	End Rem
+	Method GetISteamUGC:TSteamUGC()
+		Return TSteamUGC._create(bmx_SteamAPI_ISteamClient_GetISteamUGC(instancePtr, _user, _steamPipe, TSteamUGC.STEAMUGC_INTERFACE_VERSION))
+	End Method
 	
 End Type
 
@@ -1221,3 +1228,1334 @@ Type TSteamUserStats Extends TSteamAPI
 	End Function 
 	
 End Type
+
+Rem
+bbdoc: Steam UGC listener interface
+about: Implement this and add as a listener to an instance of #TSteamUGC to receive appropriate event callbacks.
+End Rem
+Interface ISteamUGCListener
+
+	Rem
+	bbdoc: The result of a call to #AddAppDependency
+	End Rem
+	Method OnAddAppDependency(result:EResult, publishedFileId:ULong, appID:UInt)
+	Rem
+	bbdoc: The result of a call to #AddDependency.
+	End Rem
+	Method OnAddDependency(result:EResult, publishedFileId:ULong, childPublishedFileId:ULong)
+	Rem
+	bbdoc: Called when the user has added or removed an item to/from their favorites.
+	End Rem
+	Method OnUserFavoriteItemsListChanged(result:EResult, publishedFileId:ULong, wasAddRequest:Int)
+	Rem
+	bbdoc: Called when a new workshop item has been created.
+	End Rem
+	Method OnCreateItem(result:EResult, publishedFileId:ULong, userNeedsToAcceptWorkshopLegalAgreement:Int)
+	Rem
+	bbdoc: Called when an attempt at deleting an item completes.
+	End Rem
+	Method OnDeleteItem(result:EResult, publishedFileId:ULong)
+	Rem
+	bbdoc: Called when a workshop item has been downloaded.
+	about: NOTE: This callback goes out to all running applications, ensure that the app ID associated with the item matches what you expect.
+	End Rem
+	Method OnDownloadItem(result:EResult, appID:UInt, publishedFileId:ULong)
+	Rem
+	bbdoc: Called when getting the users vote status on an item.
+	End Rem
+	Method OnGetUserItemVote(result:EResult, publishedFileId:ULong, votedUp:Int, votedDown:Int, voteSkipped:Int)
+	Rem
+	bbdoc: The result of a call to #RemoveAppDependency.
+	End Rem
+	Method OnRemoveAppDependency(result:EResult, publishedFileId:ULong, appID:UInt)
+	Rem
+	bbdoc: The result of a call to #RemoveDependency.
+	End Rem
+	Method OnRemoveUGCDependency(result:EResult, publishedFileId:ULong, childPublishedFileId:ULong)
+	Rem
+	bbdoc: Called when a UGC query request completes.
+	End Rem
+	Method OnSteamUGCQueryCompleted(result:EResult, queryHandle:ULong, numResultsReturned:UInt, totalMatchingResults:UInt)
+	Rem
+	bbdoc: Called when the user has voted on an item.
+	End Rem
+	Method OnSetUserItemVote(result:EResult, publishedFileId:ULong, voteUp:Int)
+	Rem
+	bbdoc: Called when workshop item playtime tracking has started.
+	End Rem
+	Method OnStartPlaytimeTracking(result:EResult)
+	Rem
+	bbdoc: Called when workshop item playtime tracking has stopped.
+	End Rem
+	Method OnStopPlaytimeTracking(result:EResult)
+	Rem
+	bbdoc: Called when getting the app dependencies for an item.
+	End Rem
+	Method OnGetAppDependencies(result:EResult, publishedFileId:ULong, appID:UInt Ptr, numAppDependencies:Int, totalNumAppDependencies:Int)
+	Rem
+	bbdoc: Called when an item update has completed.
+	End Rem
+	Method OnSubmitItemUpdate(result:EResult, userNeedsToAcceptWorkshopLegalAgreement:Int)
+	Rem
+	bbdoc: Called when the user has subscribed to a piece of UGC.
+	End Rem
+	Method OnRemoteStorageSubscribePublishedFile(result:EResult, publishedFileId:ULong)
+	Rem
+	bbdoc: Called when the user has unsubscribed from a piece of UGC.
+	End Rem
+	Method OnRemoteStorageUnsubscribePublishedFile(result:EResult, publishedFileId:ULong)
+	
+End Interface
+
+Rem
+bbdoc: Steam UGC API
+about: Steam Workshop is a system of back-end storage and front-end web pages that make it easy to store, organize, sort, rate, and download content for your game or application.
+
+In a typical set-up, customers of your game would use tools provided by you with purchase of your game to create modifications or entirely new content.
+Those customers would then submit that content through a form built into your tool to the Steam Workshop.
+Other customers would then be able to browse, sort, rate, and subscribe to items they wish to add to their game by going to the Steam Workshop
+in the Steam Community. Those items would then download through Steam. By using the #OnItemInstalled callback within your game, you can then
+call #GetItemInstallInfo to get the installed location and read the data directly from that folder. That new content would then be recognized
+by the game in whatever capacity makes sense for your game and the content created.
+
+### Steam Workshop Types, Monetization, & Best Practices
+For more information and definitions of the various types of Workshop integration you can utilize and how to make the best out of the
+tools provided by Steam, please see the [Steam Workshop](https://partner.steamgames.com/doc/features/workshop) documentation.
+
+### Enabling ISteamUGC for a Game or Application
+Before workshop items can be uploaded to the Steamworks backend there are two configuration settings that must be made,
+Configuring Steam Cloud Quotas and Enabling the ISteamUGC API.
+
+The Steam Cloud feature is used to store the preview images associated to workshop items. The Steam Cloud Quota can be configured with the following steps:
+1. Navigate to the Steam Cloud Settings page in the App Admin panel.
+2. Set the Byte quota per user and Number of files allowed per user to appropriate values for preview image storage
+3. Click Save Cloud Changes
+4. From the Publish tab, click Prepare for Publishing
+5. Click Publish to Steam and complete the process to publish the change.
+
+Enabling the ISteamUGC API can be accomplished with the following steps:
+1. Navigate to the Steam Workshop Configuration page in the App Admin panel.
+2. Find the Additional Configuration Options section
+3. Check on Use ISteamUGC for file transfer
+4. Click Save Additional Configuration Options
+5. From the Publish tab, click Prepare for Publishing
+6. Click Publish to Steam and complete the process to publish the change.
+
+Once these settings are in place workshop content can be uploaded via the API.
+
+### Creating and Uploading Content
+The process of creating and uploading workshop content is a simple and repeatable process.
+
+#### Creating a Workshop Item
+1. All workshop items begin their existence with a call to #CreateItem
+ * The @consumerAppId variable should contain the App ID for the game or application. Do not pass the App ID of the workshop item creation tool if that is a separate App ID.
+ * #EWorkshopFileType is an enumeration type that defines how the shared file will be shared with the community. The valid values are:
+   * k_EWorkshopFileTypeCommunity - This file type is used to describe files that will be uploaded by users and made available to download by anyone in the community. Common usage of this would be to share user created mods.
+   * k_EWorkshopFileTypeMicrotransaction - This file type is used to describe files that are uploaded by users, but intended only for the game to consider adding as official content. These files will not be downloaded by users through the Workshop, but will be viewable by the community to rate. This is the implementation that Team Fortress 2 uses.
+2. Register a call result handler for #OnCreateItem.
+3. First check the @result to ensure that the item was created successfully.
+4. When the call result handler is executed, read the @publishedFileId value and store for future updates to the workshop item (e.g. in a project file associated with the creation tool).
+5. The @userNeedsToAcceptWorkshopLegalAgreement variable should also be checked and if it's true, the user should be redirected to accept the legal agreement. See the [Workshop Legal Agreement](https://partner.steamgames.com/doc/features/workshop/implementation#Legal) section for more details.
+
+#### Uploading a Workshop Item
+1. Once a workshop item has been created and a published file id value has been returned, the content of the workshop item can be populated and uploaded to the Steam Workshop.
+2. An item update begins with a call to #StartItemUpdate
+3. Using the update handle that is returned from #StartItemUpdate, calls can be made to update the Title, Description, Visibility, Tags, Item Content and Item Preview Image through the various `SetItem[...]` methods.
+  * #SetItemTitle - Sets a new title for an item.
+  * #SetItemDescription - Sets a new description for an item.
+  * #SetItemUpdateLanguage - Sets the language of the title and description that will be set in this item update.
+  * #SetItemMetadata - Sets arbitrary metadata for an item. This metadata can be returned from queries without having to download and install the actual content.
+  * #SetItemVisibility - Sets the visibility of an item.
+  * #SetItemTags - Sets arbitrary developer specified tags on an item.
+  * #AddItemKeyValueTag - Adds a key-value tag pair to an item. Keys can map to multiple different values (1-to-many relationship).
+  * #RemoveItemKeyValueTags - Removes an existing key value tag from an item.
+  * #SetItemContent - Sets the folder that will be stored as the content for an item.
+  * #SetItemPreview -Sets the primary preview image for the item.
+4. Once the update calls have been completed, calling #SubmitItemUpdate will initiate the upload process to the Steam Workshop.
+  * Register a call result handler for #OnSubmitItemUpdate
+  * When the call result handler is executed, check the @result to confirm the upload completed successfully.
+  * Note: There is no method to cancel the item update and upload once it's been called.
+5. If desired, the progress of the upload can be tracked using #GetItemUpdateProgress
+  * #EItemUpdateStatus defines the upload and update progress.
+  * @bytesProcessed and @bytesTotal can be used to provide input for a user interface control such as a progress bar to indicate progress of the upload.
+  * @bytesTotal may update during the upload process based upon the stage of the item update.
+6. In the same way as Creating a Workshop Item, confirm the user has accepted the legal agreement. This is necessary in case where the user didn't initially create the item but is editing an existing item.
+
+##### Additional Notes
+ * Workshop items were previously designated as single files. With ISteamUGC, a workshop item is a representation of a folder of files.
+ * If a workshop item requires additional metadata for use by the consuming application, you can attach metadata to your item using the #SetItemMetadata call. This metadata can be returned in queries without having to download and install the item content.  Previously we suggested that you save this metadata to a file inside the workshop item folder, which of course you can still do.
+
+### Consuming Content
+Consuming workshop content falls into two categories, Item Subscription and Item Installation.
+
+#### Item Subscription
+The majority of subscriptions to a workshop item will happen through the Steam Workshop portal. It is a known location, common to all games and applications, and as such, users are likely to find and subscribe to items regularly on the workshop site.
+
+However, ISteamUGC provides two methods for programmatically subscribing and unsubscribing to workshop items to support in-game item subscription management.
+ * #SubscribeItem - Subscribe to a workshop item. It will be downloaded and installed as soon as possible.
+ * #UnsubscribeItem - Unsubscribe from a workshop item. This will result in the item being removed after the game quits.
+
+Two additional methods exist for enumerating through a user's subscribed items.
+ * #GetNumSubscribedItems - Gets the total number of items the current user is subscribed to for the game or application.
+ * #GetSubscribedItems - Gets a list of all of the items the current user is subscribed to for the current game.
+
+##### Receiving Notifications for External Subscription Actions
+In-game notifications can be received when a user has subscribed or unsubscribed from a file through any mechanism (e.g. ISteamUGC, Steam Workshop Website):
+ * Register a callback handler for #OnRemoteStoragePublishedFileSubscribed and #OnRemoteStoragePublishedFileUnsubscribed
+ * The @publishedFileId will be returned which can then be used to access the information about the workshop item.
+ * The application ID (@appID) associated with the workshop item will also be returned. It should be compared against the running application ID as the handler will be called for all item subscriptions regardless of the running application.
+
+#### Item Installation
+Once Item Subscription information is known, the remaining consumption methods can be utilized. These methods provide information back to the game about the state of the item download and installation. Workshop item downloads are executed via the Steam Client and happen automatically, based on the following rules:
+
+1. When the Steam Client indicates a game or application is to launch, all app depots that have been updated will be downloaded and installed.
+2. Any existing installed workshop items are updated if needed
+3. Game or application then launches
+4. Newly subscribed workshop items that are not downloaded will then download and be installed in the background.
+ * Subscribed files will be downloaded to the client in the order they were subscribed in.
+ * The Steam download page will show workshop item downloads with a specific banner to indicate a workshop item download is occurring.
+
+> Note: Using the "Verify Integrity of Game Files" feature in the Steam Client will also cause workshop items to be downloaded.
+
+As the game will start before newly subscribed content is downloaded and installed, the remaining consumption methods exist to aid in monitoring and managing the install progress. They can also be used when items are subscribed in-game to provide status of installation in real time.
+
+##### Status of a Workshop Item
+ * #GetItemState - Gets the current state of a workshop item on this client.
+
+##### Download Progress of a Workshop Item
+ * #GetItemDownloadInfo - Get info about a pending download of a workshop item that has k_EItemStateNeedsUpdate set.
+
+##### Initiate or Increase the Priority of Downloading a Workshop Item
+1. #DownloadItem
+ * Set @highPriority to #True to pause any existing in-progress downloads and immediately begin downloading this workshop item.
+ * If the return value is #True then register and wait for the callback #OnDownloadItem before calling #GetItemInstallInfo or accessing the workshop item on disk.
+ * If the user is not subscribed to the item (e.g. a Game Server using anonymous login), the workshop item will be downloaded and cached temporarily.
+ * If the workshop item has an #EItemState of k_EItemStateNeedsUpdate, #DownloadItem can be called to initiate the update. Do not access the workshop item on disk until the callback ISteamUGC::DownloadItemResult_t is called.
+ * This method only works with ISteamUGC created workshop items. It will not work with legacy ISteamRemoteStorage workshop items.
+ * The #OnDownloadItem callback struct contains the application ID (m_unAppID) associated with the workshop item. It should be compared against the running application ID as the handler will be called for all item downloads regardless of the running application.
+
+##### Retrieving information about the local copy of the Workshop Item
+ * #GetItemInstallInfo - Gets info about currently installed content on the disc for workshop items that have k_EItemStateInstalled set.
+
+##### Notification when a Workshop Item is Installed or Updated
+ * Register a callback handler for #OnItemInstalled.
+
+### Querying Content
+The #TSteamUGC interface provides a flexible way to enumerate the various kinds of UGC in Steam (e.g. Workshop items, screenshots, videos, etc.).
+
+1. Register a call result handler for #OnSteamUGCQueryCompleted.
+2. There are a few methods available for creating the query depending upon the required scenario, Querying by Content Associated to a User or Querying All Content or getting the details of content you have ids for.
+  * #CreateQueryUserUGCRequest - Query UGC associated with a user. You can use this to list the UGC the user is subscribed to amongst other things.
+  * CreateQueryAllUGCRequest - Query for all matching UGC. You can use this to list all of the available UGC for your app.
+  * CreateQueryUGCDetailsRequest - Query for the details of specific workshop items.
+3. Customize the query as appropriate by calling the option setting methods:
+  
+  When querying for User UGC
+  * #SetCloudFileNameFilter - Sets to only return items that have a specific filename on a pending UGC Query.
+
+  When querying for All UGC
+  * #SetMatchAnyTag - Sets whether workshop items will be returned if they have one or more matching tag, or if all tags need to match on a pending UGC Query.
+  * #SetSearchText - Sets a string to that items need to match in either the title or the description on a pending UGC Query.
+  * #SetRankedByTrendDays - Sets whether the order of the results will be updated based on the rank of items over a number of days on a pending UGC Query.
+
+When querying for either type of UGC
+
+  * #AddRequiredTag - Adds a required tag to a pending UGC Query. This will only return UGC with the specified tag.
+  * #AddExcludedTag - Adds a excluded tag to a pending UGC Query. This will only return UGC without the specified tag.
+  * #AddRequiredKeyValueTag - Adds a required key-value tag to a pending UGC Query. This will only return workshop items that have a key = `key` and a value = `value`.
+  * #SetReturnOnlyIDs - Sets whether to only return IDs instead of all the details on a pending UGC Query. This is useful for when you don't need all the information (e.g. you just want to get the IDs of the items a user has in their favorites list.)
+  * #SetReturnKeyValueTags - Sets whether to return any key-value tags for the items on a pending UGC Query.
+  * #SetReturnLongDescription - Sets whether to return the full description for the items on a pending UGC Query.
+  * #SetReturnMetadata - Sets whether to return the developer specified metadata for the items on a pending UGC Query.
+  * #SetReturnChildren - Sets whether to return the IDs of the child items of the items on a pending UGC Query.
+  * #SetReturnAdditionalPreviews - Sets whether to return any additional images/videos attached to the items on a pending UGC Query.
+  * #SetReturnTotalOnly - Sets whether to only return the total number of matching items on a pending UGC Query. -- The actual items will not be returned when ISteamUGC::SteamUGCQueryCompleted_t is called.
+  * #SetLanguage - Sets the language to return the title and description in for the items on a pending UGC Query.
+  * #SetAllowCachedResponse - Sets whether results to be will be returned from the cache for the specific period of time on a pending UGC Query.
+
+4. Send the query to Steam using #SendQueryUGCRequest which will invoke the #OnSteamUGCQueryCompleted call result handler registered in step 1.
+5. In the call result handler for #OnSteamUGCQueryCompleted, call #GetQueryUGCResult to retrieve the details for each item returned.
+6. You can also call these functions to retrieve additional information for each item (some of this data is not returned by default, so you need to configure your query appropriately):
+  * #GetQueryUGCPreviewURL - Retrieve the URL to the preview image of an individual workshop item after receiving a querying UGC call result.
+  * #GetQueryUGCMetadata - Retrieve the developer set metadata of an individual workshop item after receiving a querying UGC call result.
+  * #GetQueryUGCChildren - Retrieve the ids of any child items of an individual workshop item after receiving a querying UGC call result.
+  * #GetQueryUGCStatistic - Retrieve various statistics of an individual workshop item after receiving a querying UGC call result.
+  * #GetQueryUGCNumAdditionalPreviews and #GetQueryUGCAdditionalPreview - Retrieve the details of an additional preview associated with an individual workshop item after receiving a querying UGC call result.
+  * #GetQueryUGCNumKeyValueTags and #GetQueryUGCKeyValueTag - Retrieve the details of a key-value tag associated with an individual workshop item after receiving a querying UGC call result.
+
+7. Call #ReleaseQueryUGCRequest to free up any memory allocated while querying or retrieving the results.
+
+##### Paging Results
+Up to 50 results will be returned from each query. Paging through more results can be achieved by creating a query that increments the unPage parameter (which should start at 1).
+
+### Playtime Tracking
+To track the playtime of Workshop items simply call #StartPlaytimeTracking with the ids of the items you want to track. Then when the items are removed from play call #StopPlaytimeTracking with the ids you want to stop tracking or call #StopPlaytimeTrackingForAllItems to stop tracking playtime for all items at once.
+When your app shuts down, playtime tracking will automatically stop.
+
+You will also be able to sort items by various playtime metrics in #CreateQueryAllUGCRequest queries. Here are the playtime based query types you can use:
+ * k_EUGCQuery_RankedByPlaytimeTrend - Sort by total playtime in the "trend" period descending (set with #SetRankedByTrendDays)
+ * k_EUGCQuery_RankedByTotalPlaytime - Sort by total lifetime playtime descending.
+ * k_EUGCQuery_RankedByAveragePlaytimeTrend - Sort by average playtime in the "trend" period descending (set with #SetRankedByTrendDays)
+ * k_EUGCQuery_RankedByLifetimeAveragePlaytime - Soft by lifetime average playtime descending
+ * k_EUGCQuery_RankedByPlaytimeSessionsTrend - Sort by number of play sessions in the "trend" period descending (set in #SetRankedByTrendDays)
+ * k_EUGCQuery_RankedByLifetimePlaytimeSessions - Sort by number of lifetime play sessions descending
+
+### Deleting Workshop Item Content
+To delete a Workshop item, you can call #DeleteItem. Please note that this does not prompt the user and cannot be undone.
+
+### Workshop Legal Agreement
+Workshop items will be hidden by default until the contributor agrees to the Steam Workshop Legal Agreement. In order to make it easy for the contributor to make the item publicly visible, please do the following.
+1. Include text next to the button that submits an item to the workshop, something to the effect of: "By submitting this item, you agree to the [workshop terms of service](http://steamcommunity.com/sharedfiles/workshoplegalagreement)" (including the link)
+2. After a user submits an item, open a browser window to the Steam Workshop page for that item by calling ISteamFriends::ActivateGameOverlayToWebPage with pchURL set to steam://url/CommunityFilePage/&lt;PublishedFileId_t&gt; replacing &lt;PublishedFileId_t&gt; with the workshop item id.
+
+This has the benefit of directing the author to the workshop page so that they can see the item and configure it further if necessary and will make it easy for the user to read and accept the Steam Workshop Legal Agreement.
+
+### Errors and Logging
+The majority of #TSteamUGC methods return boolean values. For additional information on specific errors, there are a number of places to review:
+ * `Steam\logs\Workshop_log.txt` is a log for all transfers that occur during workshop item downloading and installation.
+ * `Steam\workshopbuilds\depot_build_<appid>.log` is a log for all actions during the upload and update of a workshop item.
+ * #OnSteamUGCQueryCompleted, #OnCreateItem and #OnSubmitItemUpdate contain #EResult variables that can be checked.
+
+End Rem
+Type TSteamUGC Extends TSteamAPI
+
+	Const STEAMUGC_INTERFACE_VERSION:String = "STEAMUGC_INTERFACE_VERSION012"
+
+	Field listener:ISteamUGCListener
+
+	Function _create:TSteamUGC(instancePtr:Byte Ptr)
+		Local this:TSteamUGC = New TSteamUGC
+		this.instancePtr = instancePtr
+		
+		this.callbackPtr = bmx_steamsdk_register_steamugc(instancePtr, this)
+		
+		Return this
+	End Function
+	
+	Method Delete()
+		bmx_steamsdk_unregister_steamugc(callbackPtr)
+	End Method
+
+	Rem
+	bbdoc: Adds a dependency between the given item and the appid.
+	about: This list of dependencies can be retrieved by calling #GetAppDependencies.
+	This is a soft-dependency that is displayed on the web. It is up to the application to determine whether the item can actually be used or not.
+
+	See Also: #RemoveAppDependency
+	End Rem
+	Method AddAppDependency(publishedFileID:ULong, appID:UInt)
+		bmx_SteamAPI_ISteamUGC_AddAppDependency(callbackPtr, publishedFileID, appID)
+	End Method
+	
+	Rem
+	bbdoc: Adds a workshop item as a dependency to the specified item.
+	about: If the @parentPublishedFileID item is of type #k_EWorkshopFileTypeCollection, then the childPublishedFileID is simply added to that collection.
+	Otherwise, the dependency is a soft one that is displayed on the web and can be retrieved via the #TSteamUGC API using a combination of the @numChildren member variable of the SteamUGCDetails_t struct and #GetQueryUGCChildren.
+
+	See Also: #RemoveDependency
+	End Rem
+	Method AddDependency(publishedFileId:ULong, childPublishedFileId:ULong)
+		bmx_SteamAPI_ISteamUGC_AddDependency(callbackPtr, publishedFileId, childPublishedFileId)
+	End Method
+	
+	Rem
+	bbdoc: Adds a excluded tag to a pending UGC Query.
+	returns: #True upon success or #False if the UGC query handle is invalid, if the UGC query handle is from #CreateQueryUGCDetailsRequest, or @tagName was #Null.
+	about: This will only return UGC without the specified tag.
+	
+	NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	
+	See Also: #AddRequiredTag, #SetMatchAnyTag, #SetItemTags
+	End Rem
+	Method AddExcludedTag:Int(queryHandle:ULong, tagName:String)
+		Return bmx_SteamAPI_ISteamUGC_AddExcludedTag(instancePtr, queryHandle, tagName)
+	End Method
+	
+	Rem
+	bbdoc: Adds a key-value tag pair to an item.
+	about: Keys can map to multiple different values (1-to-many relationship).
+
+	Key names are restricted to alpha-numeric characters and the '_' character.
+	Both keys and values cannot exceed 255 characters in length.
+	Key-value tags are searchable by exact match only.
+	
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+
+	See Also: #RemoveItemKeyValueTags, #SetReturnKeyValueTags, #GetQueryUGCNumKeyValueTags, #GetQueryUGCKeyValueTag
+	End Rem
+	Method AddItemKeyValueTag:Int(queryHandle:ULong, key:String, value:String)
+		Return bmx_SteamAPI_ISteamUGC_AddItemKeyValueTag(instancePtr, queryHandle, key, value)
+	End Method
+	
+	Rem
+	bbdoc: Adds an additional preview file for the item.
+	about: Then the format of the image should be one that both the web and the application (if necessary) can render, and must be under 1MB.
+	Suggested formats include JPG, PNG and GIF.
+
+	> NOTE: Using k_EItemPreviewType_YouTubeVideo or k_EItemPreviewType_Sketchfab are not currently supported with this API.
+	> For YouTube videos you should use #AddItemPreviewVideo.
+
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+
+	See Also: #GetQueryUGCNumAdditionalPreviews, #GetQueryUGCAdditionalPreview, #SetReturnAdditionalPreviews, #UpdateItemPreviewFile, #AddItemPreviewVideo, #RemoveItemPreview
+	End Rem
+	Method AddItemPreviewFile:Int(queryHandle:ULong, previewFile:String, previewType:EItemPreviewType)
+		Return bmx_SteamAPI_ISteamUGC_AddItemPreviewFile(instancePtr, queryHandle, previewFile, previewType)
+	End Method
+	
+	Rem
+	bbdoc: Adds an additional video preview from YouTube for the item.
+	about:
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+	
+	See Also: #GetQueryUGCNumAdditionalPreviews, #GetQueryUGCAdditionalPreview, #SetReturnAdditionalPreviews, #UpdateItemPreviewVideo, #AddItemPreviewFile, #RemoveItemPreview
+	End Rem
+	Method AddItemPreviewVideo:Int(queryHandle:ULong, videoID:String)
+		Return bmx_SteamAPI_ISteamUGC_AddItemPreviewVideo(instancePtr, queryHandle, videoID)
+	End Method
+	
+	Rem
+	bbdoc: Adds a workshop item to the users favorites list.
+	about: See Also: #RemoveItemFromFavorites
+	End Rem
+	Method AddItemToFavorites(appId:UInt, publishedFileID:ULong)
+		bmx_SteamAPI_ISteamUGC_AddItemToFavorites(callbackPtr, appId, publishedFileID)
+	End Method
+	
+	Rem
+	bbdoc: Adds a required key-value tag to a pending UGC Query.
+	about: This will only return workshop items that have a key = pKey and a value = pValue.
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+
+	See Also: #AddExcludedTag, #SetMatchAnyTag, #SetItemTags
+	End Rem
+	Method AddRequiredKeyValueTag:Int(queryHandle:ULong, key:String, value:String)
+		Return bmx_SteamAPI_ISteamUGC_AddRequiredKeyValueTag(instancePtr, queryHandle, key, value)
+	End Method
+	
+	Rem
+	bbdoc: Adds a required tag to a pending UGC Query.
+	about: This will only return UGC with the specified tag.
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	
+	See Also: #AddExcludedTag, #SetMatchAnyTag, #SetItemTags
+	End Rem
+	Method AddRequiredTag:Int(queryHandle:ULong, tagName:String)
+		Return bmx_SteamAPI_ISteamUGC_AddRequiredTag(instancePtr, queryHandle, tagName)
+	End Method
+	
+	Rem
+	bbdoc: Lets game servers set a specific workshop folder before issuing any UGC commands.
+	returns: #True upon success, otherwise, #False if the calling user is not a game server or if the workshop is currently updating it's content.
+	about: This is helpful if you want to support multiple game servers running out of the same install folder.
+	End Rem
+	Method InitWorkshopForGameServer:Int(workshopDepotID:ULong, folder:String)
+		Return bmx_SteamAPI_ISteamUGC_InitWorkshopForGameServer(instancePtr, workshopDepotID, folder)
+	End Method
+	
+	Rem
+	bbdoc: Creates a new workshop item with no content attached yet.
+	End Rem
+	Method CreateItem(consumerAppId:UInt, FileType:EWorkshopFileType)
+		bmx_SteamAPI_ISteamUGC_CreateItem(callbackPtr, consumerAppId, FileType)
+	End Method
+	
+	Rem
+	bbdoc: Query for all matching UGC.
+	about: You can use this to list all of the available UGC for your app.
+
+	This will return up to 50 results per page. You can make subsequent calls to this method, increasing @page each time to get the next set of results.
+	
+	> NOTE: Either @consumerAppID or @creatorAppID must have a valid AppID!
+
+	> NOTE: You must release the handle returned by this function by calling #ReleaseQueryUGCRequest when you are done with it!
+
+	To query for the UGC associated with a single user you can use #CreateQueryUserUGCRequest instead.
+	End Rem
+	Method CreateQueryAllUGCRequest:ULong(queryType:EUGCQuery, matchingeMatchingUGCTypeFileType:EUGCMatchingUGCType, creatorAppID:UInt, consumerAppID:UInt, page:UInt)
+		Return bmx_SteamAPI_ISteamUGC_CreateQueryAllUGCRequest(instancePtr, queryType, matchingeMatchingUGCTypeFileType, creatorAppID, consumerAppID, page)
+	End Method
+	
+	Rem
+	bbdoc: Query for the details of specific workshop items.
+	about: This will return up to 50 results per page.
+
+	> NOTE: Either @consumerAppID or @creatorAppID must have a valid AppID!
+
+	> NOTE: You must release the handle returned by this function by calling #ReleaseQueryUGCRequest when you are done with it!
+
+	To query all the UGC for your app you can use #CreateQueryAllUGCRequest instead.
+	End Rem
+	Method CreateQueryUGCDetailsRequest:ULong(publishedFileIDs:ULong[])
+		Return CreateQueryUGCDetailsRequest(publishedFileIDs, publishedFileIDs.length)
+	End Method
+
+	Rem
+	bbdoc: Query for the details of specific workshop items.
+	about: This will return up to 50 results per page.
+
+	> NOTE: Either @consumerAppID or @creatorAppID must have a valid AppID!
+
+	> NOTE: You must release the handle returned by this function by calling #ReleaseQueryUGCRequest when you are done with it!
+
+	To query all the UGC for your app you can use #CreateQueryAllUGCRequest instead.
+	End Rem
+	Method CreateQueryUGCDetailsRequest:ULong(publishedFileIDs:ULong Ptr, numPublishedFileIDs:Int)
+		Return bmx_SteamAPI_ISteamUGC_CreateQueryUGCDetailsRequest(instancePtr, publishedFileIDs, numPublishedFileIDs)
+	End Method
+	
+	Rem
+	bbdoc: Query UGC associated with a user.
+	about: You can use this to list the UGC the user is subscribed to amongst other things.
+	This will return up to 50 results per page. You can make subsequent calls to this method, increasing @page each time to get the next set of results.
+
+	> NOTE: Either @consumerAppID or @creatorAppID must have a valid AppID!
+
+	> NOTE: You must release the handle returned by this function by calling #ReleaseQueryUGCRequest when you are done with it!
+
+	To query all the UGC for your app you can use #CreateQueryAllUGCRequest instead.
+	End Rem
+	Method CreateQueryUserUGCRequest:ULong(accountID:UInt, listType:EUserUGCList, matchingUGCType:EUGCMatchingUGCType, sortOrder:EUserUGCListSortOrder, creatorAppID:UInt, consumerAppID:UInt, page:UInt)
+		Return bmx_SteamAPI_ISteamUGC_CreateQueryUserUGCRequest(instancePtr, accountID, listType, matchingUGCType, sortOrder, creatorAppID, consumerAppID, page)
+	End Method
+	
+	Rem
+	bbdoc: Deletes the item without prompting the user.
+	about: Results in a cal to #OnDeleteItem.
+	End Rem
+	Method DeleteItem(publishedFileID:ULong)
+		bmx_SteamAPI_ISteamUGC_DeleteItem(callbackPtr, publishedFileID)
+	End Method
+	
+	Rem
+	bbdoc: Downloads or updates a workshop item.
+	returns: #True if the download was successfully started, otherwise, #False if @publishedFileID is invalid or the user is not logged on.
+	about: If the return value is #True then wait for the callback to #OnDownloadItem before calling #GetItemInstallInfo or accessing the workshop item on disk.
+
+	If the user is not subscribed to the item (e.g. a Game Server using anonymous login), the workshop item will be downloaded and cached temporarily.
+
+	If the workshop item has an item state of k_EItemStateNeedsUpdate, then this method can be called to initiate the update.
+	Do not access the workshop item on disk until the callback #OnDownloadItem is called.
+
+	The #OnDownloadItem callback contains the app ID associated with the workshop item. It should be compared against the running app ID as
+	the handler will be called for all item downloads regardless of the running application.
+	End Rem
+	Method DownloadItem:Int(publishedFileID:ULong, highPriority:Int)
+		Return bmx_SteamAPI_ISteamUGC_DownloadItem(instancePtr, publishedFileID, highPriority)
+	End Method
+
+	Rem
+	bbdoc: Gets the app dependencies associated with the given @publishedFileID.
+	about: These are "soft" dependencies that are shown on the web. It is up to the application to determine whether an item can be used or not.
+	
+	Results in a call to #OnGetAppDependencies.
+	
+	See Also: #AddAppDependency, #RemoveAppDependency
+	End Rem
+	Method GetAppDependencies(publishedFileID:ULong)
+		bmx_SteamAPI_ISteamUGC_GetAppDependencies(callbackPtr, publishedFileID)
+	End Method
+	
+	Rem
+	bbdoc: Gets info about a pending download of a workshop item that has k_EItemStateNeedsUpdate set.
+	returns: #True if the download information was available, otherwise, #False.
+	End Rem
+	Method GetItemDownloadInfo:Int(publishedFileID:ULong, bytesDownloaded:ULong Var, bytesTotal:ULong Var)
+		Return bmx_SteamAPI_ISteamUGC_GetItemDownloadInfo(instancePtr, publishedFileID, bytesDownloaded, bytesTotal)
+	End Method
+	
+	Rem
+	bbdoc: Gets info about currently installed content on the disc for workshop items that have k_EItemStateInstalled set.
+	about: Calling this sets the "used" flag on the workshop item for the current player and adds it to their k_EUserUGCList_UsedOrPlayed list.
+
+	If k_EItemStateLegacyItem is set then @folder contains the path to the legacy file itself, not a folder.
+	End Rem
+	Method GetItemInstallInfo:Int(publishedFileID:ULong, sizeOnDisk:ULong Var, folder:String Var, timestamp:UInt Var)
+		Return bmx_SteamAPI_ISteamUGC_GetItemInstallInfo(instancePtr, publishedFileID, sizeOnDisk, folder, timestamp)
+	End Method
+	
+	Rem
+	bbdoc: Gets the current state of a workshop item on this client.
+	End Rem
+	Method GetItemState:EItemState(publishedFileID:ULong)
+		Return bmx_SteamAPI_ISteamUGC_GetItemState(instancePtr, publishedFileID)
+	End Method
+	
+	Rem
+	bbdoc: Gets the progress of an item update.
+	returns: The current status.
+	about: See Also: #SubmitItemUpdate
+	End Rem
+	Method GetItemUpdateProgress:EItemUpdateStatus(queryHandle:ULong, bytesProcessed:ULong Var, bytesTotal:ULong Var)
+		Return bmx_SteamAPI_ISteamUGC_GetItemUpdateProgress(instancePtr, queryHandle, bytesProcessed, bytesTotal)
+	End Method
+	
+	Rem
+	bbdoc: Gets the total number of items the current user is subscribed to for the game or application.
+	returns: 0 if called from a game server.
+	End Rem
+	Method GetNumSubscribedItems:UInt()
+		Return bmx_SteamAPI_ISteamUGC_GetNumSubscribedItems(instancePtr)
+	End Method
+	
+	Rem
+	bbdoc: Retrieves the details of an additional preview associated with an individual workshop item after receiving a querying UGC call result.
+	returns: #True upon success, indicates that @URLOrVideoID and @previewType have been filled out. Otherwise, #False if the UGC query handle is invalid, the @index is out of bounds, or @previewIndex is out of bounds.
+	about: You should call this in a loop to get the details of all the workshop items returned.
+
+	> NOTE: This must only be called with the handle obtained from a successful #OnSteamUGCQueryCompleted call result.
+
+	Before calling this you should call #GetQueryUGCNumAdditionalPreviews to get number of additional previews.
+	End Rem
+	Method GetQueryUGCAdditionalPreview:Int(queryHandle:ULong, index:UInt, previewIndex:UInt, URLOrVideoID:String Var, originalFileName:String Var, previewType:EItemPreviewType Var)
+		Return bmx_SteamAPI_ISteamUGC_GetQueryUGCAdditionalPreview(instancePtr, queryHandle, index, previewIndex, URLOrVideoID, originalFileName, previewType)
+	End Method
+	
+	Rem
+	bbdoc: Retrieves the ids of any child items of an individual workshop item after receiving a querying UGC call result.
+	returns: #True upon success, indicates that @publishedFileIDs has been filled out. Otherwise, #False if the UGC query handle is invalid or the @index is out of bounds.
+	about: These items can either be a part of a collection or some other dependency (see #AddDependency).
+
+	You should call this in a loop to get the details of all the workshop items returned.
+
+	> NOTE: This must only be called with the handle obtained from a successful #OnSteamUGCQueryCompleted call result.
+
+	You should create @publishedFileIDs with @numChildren provided in #OnSteamUGCDetails after getting the UGC details with #GetQueryUGCResult.
+	End Rem
+	Method GetQueryUGCChildren:Int(queryHandle:ULong, index:UInt, publishedFileIDs:ULong Ptr, maxEntries:UInt)
+		Return bmx_SteamAPI_ISteamUGC_GetQueryUGCChildren(instancePtr, queryHandle, index, publishedFileIDs, maxEntries)
+	End Method
+	
+	Rem
+	bbdoc: Retrieves the details of a key-value tag associated with an individual workshop item after receiving a querying UGC call result.
+	returns: #True upon success, indicates that @key and @value have been filled out. Otherwise, #False if the UGC query handle is invalid, the @index is out of bounds, or @keyValueTagIndex is out of bounds.
+	about: You should call this in a loop to get the details of all the workshop items returned.
+
+	> NOTE: This must only be called with the handle obtained from a successful #OnSteamUGCQueryCompleted call result.
+
+	Before calling this you should call #GetQueryUGCNumKeyValueTags to get number of tags.
+	End Rem
+	Method GetQueryUGCKeyValueTag:Int(queryHandle:ULong, index:UInt, keyValueTagIndex:UInt, key:String Var, value:String Var)
+		Return bmx_SteamAPI_ISteamUGC_GetQueryUGCKeyValueTag(instancePtr, queryHandle, index, keyValueTagIndex, key, value)
+	End Method
+	
+	Rem
+	bbdoc: Retrieves the developer set metadata of an individual workshop item after receiving a querying UGC call result.
+	returns: #True upon success, indicates that @metadata has been filled out. Otherwise, false if the UGC query handle is invalid or the @index is out of bounds.
+	about: You should call this in a loop to get the details of all the workshop items returned.
+
+	> NOTE: This must only be called with the handle obtained from a successful #OnSteamUGCQueryCompleted call result.
+	
+	See Also: #SetItemMetadata
+	End Rem
+	Method GetQueryUGCMetadata:Int(queryHandle:ULong, index:UInt, metadata:String Var)
+		Return bmx_SteamAPI_ISteamUGC_GetQueryUGCMetadata(instancePtr, queryHandle, index, metadata)
+	End Method
+	
+	Rem
+	bbdoc: Retrieve the number of additional previews of an individual workshop item after receiving a querying UGC call result.
+	returns: The number of additional previews associated with the specified workshop item. Returns 0 if the UGC query handle is invalid or the @index is out of bounds.
+	about: You should call this in a loop to get the details of all the workshop items returned.
+
+	> NOTE: This must only be called with the handle obtained from a successful #OnSteamUGCQueryCompleted call result.
+
+	You can then call #GetQueryUGCAdditionalPreview to get the details of each additional preview.
+	End Rem
+	Method GetQueryUGCNumAdditionalPreviews:UInt(queryHandle:ULong, index:UInt)
+		Return bmx_SteamAPI_ISteamUGC_GetQueryUGCNumAdditionalPreviews(instancePtr, queryHandle, index)
+	End Method
+	
+	Rem
+	bbdoc: Retrieves the number of key-value tags of an individual workshop item after receiving a querying UGC call result.
+	returns: The number of key-value tags associated with the specified workshop item. Returns 0 if the UGC query handle is invalid or the @index is out of bounds.
+	about: You should call this in a loop to get the details of all the workshop items returned.
+
+	> NOTE: This must only be called with the handle obtained from a successful #OnSteamUGCQueryCompleted call result.
+
+	You can then call #GetQueryUGCKeyValueTag to get the details of each tag.
+	End Rem
+	Method GetQueryUGCNumKeyValueTags:UInt(queryHandle:ULong, index:UInt)
+		Return bmx_SteamAPI_ISteamUGC_GetQueryUGCNumKeyValueTags(instancePtr, queryHandle, index)
+	End Method
+	
+	Rem
+	bbdoc: Retrieves the URL to the preview image of an individual workshop item after receiving a querying UGC call result.
+	returns: #True upon success, indicates that pchURL has been filled out. Otherwise, false if the UGC query handle is invalid or the @index is out of bounds.
+	about: You should call this in a loop to get the details of all the workshop items returned.
+
+	> NOTE: This must only be called with the handle obtained from a successful #OnSteamUGCQueryCompleted call result.
+	
+	You can use this URL to download and display the preview image instead of having to download it using the @previewFile from the SteamUGCDetails.
+	End Rem
+	Method GetQueryUGCPreviewURL:Int(queryHandle:ULong, index:UInt, URL:String Var)
+		Return bmx_SteamAPI_ISteamUGC_GetQueryUGCPreviewURL(instancePtr, queryHandle, index, URL)
+	End Method
+	
+	Rem
+	bbdoc: Retrieves various statistics of an individual workshop item after receiving a querying UGC call result.
+	returns: #True upon success, indicates that pStatValue has been filled out. Otherwise, #False if the UGC query handle is invalid, the @index is out of bounds, or @statType was invalid.
+
+	about: You should call this in a loop to get the details of all the workshop items returned.
+
+	> NOTE: This must only be called with the handle obtained from a successful #OnSteamUGCQueryCompleted call result.
+	End Rem
+	Method GetQueryUGCStatistic:Int(queryHandle:ULong, index:UInt, statType:EItemStatistic, statValue:ULong Var)
+		Return bmx_SteamAPI_ISteamUGC_GetQueryUGCStatistic(instancePtr, queryHandle, index, statType, statValue)
+	End Method
+	
+	Rem
+	bbdoc: Gets a list of all of the items the current user is subscribed to for the current game.
+	returns: The number of subscribed workshop items that were populated into @publishedFileIDs. Returns 0 if called from a game server.
+	about: You create an array with the size provided by #GetNumSubscribedItems before calling this.
+	End Rem
+	Method GetSubscribedItems:UInt(publishedFileIDs:ULong Ptr, maxEntries:UInt)
+		Return bmx_SteamAPI_ISteamUGC_GetSubscribedItems(instancePtr, publishedFileIDs, maxEntries)
+	End Method
+	
+	Rem
+	bbdoc: Gets the users vote status on a workshop item.
+	about: Results in a call to #OnGetUserItemVote.
+	
+	See Also: #SetUserItemVote
+	End Rem
+	Method GetUserItemVote(publishedFileID:ULong)
+		bmx_SteamAPI_ISteamUGC_GetUserItemVote(callbackPtr, publishedFileID)
+	End Method
+	
+	Rem
+	bbdoc: Releases a UGC query handle when you are done with it to free up memory.
+	returns: Always returns #True.
+	End Rem
+	Method ReleaseQueryUGCRequest:Int(queryHandle:ULong)
+		Return bmx_SteamAPI_ISteamUGC_ReleaseQueryUGCRequest(instancePtr, queryHandle)
+	End Method
+	
+	Rem
+	bbdoc: Removes the dependency between the given item and the appid.
+	about: This list of dependencies can be retrieved by calling #GetAppDependencies.
+	
+	Results in a call to #OnRemoveAppDependency.
+	
+	See Also: #AddAppDependency
+	End Rem
+	Method RemoveAppDependency(publishedFileID:ULong, appID:UInt)
+		bmx_SteamAPI_ISteamUGC_RemoveAppDependency(callbackPtr, publishedFileID, appID)
+	End Method
+	
+	Rem
+	bbdoc: Removes a workshop item as a dependency from the specified item.
+	about: Results in a call to #OnRemoveUGCDependency.
+	
+	See Also: #AddDependency
+	End Rem
+	Method RemoveDependency(parentPublishedFileID:ULong, childPublishedFileID:ULong)
+		bmx_SteamAPI_ISteamUGC_RemoveDependency(callbackPtr, parentPublishedFileID, childPublishedFileID)
+	End Method
+	
+	Rem
+	bbdoc: Removes a workshop item from the users favorites list.
+	about: Results in a call to #OnUserFavoriteItemsListChanged.
+	
+	See Also: #AddItemToFavorites
+	End Rem
+	Method RemoveItemFromFavorites(appId:UInt, publishedFileID:ULong)
+		bmx_SteamAPI_ISteamUGC_RemoveItemFromFavorites(callbackPtr, appId, publishedFileID)
+	End Method
+	
+	Rem
+	bbdoc: Removes an existing key value tag from an item.
+	returns: #True upon success, otherwise #False if the UGC update handle is invalid or if you are trying to remove more than 100 key-value tags in a single update.
+	about: You can only call this up to 100 times per item update. If you need remove more tags than that you'll need to make subsequent item updates.
+
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+
+	See Also: #AddItemKeyValueTag
+	End Rem
+	Method RemoveItemKeyValueTags:Int(queryHandle:ULong, key:String)
+		Return bmx_SteamAPI_ISteamUGC_RemoveItemKeyValueTags(instancePtr, queryHandle, key)
+	End Method
+	
+	Rem
+	bbdoc: Removes an item preview.
+	End Rem
+	Method RemoveItemPreview:Int(queryHandle:ULong, index:UInt)
+		Return bmx_SteamAPI_ISteamUGC_RemoveItemPreview(instancePtr, queryHandle, index)
+	End Method
+	
+	Rem
+	bbdoc: Sends a UGC query to Steam.
+	about: This must be called with a handle obtained from #CreateQueryUserUGCRequest, #CreateQueryAllUGCRequest, or #CreateQueryUGCDetailsRequest to actually send the request to Steam.
+	Before calling this you should use one or more of the following APIs to customize your query:
+	#AddRequiredTag, #AddExcludedTag, #SetReturnOnlyIDs, #SetReturnKeyValueTags, #SetReturnLongDescription, #SetReturnMetadata, #SetReturnChildren, #SetReturnAdditionalPreviews,
+	#SetReturnTotalOnly, #SetLanguage, #SetAllowCachedResponse, #SetCloudFileNameFilter, #SetMatchAnyTag, #SetSearchText, #SetRankedByTrendDays, 
+	#AddRequiredKeyValueTag
+
+	Results in a call to #OnSteamUGCQueryCompleted.
+	End Rem
+	Method SendQueryUGCRequest(queryHandle:ULong)
+		bmx_SteamAPI_ISteamUGC_SendQueryUGCRequest(callbackPtr, queryHandle)
+	End Method
+
+	Rem
+	bbdoc: Sets whether results will be returned from the cache for the specific period of time on a pending UGC Query.
+	returns: #True upon success, #False if the UGC query handle is invalid.
+	about: 
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+
+	End Rem
+	Method SetAllowCachedResponse:Int(queryHandle:ULong, maxAgeSeconds:UInt)
+		Return bmx_SteamAPI_ISteamUGC_SetAllowCachedResponse(instancePtr, queryHandle, maxAgeSeconds)
+	End Method
+	
+	Rem
+	bbdoc: Sets to only return items that have a specific filename on a pending UGC Query.
+	returns: #True upon success, otherwise #False if the UGC query handle is invalid, if the UGC query handle is not from #CreateQueryUserUGCRequest or if @matchCloudFileName is not set.
+	about:
+	> NOTE: This can only be used with #CreateQueryUserUGCRequest!
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	End Rem
+	Method SetCloudFileNameFilter:Int(queryHandle:ULong, matchCloudFileName:String)
+		Return bmx_SteamAPI_ISteamUGC_SetCloudFileNameFilter(instancePtr, queryHandle, matchCloudFileName)
+	End Method
+	
+	Rem
+	bbdoc: Sets the folder that will be stored as the content for an item.
+	returns: #True upon success, #False if the UGC update handle is invalid.
+	about: For efficient upload and download, files should not be merged or compressed into single files (e.g. zip files).
+
+	> NOTE: This must be set before you submit the UGC update handle using SubmitItemUpdate.
+	End Rem
+	Method SetItemContent:Int(updateHandle:ULong, contentFolder:String)
+		Return bmx_SteamAPI_ISteamUGC_SetItemContent(instancePtr, updateHandle, contentFolder)
+	End Method
+	
+	Rem
+	bbdoc: Sets a new description for an item.
+	returns: #True upon success, otherwise #False if the UGC update handle is invalid.
+	about: The description must be limited to the length defined by #k_cchPublishedDocumentDescriptionMax.
+
+	You can set what language this is for by using #SetItemUpdateLanguage, if no language is set then "english" is assumed.
+
+	> NOTE: This must be set before you submit the UGC update handle using SubmitItemUpdate.
+	
+	See Also: #SetReturnLongDescription
+	End Rem
+	Method SetItemDescription:Int(updateHandle:ULong, description:String)
+		Return bmx_SteamAPI_ISteamUGC_SetItemDescription(instancePtr, updateHandle, description)
+	End Method
+	
+	Rem
+	bbdoc: Sets arbitrary metadata for an item.
+	returns: #True upon success, otherwise #False if the UGC update handle is invalid, or if @metadata is longer than #k_cchDeveloperMetadataMax.
+	about: This metadata can be returned from queries without having to download and install the actual content.
+
+	The metadata must be limited to the size defined by #k_cchDeveloperMetadataMax.
+
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+
+	See Also: #SetReturnMetadata
+	End Rem
+	Method SetItemMetadata:Int(updateHandle:ULong, metaData:String)
+		Return bmx_SteamAPI_ISteamUGC_SetItemMetadata(instancePtr, updateHandle, metaData)
+	End Method
+	
+	Rem
+	bbdoc: Sets the primary preview image for the item.
+	returns: #True upon success, otherwise #False if the UGC update handle is invalid.
+	about: The format should be one that both the web and the application (if necessary) can render. Suggested formats include JPG, PNG and GIF.
+
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+	End Rem
+	Method SetItemPreview:Int(updateHandle:ULong, previewFile:String)
+		Return bmx_SteamAPI_ISteamUGC_SetItemPreview(instancePtr, updateHandle, previewFile)
+	End Method
+	
+	Rem
+	bbdoc: Sets arbitrary developer specified tags on an item.
+	returns: #True upon success, otherwise #False if the UGC update handle is invalid, or if one of the tags is invalid either due to exceeding the maximum length or because it is empty.
+	about: Each tag must be limited to 255 characters. Tag names can only include printable characters, excluding ','. For reference on what characters are allowed, refer to http://en.cppreference.com/w/c/string/byte/isprint
+
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+	End Rem
+	Method SetItemTags:Int(updateHandle:ULong, tags:String[])
+		Return bmx_SteamAPI_ISteamUGC_SetItemTags(instancePtr, updateHandle, tags)
+	End Method
+	
+	Rem
+	bbdoc: Sets a new title for an item.
+	returns: #True upon success, otherwise #False if the UGC update handle is invalid.
+	about: The title must be limited to the size defined by #k_cchPublishedDocumentTitleMax.
+
+	You can set what language this is for by using #SetItemUpdateLanguage, if no language is set then "english" is assumed.
+
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+	End Rem
+	Method SetItemTitle:Int(updateHandle:ULong, title:String)
+		Return bmx_SteamAPI_ISteamUGC_SetItemTitle(instancePtr, updateHandle, title)
+	End Method
+	
+	Rem
+	bbdoc: Sets the language of the title and description that will be set in this item update.
+	returns: #True upon success, otherwise #False if the UGC update handle is invalid.
+	about: This must be in the format of the API language code.
+
+	If this is not set then "english" is assumed.
+
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+	
+	See Also: #SetItemTitle, #SetItemDescription, #SetLanguage
+	End Rem
+	Method SetItemUpdateLanguage:Int(updateHandle:ULong, language:String)
+		Return bmx_SteamAPI_ISteamUGC_SetItemUpdateLanguage(instancePtr, updateHandle, language)
+	End Method
+	
+	Rem
+	bbdoc: Sets the visibility of an item.
+	returns: #True upon success, otherwise #False if the UGC update handle is invalid.
+
+	about: 
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+	End Rem
+	Method SetItemVisibility:Int(updateHandle:ULong, visibility:ERemoteStoragePublishedFileVisibility)
+		Return bmx_SteamAPI_ISteamUGC_SetItemVisibility(instancePtr, updateHandle, visibility)
+	End Method
+	
+	Rem
+	bbdoc: Sets the language to return the title and description in for the items on a pending UGC Query.
+	returns: #True upon success, otherwise #False if the UGC query handle is invalid.
+	about: This must be in the format of the API Language code.
+
+	If this is not set then "english" is assumed.
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	
+	See Also: #SetItemUpdateLanguage
+	End Rem
+	Method SetLanguage:Int(queryHandle:ULong, language:String)
+		Return bmx_SteamAPI_ISteamUGC_SetLanguage(instancePtr, queryHandle, language)
+	End Method
+	
+	Rem
+	bbdoc: Sets whether workshop items will be returned if they have one or more matching tag, or if all tags need to match on a pending UGC Query.
+	returns: #True upon success, otherwise #False if the UGC query handle is invalid or if the UGC query handle is not from #CreateQueryAllUGCRequest.
+	about: 
+	> NOTE: This can only be used with #CreateQueryAllUGCRequest!
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	
+	See Also: #AddRequiredTag, #AddExcludedTag, #SetItemTags
+	End Rem
+	Method SetMatchAnyTag:Int(queryHandle:ULong, matchAnyTag:Int)
+		Return bmx_SteamAPI_ISteamUGC_SetMatchAnyTag(instancePtr, queryHandle, matchAnyTag)
+	End Method
+	
+	Rem
+	bbdoc: Sets whether the order of the results will be updated based on the rank of items over a number of days on a pending UGC Query.
+	returns: #True upon success, otherwise #False if the UGC query handle is invalid, if the UGC query handle is not from #CreateQueryAllUGCRequest or if the #EUGCQuery of the query is not one of k_PublishedFileQueryType_RankedByTrend, k_PublishedFileQueryType_RankedByPlaytimeTrend, k_PublishedFileQueryType_RankedByAveragePlaytimeTrend, k_PublishedFileQueryType_RankedByVotesUp, or k_PublishedFileQueryType_RankedByPlaytimeSessionsTrend.
+	about:
+	> NOTE: This can only be used with #CreateQueryAllUGCRequest!
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	End Rem
+	Method SetRankedByTrendDays:Int(queryHandle:ULong, days:UInt)
+		Return bmx_SteamAPI_ISteamUGC_SetRankedByTrendDays(instancePtr, queryHandle, days)
+	End Method
+	
+	Rem
+	bbdoc: Sets whether to return any additional images/videos attached to the items on a pending UGC Query.
+	returns: #True upon success, otherwise #False if the UGC query handle is invalid.
+	about: 
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	End Rem
+	Method SetReturnAdditionalPreviews:Int(queryHandle:ULong, returnAdditionalPreviews:Int)
+		Return bmx_SteamAPI_ISteamUGC_SetReturnAdditionalPreviews(instancePtr, queryHandle, returnAdditionalPreviews)
+	End Method
+	
+	Rem
+	bbdoc: Sets whether to return the IDs of the child items of the items on a pending UGC Query.
+	returns: #True upon success, otherwise #False if the UGC query handle is invalid.
+	about: 
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	End Rem
+	Method SetReturnChildren:Int(queryHandle:ULong, returnChildren:Int)
+		Return bmx_SteamAPI_ISteamUGC_SetReturnChildren(instancePtr, queryHandle, returnChildren)
+	End Method
+	
+	Rem
+	bbdoc: Sets whether to return any key-value tags for the items on a pending UGC Query.
+	returns: #True upon success, #False if the UGC query handle is invalid.
+	about: 
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	End Rem
+	Method SetReturnKeyValueTags:Int(queryHandle:ULong, returnKeyValueTags:Int)
+		Return bmx_SteamAPI_ISteamUGC_SetReturnKeyValueTags(instancePtr, queryHandle, returnKeyValueTags)
+	End Method
+
+	Rem
+	bbdoc: Sets whether to return the full description for the items on a pending UGC Query.
+	returns: #True upon success, otherwise #False if the UGC query handle is invalid.
+	about: If you don't set this then you only receive the summary which is the description truncated at 255 bytes.
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	
+	See Also: #SetItemDescription
+	End Rem
+	Method SetReturnLongDescription:Int(queryHandle:ULong, returnLongDescription:Int)
+		Return bmx_SteamAPI_ISteamUGC_SetReturnLongDescription(instancePtr, queryHandle, returnLongDescription)
+	End Method
+	
+	Rem
+	bbdoc: Sets whether to return the developer specified metadata for the items on a pending UGC Query.
+	returns: #True upon success, #False if the UGC query handle is invalid.
+	about: 
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	
+	See Also: #SetItemMetadata
+	End Rem
+	Method SetReturnMetadata:Int(queryHandle:ULong, returnMetadata:Int)
+		Return bmx_SteamAPI_ISteamUGC_SetReturnMetadata(instancePtr, queryHandle, returnMetadata)
+	End Method
+	
+	Rem
+	bbdoc: Sets whether to only return IDs instead of all the details on a pending UGC Query.
+	returns: #True upon success, otherwise #False if the UGC query handle is invalid or if the UGC query handle is from #CreateQueryUGCDetailsRequest.
+
+	about: 
+	This is useful for when you don't need all the information (e.g. you just want to get the IDs of the items a user has in their favorites list.)
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	End Rem
+	Method SetReturnOnlyIDs:Int(queryHandle:ULong, returnOnlyIDs:Int)
+		Return bmx_SteamAPI_ISteamUGC_SetReturnOnlyIDs(instancePtr, queryHandle, returnOnlyIDs)
+	End Method
+	
+	Rem
+	bbdoc: Sets whether to return the the playtime stats on a pending UGC Query.
+	returns: #True upon success, otherwise #False if the UGC query handle is invalid.
+	about: 
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	End Rem
+	Method SetReturnPlaytimeStats:Int(queryHandle:ULong, days:UInt)
+		Return bmx_SteamAPI_ISteamUGC_SetReturnPlaytimeStats(instancePtr, queryHandle, days)
+	End Method
+	
+	Rem
+	bbdoc: Sets whether to only return the the total number of matching items on a pending UGC Query.
+	returns: #True upon success, #False if the UGC query handle is invalid or if the UGC query handle is from #CreateQueryUGCDetailsRequest.
+	about: The actual items will not be returned when #OnSteamUGCQueryCompleted is called.
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	End Rem
+	Method SetReturnTotalOnly:Int(queryHandle:ULong, returnTotalOnly:Int)
+		Return bmx_SteamAPI_ISteamUGC_SetReturnTotalOnly(instancePtr, queryHandle, returnTotalOnly)
+	End Method
+	
+	Rem
+	bbdoc: Sets a string to that items need to match in either the title or the description on a pending UGC Query.
+	returns: #True upon success, #False if the UGC query handle is invalid, if the UGC query handle is not from #CreateQueryAllUGCRequest or if @searchText is empty.
+	about: 
+	> NOTE: This can only be used with #CreateQueryAllUGCRequest!
+
+	> NOTE: This must be set before you send a UGC Query handle using #SendQueryUGCRequest.
+	End Rem
+	Method SetSearchText:Int(queryHandle:ULong, searchText:String)
+		Return bmx_SteamAPI_ISteamUGC_SetSearchText(instancePtr, queryHandle, searchText)
+	End Method
+	
+	Rem
+	bbdoc: Allows the user to rate a workshop item up or down.
+	about: Results in a call to #OnSetUserItemVote.
+	
+	See Also: #GetUserItemVote
+	End Rem
+	Method SetUserItemVote(publishedFileID:ULong, voteUp:Int)
+		bmx_SteamAPI_ISteamUGC_SetUserItemVote(callbackPtr, publishedFileID, voteUp)
+	End Method
+	
+	Rem
+	bbdoc: Starts the item update process.
+	returns: A handle that you can use with future calls to modify the item before finally sending the update.
+	about: This gets you a handle that you can use to modify the item before finally sending off the update to the server with #SubmitItemUpdate.
+	
+	See Also: Uploading a Workshop Item, #SetItemTitle, #SetItemDescription, #SetItemUpdateLanguage, #SetItemMetadata, #SetItemVisibility, #SetItemTags, #SetItemContent, #SetItemPreview, #RemoveItemKeyValueTags, #AddItemKeyValueTag, #AddItemPreviewFile, #AddItemPreviewVideo, #UpdateItemPreviewFile, #UpdateItemPreviewVideo, #RemoveItemPreview
+	End Rem
+	Method StartItemUpdate:ULong(consumerAppId:UInt, publishedFileID:ULong)
+		Return bmx_SteamAPI_ISteamUGC_StartItemUpdate(instancePtr, consumerAppId, publishedFileID)
+	End Method
+	
+	Rem
+	bbdoc: Starts tracking playtime on a set of workshop items.
+	about: When your app shuts down, playtime tracking will automatically stop.
+
+	Results in a call to #OnStartPlaytimeTracking
+	
+	See Also: #StopPlaytimeTracking, #StopPlaytimeTrackingForAllItems
+	End Rem
+	Method StartPlaytimeTracking(publishedFileIDs:ULong Ptr, numPublishedFileIDs:UInt)
+		bmx_SteamAPI_ISteamUGC_StartPlaytimeTracking(callbackPtr, publishedFileIDs, numPublishedFileIDs)
+	End Method
+	
+	Rem
+	bbdoc: Stops tracking playtime on a set of workshop items.
+	about: When your app shuts down, playtime tracking will automatically stop.
+	
+	Results in a call to #OnStopPlaytimeTracking
+	End Rem
+	Method StopPlaytimeTracking(publishedFileIDs:ULong Ptr, numPublishedFileIDs:UInt)
+		bmx_SteamAPI_ISteamUGC_StopPlaytimeTracking(callbackPtr, publishedFileIDs, numPublishedFileIDs)
+	End Method
+	
+	Rem
+	bbdoc: Stops tracking playtime of all workshop items.
+	about: When your app shuts down, playtime tracking will automatically stop.
+
+	Results in a call to #OnStopPlaytimeTracking
+	End Rem
+	Method StopPlaytimeTrackingForAllItems()
+		bmx_SteamAPI_ISteamUGC_StopPlaytimeTrackingForAllItems(callbackPtr)
+	End Method
+	
+	Rem
+	bbdoc: Uploads the changes made to an item to the Steam Workshop.
+	about: You can track the progress of an item update with #GetItemUpdateProgress.
+
+	Results in a call to #OnSubmitItemUpdate
+	End Rem
+	Method SubmitItemUpdate(updateHandle:ULong, changeNote:String)
+		bmx_SteamAPI_ISteamUGC_SubmitItemUpdate(callbackPtr, updateHandle, changeNote)
+	End Method
+	
+	Rem
+	bbdoc: Subscribe to a workshop item. It will be downloaded and installed as soon as possible.
+	about: Results in a call to #OnRemoteStorageSubscribePublishedFile
+	
+	See Also: #SubscribeItem
+	End Rem
+	Method SubscribeItem(publishedFileID:ULong)
+		bmx_SteamAPI_ISteamUGC_SubscribeItem(callbackPtr, publishedFileID)
+	End Method
+	
+	Rem
+	bbdoc: Suspends and resumes all workshop downloads.
+	about: If you call this with @suspend set to #True then downloads will be suspended until you resume them by setting @suspend to #False or when the game ends.
+	End Rem
+	Method SuspendDownloads(suspend:Int)
+		bmx_SteamAPI_ISteamUGC_SuspendDownloads(instancePtr, suspend)
+	End Method
+	
+	Rem
+	bbdoc: Unsubscribes from a workshop item.
+	about: This will result in the item being removed after the game quits.
+
+	Results in a call to #OnRemoteStorageUnsubscribePublishedFile
+	
+	See Also: #UnsubscribeItem
+	End Rem
+	Method UnsubscribeItem(publishedFileID:ULong)
+		bmx_SteamAPI_ISteamUGC_UnsubscribeItem(callbackPtr, publishedFileID)
+	End Method
+	
+	Rem
+	bbdoc: Updates an existing additional preview file for the item.
+	returns: #True upon success, otherwise #False if the UGC update handle is invalid.
+	about: If the preview type is an image then the format should be one that both the web and the application (if necessary) can render, and must be under 1MB.
+	Suggested formats include JPG, PNG and GIF.
+
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+
+	See Also: #AddItemPreviewFile
+	End Rem
+	Method UpdateItemPreviewFile:Int(updateHandle:ULong, index:UInt, previewFile:String)
+		Return bmx_SteamAPI_ISteamUGC_UpdateItemPreviewFile(instancePtr, updateHandle, index, previewFile)
+	End Method
+	
+	Rem
+	bbdoc: Updates an additional video preview from YouTube for the item.
+	returns: #True upon success, otherwise #False if the UGC update handle is invalid.
+	about: 
+	> NOTE: This must be set before you submit the UGC update handle using #SubmitItemUpdate.
+
+	See Also: #AddItemPreviewVideo
+	End Rem
+	Method UpdateItemPreviewVideo:Int(updateHandle:ULong, index:UInt, videoID:String)
+		Return bmx_SteamAPI_ISteamUGC_UpdateItemPreviewVideo(instancePtr, updateHandle, index, videoID)
+	End Method
+	
+	' callbacks
+	Private
+
+	Method OnAddAppDependency(result:EResult, publishedFileId:ULong, appID:UInt)
+		If listener Then
+			listener.OnAddAppDependency(result, publishedFileId, appID)
+		End If
+	End Method
+
+	Function _OnAddAppDependency(inst:TSteamUGC, result:EResult, publishedFileId:ULong, appID:UInt) { nomangle }
+		inst.OnAddAppDependency(result, publishedFileId, appID)
+	End Function 
+
+	Method OnAddDependency(result:EResult, publishedFileId:ULong, childPublishedFileId:ULong)
+		If listener Then
+			listener.OnAddDependency(result, publishedFileId, childPublishedFileId)
+		End If
+	End Method
+
+	Function _OnAddDependency(inst:TSteamUGC, result:EResult, publishedFileId:ULong, childPublishedFileId:ULong) { nomangle }
+		inst.OnAddDependency(result, publishedFileId, childPublishedFileId)
+	End Function
+
+	Method OnUserFavoriteItemsListChanged(result:EResult, publishedFileId:ULong, wasAddRequest:Int)
+		If listener Then
+			listener.OnUserFavoriteItemsListChanged(result, publishedFileId, wasAddRequest)
+		End If
+	End Method
+	
+	Function _OnUserFavoriteItemsListChanged(inst:TSteamUGC, publishedFileId:ULong, result:EResult, wasAddRequest:Int) { nomangle }
+		inst.OnUserFavoriteItemsListChanged(result:EResult, publishedFileId, wasAddRequest)
+	End Function
+
+	Method OnCreateItem(result:EResult, publishedFileId:ULong, userNeedsToAcceptWorkshopLegalAgreement:Int)
+		If listener Then
+			listener.OnCreateItem(result, publishedFileId, userNeedsToAcceptWorkshopLegalAgreement)
+		End If
+	End Method
+
+	Function _OnCreateItem(inst:TSteamUGC, result:EResult, publishedFileId:ULong, userNeedsToAcceptWorkshopLegalAgreement:Int) { nomangle }
+		inst.OnCreateItem(result, publishedFileId, userNeedsToAcceptWorkshopLegalAgreement)
+	End Function
+
+	Method OnDeleteItem(result:EResult, publishedFileId:ULong)
+		If listener Then
+			listener.OnDeleteItem(result, publishedFileId)
+		End If
+	End Method
+
+	Function _OnDeleteItem(inst:TSteamUGC, result:EResult, publishedFileId:ULong) { nomangle }
+		inst.OnDeleteItem(result, publishedFileId)
+	End Function
+
+	Method OnDownloadItem(result:EResult, appID:UInt, publishedFileId:ULong)
+		If listener Then
+			listener.OnDownloadItem(result, appID, publishedFileId)
+		End If
+	End Method
+	
+	Function _OnDownloadItem(inst:TSteamUGC, result:EResult, appID:UInt, publishedFileId:ULong) { nomangle }
+		inst.OnDownloadItem(result, appID, publishedFileId)
+	End Function 
+
+	Method OnGetUserItemVote(result:EResult, publishedFileId:ULong, votedUp:Int, votedDown:Int, voteSkipped:Int)
+		If listener Then
+			listener.OnGetUserItemVote(result, publishedFileId, votedUp, votedDown, voteSkipped)
+		End If
+	End Method
+
+	Function _OnGetUserItemVote(inst:TSteamUGC, publishedFileId:ULong, result:EResult, votedUp:Int, votedDown:Int, voteSkipped:Int) { nomangle }
+		inst.OnGetUserItemVote(result, publishedFileId, votedUp, votedDown, voteSkipped)
+	End Function
+
+	Method OnRemoveAppDependency(result:EResult, publishedFileId:ULong, appID:UInt)
+		If listener Then
+			listener.OnRemoveAppDependency(result, publishedFileId, appID)
+		End If
+	End Method
+
+	Function _OnRemoveAppDependency(inst:TSteamUGC, result:EResult, publishedFileId:ULong, appID:UInt) { nomangle }
+		inst.OnRemoveAppDependency(result, publishedFileId, appID)
+	End Function
+
+	Method OnRemoveUGCDependency(result:EResult, publishedFileId:ULong, childPublishedFileId:ULong)
+		If listener Then
+			listener.OnRemoveUGCDependency(result, publishedFileId, childPublishedFileId)
+		End If
+	End Method
+
+	Function _OnRemoveUGCDependency(inst:TSteamUGC, result:EResult, publishedFileId:ULong, childPublishedFileId:ULong) { nomangle }
+		inst.OnRemoveUGCDependency(result, publishedFileId, childPublishedFileId)
+	End Function
+
+	Method OnSteamUGCQueryCompleted(result:EResult, queryHandle:ULong, numResultsReturned:UInt, totalMatchingResults:UInt)
+		If listener Then
+			listener.OnSteamUGCQueryCompleted(result, queryHandle, numResultsReturned, totalMatchingResults)
+		End If
+	End Method
+
+	Function _OnSteamUGCQueryCompleted(inst:TSteamUGC, queryHandle:ULong, result:EResult, numResultsReturned:UInt, totalMatchingResults:UInt) { nomangle }
+		inst.OnSteamUGCQueryCompleted(result, queryHandle, numResultsReturned, totalMatchingResults)
+	End Function
+
+	Method OnSetUserItemVote(result:EResult, publishedFileId:ULong, voteUp:Int)
+		If listener Then
+			listener.OnSetUserItemVote(result, publishedFileId, voteUp)
+		End If
+	End Method
+
+	Function _OnSetUserItemVote(inst:TSteamUGC, publishedFileId:ULong, result:EResult, voteUp:Int) { nomangle }
+		inst.OnSetUserItemVote(result, publishedFileId, voteUp)
+	End Function
+
+	Method OnStartPlaytimeTracking(result:EResult)
+		If listener Then
+			listener.OnStartPlaytimeTracking(result)
+		End If
+	End Method
+
+	Function _OnStartPlaytimeTracking(inst:TSteamUGC, result:EResult) { nomangle }
+		inst.OnStartPlaytimeTracking(result)
+	End Function
+
+	Method OnStopPlaytimeTracking(result:EResult)
+		If listener Then
+			listener.OnStopPlaytimeTracking(result)
+		End If
+	End Method
+
+	Function _OnStopPlaytimeTracking(inst:TSteamUGC, result:EResult) { nomangle }
+		inst.OnStopPlaytimeTracking(result)
+	End Function
+
+	Method OnGetAppDependencies(result:EResult, publishedFileId:ULong, appID:UInt Ptr, numAppDependencies:Int, totalNumAppDependencies:Int)
+		If listener Then
+			listener.OnGetAppDependencies(result, publishedFileId, appID, numAppDependencies, totalNumAppDependencies)
+		End If
+	End Method
+
+	Function _OnGetAppDependencies(inst:TSteamUGC, result:EResult, publishedFileId:ULong, appID:UInt Ptr, numAppDependencies:Int, totalNumAppDependencies:Int) { nomangle }
+		inst.OnGetAppDependencies(result, publishedFileId, appID, numAppDependencies, totalNumAppDependencies)
+	End Function
+
+	Method OnSubmitItemUpdate(result:EResult, userNeedsToAcceptWorkshopLegalAgreement:Int)
+		If listener Then
+			listener.OnSubmitItemUpdate(result, userNeedsToAcceptWorkshopLegalAgreement)
+		End If
+	End Method
+
+	Function _OnSubmitItemUpdate(inst:TSteamUGC, result:EResult, userNeedsToAcceptWorkshopLegalAgreement:Int) { nomangle }
+		inst.OnSubmitItemUpdate(result, userNeedsToAcceptWorkshopLegalAgreement)
+	End Function
+
+	Method OnRemoteStorageSubscribePublishedFile(result:EResult, publishedFileId:ULong)
+		If listener Then
+			listener.OnRemoteStorageSubscribePublishedFile(result, publishedFileId)
+		End If
+	End Method
+
+	Function _OnRemoteStorageSubscribePublishedFile(inst:TSteamUGC, result:EResult, publishedFileId:ULong) { nomangle }
+		inst.OnRemoteStorageSubscribePublishedFile(result, publishedFileId)
+	End Function
+
+	Method OnRemoteStorageUnsubscribePublishedFile(result:EResult, publishedFileId:ULong)
+		If listener Then
+			listener.OnRemoteStorageUnsubscribePublishedFile(result, publishedFileId)
+		End If
+	End Method
+
+	Function _OnRemoteStorageUnsubscribePublishedFile(inst:TSteamUGC, result:EResult, publishedFileId:ULong) { nomangle }
+		inst.OnRemoteStorageUnsubscribePublishedFile(result, publishedFileId)
+	End Function
+
+End Type