Where do i put the New local script inside of? Im pretty sure Localscripts dont run inside of ServerScriptService
Oh yeah, put it in StarterGui or something like that. Sorry, I forgot to clarify that.
Alright, should’ve researched that before-hand. Anyways, process the purchase and cash on the server, and use a bindable event to read the TextLabel’s texts.
Server Script:
local BindableEvent = game:GetService("ReplicatedStorage").BindableEvent
function onPurchase(receiptInfo)
-- your code here
local cashToAdd = BindableEvent:InvokeClient()
local cashAmount = cashToAdd[receiptInfo["ProductId"]]
player.leaderstats.Cash.Value += cashAmount
return Enum.ProductPurchaseDecision.PurchaseGranted
end
MarketPlaceService.ProcessReceipt = onPurchase
LocalScript:
local BindableEvent = game:GetService("ReplicatedStorage").BindableEvent
function BindableEvent.OnClientInvoke(productId)
local cashToAdd = {
[1852179613] = tonumber(playerGui.CashShopGui.Frame.BronzeLabel.Text),
[1852179828] = tonumber(playerGui.CashShopGui.Frame.SilverLabel.Text),
[1852179993] = tonumber(playerGui.CashShopGui.Frame.GoldLabel.Text),
[1852180091] = tonumber(playerGui.CashShopGui.Frame.DiamondLabel.Text)
}
return cashToAdd
end
Sorry, my mistake. It was supposed to be BindableFunction, not a BindableEvent, hopefully it should work.
Someone on a discord server said that Bindable functions and events are bad practise
Really? That’s weird, they were probably not using it correctly. If it was really bad to use, Roblox would probably deprecate it and make something better to replace it. Here’s the Roblox Documentary page if you want to take a look: BindableFunction | Documentation - Roblox Creator Hub
Anyways, try replacing the BindableEvent with BindableFunction. That was a mistake on my part, sorry.
did it and it doesnt display errors, but it does not give the player any cash what so ever
There are many things wrong with these replies, and a few things with your code. You should keep your code mostly the same but keep a few things in mind:
-
You should not be accessing the
Player
’sPlayerGui
on the server. Any gui changes done on the client would not replicate to the server in the first place.
What you should be doing instead is having one source of calculation truth (via aModuleScript
for example) that both the server and client can access. The client should then be synced up with the server on the actual amount of cash being added. -
@J_Angry’s
RemoteEvent
example should not be followed.
A.ProcessReceipt
has to be done on the server, not the client.
B. Players can exploit this structure by simply firing theRemoteEvent
with the amount of cash they want to receive.
C. That is not the wayBindable
s work.Remote
s are the objects used for server-to-client communication.Bindable
s are for server-server and client-client communication only.
how can i make the module script if all of my TextLabel calculations are done by each having their own LocalScript and Multiplier and their each fixed amount (200, 500, 2000, 5000)
Something like this as an example:
-- ModuleScript somewhere in ReplicatedStorage
return function(initialAmount: number, fixedAmount: number, fixedThreshold: number, multiplierAmount: number): number
if initialAmount <= fixedThreshold then
return fixedAmount
else
return initialAmount * multiplierAmount
end
end
Then on the client and server, you can do something like this:
-- client
local calculateNewCashAmount = require(path_to_module)
local fixedAmount = 200
local fixedThreshold = 199
local cashMultiplier = 1.5
player.leaderstats.Cash.Changed:Connect(function()
local amountToGive: number = calculateNewCashAmount(
player.leaderstats.Cash.Value,
fixedAmount,
fixedThreshold,
cashMultiplier
)
script.Parent.Text = tostring(amountToGive)
end)
-- server
local calculateNewCashAmount = require(path_to_module)
local function onPurchase(receiptInfo)
local plr = players:GetPlayerByUserId(receiptInfo["PlayerId"])
local leaderstats = plr:FindFirstChild("leaderstats")
local cashToAdd = {
[id_here] = calculateNewCashAmount(
leaderstats.Cash.Value,
200,
199,
1.5
),
-- etc.
}
end
Now you have both the server and client calculating the same amount of cash.
ill give it a try, iiiiiiiiiiiiiiiiiiii
So i think that this is what you meant, how would i go about giving the player the cash amount that is displayed on the textlabel?
local MarketPlaceService = game:GetService("MarketplaceService")
local CashModule = game.ReplicatedStorage.CashModule
local players = game:GetService("Players")
local calculateNewCashAmount = require(CashModule)
local function onPurchase(receiptInfo)
local plr = players:GetPlayerByUserId(receiptInfo["PlayerId"])
local leaderstats = plr:FindFirstChild("leaderstats")
local cashToAdd = {
[1852179613] = calculateNewCashAmount(
leaderstats.Cash.Value,
200,
199,
1.5
),
[1852179828] = calculateNewCashAmount(
leaderstats.Cash.Value,
500,
499,
2
),
[1852179993] = calculateNewCashAmount(
leaderstats.Cash.Value,
2000,
1999,
2.5
),
[1852180091] = calculateNewCashAmount(
leaderstats.Cash.Value,
5000,
4999,
3
)
}
end
MarketPlaceService.ProcessReceipt = onPurchase
The cash amount on the server should match the cash amount shown on the TextLabel. They are both using the same calculation function.
Right, how can i make it so once the player buys a dev product it gives the player that amount?
Same way you had it before, except you add the actual Value property instead of a variable of that Value.
local cashAmount = cashToAdd[receiptInfo["ProductId"]]
leaderstats.Cash.Value += cashAmount
ReplicatedStorage.CashPurchaseEvent:FireClient(plr)
return Enum.ProductPurchaseDecision.PurchaseGranted
Holy moly, finally, thanks for the solution
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.