Exploiters and how they spoof stuff in your own game

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Wait()
	while wait() do
		local char = plr.Character or plr.CharacterAdded:Wait()
		local Pos1 = char.UpperTorso.Position
		wait(1)
		local Pos2 = char.UpperTorso.Position
		local Distance = (Pos2 - Pos1).magnitude
		print(Distance)
		if Distance > 19 then
			plr:Kick("Sussy speed pls stop hacking")
		end
	end
end)

I suggest you don’t actually kick people

It kicked me even though I wasn’t exploiting. You should replace the kick with

local HRP = char.HumanoidRootPart
HRP.CFrame = CFrame.new(Pos1) * CFrame.Angles(HRP.CFrame:ToOrientation())
--You can remove " * CFrame.Angles(HRP.CFrame:ToOrientation())",
--It's more of a cosmetic thing
1 Like

I notice that falling out of map kick players

1 Like

Can be spoofed in 2 seconds, using metatables… don’t use this please

I don’t think you should do

I would suggest checking if the distance is over the ServerSided WalkSpeed Value +3, That way, if you have a game mechanic that sets the speed to over 19 normal users would not get falsely detected! Example:

if Distance > character.Humanoid.WalkSpeed + 3 then
 --- punishment here
end
1 Like

I’m pretty sure with the current power of metatables, you could spoof humanoid.Running too, I have 0 knowledge on metatables but I’d like to see someone do this

Yes is it is true; you can spoof Humanoid.Running

Yes, but I wanna know how

Humanoid.Running gives the client walkspeed - a simple metatable can fake it.

I’m not experienced in metatables at all, so I want the script of it

What script? the metatable script?

Yes, the metatables script

Since the Humanoid.Running gets the client speed its this code:

local mt = getrawmetatable(game)
local oldindex = mt.__index
setreadonly(mt,false)

mt.__index = function(indexed,property)
	if indexed == "Humanoid" and property == "WalkSpeed" then 
		return 16 -- or whatever speed value
	end
	return oldindex(indexed,property)
end

setreadonly(mt,true)
1 Like

oh I’m an idiot, I could’ve just straight copied the sample code from the tutorial.

Lol, true. It’s on the top by the original author.

1 Like

Can Exploiters change attributes?

anything you can do an exploiter can do plus alot more

You need to learn more about how to use module correctly

Wrong:

function self:SafeKickClient(Message)
	local Success, Error = pcall(function() game:GetService("Players").LocalPlayer:Kick(Message) end)
	local StatsService = game:GetService("Stats")
	
	RunService.RenderStepped:Wait()
	
	if not Success or StatsService.DataSendKbps ~= 0 then
		repeat until true ~= true
	end
end

Lead function located named self? Huh.
Also useless using RenderStepped as wait/sleep

Correct & Better:

local Module = {}
Module.__index = Module
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Storage

if RunService:IsServer() then
if not Storage or not script:FindFirstChild("Folder") then
Storage = Instance.new("Folder", script)
else
Storage = script:WaitForChild("Folder", 15)
end
else
Storage = script:WaitForChild("Folder", 15)
end


function Module.init()
return setmetatable({}, Module)
end

function Module:findObject(name: string, withInstance: boolean)
-- prevent error by exploited
assert(typeof(name) == "string", "Invalid type of player name.")

if Storage and Storage:IsA("Folder") and Storage:FindFirstChild(name) then
if withInstance then
return {true, Storage:WaitForChild(name)}
end
return true
end
if withInstance then
return {false, nil}
end
return false
end

-- decated function only for server
If RunService:IsServer() then
function Module:Add(playerName: string)
-- prevent error by exploited
assert(typeof(playerName) == "string", "Invalid type of player name.")
assert(playerName:len() > 0, "Invalid minimum player name length")

if not self:findObject(playerName) then
Instance.new("IntValue", Storage).Name = playerName
return self:findObject(playerName)
end
return false
end)

function Module:Remove(playerName: string)
-- prevent error by exploited
assert(typeof(playerName) == "string", "Invalid type of player name.")
assert(playerName:len() > 0, "Invalid minimum player name length")

local GetObject = self:findObject(playerName, true)
if GetObject and GetObject[1] == true then
GetObject[2]:Destroy()
return true
end
return false
end)

end

function Module:SafeKickClient(playerName: string, Message: string)
-- prevent error by exploited
assert(typeof(playerName) == "string", "Invalid type of player name.")
assert(typeof(Message) == "string", "Invalid type of message or message is required.")
if RunService:IsClient() and Players.LocalPlayer then
assert(Players.LocalPlayer.Name == playerName, "Are you trying to using other person name?.")
return
end

local GetObject = self:findObject(playerName, true)
if GetObject and GetObject[1] == true then
if Players:FindFirstChild(playerName) then
	local Success, Error = pcall(function()
Players:WaitForChild(playerName):Kick(Message) end)

	if not Success then
warn(Error)
	end
GetObject[2]:Destroy()
end
end
end

-- for client only
if RunService:IsClient() then

local _lastchecked = tick()
RunService.Hearbeat:Connect()
if (tick() - _lastchecked) >= 1/60 then
if Players.LocalPlayer and self:findObject(Players.LocalPlayer.Name) and Players.LocalPlayer.Character and Players.LocalPlayer.Character:FindFirstChild("Humanoid") and Players.LocalPlayer.Character:FindFirstChild("Humanoid").WalkSpeed > 16 then
-- Players.LocalPlayer.Character:WaitForChild("Humanoid").WalkSpeed = 16
self:SafeKickClient(Players.LocalPlayer.Name, string.format("Caught change default walksped [%s]", Players.LocalPlayer.Character:WaitForChild("Humanoid").WalkSpeed))
end
_lastchecked = tick()
end
end)

repeat task.wait() until Players.LocalPlayer and Storage and self:findObject(Players.LocalPlayer.Name) == true

local GetObject = self:findObject(Players.LocalPlayer.Name, true)
Storage.ChildRemoved:Connect(function(child)
if child and child:IsA("IntValue") and child.Name == Players.LocalPlayer.Name then
Instance.new("IntValue", Storage).Name = Players.LocalPlayer.Name
end
end)

end

return Module

Sorry if there any wrong or typo and not formated i was coded it on phone

Important Note: this may able to be bypassed, have bug/glitch and need to be improved

:wave: Ah, this might be worth more if it was said two years ago when I made this post.


I’ve both forgotten this resource page and what I have said, so you may be correct or incorrect; However I do want to iterate this :-

Please, don’t waste your time trying to solidify your “Client” AntiCheat it is simply put; A waste of both resource and developer time being invested into solidifying the client.

It’s better if you set your sights on the server and how to combat exploits in your own game! :smile:

Exploiters can manipulate attributes but they’re still constricted to the rules of FilteringEnabled. Attributes changed on the client will not replicate to the server unless you have some sort of vulnerability in your game architecture that allows exploiters to make sever-sided requests to manipulate attributes through an unprotected remote.

Not sure if this was directed towards @AsynchronousMatrix or OP, but regardless there is very little benefits to trying to detect/prevent exploiters from exploiting in your experiences. Server validation is the only reliable way to minimize the effects of exploiting as a whole.