Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I make sure that my code is protected from exploiters?

Asked by 3 years ago
Edited 3 years ago

I am creating a speed run game that starts a timer on the player's screen once they touch a starting brick. The timer is saved as a stat in their leaderboard and if it is better than their fastest time, it will replace their fastest time with the timer. I have this script inside of a local script inside the player's GUI and I am using remote events to trigger the timer. I'm pretty new to scripting and I don't know the best ways of combatting exploiters. Is it fine that I coded it the way I did?

Local Script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local remoteEvent = ReplicatedStorage:WaitForChild("ShowTime")
local Clear = ReplicatedStorage:WaitForChild("ClearTimeran")
local Replace = ReplicatedStorage:WaitForChild("Replace")


local SpeedBrick = workspace.RunBlock
local EndBrick = workspace.EndBlock

local go = true
local db = false
SpeedBrick.Touched:Connect(function(hit)
    local startplayer = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
    if startplayer ~= nil and startplayer ==  game:GetService("Players").LocalPlayer then
        if db == false then
            db = true
            Clear:FireServer()
            repeat
                wait(0.1)
                remoteEvent:FireServer()

                ---SHOWING ON GUI---
                local player = script.Parent.Parent.Parent.Parent.Parent 

                local leaderstats = player:WaitForChild("leaderstats")
                local stat = leaderstats:WaitForChild("runningtime") 
                local besttime = leaderstats:WaitForChild("time1")

                script.Parent.Text = stat.Value

                stat.Changed:Connect(function()
                    script.Parent.Text = stat.Value 
                end)
                if stat.Value < besttime.Value then
                    local ColorNew = Color3.new(0.333333, 1, 0) --GREEN
                    script.Parent.TextColor3 = ColorNew
                end
                if stat.Value > besttime.Value and besttime.Value ~= 0 then
                    local ColorNew = Color3.new(1, 0, 0) --RED
                    script.Parent.TextColor3 = ColorNew
                end
                -------------------

                EndBrick.Touched:Connect(function(hit)
                    local endplayer = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
                    if endplayer ~= nil and endplayer ==  game:GetService("Players").LocalPlayer then
                        go = false
                    end
                end)
            until go == false
        end
        wait(0.5)
        db = true
    end
    --Clearing timeran and replacing leveltime
    if go == false then
        local player = script.Parent.Parent.Parent.Parent.Parent
        local leaderstats = player:WaitForChild("leaderstats")
        local stat = leaderstats:WaitForChild("runningtime")
        local leveltime = leaderstats:WaitForChild("time1")
        if stat.Value < leveltime.Value then
            Replace:FireServer(leveltime,stat)
            script.Parent.Parent.BestTimeValue.Text = stat.Value
        elseif leveltime.Value == 0 then
            Replace:FireServer(leveltime,stat)
            script.Parent.Parent.BestTimeValue.Text = stat.Value
        end
    end
end)

Server Script:

local remote = game:GetService("ReplicatedStorage")
local remoteEvent = remote:WaitForChild("ShowTime")

remoteEvent.OnServerEvent:Connect(function(player)  
    player.leaderstats.runningtime.Value = player.leaderstats.runningtime.Value + 0.1
end)

I know that putting sensitive information in local scripts is never the best option but is the way I coded it still safe from exploiters being able to tamper with their run timer?

Also, the game will give better rewards the faster they complete the speed run

Any help would be appreciated!

0
Pro tip, in your SS line 5, you can use the operator "+=" which is a shorthand for "variable = variable + value" so you can just write "player.leaderstats.runningtime.Value += 0.1" instead of having to write out the entire path twice BrimoireGrimoire 11 — 3y

1 answer

Log in to vote
0
Answered by 3 years ago

Try moving the calculations to the server side. Or exploiters can just fire it and get 10 Value a second.

You may have to change some things around. I didnt have time to fully read over the script

Local Script

SpeedBrick.Touched:Connect(function()
    remoteEvent:FireServer()
end)

Server Script

remoteEvent.OnServerEvent:Connect(function()
    local startplayer = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
    if startplayer ~= nil and startplayer ==  game:GetService("Players").LocalPlayer then
        if db == false then
            db = true
            Clear:FireServer()
            repeat
                wait(0.1)
                remoteEvent:FireServer()

                ---SHOWING ON GUI---
                local player = script.Parent.Parent.Parent.Parent.Parent 

                local leaderstats = player:WaitForChild("leaderstats")
                local stat = leaderstats:WaitForChild("runningtime") 
                local besttime = leaderstats:WaitForChild("time1")

                script.Parent.Text = stat.Value

                stat.Changed:Connect(function()
                    script.Parent.Text = stat.Value 
                end)
                if stat.Value < besttime.Value then
                    local ColorNew = Color3.new(0.333333, 1, 0) --GREEN
                    script.Parent.TextColor3 = ColorNew
                end
                if stat.Value > besttime.Value and besttime.Value ~= 0 then
                    local ColorNew = Color3.new(1, 0, 0) --RED
                    script.Parent.TextColor3 = ColorNew
                end
                -------------------

                EndBrick.Touched:Connect(function(hit)
                    local endplayer = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
                    if endplayer ~= nil and endplayer ==  game:GetService("Players").LocalPlayer then
                        go = false
                    end
                end)
            until go == false
        end
        wait(0.5)
        db = true
    end
    --Clearing timeran and replacing leveltime
    if go == false then
        local player = script.Parent.Parent.Parent.Parent.Parent
        local leaderstats = player:WaitForChild("leaderstats")
        local stat = leaderstats:WaitForChild("runningtime")
        local leveltime = leaderstats:WaitForChild("time1")
        if stat.Value < leveltime.Value then
            player.leaderstats.runningtime.Value = player.leaderstats.runningtime.Value + 0.1
            script.Parent.Parent.BestTimeValue.Text = stat.Value
        elseif leveltime.Value == 0 then
            player.leaderstats.runningtime.Value = player.leaderstats.runningtime.Value + 0.1
            script.Parent.Parent.BestTimeValue.Text = stat.Value
        end
end)
0
Please accept this if it works deadwalker601 110 — 3y
0
Well would that not really be an issue since the values they are adding would just be to their time? It wouldn't benefit them. One thing I should've explained that I will make an edit for is that the game will give greater rewards the faster their time is. xboxking2000 2 — 3y
Ad

Answer this question