I am attempting to make a ServerScript where a player gets JumpPower if they purchase a certain product so that it is harder to cheat.
Here is my script, the jumppower is not received by the player.
local MarketPlaceService = game:GetService("MarketPlaceService")
Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
local Humanoid = Character:FindFirstChild("Humanoid")
MarketPlaceService.PromptProductPurchaseFinished:Connect(function(Player, ProductId, PurchaseResult)
if ProductId == 1562085041 and PurchaseResult == Enum.ProductPurchaseDecision.PurchaseGranted then
Humanoid.JumpPower += 25
end
end)
end)
end)
Hello there! I’m here to assist you. It would be advisable to modify the JumpPower of the player within the local script rather than the server script. This is because the client has control over their own avatar. Therefore, utilizing a remote event to adjust the JumpPower would be a suitable approach.
--SERVER SCRIPT
game.ReplicatedStorage.Remotes.Skill.OnClient
local MarketPlaceService = game:GetService("MarketPlaceService")
local Players = game:GetService("Players")
local ChangeJumpPower_remote -- remote event
Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
MarketPlaceService.PromptProductPurchaseFinished:Connect(function(Player, ProductId, PurchaseResult)
if ProductId == 1562085041 and PurchaseResult == Enum.ProductPurchaseDecision.PurchaseGranted then
ChangeJumpPower_remote:FireClient(Player,25)
end
end)
end)
end)
--LOCAL SCRIPT
local ChangeJumpPower_remote -- remote event
local Humanoid -- Humanoid
ChangeJumpPower_remote.OnClientEvent:Connect(function(amount)
Humanoid.JumpPower += amount
end)
Instead of putting your PromptProductPurchaseFinished event inside of a CharacterAdded event you should put it outside. This will trigger when a player purchases the product correctly. Right now what’s happening is that every time someone buys it every player will get the product because the event is attached to each individual player but the event fires when any player buys the item.
You also shouldn’t be using PromptProductPurchaseFinished for this as it’s a deprecated event and ProcessReceipt callback has been added instead
Here’s how I’d do it
local MarketPlaceService = game:GetService("MarketplaceService")
-- You can only use this callback function once in your game
-- Any other products you want to sell should also be added into this function
-- Otherwise it won't work properly
MarketPlaceService.ProcessReceipt = function(receiptInfo)
if receiptInfo.ProductId == 1562085041 then
-- Get the player who purchased the product
local player = game:GetService("Players"):GetPlayerByUserId(receiptInfo.PlayerId)
-- Get the player's character. If it's not there wait for it to be added
local char = player.Character or player.CharacterAdded:Wait()
-- Add 25 JumpPower to the character
char:WaitForChild("Humanoid").JumpPower += 25
-- IMPORTANT: return purchase decision as processed to finish the purchase
return Enum.ProductPurchaseDecision.PurchaseGranted
end
-- If they purchased something else you aren't accounting for then don't process the purchase
return Enum.ProductPurchaseDecision.NotProcessedYet
end
Like I wrote in my script above the ProcessReceipt you have to add every product you’re selling into that single callback function. So if you have multiple products you should be adding them into that same ProcessReceipt instead of spreading them out across multiple scripts. This can be done with simple elseif chaining or other things like tables depending on how complex you want it to be
How would I add mulitple products into one ProcessReceipt in this script since I am not understanding what you are saying
local MarketPlaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local function KillAllPlayers(Receipt)
if(Receipt.ProductId == 1562084909) then
for _, v in pairs(Players:GetPlayers()) do
if(v.UserId ~= Receipt.PlayerId and v.Character and v.Character:FindFirstChild("Humanoid")) then
v.Character:FindFirstChild("Humanoid").Health = 0
end
end
return Enum.ProductPurchaseDecision.PurchaseGranted
end
end
MarketPlaceService.ProcessReceipt = KillAllPlayers
Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Character)
local Humanoid = Character:FindFirstChild("Humanoid")
MarketPlaceService.PromptProductPurchaseFinished:Connect(function(Player, ProductId, PurchaseResult)
if ProductId == 1562085041 and PurchaseResult == Enum.ProductPurchaseDecision.PurchaseGranted then
Humanoid.JumpPower += 25
end
end)
end)
end)
So this is fairly simple. We’re going to combine the PromptProductPurchaseFinished event with the KillAllPlayers function.
We can do this by getting both product ids and using an elseif on the if statement in the KillAllPlayers function
local MarketPlaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
-- You can only use this callback function once in your game
-- Any other products you want to sell should also be added into this function
-- Otherwise it won't work properly
MarketPlaceService.ProcessReceipt = function(receiptInfo)
if receiptInfo.ProductId == 1562085041 then
-- Get the player who purchased the product
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
-- Get the player's character. If it's not there wait for it to be added
local char = player.Character or player.CharacterAdded:Wait()
-- Add 25 JumpPower to the character
char:WaitForChild("Humanoid").JumpPower += 25
-- IMPORTANT: return purchase decision as processed to finish the purchase
return Enum.ProductPurchaseDecision.PurchaseGranted
-- Notice how we use an elseif to handle multiple products in the same function
elseif receiptInfo.ProductId == 1562084909 then
-- KILL ALL PLAYERS
for _, v in pairs(Players:GetPlayers()) do
if(v.UserId ~= receiptInfo.PlayerId and v.Character and v.Character:FindFirstChild("Humanoid")) then
v.Character:FindFirstChild("Humanoid").Health = 0
end
end
return Enum.ProductPurchaseDecision.PurchaseGranted
-- If you have more products just use another elseif here
end
-- If they purchased something else you aren't accounting for then don't process the purchase
return Enum.ProductPurchaseDecision.NotProcessedYet
end
It works with one edit to make HumanoidRootPart just to Humanoid. I don’t quite understand how this works, can you explain why you include at the bottom
For the NotProcessedYet let’s say I buy a gravity coil. But you have not coded it to give me a gravity coil. In order for the purchase to not go through we return NotProcessedYet so that the person does not get scammed