Skip to content

Instantly share code, notes, and snippets.

@Cuyler36
Last active October 31, 2018 09:53
Show Gist options
  • Save Cuyler36/7c6b77073e06881357fce713af76d1d3 to your computer and use it in GitHub Desktop.
Save Cuyler36/7c6b77073e06881357fce713af76d1d3 to your computer and use it in GitHub Desktop.
local Players = game:GetService("Players");
local MaximumMovementDistance = 50; -- How many studs a Player can move in one server game tick.
local TeleportDistanceThreshold = 2; -- How many studs away from the estimated teleport position the player needs to be.
local InfractionsBeforeBan = 2; -- How many times a Player needs to be caught before a ban will occur. This helps prevent possible false bans.
local BannedPlayers = {};
local InfractionTable = {};
local LastPositionsTable = {};
Players.PlayerAdded:Connect(function(player)
if (BannedPlayers[player.UserId] == true) then
player:Kick();
return;
end
player.CharacterAdded:Connect(function(character)
local enabled = true;
local rootPart = character:WaitForChild("HumanoidRootPart");
LastPositionsTable[player] = rootPart.Position; -- Set this every time the character is added to avoid false flagging issues.
character:WaitForChild("Humanoid").Died:Connect(function()
enabled = false; -- Disable on death so flying body parts don't cause a false trigger.
end);
rootPart:GetPropertyChangedSignal("CFrame"):Connect(function()
if (enabled) then
local cframe = rootPart.CFrame;
if (LastPositionsTable[player] == nil) then
LastPositionsTable[player] = cframe.Position;
end
if ((LastPositionsTable[player] - cframe.Position).Magnitude >= MaximumMovementDistance) then
warn(string.format("Player [%s] moved more than the threshold distance of %d in one server game tick! Checking for exploiters.", tostring(player), MaximumMovementDistance));
for _, otherPlayer in ipairs(Players:GetPlayers()) do
if (otherPlayer ~= player and otherPlayer.Character ~= nil) then
local otherRootPart = otherPlayer.Character:WaitForChild("HumanoidRootPart");
local exploitedCFrame = otherRootPart.CFrame + otherRootPart.CFrame.LookVector;
if ((exploitedCFrame.Position - cframe.Position).Magnitude <= TeleportDistanceThreshold) then
InfractionTable[otherPlayer] = InfractionTable[otherPlayer] and InfractionTable[otherPlayer] + 1 or 1;
warn(string.format("It appears player [%s] is exploiting and attempting to kill others! Current infractions: %d", tostring(otherPlayer), InfractionTable[otherPlayer]));
if (InfractionTable[otherPlayer] >= InfractionsBeforeBan) then
warn(string.format("Player [%s] has reached the infraction ban threshold and is now banned!", otherPlayer));
BannedPlayers[otherPlayer.UserId] = true;
otherPlayer:Kick(); -- I don't suggest adding a message here so they don't know why they were banned immediately.
end
end
end
end
end
LastPositionsTable[player] = cframe.Position; -- Update the position of the player in the position table for next frame.
end
end);
end);
end);
-- Clean up table entries to reduce memory usage.
Players.PlayerRemoving:Connect(function(player)
LastPositionsTable[player] = nil;
InfractionTable[player] = nil;
end);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment