Only left in the necessary code.

local SelectedItem
local SafeSelectedItem
			
A.MouseButton1Down:Connect(function() 
	SelectedItem = A.Name
	SafeSelectedItem = A  -- A is the clicked button.
	Buy.Text = string.upper("buy " .. A.Text)
	Buy.Visible = true
end)

Buy.MouseButton1Down:Connect(function()
	local Price = tonumber(script.Parent:FindFirstChild(SelectedItem):FindFirstChild("ActualPrice").Text)
	local SafePrice = script.Parent:FindFirstChild(SelectedItem):FindFirstChild("ActualPrice")
	if Player.leaderstats.Candy.Value >  Price then
		Event:FireServer(SafeSelectedItem, SafePrice)

Since exploiters can change what the event fires, couldn't they change the SafeSelectedItem to an item that costs more, and keep the price of the other item? Then the server script would have the wrong item.

I've attempted to make 'safe' variables, but I think they can still be exploited.

How could I make this safe?

SOLVED! Here's my solution. Can't be 100% sure it works, but I don't see any flaws.

local Players = game:GetService("Players")
local rs = game:GetService("ReplicatedStorage")
local Event = rs:WaitForChild("NametagEvent")
	
	
Event.OnServerEvent:Connect(function(plr, SafeSelectedItem, SafePrice)
	local SelectedItemName = SafeSelectedItem.Name
	local SelectedItemPrice = tonumber(SafeSelectedItem.ActualPrice.Text)
	local NewName
	if string.find(SelectedItemName, "1") then
		NewName = string.gsub(SelectedItemName, "1", "")
	elseif string.find(SelectedItemName, "2") then
		NewName = string.gsub(SelectedItemName, "2", "")
	elseif string.find(SelectedItemName, "3") then
		NewName = string.gsub(SelectedItemName, "3", "")
	else
	end
	if tonumber(SafePrice.Text) == SelectedItemPrice then
		if plr.leaderstats.Candy.Value >= SelectedItemPrice then
			if not string.find(tostring(plr.Playerstats.OwnedNametags.Value), NewName) then
				plr.leaderstats.Candy.Value = plr.leaderstats.Candy.Value - SelectedItemPrice
				plr.Playerstats.OwnedNametags.Value = (plr.Playerstats.OwnedNametags.Value .. NewName)
			else
				print("Already owned")
			end
		end
	else
		plr:Kick()
	end
end)

Basically, this compares the price received by the event to the actual price of the item. If it's the same, then good, if not, the player gets kicked.

4 comments

0

I think I figured this out. Writing the code right now.

0

i'd suggest something that keeps the value constantly the same like a look or along side the event firing so it gives the exploiter a very small time frame to use the script they injected.

0

It doesn't matter what the value is. The thing that matters is what the event fired, and that's the thing the player can change. So even if the value was "A", the exploiter could send it to the server as "B" or anything else.

0

Make an admin list: Example: local admins = {} (...).MouseButton1Click:Connect(function() for _,v in pairs(admins) do if (plr).Name == v then --code end end)