1016 lines
23 KiB
Lua
1016 lines
23 KiB
Lua
--[[
|
|
// Http.lua
|
|
// API for all web endpoints
|
|
// Calls are async
|
|
|
|
// Any calls to roblox.com need to use game:HttpGetAynsc() and game:HttpPostAynsc()
|
|
// use rbxGetAsync() and rbxPostAsync()
|
|
// Any calls to api.roblox.com should use HttpRbxApiService
|
|
// use rbxApiGetAsync() and rbxApiPostAsync()
|
|
// For calls to new services like avatar.roblox.com use game:HttpGetAsync()
|
|
// user rbxGetAsync() and rbxPostAsync()
|
|
|
|
// NOTE: You cannot currently get thumbnails with this API (please see the Thumbnail module), because
|
|
// Roblox GUIs cannot accept rbxcnd.com for the Image property.
|
|
|
|
// NOTE: game:HttpGetAsync() can no longer be used in networked DataModels.
|
|
// You may need to move endpoint call to C++ if you need to use an
|
|
// endpoint in-game
|
|
]]
|
|
local HttpService = game:GetService("HttpService")
|
|
local HttpRbxApiService = game:GetService("HttpRbxApiService")
|
|
|
|
local CoreGui = game:GetService("CoreGui")
|
|
local RobloxGui = CoreGui:FindFirstChild("RobloxGui")
|
|
local Modules = RobloxGui:FindFirstChild("Modules")
|
|
local ShellModules = Modules:FindFirstChild("Shell")
|
|
local Utility = require(ShellModules:FindFirstChild('Utility'))
|
|
|
|
local IsNewUsernameCheckEnabled = settings():GetFFlag("XboxUseNewValidUsernameCheck2")
|
|
|
|
local Http = {}
|
|
|
|
local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower()
|
|
BaseUrl = string.gsub(BaseUrl, "/m.", "/www.")
|
|
BaseUrl = string.gsub(BaseUrl, "http://", "https://")
|
|
|
|
local AssetGameBaseUrl = string.gsub(BaseUrl, "https://www.", "https://assetgame.")
|
|
local AccountSettingsUrl = string.gsub(BaseUrl, "https://www.", "https://accountsettings.")
|
|
|
|
Http.BaseUrl = BaseUrl
|
|
Http.AssetGameBaseUrl = AssetGameBaseUrl
|
|
|
|
-- Helper Functions
|
|
local function decodeJSON(json)
|
|
if json == nil or #json == 0 then
|
|
return nil
|
|
end
|
|
|
|
local success, result = pcall(function()
|
|
return HttpService:JSONDecode(json)
|
|
end)
|
|
if not success then
|
|
Utility.DebugLog("decodeJSON() failed because", result, "Input:", json)
|
|
return nil
|
|
end
|
|
|
|
return result
|
|
end
|
|
|
|
local function rbxGetAsync(path, returnRaw)
|
|
local success, result = pcall(function()
|
|
return game:HttpGetAsync(path)
|
|
end)
|
|
--
|
|
if not success then
|
|
Utility.DebugLog(path, "rbxGetAsync() failed because", result)
|
|
return nil
|
|
end
|
|
|
|
if returnRaw then
|
|
return result
|
|
end
|
|
return decodeJSON(result)
|
|
end
|
|
|
|
local function rbxPostAsync(path, params, contentType)
|
|
local success, result = pcall(function()
|
|
return game:HttpPostAsync(path, params, contentType)
|
|
end)
|
|
--
|
|
if not success then
|
|
Utility.DebugLog(path, "rbxPostAsync() failed because", result)
|
|
return nil
|
|
end
|
|
|
|
return decodeJSON(result)
|
|
end
|
|
|
|
local function rbxApiGetAsync(path)
|
|
local success, result = pcall(function()
|
|
return HttpRbxApiService:GetAsync(path)
|
|
end)
|
|
--
|
|
if not success then
|
|
Utility.DebugLog(path, "rbxApiGetAsync() failed because", result)
|
|
return nil
|
|
end
|
|
|
|
return decodeJSON(result)
|
|
end
|
|
|
|
local function rbxApiPostAsync(path, params, throttlePriority, contentType)
|
|
local success, result = pcall(function()
|
|
return HttpRbxApiService:PostAsync(path, params, throttlePriority, contentType)
|
|
end)
|
|
--
|
|
if not success then
|
|
Utility.DebugLog(path..params, "rbxApiPostAsync() failed because", result)
|
|
return nil
|
|
end
|
|
|
|
return decodeJSON(result)
|
|
end
|
|
|
|
local function buildServiceUrl(service)
|
|
return string.gsub(BaseUrl, "https://www.", "https://"..service..".")
|
|
end
|
|
|
|
-- Game Endpoints
|
|
|
|
--[[
|
|
Response json
|
|
[
|
|
{
|
|
"Id": 0,
|
|
"Name": "string",
|
|
"TimeOptionsAvailable": false,
|
|
"DefaultTimeOption": 0,
|
|
"GenresOptionsAvailable": true,
|
|
"NumberOfRows": 0,
|
|
"GameSetTargetId": 0
|
|
},
|
|
]
|
|
]]
|
|
function Http.GetGameSortsAsync()
|
|
return rbxGetAsync(BaseUrl.."games/default-sorts")
|
|
end
|
|
|
|
--[[
|
|
Respone json
|
|
{
|
|
"data": [
|
|
{
|
|
"CreatorID": 0,
|
|
"CreatorName": "string",
|
|
"CreatorUrl": "string",
|
|
"Plays": 0,
|
|
"Price": 0,
|
|
"ProductID": 0,
|
|
"IsOwned": false,
|
|
"IsVotingEnabled": true,
|
|
"TotalUpVotes": 0,
|
|
"TotalDownVotes": 0,
|
|
"TotalBought": 0,
|
|
"UniverseID": 0,
|
|
"HasErrorOcurred":false,
|
|
"GameDetailReferralUrl": "string",
|
|
"Url": "string",
|
|
"RetryUrl": "string",
|
|
"Final": true,
|
|
"Name": "string",
|
|
"PlaceID": 0,
|
|
"PlayerCount": 0,
|
|
"ImageId": 0,
|
|
"IsSecure": false,
|
|
"ShowExperimentalMode": false
|
|
},
|
|
]
|
|
"paging" {
|
|
"previousCursor": "string",
|
|
"previousUrl": "string",
|
|
"nextCursor": "string",
|
|
"nextUrl": "string"
|
|
}
|
|
}
|
|
]]
|
|
function Http.GetCuratedSortAsync(gameSetTargetId, maxRows)
|
|
local path = string.format("%sgames/set?GameSetTargetId=%d&MaxRows=%d", BaseUrl, gameSetTargetId, maxRows)
|
|
return rbxGetAsync(path)
|
|
end
|
|
|
|
-- the subsequent page request's maxRows depends on the first request (Http.GetCuratedSortAsync)
|
|
-- the maxRows info is included in pageUrl
|
|
-- this has the same response as Http.GetCuratedSortAsync
|
|
function Http.GetCuratedSortByUrlAsync(pageUrl)
|
|
return rbxGetAsync(pageUrl)
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
[
|
|
{
|
|
"CreatorID": 0,
|
|
"CreatorName": "string",
|
|
"CreatorUrl": "string",
|
|
"Plays": 0,
|
|
"Price": 0,
|
|
"ProductID": 0,
|
|
"IsOwned": false,
|
|
"IsVotingEnabled": true,
|
|
"TotalUpVotes": 0,
|
|
"TotalDownVotes": 0,
|
|
"TotalBought": 0,
|
|
"UniverseID": 0,
|
|
"HasErrorOcurred": false,
|
|
"GameDetailReferralUrl": "string",
|
|
"Url": "string",
|
|
"RetryUrl": "string",
|
|
"Final": true,
|
|
"Name": "string",
|
|
"PlaceID": 0,
|
|
"PlayerCount": 0,
|
|
"ImageId": 0,
|
|
"IsSecure": false,
|
|
"ShowExperimentalMode": false
|
|
},
|
|
]
|
|
]]
|
|
function Http.GetSortAsync(startRows, maxRows, sortId, timeFilter)
|
|
local path =
|
|
string.format("%sgames/list-json?sortFilter=%d&StartRows=%d&MaxRows=%d&searchAllGames=false&filterByDeviceType=true",
|
|
BaseUrl, sortId, startRows, maxRows)
|
|
|
|
if timeFilter then
|
|
path = string.format("%s&timeFilter=%d", path, timeFilter)
|
|
end
|
|
|
|
return rbxGetAsync(path)
|
|
end
|
|
|
|
-- Response, see Http.GetSortAsync
|
|
function Http.GetUserFavoritesAsync(startRows, maxRows)
|
|
local path = string.format("%sgames/moreresultsuncached-json?sortFilter=MyFavorite&StartRows=%d&"..
|
|
"MaxRows=%d&searchAllGames=true&filterByDeviceType=true",
|
|
BaseUrl, startRows, maxRows)
|
|
|
|
return rbxGetAsync(path)
|
|
end
|
|
|
|
-- Response, see Http.GetSortAsync
|
|
function Http.GetUserRecentAsync(startRows, maxRows)
|
|
local path = string.format("%sgames/moreresultsuncached-json?sortFilter=MyRecent&StartRows=%d&"..
|
|
"MaxRows=%d&searchAllGames=true&filterByDeviceType=true",
|
|
BaseUrl, startRows, maxRows)
|
|
|
|
return rbxGetAsync(path)
|
|
end
|
|
|
|
-- Response, see Http.GetSortAsync
|
|
function Http.GetUserPlacesAsync(startIndex, pageSize, userid)
|
|
local path = string.format("%sgames/list-users-games-json?userid=%d&startIndex=%d&pageSize=%d",
|
|
BaseUrl, userid, startIndex, pageSize)
|
|
|
|
return rbxGetAsync(path)
|
|
end
|
|
|
|
-- Response, see Http.GetSortAsync
|
|
function Http.SearchGamesAsync(startRows, maxRows, keyword)
|
|
local path = string.format("%sgames/list-json?keyword=%s&StartRows=%d&MaxRows=%d&filterByDeviceType=true",
|
|
BaseUrl, HttpService:UrlEncode(keyword), startRows, maxRows)
|
|
|
|
return rbxGetAsync(path)
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"AssetId": 0,
|
|
"Name": "string",
|
|
"Description": "string",
|
|
"Created": "string",
|
|
"Updated": "string",
|
|
"FavoritedCount": 0,
|
|
"Url": "string",
|
|
"ReportAbuseAbsoluteUrl": "string",
|
|
"IsFavoritedByUser": false,
|
|
"IsFavoritesUnavailable": false,
|
|
"UserCanManagePlace": false,
|
|
"VisitedCount": 0,
|
|
"MaxPlayers": 8,
|
|
"Builder": "string",
|
|
"BuilderId": 0,
|
|
"BuilderAbsoluteUrl": "string",
|
|
"IsPlayable": true,
|
|
"ReasonProhibited": "string",
|
|
"ReasonProhibitedMessage": "string",
|
|
"IsBuildersClubOnly": false,
|
|
"IsCopyingAllowed": true,
|
|
"BuildersClubOverlay": "string",
|
|
"PlayButtonType": "string",
|
|
"AssetGenre": "string",
|
|
"AssetGenreViewModel": {
|
|
"DisplayName": "string",
|
|
"Id": 0
|
|
},
|
|
"OnlineCount": 0,
|
|
"UniverseId": 0,
|
|
"UniverseRootPlaceId": 0,
|
|
"TotalUpVotes": 0,
|
|
"TotalDownVotes": 0,
|
|
"UserVote": true,
|
|
"OverridesDefaultAvatar": false,
|
|
"UsePortraitMode": false,
|
|
"IsExperimental": false,
|
|
"Price": 0
|
|
}
|
|
]]
|
|
function Http.GetGameDetailsAsync(placeId)
|
|
return rbxGetAsync(BaseUrl.."places/api-get-details?assetId="..tostring(placeId))
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"Id": 0,
|
|
"PlaceId": 0,
|
|
"ImageId": 0,
|
|
"IconUrl": "string",
|
|
"IconFinal": true,
|
|
"WikiUrl": "string",
|
|
"ReleaseDate": "string",
|
|
"IconUpdateSuccess": true,
|
|
"IconUpdateMessage": "string"
|
|
}
|
|
]]
|
|
function Http.GetGameIconIdAsync(placeId)
|
|
return rbxGetAsync(BaseUrl.."places/icons/json?placeId="..tostring(placeId))
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"VotingModel":{
|
|
"ShowVotes": true,
|
|
"UpVotes": 0,
|
|
"DownVotes": 0,
|
|
"CanVote": false,
|
|
"UserVote": false,
|
|
"HasVoted": false,
|
|
"ReasonForNotVoteable": "string"
|
|
},
|
|
"ShowVotes": true
|
|
}
|
|
]]
|
|
function Http.GetGameVotesAsync(placeId)
|
|
return rbxGetAsync(BaseUrl.."PlaceItem/GameDetailsVotingPanelJson?placeId="..tostring(placeId))
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
[
|
|
{
|
|
"Creator":{
|
|
"CreatorName": "string",
|
|
"CreatorTargetId": 0,
|
|
"CreatorType": 0
|
|
},
|
|
"GameName": "string",
|
|
"GameSeoUrl": "string",
|
|
"GameThumbnail": {
|
|
"AssetId": 0,
|
|
"AssetHash": null,
|
|
"AssetTypeId": 0,
|
|
"Url": "string",
|
|
"IsFinal": true
|
|
},
|
|
"PlaceId": 0,
|
|
"ImageId": 0
|
|
},
|
|
]
|
|
]]
|
|
function Http.GetRecommendedGamesAsync(currentPlaceId)
|
|
return rbxGetAsync(BaseUrl.."Games/GetRecommendedGamesJson?currentPlaceId="..tostring(currentPlaceId))
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"IsJpegThumbnailEnabled": true,
|
|
"PlaceId": 0,
|
|
"thumbnails": [
|
|
{
|
|
"AssetId": 0,
|
|
"AssetHash":null,
|
|
"AssetTypeId": 0,
|
|
"Url": "string",
|
|
"IsFinal": true
|
|
}
|
|
],
|
|
"thumbnailCount": 1,
|
|
"IsVideoAutoplayedOnReady": false,
|
|
"ShowYouTubeVideo": true,
|
|
"IsMobile": false,
|
|
"PlaceThumbnailsResources": {
|
|
"LabelNext": "string",
|
|
"LabelPrevious": "string",
|
|
"State": 0
|
|
}
|
|
}
|
|
]]
|
|
function Http.GetGameThumbnailsAsync(placeId)
|
|
return rbxGetAsync(BaseUrl.."thumbnail/place-thumbnails?placeId="..tostring(placeId))
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"PlaceId": 0,
|
|
"GameBadges": [
|
|
{
|
|
"BadgeAssetId": 0,
|
|
"CreatorId": 0,
|
|
"IsOwned": true,
|
|
"Rarity": 0,
|
|
"RarityName": "string",
|
|
"TotalAwarded": 0,
|
|
"TotalAwardedYesterday": 0,
|
|
"Created": "string",
|
|
"Updated": "string",
|
|
"AssetSeoUrl": "string",
|
|
"Thumbnail": {
|
|
"Final": false,
|
|
"Url": "string",
|
|
"RetryUrl": "string",
|
|
"UserId": 0,
|
|
"EndpointType": "string"
|
|
},
|
|
"Name": "string",
|
|
"FormatName": "string",
|
|
"Description": "string",
|
|
"AssetRestrictionIcon": null
|
|
},
|
|
],
|
|
"GameBadgesResources": {
|
|
"HeadingGameBadges":"Game Badges",
|
|
"LabelRarityCakeWalk":"Cake Walk",
|
|
"LabelRarityChallenging":"Challenging",
|
|
"LabelRarityEasy":"Easy",
|
|
"LabelRarityExtreme":"Extreme",
|
|
"LabelRarityFreebie":"Freebie",
|
|
"LabelRarityHard":"Hard",
|
|
"LabelRarityImpossible":"Impossible",
|
|
"LabelRarityInsane":"Insane",
|
|
"LabelRarityModerate":"Moderate",
|
|
"LabelRarity":"Rarity",
|
|
"LabelSeeMore":"See More",
|
|
"LabelWonEver":"Won Ever",
|
|
"LabelWonYesterday":"Won Yesterday",
|
|
"State":0
|
|
}
|
|
}
|
|
]]
|
|
-- TODO: Remove with FFlagXboxUpdateBadgeEndpoints
|
|
function Http.GetGameBadgeDataAsync(placeId)
|
|
return rbxGetAsync(BaseUrl.."badges/list-badges-for-place/json?placeId="..tostring(placeId))
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"previousPageCursor": "string",
|
|
"nextPageCursor": "string",
|
|
"data": [
|
|
{
|
|
"id": 0,
|
|
"name": "string",
|
|
"description": "string",
|
|
"enabled": true,
|
|
"iconImageId": 0,
|
|
"created": "2018-07-05T17:45:05.868Z",
|
|
"updated": "2018-07-05T17:45:05.868Z",
|
|
"statistics": {
|
|
"pastDayAwardedCount": 0,
|
|
"awardedCount": 0,
|
|
"winRatePercentage": 0
|
|
},
|
|
"awardingUniverse": {
|
|
"id": 0,
|
|
"name": "string",
|
|
"rootPlaceId": 0
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]]
|
|
function Http.GetBadgesForUniverseAsync(universeId, cursor)
|
|
local url = string.format("%sv1/universes/%d/badges?sortOrder=Asc&limit=100", buildServiceUrl("badges"), universeId)
|
|
|
|
if cursor then
|
|
url = string.format(url.."&cursor=%s", cursor)
|
|
end
|
|
|
|
return rbxGetAsync(url)
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"data": [
|
|
{
|
|
"badgeId": 0,
|
|
"awardedDate": "2018-07-05T17:52:25.648Z"
|
|
}
|
|
]
|
|
}
|
|
]]
|
|
function Http.GetUserAwardedBadgesAsync(userId, badgeIdsTable)
|
|
local badgeIds = table.concat(badgeIdsTable, ",")
|
|
local url = string.format("%sv1/users/%d/badges/awarded-dates?badgeIds=%s", buildServiceUrl("badges"), userId, badgeIds)
|
|
return rbxGetAsync(url)
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"success": true,
|
|
"message": "string"
|
|
}
|
|
]]
|
|
function Http.PostFavoriteToggleAsync(assetId)
|
|
return rbxPostAsync(BaseUrl.."favorite/toggle?assetID="..tostring(assetId), "favoriteToggle")
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"Success": true,
|
|
"Message": "string",
|
|
"ModalType": "string",
|
|
"Model": {
|
|
"ShowVotes": true,
|
|
"UpVotes": 0,
|
|
"DownVotes": 0,
|
|
"CanVote": true,
|
|
"UserVote": true,
|
|
"HasVoted": false,
|
|
"ReasonForNotVoteable": "string"
|
|
}
|
|
}
|
|
]]
|
|
function Http.PostGameVoteAsync(assetId, status)
|
|
return rbxPostAsync(BaseUrl.."voting/vote?assetId="..tostring(assetId).."&vote="..tostring(status), "vote")
|
|
end
|
|
|
|
-- Social
|
|
|
|
--[[
|
|
Response json - none
|
|
]]
|
|
function Http.RegisterAppPresence()
|
|
return rbxApiPostAsync("presence/register-app-presence", "",
|
|
Enum.ThrottlingPriority.Default, Enum.HttpContentType.ApplicationJson)
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"userId": 0,
|
|
"isEnabled": true,
|
|
"created": "string",
|
|
"updated": "string"
|
|
}
|
|
]]
|
|
function Http.GetCrossplayEnabledStatusAsync()
|
|
return rbxApiGetAsync("user/CrossPlayStatus")
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"success": true
|
|
}
|
|
]]
|
|
function Http.PostCrossplayStatusAsync(value)
|
|
return rbxApiPostAsync("user/CrossPlayStatus?isEnabled="..tostring(value), "")
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
{
|
|
"VisitorId": 0,
|
|
"GameId": "string",
|
|
"IsOnline": true,
|
|
"LastOnline": "string",
|
|
"LastLocation": "string",
|
|
"LocationType": 0,
|
|
"PlaceId": 0,
|
|
"UserName": "string"
|
|
},
|
|
}
|
|
]]
|
|
function Http.GetOnlineFriendsAsync()
|
|
return rbxApiGetAsync("my/friendsonline")
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"recommendedUsers": [
|
|
{
|
|
"userId": 0,
|
|
"userName": "string",
|
|
"userProfilePageUrl": "string",
|
|
"userPresenceType": "Offline"
|
|
}
|
|
]
|
|
}
|
|
]]
|
|
--Only get used in studio mode
|
|
function Http.GetRecommendedUsersndsAsync()
|
|
local url = string.format("%s/v1/recommended-users", buildServiceUrl("friends"))
|
|
return rbxGetAsync(url)
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"userPresences": [
|
|
{
|
|
"userPresenceType": "Offline",
|
|
"lastLocation": "string",
|
|
"placeId": 0,
|
|
"rootPlaceId": 0,
|
|
"gameId": "string",
|
|
"userId": 0,
|
|
"lastOnline": "2018-05-07T22:18:08.290Z"
|
|
}
|
|
]
|
|
}
|
|
]]
|
|
--Only get used in studio mode
|
|
function Http.GetUsersPresenceAsync(userIds)
|
|
local userIdsModel = {
|
|
userIds = userIds,
|
|
}
|
|
userIdsModel = HttpService:JSONEncode(userIdsModel)
|
|
local url = string.format("%s/v1/presence/users", buildServiceUrl("presence"))
|
|
return rbxPostAsync(url, userIdsModel)
|
|
end
|
|
|
|
|
|
-- Account
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"Robux": 0
|
|
}
|
|
]]
|
|
function Http.GetPlatformUserBalanceAsync()
|
|
return rbxApiGetAsync("my/platform-currency-budget")
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"robux": 0
|
|
}
|
|
]]
|
|
function Http.GetTotalUserBalanceAsync()
|
|
return rbxApiGetAsync("currency/balance")
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"IsValid": true
|
|
"Data": {
|
|
"TotalItems": null,
|
|
"Start": 0,
|
|
"End": 0,
|
|
"Page": 0,
|
|
"nextPageCursor": "string",
|
|
"previousPageCursor": "string",
|
|
"ItemsPerPage":0 ,
|
|
"PageType": "string",
|
|
"Items": [
|
|
{
|
|
"AssetRestrictionIcon": {
|
|
"TooltipText": "string",
|
|
"CssTag": "string",
|
|
"LoadAssetRestrictionIconCss": true,
|
|
"HasTooltip": false
|
|
},
|
|
"Item":{
|
|
"AssetId": 0,
|
|
"Name": "string",
|
|
"AbsoluteUrl": "string",
|
|
"AssetType": 0,
|
|
"AssetTypeFriendlyLabel": "string",
|
|
"Description": "string",
|
|
"Genres": "string",
|
|
"GearAttributes": "string",
|
|
"AssetCategory": 0,
|
|
"CurrentVersionId": 0,
|
|
"IsApproved": false,
|
|
"LastUpdated": "string",
|
|
"LastUpdatedBy": "string",
|
|
"AudioUrl": "string"
|
|
},
|
|
"Creator":{
|
|
"Id": 1,
|
|
"Name": "string",
|
|
"Type": 1,
|
|
"CreatorProfileLink": "string"
|
|
},
|
|
"Product":{
|
|
"Id": 0,
|
|
"PriceInRobux": 0,
|
|
"IsForSale": false,
|
|
"IsPublicDomain": true,
|
|
"IsResellable": false,
|
|
"IsLimited": false,
|
|
"IsLimitedUnique": false,
|
|
"SerialNumber": 0,
|
|
"IsRental": false,
|
|
"RentalDurationInHours": 0,
|
|
"BcRequirement": 0,
|
|
"TotalPrivateSales": 0,
|
|
"SellerId": 0,
|
|
"SellerName": "string",
|
|
"LowestPrivateSaleUserAssetId": 0,
|
|
"IsXboxExclusiveItem": false,
|
|
"OffsaleDeadline": "string",
|
|
"NoPriceText": "string",
|
|
"IsFree": true
|
|
},
|
|
"PrivateServer": false,
|
|
"Thumbnail": {
|
|
"Final": true,
|
|
"Url": "string",
|
|
"RetryUrl": "string",
|
|
"IsApproved": false
|
|
},
|
|
"UserItem":{
|
|
"UserAsset": 0,
|
|
"IsItemOwned": false,
|
|
"ItemOwnedCount": 0,
|
|
"IsRentalExpired": false,
|
|
"IsItemCurrentlyRented": false,
|
|
"CanUserBuyItem": false,
|
|
"RentalExpireTime": "string",
|
|
"CanUserRentItem": false
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]]
|
|
function Http.GetUserOwnedPackagesAsync(userId, currentPage)
|
|
currentPage = currentPage or 1
|
|
local packageAssetIdType = 32
|
|
|
|
return rbxGetAsync(BaseUrl.."users/inventory/list-json?userId="..tostring(userId)..
|
|
"&assetTypeId="..tostring(packageAssetIdType).."&pageNumber="..tostring(currentPage))
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"assetIds": [
|
|
0
|
|
]
|
|
}
|
|
]]
|
|
function Http.GetCurrentlyWearingAsync(userId)
|
|
local url = string.format("%s/v1/users/%d/currently-wearing",
|
|
buildServiceUrl("avatar"), userId)
|
|
|
|
return rbxGetAsync(url)
|
|
end
|
|
|
|
-- Avatar/Inventory
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"assetIds:" [
|
|
0
|
|
]
|
|
}
|
|
]]
|
|
function Http.GetPackageAssetsAsync(packageId)
|
|
local url = string.format("%s/v1/packages/%d/assets", buildServiceUrl("inventory"), packageId)
|
|
return rbxGetAsync(url)
|
|
end
|
|
|
|
--[[
|
|
Respone json
|
|
{
|
|
"invalidAssets": [
|
|
{
|
|
"id": 0,
|
|
"name": "string",
|
|
"assetType": {
|
|
"id": 0,
|
|
"name": "string"
|
|
}
|
|
}
|
|
],
|
|
"invalidAssetIds": [
|
|
0,
|
|
],
|
|
"success": true
|
|
}
|
|
]]
|
|
function Http.SetWearingAssetsAsync(assetIds)
|
|
local assetIdsModel = {
|
|
assetIds = assetIds,
|
|
}
|
|
assetIdsModel = HttpService:JSONEncode(assetIdsModel)
|
|
|
|
local url = string.format("%s/v1/avatar/set-wearing-assets", buildServiceUrl("avatar"))
|
|
return rbxPostAsync(url, assetIdsModel)
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"sl_translate": "string",
|
|
"AssetID": 0,
|
|
"AssetName": "string",
|
|
"AssetType": "string",
|
|
"AssetIsWearable": true,
|
|
"SellerName": "string",
|
|
"TransactionVerb": "string",
|
|
"Price": 0,
|
|
"Currency": 0,
|
|
"IsMultiPrivateSale": false
|
|
}
|
|
]]
|
|
function Http.PurchaseProductAsync(productId, expectedPrice, expectedSellerId, expectedCurrency)
|
|
local formattedUrl = string.format("%sAPI/Item.ashx?rqtype=purchase&productID=%d&expectedCurrency="..
|
|
"%d&expectedPrice=%d&expectedSellerID=%d",
|
|
BaseUrl, productId, expectedCurrency, expectedPrice, expectedSellerId)
|
|
return rbxPostAsync(formattedUrl, "")
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"Products": [
|
|
{
|
|
"TargetId": 0,
|
|
"ProductType": "string",
|
|
"AssetId": 0,
|
|
"ProductId": 0,
|
|
"Name": "string",
|
|
"Description": "string",
|
|
"AssetTypeId": 0,
|
|
"Creator": {
|
|
"Id": 0,
|
|
"Name": "string",
|
|
"CreatorType": "string",
|
|
"CreatorTargetId": 0
|
|
},
|
|
"IconImageAssetId": 0,
|
|
"Created": "string",
|
|
"Updated": "string",
|
|
"PriceInRobux": 0,
|
|
"PriceInTickets": null,
|
|
"Sales": 0,
|
|
"IsNew": false,
|
|
"IsForSale": true,
|
|
"IsPublicDomain": false,
|
|
"IsLimited": false,
|
|
"IsLimitedUnique": false,
|
|
"Remaining": 0,
|
|
"MinimumMembershipLevel": 0,
|
|
"ContentRatingTypeId": 0
|
|
},
|
|
]
|
|
}
|
|
]]
|
|
function Http.GetXboxProductsAsync(startIndex, count)
|
|
startIndex = startIndex or 0
|
|
count = count or 100
|
|
local url = string.format("xbox/catalog/contents?startIndex=%d&count=%d", startIndex, count)
|
|
return rbxApiGetAsync(url)
|
|
end
|
|
|
|
--[[
|
|
Response - redirects to the cdn url; game engine takes care of this
|
|
]]
|
|
function Http.GetThumbnailUrlForAsset(assetId, width, height)
|
|
width = width or 420
|
|
height = height or 420
|
|
|
|
return AssetGameBaseUrl.."Thumbs/Asset.ashx?width="..tostring(width).."&height="..tostring(height)..
|
|
"&assetId="..tostring(assetId)
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"Url": "string",
|
|
"Final": true,
|
|
"SubstitutionType": 0
|
|
}
|
|
]]
|
|
function Http.GetAssetThumbnailFinalAsync(assetId, width, height, format)
|
|
return rbxGetAsync(AssetGameBaseUrl.."asset-thumbnail/json?assetId="..tostring(assetId).."&width="..tostring(width)..
|
|
"&height="..tostring(height).."&format="..format)
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"Url": "string",
|
|
"Final": true,
|
|
"SubstitutionType": 0
|
|
}
|
|
]]
|
|
function Http.GetAssetAvatarFinalAsync(userId, width, height, format)
|
|
local result = rbxGetAsync(BaseUrl..'avatar-thumbnail/json?userId='..tostring(userId)..'&width='..tostring(width)..
|
|
'&height='..tostring(height)..'&format='..format)
|
|
return result
|
|
end
|
|
|
|
--[[
|
|
]]
|
|
function Http.GetOutfitThumbnailFinalAsync(outfitId, width, height, format)
|
|
local requestData = {["userOutfitId"] = outfitId}
|
|
local requestDataJson = HttpService:JSONEncode(requestData)
|
|
local encodedRequestData = requestDataJson and HttpService:UrlEncode(requestDataJson) or ""
|
|
|
|
local url = string.format("%savatar-thumbnails?params=%s", BaseUrl, encodedRequestData)
|
|
|
|
local result = rbxGetAsync(url)
|
|
return result
|
|
end
|
|
|
|
--[[
|
|
Response json - none
|
|
]]
|
|
function Http.ReportAbuseAsync(reportingItemTypeName, reportingItemId, reportCategoryId, comment)
|
|
local jsonPostBody = {
|
|
reportingItemTypeName = reportingItemTypeName;
|
|
reportingItemId = tostring(reportingItemId);
|
|
reportCategoryId = tostring(reportCategoryId);
|
|
comment = comment;
|
|
}
|
|
local params = HttpService:JSONEncode(jsonPostBody)
|
|
if params then
|
|
return rbxApiPostAsync("moderation/reportabuse", params,
|
|
Enum.ThrottlingPriority.Default, Enum.HttpContentType.ApplicationJson)
|
|
end
|
|
end
|
|
|
|
-- Achievements
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"count": 1
|
|
}
|
|
]]
|
|
function Http.GetConsecutiveDaysLoggedInAsync()
|
|
local url = string.format("/xbox/get-login-consecutive-days")
|
|
return rbxApiGetAsync(url)
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"UserId": 0,
|
|
"TargetType": "string",
|
|
"PlatformTypeId": 0,
|
|
"VoteCount": 0
|
|
}
|
|
]]
|
|
function Http.GetVoteCountAsync()
|
|
local url = string.format("/user/get-vote-count?targetType=Place")
|
|
return rbxApiGetAsync(url)
|
|
end
|
|
|
|
-- Account Linking
|
|
|
|
--[[
|
|
Response - TODO
|
|
]]
|
|
function Http.IsValidUsername(username)
|
|
if not username then
|
|
return
|
|
end
|
|
|
|
if IsNewUsernameCheckEnabled then
|
|
local url = string.format("%sv1/xbox/is-username-valid?username=%s",
|
|
AccountSettingsUrl, HttpService:UrlEncode(username))
|
|
return rbxGetAsync(url)
|
|
else
|
|
local url = string.format("signup/is-username-valid?username=%s", HttpService:UrlEncode(username))
|
|
return rbxApiGetAsync(url)
|
|
end
|
|
end
|
|
|
|
--[[
|
|
Response json
|
|
{
|
|
"IsValid": true,
|
|
"ErrorCode": 0,
|
|
"ErrorMessage": "string"
|
|
}
|
|
]]
|
|
function Http.IsValidPassword(username, password)
|
|
if not username or not password then
|
|
return
|
|
end
|
|
local url = string.format("signup/is-password-valid?username=%s&password=%s",
|
|
HttpService:UrlEncode(username), HttpService:UrlEncode(password))
|
|
return rbxApiGetAsync(url)
|
|
end
|
|
|
|
return Http
|