iwe’re wanting to understand how much they bought what they bought for yeah. or else i dont think this would be an issue.
in short
they change price to say 1 robux
then prompt and buy
they change price to say 1 million robux
then press okay
roblox reads the value as what they pressed buy for (what the prompt was for)
your game server reads the prompt as what the value was when they press okay
in theory though, if what oddcraft was saying is true and the price value holds true (which i believe it does, it’s just the updated that is chached and does not hold true) then this should be a fix…
although my quesstion is the rate limit. if we have multiple players in a game going through this process would it work?
You can test that your self with multiple of friends or devices. I’m not sure if its rate limited because PLS donate definetly might have the same syste,
but that is client sided so if we’re getting price from client they could manipulate that. is it not a better option to have an event fire to server letting the server know a player is making a purchase and then repeatedly checking the price to get what holds true? then if there isnt any pending transaction we just dont count it.
-- Client
local marketplace = game:GetService("MarketplaceService")
local shirtId = 8245844314
local remote = game:GetService("ReplicatedStorage"):WaitForChild("thingIdk")
script.Parent.MouseButton1Click:Connect(function()
marketplace:PromptPurchase(game.Players.LocalPlayer,shirtId)
remote:FireServer(shirtId)
end)
Server
-- Server
local remote = game:GetService("ReplicatedStorage"):WaitForChild("thingIdk")
local marketplace = game:GetService("MarketplaceService")
local players = game:GetService("Players")
players.PlayerAdded:Connect(function(plr)
local leaderstats = Instance.new("Folder",plr)
leaderstats.Name = "leaderstats"
local num = Instance.new("NumberValue", leaderstats)
num.Name = "Donated"
end)
remote.OnServerEvent:Connect(function(plr, shirtId)
local info = marketplace:GetProductInfo(shirtId,Enum.InfoType.Asset)
local oldPrice = info.PriceInRobux
plr:SetAttribute("shirtId", shirtId)
plr:SetAttribute("price", oldPrice)
end)
marketplace.PromptPurchaseFinished:Connect(function(player, assetId, ispurchased)
if ispurchased then
local shirtId = player:GetAttribute("shirtId")
local price = player:GetAttribute("price")
if shirtId == assetId then
player.leaderstats.Donated.Value += price
player:SetAttribute("shirtId", nil)
player:SetAttribute("price", nil)
end
end
end)
they could exploit that. but i think can just use getProductInfo because that price holds true. and just run that every 0.5 seconds to see if any modifications.
i don’t think i understand what you’re saying because it seems they can still exploit this by manipulating the price.
if they join the game with price of 1,000,000 it gets set to 1,000,000.
they change price to 1 robux then buy
they change back to 1,000,000 then press okay.
No, server will not read it 1,000,000.
Whenever player clicks shirt button as shown in the video, the prompt will be shown.
Then it will send product id to the server, server will get the asset information (price) which is currently 1, then it will set that price to attribute on player’s instance.
Once someone clicks buy button, server will check the asset id and get the price that is stored in a attribute, and then it will update the donated value.
(we are not checking product price whenever the prompt is purchased)
If I was a hacker, I could still fire game.ReplicatedStorage.thingIdk:FireServer(8245844314) after pressing ‘click to buy for 5 R$’ and before clicking ‘ok’ to make your script think that I purchased it for 999999 R$.
I could also disable your localscript, and make your remote fire whenever I want so tracking the lowest price after the remote starts isn’t an option.
Any other ideas besides looping from the start of game?