/// <summary> /// Gets an <see cref="Asset"/> with information filled in. /// </summary> /// <param name="assetId">The asset id to pull from</param> /// <returns>Asset filled with information</returns> public static async Task <Asset> FromID(int assetId) { try { string data = await HttpHelper.GetStringFromURL(string.Format("https://api.roblox.com/marketplace/productinfo?assetId={0}", assetId)); JObject obj = JObject.Parse(data); Asset asset = new Asset(); asset.ID = (int)obj["AssetId"]; asset.ProductId = (int?)obj["ProductId"] ?? -1; asset.Name = (string)obj["Name"]; asset.Description = (string)obj["Description"]; asset.AssetType = (EAssetType)(int)obj["AssetTypeId"]; // eww. string creatorType = (string)obj["Creator"]["CreatorType"]; if (creatorType == "Group") { Group group = await Group.FromID((int)obj["Creator"]["CreatorTargetId"]); asset.CreatorType = ECreatorType.Group; } else { User user = new User(); user.ID = (int)obj["Creator"]["CreatorTargetId"]; user.Username = (string)obj["Creator"]["Name"]; asset.CreatorType = ECreatorType.User; } asset.IconImageAssetId = (int?)obj["IconImageAssetId"] ?? 0; asset.Created = DateTime.Parse((string)obj["Created"]); asset.Updated = DateTime.Parse((string)obj["Updated"]); asset.PriceInRobux = (int?)obj["PriceInRobux"] ?? 0; // We don't use PriceInTickets since Tickets are gone from roblox. asset.Sales = (int?)obj["Sales"] ?? 0; asset.IsNew = (bool?)obj["IsNew"] ?? false; asset.IsForSale = (bool?)obj["IsForSale"] ?? false; asset.IsPublicDomain = (bool?)obj["IsPublicDomain"] ?? false; asset.IsLimited = (bool?)obj["IsLimited"] ?? false; asset.IsLimitedUnique = (bool?)obj["IsLimitedUnique"] ?? false; if (obj.Value <int?>("Remaining") != null) { asset.Remaining = (int)obj["Remaining"]; } else { asset.Remaining = -1; // Infinite amount of this item. } asset.MinimumMembershipLevel = (EMembershipLevel)(int)obj["MinimumMembershipLevel"]; asset.Is13OrOver = ((int?)obj["ContentRatingTypeId"] == 1); return(asset); } catch (WebException) { return(null); } }