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
I think I figured this out. Writing the code right now.
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.
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.
Make an admin list: Example: local admins = {} (...).MouseButton1Click:Connect(function() for _,v in pairs(admins) do if (plr).Name == v then --code end end)