website/public/asset/10

1002 lines
36 KiB
Plaintext

%10%
-- this script creates the gui and sends the web requests for in game purchase prompts
-- wait for important items to appear
while not game do
wait(0.1)
end
while not game:GetService("MarketplaceService") do
wait(0.1)
end
while not game:FindFirstChild("CoreGui") do
wait(0.1)
end
while not game.CoreGui:FindFirstChild("RobloxGui") do
wait(0.1)
end
local allowedPlaceIds = nil--{41647283, 54352498, 96623001, 100364292}
if allowedPlaceIds ~= nil then
local currentPlaceId = game.PlaceId
local canRunScript = false
for index, id in pairs(allowedPlaceIds) do
if currentPlaceId == id then
canRunScript = true
break
end
end
if not canRunScript then
script:Destroy()
return -- don't think this gets hit, but just in case return
end
end
-------------------------------- Global Variables ----------------------------------------
-- utility variables
local RbxUtility = nil
local baseUrl = game:GetService("ContentProvider").BaseUrl:lower()
-- data variables
local currentProductInfo, currentAssetId, currentCurrencyType, currentCurrencyAmount, currentEquipOnPurchase, currentProductId
local checkingPlayerFunds = false
local openBCUpSellWindowConnection = nil
-- When a player has insufficient funds to buy something, this is how often we check to see if their funds have changed (in seconds)
local checkPlayerFundsLoopTime = 5
-- gui variables
local openBuyCurrencyWindowConnection = nil
local currentlyPrompting = false
local purchaseDialog, errorDialog = nil
local tweenTime = 0.3
local showPosition = UDim2.new(0.5,-330,0.5,-200)
local hidePosition = UDim2.new(0.5,-330,1,5)
local isSmallScreen = nil
local spinning = false
local spinnerIcons = nil
local smallScreenThreshold = 450
local hereText
-- user facing images
local assetUrls = {}
local assetUrl = "http://www.jarfeh.xyz/Asset/?id="
local errorImageUrl = assetUrl .. "42557901" table.insert(assetUrls, errorImageUrl)
local buyImageUrl = assetUrl .. "104651457" table.insert(assetUrls,buyImageUrl)
local buyImageDownUrl = assetUrl .. "104651515" table.insert(assetUrls, buyImageDownUrl)
local buyImageDisabledUrl = assetUrl .. "104651532" table.insert(assetUrls, buyImageDisabledUrl)
local cancelButtonImageUrl = assetUrl .. "104651592" table.insert(assetUrls, cancelButtonImageUrl)
local cancelButtonDownUrl = assetUrl .. "104651639" table.insert(assetUrls, cancelButtonDownUrl)
local okButtonUrl = assetUrl .. "104651665" table.insert(assetUrls, okButtonUrl)
local okButtonPressedrl = assetUrl .."104651707" table.insert(assetUrls, okButtonPressedrl)
local freeButtonImageUrl = assetUrl .. "104651733" table.insert(assetUrls, freeButtonImageUrl)
local freeButtonImageDownUrl = assetUrl .. "104651761" table.insert(assetUrls, freeButtonImageDownUrl)
local tixIcon = assetUrl .. "102481431" table.insert(assetUrls,tixIcon)
local robuxIcon = assetUrl .. "102481419" table.insert(assetUrls,robuxIcon)
-- user facing string
local buyHeaderText = "Buy Item"
local takeHeaderText = "Take Item"
local buyFailedHeaderText = "An Error Occurred"
local errorPurchasesDisabledText = "in-game purchases are disabled"
local errorPurchasesUnknownText = "Roblox is performing maintenance"
local purchaseSucceededText = "Your purchase of itemName succeeded!"
local purchaseFailedText = "Your purchase of itemName failed because errorReason. Your account has not been charged. Please try again soon."
local itemPurchaseText = "Would you like to buy the assetType 'itemName' for currencyType currencyAmount?"
local freeItemPurchaseText = "Would you like to take the assetType 'itemName' for FREE?"
local freeItemBalanceText = "Your balance of Robux or Tix will not be affected by this transaction."
local buildsClubUpsellText = "You don't have the appropriate membership to buy this item. Please click here to upgrade your builders club"
-------------------------------- End Global Variables ----------------------------------------
----------------------------- Util Functions ---------------------------------------------
function getSecureApiBaseUrl()
local secureApiUrl = baseUrl
secureApiUrl = string.gsub(secureApiUrl,"http","https")
secureApiUrl = string.gsub(secureApiUrl,"www","api")
return secureApiUrl
end
function getRbxUtility()
if not RbxUtility then
RbxUtility = LoadLibrary("RbxUtility")
end
return RbxUtility
end
function preloadAssets()
for i = 1, #assetUrls do
game:GetService("ContentProvider"):Preload(assetUrls[i])
end
end
----------------------------- End Util Functions ---------------------------------------------
-------------------------------- Accept/Decline Functions --------------------------------------
function removeCurrentPurchaseInfo()
currentAssetId = nil
currentCurrencyType = nil
currentCurrencyAmount = nil
currentEquipOnPurchase = nil
currentProductId = nil
currentProductInfo = nil
end
function closePurchasePrompt()
purchaseDialog:TweenPosition(hidePosition, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, tweenTime, true, function()
game.GuiService:RemoveCenterDialog(purchaseDialog)
hidePurchasing()
purchaseDialog.Visible = false
currentlyPrompting = false
end)
end
function userPurchaseActionsEnded(isSuccess)
checkingPlayerFunds = false
if isSuccess then -- show the user we bought the item successfully, when they close this dialog we will call signalPromptEnded
local newPurchasedSucceededText = string.gsub( purchaseSucceededText,"itemName", tostring(currentProductInfo["Name"]))
purchaseDialog.BodyFrame.ItemPreview.ItemDescription.Text = newPurchasedSucceededText
setButtonsVisible(purchaseDialog.BodyFrame.OkPurchasedButton)
hidePurchasing()
else -- otherwise we didn't purchase, no need to show anything, just signal and close dialog
signalPromptEnded(isSuccess)
end
end
function signalPromptEnded(isSuccess)
closePurchasePrompt()
game:GetService("MarketplaceService"):SignalPromptPurchaseFinished(game.Players.LocalPlayer, currentAssetId, isSuccess)
removeCurrentPurchaseInfo()
end
-- make sure our gui displays the proper purchase data, and set the productid we will try and buy if use specifies a buy action
function updatePurchasePromptData(toggleColoredText)
local newItemDescription = ""
if hereText then
hereText.Parent = nil
end
if not currentProductInfo then return end
-- id to use when we request a purchase
currentProductId = currentProductInfo["ProductId"]
if isFreeItem() then
newItemDescription = string.gsub( freeItemPurchaseText,"itemName", tostring(currentProductInfo["Name"]))
newItemDescription = string.gsub( newItemDescription,"assetType", tostring(assetTypeToString(currentProductInfo["AssetTypeId"])) )
setHeaderText(takeHeaderText)
else -- otherwise item costs something, so different prompt
newItemDescription = string.gsub( itemPurchaseText,"itemName", tostring(currentProductInfo["Name"]))
newItemDescription = string.gsub( newItemDescription,"assetType", tostring(assetTypeToString(currentProductInfo["AssetTypeId"])) )
newItemDescription = string.gsub( newItemDescription,"currencyType", tostring(currencyTypeToString(currentCurrencyType)) )
newItemDescription = string.gsub( newItemDescription,"currencyAmount", tostring(currentCurrencyAmount))
setHeaderText(buyHeaderText)
end
purchaseDialog.BodyFrame.ItemPreview.ItemDescription.Text = newItemDescription
purchaseDialog.BodyFrame.ItemPreview.Image = baseUrl .. "thumbs/asset.ashx?assetid=" .. tostring(currentAssetId) .. '&x=100&y=100&format=png';
end
function showPurchasePrompt()
local canPurchase, insufficientFunds, notRightBC, override, descText = canPurchaseItem()
if canPurchase then
updatePurchasePromptData()
if override and descText then
purchaseDialog.BodyFrame.ItemPreview.ItemDescription.Text = descText
purchaseDialog.BodyFrame.AfterBalanceButton.Visible = false
end
game.GuiService:AddCenterDialog(purchaseDialog, Enum.CenterDialogType.ModalDialog,
--ShowFunction
function()
-- set the state for our buttons
purchaseDialog.Visible = true
if isFreeItem() then
setButtonsVisible(purchaseDialog.BodyFrame.FreeButton, purchaseDialog.BodyFrame.CancelButton, purchaseDialog.BodyFrame.AfterBalanceButton)
elseif notRightBC then
purchaseDialog.BodyFrame.AfterBalanceButton.Text = "You require an upgrade to your Builders Club membership to purchase this item. Click here to upgrade."
if not openBCUpSellWindowConnection then
openBCUpSellWindowConnection = purchaseDialog.BodyFrame.AfterBalanceButton.MouseButton1Click:connect(function()
if purchaseDialog.BodyFrame.AfterBalanceButton.Text == "You require an upgrade to your Builders Club membership to purchase this item. Click here to upgrade." then
print('Upselling BC')
openBCUpSellWindow()
end
end)
end
setButtonsVisible(purchaseDialog.BodyFrame.BuyDisabledButton, purchaseDialog.BodyFrame.CancelButton, purchaseDialog.BodyFrame.AfterBalanceButton)
elseif insufficientFunds then
setButtonsVisible(purchaseDialog.BodyFrame.BuyDisabledButton, purchaseDialog.BodyFrame.CancelButton, purchaseDialog.BodyFrame.AfterBalanceButton)
elseif override then
setButtonsVisible(purchaseDialog.BodyFrame.BuyDisabledButton, purchaseDialog.BodyFrame.CancelButton) -- , purchaseDialog.BodyFrame.AfterBalanceButton)
else
setButtonsVisible(purchaseDialog.BodyFrame.BuyButton, purchaseDialog.BodyFrame.CancelButton) -- , purchaseDialog.BodyFrame.AfterBalanceButton)
end
purchaseDialog:TweenPosition(showPosition, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, tweenTime, true)
-- funds are insufficient so we have prompted the user to buy more, now we check until the user buys or cancels
if insufficientFunds and notRightBC == false then
Spawn(function()
checkingPlayerFunds = true
checkPlayerFundLoop()
end)
end
end,
--HideFunction
function()
purchaseDialog.Visible = false
end)
else -- we failed in prompting a purchase, do a decline
doDeclinePurchase()
end
end
-- given an asset id, this function will grab that asset from the website, and return the first "Tool" object found inside it
function getToolAssetID(assetID)
local newTool = game:GetService("InsertService"):LoadAsset(assetID)
if not newTool then return nil end
if newTool:IsA("Tool") then
return newTool
end
local toolChildren = newTool:GetChildren()
for i = 1, #toolChildren do
if toolChildren[i]:IsA("Tool") then
return toolChildren[i]
end
end
return nil
end
-- the user tried to purchase by clicking the purchase button, but something went wrong.
-- let them know their account was not charged, and that they do not own the item yet.
function purchaseFailed(inGamePurchasesDisabled)
local newPurchasedFailedText = string.gsub( purchaseFailedText,"itemName", tostring(currentProductInfo["Name"]))
if inGamePurchasesDisabled then
newPurchasedFailedText = string.gsub( newPurchasedFailedText,"errorReason", tostring(errorPurchasesDisabledText) )
else
newPurchasedFailedText = string.gsub( newPurchasedFailedText,"errorReason", tostring(errorPurchasesUnknownText) )
end
purchaseDialog.BodyFrame.ItemPreview.ItemDescription.Text = newPurchasedFailedText
purchaseDialog.BodyFrame.ItemPreview.Image = errorImageUrl
setButtonsVisible(purchaseDialog.BodyFrame.OkButton)
setHeaderText(buyFailedHeaderText)
hidePurchasing()
end
-- user has specified they want to buy an item, now try to attempt to buy it for them
function doAcceptPurchase(currencyPreferredByUser)
showPurchasing() -- shows a purchasing ui (shows spinner)
-- http call to do the purchase
local response = "none"
local success, reason = ypcall(function()
response = game:HttpPostAsync(getSecureApiBaseUrl() .. "marketplace/purchase?productId=" .. tostring(currentProductId) ..
"&currencyTypeId=" .. tostring(currencyEnumToInt(currentCurrencyType)) ..
"&purchasePrice=" .. tostring(currentCurrencyAmount) ..
"&locationType=Game" .. "&locationId=" .. Game.PlaceId,
"RobloxPurchaseRequest")
end)
-- debug output for us (found in the logs from local)
print("doAcceptPurchase success from ypcall is ",success,"reason is",reason)
print("doAcceptPurchase response is ",response)
wait(1) -- allow the purchasing waiting dialog to at least be readable (otherwise it might flash, looks bad)...
-- check to make sure purchase actually happened on the web end
if response == "none" or response == nil or response == '' then
print("did not get a proper response from web on purchase of",currentAssetId)
purchaseFailed()
return
end
-- parse our response, decide how to react
response = getRbxUtility().DecodeJSON(response)
if response then
if response["success"] == false then
if response["status"] ~= "AlreadyOwned" then
print("web return response of fail on purchase of",currentAssetId)
purchaseFailed( (response["status"] == "EconomyDisabled") )
return
end
end
else
print("web return response of non parsable JSON on purchase of",currentAssetId)
purchaseFailed()
return
end
-- check to see if this item was bought, and if we want to equip it (also need to make sure the asset type was gear)
if currentEquipOnPurchase and success and tonumber(currentProductInfo["AssetTypeId"]) == 19 then
local tool = getToolAssetID(tonumber(currentAssetId))
if tool then
tool.Parent = game.Players.LocalPlayer.Backpack
end
end
userPurchaseActionsEnded(success)
end
-- user pressed the cancel button, just remove all purchasing prompts
function doDeclinePurchase()
userPurchaseActionsEnded(false)
end
-------------------------------- End Accept/Decline Functions --------------------------------------
---------------------------------------------- Currency Functions ---------------------------------------------
-- enums have no implicit conversion to numbers in lua, has to have a function to do this
function currencyEnumToInt(currencyEnum)
if currencyEnum == Enum.CurrencyType.Robux then
return 1
elseif currencyEnum == Enum.CurrencyType.Tix then
return 2
end
end
-- oi, this is ugly
function assetTypeToString(assetType)
if assetType == 1 then return "Image"
elseif assetType == 2 then return "T-Shirt"
elseif assetType == 3 then return "Audio"
elseif assetType == 4 then return "Mesh"
elseif assetType == 5 then return "Lua"
elseif assetType == 6 then return "HTML"
elseif assetType == 7 then return "Text"
elseif assetType == 8 then return "Hat"
elseif assetType == 9 then return "Place"
elseif assetType == 10 then return "Model"
elseif assetType == 11 then return "Shirt"
elseif assetType == 12 then return "Pants"
elseif assetType == 13 then return "Decal"
elseif assetType == 16 then return "Avatar"
elseif assetType == 17 then return "Head"
elseif assetType == 18 then return "Face"
elseif assetType == 19 then return "Gear"
elseif assetType == 21 then return "Badge"
elseif assetType == 22 then return "Group Emblem"
elseif assetType == 24 then return "Animation"
elseif assetType == 25 then return "Arms"
elseif assetType == 26 then return "Legs"
elseif assetType == 27 then return "Torso"
elseif assetType == 28 then return "Right Arm"
elseif assetType == 29 then return "Left Arm"
elseif assetType == 30 then return "Left Leg"
elseif assetType == 31 then return "Right Leg"
elseif assetType == 32 then return "Package"
elseif assetType == 33 then return "YouTube Video"
elseif assetType == 34 then return "Game Pass"
end
return ""
end
function currencyTypeToString(currencyType)
if currencyType == Enum.CurrencyType.Tix then
return "Tix"
else
return "R$"
end
end
-- figure out what currency to use based on the currency you can actually sell the item in and what the script specified
function setCurrencyAmountAndType(priceInRobux, priceInTix)
if currentCurrencyType == Enum.CurrencyType.Default or currentCurrencyType == Enum.CurrencyType.Robux then -- sell for default (user doesn't care) or robux
if priceInRobux ~= nil and priceInRobux ~= 0 then -- we can sell for robux
currentCurrencyAmount = priceInRobux
currentCurrencyType = Enum.CurrencyType.Robux
else -- have to use tix
currentCurrencyAmount = priceInTix
currentCurrencyType = Enum.CurrencyType.Tix
end
elseif currentCurrencyType == Enum.CurrencyType.Tix then -- we want to sell for tix
if priceInTix ~= nil and priceInTix ~= 0 then -- we can sell for tix
currentCurrencyAmount = priceInTix
currentCurrencyType = Enum.CurrencyType.Tix
else -- have to use robux
currentCurrencyAmount = priceInRobux
currentCurrencyType = Enum.CurrencyType.Robux
end
else
return false
end
if currentCurrencyAmount == nil then
return false
end
return true
end
-- will get the player's balance of robux and tix, return in a table
function getPlayerBalance()
local playerBalance = nil
local success, errorCode = ypcall(function() playerBalance = game:HttpGetAsync(getSecureApiBaseUrl() .. "currency/balance") end)
if not success then
print("Get player balance failed because",errorCode)
return nil
end
if playerBalance == '' then
return nil
end
playerBalance = getRbxUtility().DecodeJSON(playerBalance)
return playerBalance
end
-- should open an external default browser window to this url
function openBuyCurrencyWindow()
game:GetService("GuiService"):OpenBrowserWindow(baseUrl .. "Upgrades/Robux.aspx")
end
function openBCUpSellWindow()
Game:GetService('GuiService'):OpenBrowserWindow(baseUrl .. "Upgrades/BuildersClubMemberships.aspx")
end
-- set up the gui text at the bottom of the prompt (alerts user to how much money they will have left, or if they need to buy more to buy the item)
function updateAfterBalanceText(playerBalance, notRightBc)
if isFreeItem() then
purchaseDialog.BodyFrame.AfterBalanceButton.Text = freeItemBalanceText
return true, false
end
local keyWord = nil
if currentCurrencyType == Enum.CurrencyType.Robux then
keyWord = "robux"
elseif currentCurrencyType == Enum.CurrencyType.Tix then
keyWord = "tickets"
end
if not keyWord then
return false
end
local playerBalanceNumber = tonumber(playerBalance[keyWord])
if not playerBalanceNumber then
return false
end
local afterBalanceNumber = playerBalanceNumber - currentCurrencyAmount
-- check to see if we have enough of the desired currency to allow a purchase, if not we need to prompt user to buy robux
if not notRightBc then
if afterBalanceNumber < 0 and keyWord == "robux" then
if openBuyCurrencyWindowConnection == nil then
openBuyCurrencyWindowConnection = purchaseDialog.BodyFrame.AfterBalanceButton.MouseButton1Click:connect(openBuyCurrencyWindow)
end
purchaseDialog.BodyFrame.AfterBalanceButton.Text = "You need " .. currencyTypeToString(currentCurrencyType) .. " " .. tostring(-afterBalanceNumber) .. " more to buy this, click here to purchase more."
return true, true
elseif afterBalanceNumber < 0 and keyWord == "tickets" then
purchaseDialog.BodyFrame.AfterBalanceButton.Text = "You need " .. tostring(-afterBalanceNumber) .. " " .. currencyTypeToString(currentCurrencyType) .. " more to buy this item."
return true, true -- user can't buy more tickets, so we say fail the transaction (maybe instead we can prompt them to trade currency???)
end
end
-- this ensures that we only have one connection to openBuyCurrencyWindow at a time (otherwise might open multiple browser windows)
if(openBuyCurrencyWindowConnection) then
openBuyCurrencyWindowConnection:disconnect()
openBuyCurrencyWindowConnection = nil
end
purchaseDialog.BodyFrame.AfterBalanceButton.Text = "Your balance after this transaction will be " .. currencyTypeToString(currentCurrencyType) .. " " .. tostring(afterBalanceNumber) .. "."
return true, false
end
function isFreeItem()
-- if both of these are true, then the item is free, just prompt user if they want to take one
return currentProductInfo and currentProductInfo["IsForSale"] == true and currentProductInfo["IsPublicDomain"] == true
end
-- will continuously poll the player to see if funds have changed. Poll rate is changed by adjusting checkPlayerFundsLoopTime, which is specified in seconds
function checkPlayerFundLoop()
local canPurchase = true
local insufficientFunds = true
while checkingPlayerFunds and insufficientFunds do
wait(checkPlayerFundsLoopTime)
canPurchase, insufficientFunds = canPurchaseItem() -- check again to see if we can buy item
if canPurchase then
if not insufficientFunds then
-- we can buy item! set our buttons up and we will exit this loop
setButtonsVisible(purchaseDialog.BodyFrame.BuyButton,purchaseDialog.BodyFrame.CancelButton, purchaseDialog.BodyFrame.AfterBalanceButton)
end
end
end
end
---------------------------------------------- End Currency Functions ---------------------------------------------
---------------------------------------------- Data Functions -----------------------------------------------------
-- more enum to int fun!
function membershipTypeToNumber(membership)
if membership == Enum.MembershipType.None then
return 0
elseif membership == Enum.MembershipType.BuildersClub then
return 1
elseif membership == Enum.MembershipType.TurboBuildersClub then
return 2
elseif membership == Enum.MembershipType.OutrageousBuildersClub then
return 3
end
return -1
end
-- This functions checks to make sure the purchase is even possible, if not it returns false and we don't prompt user (some situations require user feedback when we won't prompt)
function canPurchaseItem()
-- first we see if player already owns the asset
local playerOwnsAsset = false
local notRightBc = false
local descText = nil
local success, errorCode = ypcall(function() playerOwnsAsset = game:HttpGetAsync(getSecureApiBaseUrl()
.. "/ownership/hasAsset?userId="
.. tostring(game.Players.LocalPlayer.userId)
.. "&assetId=" .. tostring(currentAssetId))
end)
if not success then
print("could not tell if player owns asset because",errorCode)
return false
end
purchaseDialog.BodyFrame.AfterBalanceButton.Visible = true
-- next we get the product info and do some checks on that
local success = ypcall(function() currentProductInfo = game:GetService("MarketplaceService"):GetProductInfo(currentAssetId) end)
if currentProductInfo == nil or not success then
descText = "In-game sales are temporarily disabled. Please try again later."
return true, nil, nil, true, descText
end
if type(currentProductInfo) ~= "table" then
currentProductInfo = getRbxUtility().DecodeJSON(currentProductInfo)
end
if not currentProductInfo then
descText = "Could not get product info. Please try again later."
return true, nil, nil, true, descText
end
if playerOwnsAsset == true or playerOwnsAsset == "true" then
descText = "You already own this item."
return true, nil, nil, true, descText
end
if currentProductInfo["IsForSale"] == false and currentProductInfo["IsPublicDomain"] == false then
descText = "This item is no longer for sale."
return true, nil, nil, true, descText
end
-- now we start talking money, making sure we are going to be able to purchase this
if not setCurrencyAmountAndType(tonumber(currentProductInfo["PriceInRobux"]), tonumber(currentProductInfo["PriceInTickets"])) then
descText = "We could retrieve the price of the item correctly. Please try again later."
return true, nil, nil, true, descText
end
local playerBalance = getPlayerBalance()
if not playerBalance then
descText = "Could not retrieve your balance. Please try again later."
return true, nil, nil, true, descText
end
if tonumber(currentProductInfo["MinimumMembershipLevel"]) > membershipTypeToNumber(game.Players.LocalPlayer.MembershipType) then
notRightBc = true
end
local updatedBalance, insufficientFunds = updateAfterBalanceText(playerBalance, notRightBc)
if notRightBc then
purchaseDialog.BodyFrame.AfterBalanceButton.Active = true
return true, insufficientFunds, notRightBc, false
end
if currentProductInfo["ContentRatingTypeId"] == 1 then
if game.Players.LocalPlayer:GetUnder13() then
descText = "Your account is under 13 so purchase of this item is not allowed."
return true, nil, nil, true, descText
end
end
if (currentProductInfo["IsLimited"] == true or currentProductInfo["IsLimitedUnique"] == true) and
(currentProductInfo["Remaining"] == "" or currentProductInfo["Remaining"] == 0 or currentProductInfo["Remaining"] == nil) then
descText = "All copies of this item have been sold out! Try buying from other users on the website."
return true, nil, nil, true, descText
end
if not updatedBalance then
descText = 'Could not update your balance. Please check back after some time.'
return true, nil, nil, true, descText
end
-- we use insufficient funds to display a prompt to buy more robux
purchaseDialog.BodyFrame.AfterBalanceButton.Active = true
return true, insufficientFunds
end
function computeSpaceString(pLabel)
local nString = " "
local tempSpaceLabel = Instance.new('TextButton')
tempSpaceLabel.Size = UDim2.new(0, pLabel.AbsoluteSize.X, 0, pLabel.AbsoluteSize.Y);
tempSpaceLabel.FontSize = pLabel.FontSize;
tempSpaceLabel.Parent = pLabel.Parent;
tempSpaceLabel.BackgroundTransparency = 1.0;
tempSpaceLabel.Text = nString;
tempSpaceLabel.Name = 'SpaceButton'
while tempSpaceLabel.TextBounds.X < pLabel.TextBounds.X do
nString = nString .. " "
tempSpaceLabel.Text = nString
end
nString = nString .. " "
tempSpaceLabel.Text = ""
return nString
end
---------------------------------------------- End Data Functions -----------------------------------------------------
---------------------------------------------- Gui Functions ----------------------------------------------
function startSpinner()
spinning = true
Spawn( function()
local spinPos = 0
while spinning do
local pos = 0
while pos < 8 do
if pos == spinPos or pos == ((spinPos+1)%8) then
spinnerIcons[pos+1].Image = "http://www.jarfeh.xyz/Asset?id=45880668"
else
spinnerIcons[pos+1].Image = "http://www.jarfeh.xyz/Asset?id=45880710"
end
pos = pos + 1
end
spinPos = (spinPos + 1) % 8
wait(1/15)
end
end)
end
function stopSpinner()
spinning = false
end
-- convenience method to say exactly what buttons should be visible (all others are not!)
function setButtonsVisible(...)
local args = {...}
local argCount = select('#', ...)
local bodyFrameChildren = purchaseDialog.BodyFrame:GetChildren()
for i = 1, #bodyFrameChildren do
if bodyFrameChildren[i]:IsA("GuiButton") then
bodyFrameChildren[i].Visible = false
for j = 1, argCount do
if bodyFrameChildren[i] == args[j] then
bodyFrameChildren[i].Visible = true
break
end
end
end
end
end
-- used for the "Purchasing..." frame
function createSpinner(size,position,parent)
local spinnerFrame = Instance.new("Frame")
spinnerFrame.Name = "Spinner"
spinnerFrame.Size = size
spinnerFrame.Position = position
spinnerFrame.BackgroundTransparency = 1
spinnerFrame.ZIndex = 10
spinnerFrame.Parent = parent
spinnerIcons = {}
local spinnerNum = 1
while spinnerNum <= 8 do
local spinnerImage = Instance.new("ImageLabel")
spinnerImage.Name = "Spinner"..spinnerNum
spinnerImage.Size = UDim2.new(0, 16, 0, 16)
spinnerImage.Position = UDim2.new(.5+.3*math.cos(math.rad(45*spinnerNum)), -8, .5+.3*math.sin(math.rad(45*spinnerNum)), -8)
spinnerImage.BackgroundTransparency = 1
spinnerImage.ZIndex = 10
spinnerImage.Image = "http://www.jarfeh.xyz/Asset/?id=45880710"
spinnerImage.Parent = spinnerFrame
spinnerIcons[spinnerNum] = spinnerImage
spinnerNum = spinnerNum + 1
end
end
-- all the gui init. Would be nice if this didn't have to be a script
function createPurchasePromptGui()
purchaseDialog = Instance.new("Frame")
purchaseDialog.Name = "PurchaseFrame"
purchaseDialog.Size = UDim2.new(0,660,0,400)
purchaseDialog.Position = hidePosition
purchaseDialog.Visible = false
purchaseDialog.BackgroundColor3 = Color3.new(141/255,141/255,141/255)
purchaseDialog.BorderColor3 = Color3.new(204/255,204/255,204/255)
purchaseDialog.Parent = game.CoreGui.RobloxGui
local bodyFrame = Instance.new("Frame")
bodyFrame.Name = "BodyFrame"
bodyFrame.Size = UDim2.new(1,0,1,-60)
bodyFrame.Position = UDim2.new(0,0,0,60)
bodyFrame.BackgroundColor3 = Color3.new(67/255, 67/255, 67/255)
bodyFrame.BorderSizePixel = 0
bodyFrame.Parent = purchaseDialog
local titleLabel = createTextObject("TitleLabel", "Buy Item", "TextLabel", Enum.FontSize.Size48)
titleLabel.Size = UDim2.new(1,0,0,60)
local titleBackdrop = titleLabel:Clone()
titleBackdrop.Name = "TitleBackdrop"
titleBackdrop.TextColor3 = Color3.new(32/255,32/255,32/255)
titleBackdrop.BackgroundTransparency = 0.0
titleBackdrop.BackgroundColor3 = Color3.new(54/255, 96/255, 171/255)
titleBackdrop.Position = UDim2.new(0,0,0,-2)
titleBackdrop.Parent = purchaseDialog
titleLabel.Parent = purchaseDialog
local cancelButton = createImageButton("CancelButton")
cancelButton.Position = UDim2.new(0.75,-70,1,-120)
cancelButton.BackgroundTransparency = 1
cancelButton.BorderSizePixel = 0
cancelButton.Parent = bodyFrame
cancelButton.Modal = true
cancelButton.Image = cancelButtonImageUrl
cancelButton.MouseButton1Down:connect(function()
cancelButton.Image = cancelButtonDownUrl
end)
cancelButton.MouseButton1Up:connect(function( )
cancelButton.Image = cancelButtonImageUrl
end)
cancelButton.MouseLeave:connect(function( )
cancelButton.Image = cancelButtonImageUrl
end)
cancelButton.MouseButton1Click:connect(doDeclinePurchase)
local buyButton = createImageButton("BuyButton")
buyButton.Position = UDim2.new(0.25,-100,1,-120)
buyButton.BackgroundTransparency = 1
buyButton.BorderSizePixel = 0
buyButton.Image = buyImageUrl
buyButton.MouseButton1Down:connect(function()
buyButton.Image = buyImageDownUrl
end)
buyButton.MouseButton1Up:connect(function( )
buyButton.Image = buyImageUrl
end)
buyButton.MouseLeave:connect(function( )
buyButton.Image = buyImageUrl
end)
buyButton.Parent = bodyFrame
local buyDisabledButton = buyButton:Clone()
buyDisabledButton.Name = "BuyDisabledButton"
buyDisabledButton.AutoButtonColor = false
buyDisabledButton.Visible = false
buyDisabledButton.Active = false
buyDisabledButton.Image = buyImageDisabledUrl
buyDisabledButton.Parent = bodyFrame
local freeButton = buyButton:Clone()
freeButton.BackgroundTransparency = 1
freeButton.Name = "FreeButton"
freeButton.Visible = false
freeButton.Image = freeButtonImageUrl
freeButton.MouseButton1Down:connect(function()
freeButton.Image = freeButtonImageDownUrl
end)
freeButton.MouseButton1Up:connect(function( )
freeButton.Image = freeButtonImageUrl
end)
freeButton.MouseLeave:connect(function( )
freeButton.Image = freeButtonImageUrl
end)
freeButton.Parent = bodyFrame
local okButton = buyButton:Clone()
okButton.Name = "OkButton"
okButton.BackgroundTransparency = 1
okButton.Visible = false
okButton.Position = UDim2.new(0.5,-okButton.Size.X.Offset/2,1,-120)
okButton.Modal = true
okButton.Image = okButtonUrl
okButton.MouseButton1Down:connect(function()
okButton.Image = okButtonPressedrl
end)
okButton.MouseButton1Up:connect(function( )
okButton.Image = okButtonUrl
end)
okButton.MouseLeave:connect(function( )
okButton.Image = okButtonUrl
end)
okButton.Parent = bodyFrame
local okPurchasedButton = okButton:Clone()
okPurchasedButton.Name = "OkPurchasedButton"
okPurchasedButton.MouseButton1Down:connect(function()
okPurchasedButton.Image = okButtonPressedrl
end)
okPurchasedButton.MouseButton1Up:connect(function( )
okPurchasedButton.Image = okButtonUrl
end)
okPurchasedButton.MouseLeave:connect(function( )
okPurchasedButton.Image = okButtonUrl
end)
okPurchasedButton.Parent = bodyFrame
okButton.MouseButton1Click:connect(function () userPurchaseActionsEnded(false) end)
okPurchasedButton.MouseButton1Click:connect(function() signalPromptEnded(true) end)
buyButton.MouseButton1Click:connect(function() doAcceptPurchase(Enum.CurrencyType.Robux) end)
freeButton.MouseButton1Click:connect(function() doAcceptPurchase(false) end)
local itemPreview = Instance.new("ImageLabel")
itemPreview.Name = "ItemPreview"
itemPreview.BackgroundColor3 = Color3.new(32/255,32/255,32/255)
itemPreview.BorderColor3 = Color3.new(141/255,141/255,141/255)
itemPreview.Position = UDim2.new(0,30,0,20)
itemPreview.Size = UDim2.new(0,180,0,180)
itemPreview.ZIndex = 2
itemPreview.Parent = bodyFrame
local itemDescription = createTextObject("ItemDescription", "Would you like to buy the 'itemName' for currencyType currencyAmount?","TextLabel",Enum.FontSize.Size24)
itemDescription.Position = UDim2.new(1,20,0,0)
itemDescription.Size = UDim2.new(0,410,1,0)
itemDescription.Parent = itemPreview
local afterBalanceButton = createTextObject("AfterBalanceButton","Place holder text ip sum lorem dodo ashs","TextButton",Enum.FontSize.Size24)
afterBalanceButton.AutoButtonColor = false
afterBalanceButton.Position = UDim2.new(0,5,1,-55)
afterBalanceButton.Size = UDim2.new(1,-10,0,50)
afterBalanceButton.Parent = bodyFrame
local purchasingFrame = Instance.new("Frame")
purchasingFrame.Name = "PurchasingFrame"
purchasingFrame.Size = UDim2.new(1,0,1,0)
purchasingFrame.BackgroundColor3 = Color3.new(0,0,0)
purchasingFrame.BackgroundTransparency = 0.2
purchasingFrame.BorderSizePixel = 0
purchasingFrame.ZIndex = 9
purchasingFrame.Visible = false
purchasingFrame.Active = true
purchasingFrame.Parent = purchaseDialog
local purchasingLabel = createTextObject("PurchasingLabel","Purchasing...","TextLabel",Enum.FontSize.Size48)
purchasingLabel.Size = UDim2.new(1,0,1,0)
purchasingLabel.ZIndex = 10
purchasingLabel.Parent = purchasingFrame
createSpinner(UDim2.new(0,50,0,50), UDim2.new(0.5,-25,0.5,30), purchasingLabel)
end
-- next two functions control the "Purchasing..." overlay
function showPurchasing()
startSpinner()
purchaseDialog.PurchasingFrame.Visible = true
end
function hidePurchasing()
purchaseDialog.PurchasingFrame.Visible = false
stopSpinner()
end
-- next 2 functions are convenienvce creation functions for guis
function createTextObject(name, text, type, size)
local textLabel = Instance.new(type)
textLabel.Font = Enum.Font.ArialBold
textLabel.TextColor3 = Color3.new(217/255, 217/255, 217/255)
textLabel.TextWrapped = true
textLabel.Name = name
textLabel.Text = text
textLabel.BackgroundTransparency = 1
textLabel.BorderSizePixel = 0
textLabel.FontSize = size
return textLabel
end
function createImageButton(name)
local imageButton = Instance.new("ImageButton")
imageButton.Size = UDim2.new(0,153,0,46)
imageButton.Name = name
return imageButton
end
function setHeaderText(text)
purchaseDialog.TitleLabel.Text = text
purchaseDialog.TitleBackdrop.Text = text
end
function cutSizeInHalfRecursive(instance)
-- todo: change the gui size based on how much space we have
--[[changeSize(instance,0.5)
local children = instance:GetChildren()
for i = 1, #children do
cutSizeInHalfRecursive(children[i])
end]]
end
function doubleSizeRecursive(instance)
-- todo: change the gui size based on how much space we have
--[[changeSize(instance,2)
local children = instance:GetChildren()
for i = 1, #children do
doubleSizeRecursive(children[i])
end]]
end
function modifyForSmallScreen()
cutSizeInHalfRecursive(purchaseDialog)
end
function modifyForLargeScreen()
doubleSizeRecursive(purchaseDialog)
end
-- depending on screen size, we need to change the gui
function changeGuiToScreenSize(smallScreen)
if smallScreen then
modifyForSmallScreen()
else
modifyForLargeScreen()
end
end
---------------------------------------------- End Gui Functions ----------------------------------------------
---------------------------------------------- Script Event start/initialization ----------------------------------------------
preloadAssets()
game:GetService("MarketplaceService").PromptPurchaseRequested:connect(function(player, assetId, equipIfPurchased, currencyType)
if not purchaseDialog then
createPurchasePromptGui()
end
if player == game.Players.LocalPlayer then
if currentlyPrompting then return end
currentlyPrompting = true
currentAssetId = assetId
currentCurrencyType = currencyType
currentEquipOnPurchase = equipIfPurchased
showPurchasePrompt()
end
end)
game.CoreGui.RobloxGui.Changed:connect(function()
local nowIsSmallScreen = (game.CoreGui.RobloxGui.AbsoluteSize.Y <= smallScreenThreshold)
if nowIsSmallScreen and not isSmallScreen then
changeGuiToScreenSize(true)
elseif not nowIsSmallScreen and isSmallScreen then
changeGuiToScreenSize(false)
end
isSmallScreen = nowIsSmallScreen
end)
isSmallScreen = (game.CoreGui.RobloxGui.AbsoluteSize.Y <= smallScreenThreshold)
if isSmallScreen then
changeGuiToScreenSize(true)
end