Hello. I have made a server sided Anti-Cheat script.
This script blocks:
MultiTooling,
FE-GodMode(Humanoid Deletion),
Inappropriate animation(A balloon animation which exploiters can use in a NSFW context),
Paranoid(Deleting humanoid root part joint. Stops FE invisibility and other exploits),
StrafingNoPhysics(Stops some noclipping exploits, exploiters can still use other methods to noclip),
InvalidMeshDeletion(Stops deletion of hat meshes NOT IMPLEMENTED YET)
So the anti-cheat basically functions as Filtering Enabled but fixes some stuff FE does not.
So basically how could I improve the Anti-Cheat script?
Are there any specific improvements I could make to this script?
Are there any bugs in it?
Any general improvements?
And what else should I add to my script and what other exploits should I patch?
Also, would you use this script on your game?
Would you use this script in your game?
Yes
No (Respond with a reason)
0voters
local Players = game:GetService("Players")
local function ProtectHat(Hat)
local Handle = Hat:WaitForChild("Handle", 20)
if Handle:IsA("Part") and Handle:FindFirstChildOfClass("SpecialMesh") then
-- // UNFINHISHED
end
end
local function KillHumanoid(Humanoid)
if Humanoid then
Humanoid.Health = 0
Humanoid:ChangeState(Enum.HumanoidStateType.Dead)
if Humanoid.BreakJointsOnDeath then
Humanoid:BreakJoints()
end
end
end
Players.PlayerAdded:Connect(function(Plr)
Plr.CharacterAdded:Connect(function(Character)
for _, v in ipairs(Character:GetChildren()) do
if v:IsA("Accoutrement") then
coroutine.wrap(ProtectHat)(v)
end
end
Character.ChildAdded:Connect(function(Child)
if Child:IsA("Accoutrement") then
ProtectHat(Child)
elseif Child:IsA("BackpackItem") then
local Count = 0
task.wait()
for _, v in ipairs(Character:GetChildren()) do
if v:IsA("Tool") then
Count += 1
if Count > 1 then
v.Parent = Plr:FindFirstChildOfClass("Backpack") or Instance.new("Backpack", Plr)
end
end
end
end
end)
local Humanoid = Character:FindFirstChildOfClass("Humanoid") or Character:WaitForChild("Humanoid")
Humanoid.AncestryChanged:Connect(function(Child, Parent)
if Child == Humanoid and Character and (not Parent or not Character:IsAncestorOf(Humanoid)) then
Humanoid.Parent = Character
end
end)
Humanoid.StateChanged:Connect(function(Last, State)
if Last == Enum.HumanoidStateType.Dead and State ~= Enum.HumanoidStateType.Dead then
KillHumanoid(Humanoid)
elseif State == Enum.HumanoidStateType.StrafingNoPhysics then
KillHumanoid(Humanoid)
end
end)
local Animator = Humanoid:WaitForChild("Animator")
Animator.AnimationPlayed:Connect(function(Track)
local AnimationId = Track.Animation.AnimationId
if AnimationId == "rbxassetid://148840371" or string.match(AnimationId, "[%d%l]+://[/%w%p%?=%-_%$&'%*%+%%]*148840371/*") then
KillHumanoid(Humanoid)
end
end)
local RootJoint = Humanoid.RigType == Enum.HumanoidRigType.R15 and Character:WaitForChild("LowerTorso"):WaitForChild("Root") or Humanoid.RigType == Enum.HumanoidRigType.R6 and Character:WaitForChild("HumanoidRootPart"):WaitForChild("RootJoint")
local Connection
Connection = RootJoint.AncestryChanged:Connect(function(_, Parent)
if not Connection.Connected or Parent then
return
end
Connection:Disconnect()
if Humanoid then
KillHumanoid(Humanoid)
end
end)
end)
end)
For animations the players could use the deprecated version of animations, Humanoid:LoadAnimation(). I am unsure if this fires the Animator event. There is a similar event for the humanoid, as well. Maybe add that to prevent animations the deprecated way.
I’m not too good with anti-cheat by any means but what sussy said is true if your anti-cheat here is on the client only then it doesn’t matter at all unless it’s a noob exploiter, That being said I’ve seen people do server checks and back and fourth somehow to check when scripts are removed etc so that’s a good idea if you can figure out how.
Well sure. However the version I uploaded is broken.
Here is a newer version which works:
local Players = game:GetService("Players")
-- // If your game has admin commands which require noclipping, set this to false.
local preventStrafingNoPhysics = true
-- // Do not touch the code below unless you known what you are doing!
local function protectHat(hat)
local handle = hat:WaitForChild("Handle", 30)
if handle then
task.defer(function()
local joint = handle:WaitForChild("AccessoryWeld")
local connection
connection = joint.AncestryChanged:Connect(function(_, parent)
if not connection.Connected or parent then
return
end
connection:Disconnect()
if handle and handle:CanSetNetworkOwnership() then
handle:SetNetworkOwner(nil)
end
end)
end)
if handle:IsA("Part") then
local mesh = handle:FindFirstChildOfClass("SpecialMesh") or handle:WaitForChild("Mesh")
mesh.AncestryChanged:Connect(function(child, parent)
task.defer(function()
if child == mesh and handle and (not parent or not handle:IsAncestorOf(mesh)) then
mesh.Parent = handle
end
end)
end)
end
end
end
local function killHumanoid(humanoid)
if humanoid then
humanoid:ChangeState(Enum.HumanoidStateType.Dead)
humanoid.Health = 0
end
end
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
for _, v in ipairs(character:GetChildren()) do
if v:IsA("Accoutrement") then
coroutine.wrap(protectHat)(v)
end
end
character.ChildAdded:Connect(function(child)
if child:IsA("Accoutrement") then
protectHat(child)
elseif child:IsA("BackpackItem") then
local count = 0
task.defer(function()
for _, v in ipairs(character:GetChildren()) do
if v:IsA("Tool") then
count += 1
if count > 1 then
v.Parent = player:FindFirstChildOfClass("Backpack") or Instance.new("Backpack", player)
end
end
end
end)
end
end)
local humanoid = character:FindFirstChildOfClass("Humanoid") or character:WaitForChild("Humanoid")
humanoid.AncestryChanged:Connect(function(child, parent)
task.defer(function()
if child == humanoid and character and (not parent or not character:IsAncestorOf(humanoid)) then
humanoid.Parent = character
end
end)
end)
humanoid.StateChanged:Connect(function(last, state)
if last == Enum.HumanoidStateType.Dead and state ~= Enum.HumanoidStateType.Dead then
killHumanoid(humanoid)
elseif preventStrafingNoPhysics and state == Enum.HumanoidStateType.StrafingNoPhysics then
killHumanoid(humanoid)
end
end)
do
local connection
connection = humanoid.Died:Connect(function()
if not connection.Connected then
return
end
connection:Disconnect()
task.wait(Players.RespawnTime + 1.5)
if workspace:IsAncestorOf(humanoid) then
player:LoadCharacter()
end
end)
end
local animator = humanoid:WaitForChild("Animator")
animator.AnimationPlayed:Connect(function(animationTrack)
local animationId = animationTrack.Animation.AnimationId
if animationId == "rbxassetid://148840371" or string.match(animationId, "[%d%l]+://[/%w%p%?=%-_%$&'%*%+%%]*148840371/*") then
killHumanoid(humanoid)
end
end)
local connections = {}
local function makeConnection(Conn)
local connection
connection = Conn:Connect(function(_, parent)
if not connection.Connected or parent then
return
end
for _, v in ipairs(connections) do
v:Disconnect()
end
if humanoid then
killHumanoid(humanoid)
end
end)
table.insert(connections, connection)
end
local rootJoint = humanoid.RigType == Enum.HumanoidRigType.R15 and character:WaitForChild("LowerTorso"):WaitForChild("Root") or humanoid.RigType == Enum.HumanoidRigType.R6 and character:WaitForChild("HumanoidRootPart"):WaitForChild("RootJoint")
makeConnection(rootJoint.AncestryChanged)
if humanoid.RigType == Enum.HumanoidRigType.R15 then
makeConnection(character:WaitForChild("UpperTorso"):WaitForChild("Waist").AncestryChanged)
end
end)
end)
Anyways I will probably upload this to #resources as many people would like to use it.