Where should I place this?
local MaxSpeed = 16 -- Max speed possible in game
-- Note: I've added a rule-counter, which means you have to go too fast for 2 ticks to get punished.
-- That's necessary for teleporting by spawning, maybe your admins tp'ing, entering a vehicle, ...
local caught = {}
local function punish(plr)
if caught[plr] then
-- More than 2x too fast in a second? Seems like he needs to get punished
-- (As far as I know, it's impossible to teleport 2x in a second without exploiting)
-- (Assuming that people don't use admincommands teleport/ very fast)
-- (Also assuming that the game doesn't teleport someone 2x in a second)
if tick() - caught[plr] < 1 then
-- Should never fail, as we don't check RobloxLocked players
-- Even if it fails, punish() is called in a pcall() so it's safe anyway
plr:Kick()
print(plr,"kicked for speed hacking") -- Print in Server Console
end
end caught[plr] = tick()
end
-- We don't want to flood the caught table with offline exploiters who were here, don't we?
game:GetService("Players").PlayerRemoving:connect(function(p)
caught[p] = nil -- remove old unneeded data
end)
local function ignoreState(state)
if state == Enum.HumanoidStateType.Running then
return false
elseif state == Enum.HumanoidStateType.RunningNoPhysics then
return false
elseif state == Enum.HumanoidStateType.StrafingNoPhysics then
return false
elseif state == Enum.HumanoidStateType.Climbing then
return false
elseif state == Enum.HumanoidStateType.RunningNoPhysics then
return false
end return true
end
while true do
--[[ Saving the current position (position just before the tick change) ]]--
local pos = {}
for k,v in pairs(game:GetService("Players"):GetPlayers()) do
if v.Character and v.Character:findFirstChild("Torso") then
-- Renamed/Absent Humanoid? Oh well, can't predict that
if not v.Character:findFirstChild("Humanoid") then return end
local human = v.Character.Humanoid -- need to use it a lot
-- Torso can be flinged away on dead, making false results
if human.Health == 0 then return end
-- If he sits, we assume he's in a vehicle, thuss may go faster
if human.Sit then return end
-- If he's platformstanding, we assume he's skating or so
if human.PlatformStand then return end
-- only check if the player is actually running
if ignoreState(human:GetState()) then return end
-- Save current position, for comparing during the next loop
pos[v] = v.Character.Torso.Position
end
end
--[[ Max Distance Calculation ]]--
local tim = wait() -- Get how long the last tick happened
local dis = (MaxSpeed + 2) * tim -- Get the max distance someone can move in that time interval
-- (MaxSpeed + 2): 2 being a safe margin. (Weird calculation? Jumping while running?)
for k,v in pairs(pos) do -- Time to see if he went too fast
pcall(function()
if v.Character and v.Character:findFirstChild("Torso") then
if not v.Character:findFirstChild("Humanoid") then return end
local human = v.Character.Humanoid
if human.Health == 0 then return end
if human.PlatformStand then return end
if human.Sit then return end
if ignoreState(human:GetState()) then return end
-- Yeuy! Get the distance calculated!
local d = (pos[v] - v.Character.Torso.Position).magnitude
if d > dis then pcall(punish,v) end
end
end)
end
wait(0.1) -- Just to make this a bit more performance-friendly
-- (Not that it's very unfriendly, though, unless there are 100 players)
end
