Shop script can be abused easily with events?

I just saw the dev page for anti exploits, well i just saw that you should never trust on the client, about adding client sided events, well, i don’t know if this script for my shop is client sided:

Local script by clicking on “Buy”:

wait(1)
local player = game.Players.LocalPlayer
for i,Buttons in pairs(script.Parent.PerksFrame:GetChildren()) do
local ImageButton = Buttons:FindFirstChild("ImageButton")
	if ImageButton then
	ImageButton.MouseButton1Down:connect(function()
		local HasBought = Buttons:FindFirstChild("HasBought")
			if hasBought then
				if HasBought.Value == true then
							game.ReplicatedStorage.AddGearFromStore:FireServer(Buttons.Name)
else
local Cost = Buttons:FindFirstChild("Cost")
if Cost then
	local leaderstats = player:FindFirstChild("StatsValues")
	if leaderstats then
	local Cash = leaderstats:FindFirstChild("Nubits")
	if Cash then
		if Cash.Value >= Cost.Value then
		HasBought.Value = true
					game.ReplicatedStorage.AddGearFromStore:FireServer(Buttons.Name)		    game.ReplicatedStorage.SubCash:FireServer(Cost.Value)
end end end) end end end end end

Script giving tool:

--Give player tool
function onwin(player,Tool)

local Gear = game.Lighting.Gameitems:FindFirstChild(Tool)

if Gear then
	local Backpack = player:FindFirstChild("Backpack")
	local StarterGear = player:FindFirstChild("StarterGear")
	if StarterGear or Backpack or StarterGear and Backpack then
		for i,clearStoreItems in pairs(StarterGear:GetChildren()) do
			local Tool = game.Lighting.Gameitems:FindFirstChild(clearStoreItems.Name)
			if Tool then
				clearStoreItems:Destroy()
			end
		end
		for i,clearStoreItems in pairs(Backpack:GetChildren()) do
			local Tool = game.Lighting.Gameitems:FindFirstChild(clearStoreItems.Name)
			if Tool then
				clearStoreItems:Destroy()
			end
		end
		local char = game.Workspace:FindFirstChild(player.Name)
		if char then
			for i,clearStoreItems in pairs(char:GetChildren()) do
				if clearStoreItems.ClassName == "Tool" then
			local Tool = game.Lighting.Gameitems:FindFirstChild(clearStoreItems.Name)
			if Tool then
				clearStoreItems:Destroy()
			end
			end
			end
			end
		local findif = StarterGear:FindFirstChild(Gear.Name)
		if findif then
			else
		Gear:Clone().Parent = StarterGear
		Gear:Clone().Parent = Backpack
		end
		local OwnedStoreItems = player:FindFirstChild("OwnedStoreItems")
		if OwnedStoreItems then
			local Findif = OwnedStoreItems:FindFirstChild(Gear.Name)
			if Findif then
			else
				local newitem = Instance.new("Folder",OwnedStoreItems)
                newitem.Name = Gear.Name				
			end
		end
	end
end
end
game.ReplicatedStorage.AddGearFromStore.OnServerEvent:connect(onwin)

So, if this is a client sided script then how do i make it server sided? Thanks :+1:

I’m not an expert on this, but I think rather than checking HasBought and Cash on the client, fire a RemoteEvent to check it on the server.

hacker can get easily money with the remote game.ReplicatedStorage.SubCash:FireServer(Cost.Value)
because they can do
game.ReplicatedStorage.SubCash:FireServer(-500000000)

To put it frank, I’d store all the items and their prices on the server, something similar to

local Purchaseables = {
    ["Item1"] = 100,
    ["Item2"] = 500,
    ["Item3"] = 1000,
}

local function onPurchase(Player, Item)
    local Stats = Player and Player:FindFirstChild("Stats")
    local Currency = Stats:FindFirstChild("Currency")
    if Currency and Purchaseables[Item] and Currency.Value >= Purchaseables[Item] then
        Currency.Value = Currency.Value - Purchaseables[Item]
        -- Reward Item or whatever
        return {Success = true}
    end
    return {Success = false}
end

game.ReplicatedStorage.RemoteFunction.OnServerInvoke = onPurchase

You can update HasBought and what not on the server and also manage a way to check it there.

1 Like

Ok, so i must delete both scripts and replace this one?
and the other thing, what does return means?

Well, i just wanted to know how to change this to a server sided script, not revamp the code…
Such as what remote events i should add, or anything else about.

Which part i should edit? What i should remove and add?

I would use @vNotSiren’s solution, as it’s basically what I was talking about and I don’t want to re-post. Their method is very good, imo.

I should delete all the shop scripts and that stuff, i already asked him and he didn’t respond me.
@vNotSiren

You don’t necessarily have to delete all of the scripts, just replace the checking values on the LocalScript with getting information from the server, and you may need to write a server script like the one by @vNotSiren to handle the remotes.

Ok, i think i understood this time, i will try use this code and see if it works.

But my question is “return” in the code is only used in ModuleScripts? i must put a Script or a ModuleScript?

Return works for any function. The documentation for functions can be found here.

It has all of the info you need about functions, and returning data.

1 Like

I just forgot one script to share!

function onwin(player,Value)
local leaderstats = player:FindFirstChild("leaderstats")
	if leaderstats then
		local Cash = leaderstats:FindFirstChild("Cash")
		if Cash then
			Cash.Value = Cash.Value - Value
		end
	end
end
game.ReplicatedStorage.SubCash.OnServerEvent:connect(onwin)

This is the subcash… Should i remove this one?