I am making an anti teleport script. The goal is for each second, it will count each player with a character location, then it will store each player in a table list and compare it to their last location, if the vector value of x and z have changed a lot, it will recognize this as them being suspicious then it will run the scannearbyplayers function and check if there is an admin nearby (this way it can see if an admin just teleported them etc.)
I’ve scripted some of this, but I am not very experienced with tables so I’m not sure how to do the rest. If anyone is and can help out, so that I can read and learn from them I would appreciate it!
local Players = game:GetService("Players")
local StaffRankNum = 249
local list = {}
local function ScanNearbyPlayers(targPlayer)
for _,player in pairs(Players:GetPlayers()) do
if player.Character and player.Character.PrimaryPart then
local distance = player:DistanceFromCharacter(targPlayer.Character)
if distance <= 100 then
if player:GetRankInGroup(4525406) >= StaffRankNum then --near staff
return
else
targPlayer.Character.Health = 0 -- not near staff and teleporting
end
end
end
end
end
while true do
wait(1)
for _,player in pairs(Players:GetPlayers()) do
wait(.5)
end
end
Also, I forgot to mention. I know that scanning each second on the server could take up space, so I decided that I would also have a small .5 second wait between each player scan so that it isn’t taking up too much processing speed.
Use Magnitude checks to see the distance from their previous position.
Fixed code:
--//Services
local Players = game:GetService("Players")
--//Controls
local StaffRankNum = 249
--//Functions
local function IsStaffNear(playerPosition)
for i, player in ipairs(Players:GetPlayers()) do
if player:GetRankInGroup(4525406) < StaffRankNum then
continue
end
local character = player.Character
local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then
continue
end
local distance = (playerPosition - humanoidRootPart.Position).Magnitude
if distance <= 100 then
return true
end
end
return
end
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local previousPosition = humanoidRootPart.Position
while task.wait(1) and character:IsDescendantOf(workspace) do
local playerPosition = humanoidRootPart.Position
local distance = (playerPosition - previousPosition.Position).Magnitude
if distance >= 50 and IsStaffNear(playerPosition) then
--//I would personally use :LoadCharacter instead
pcall(player.LoadCharacter, player)
end
end
end)
end)
It would perform pretty similarly because even though I’m creating more loops, it’s only checking 1 character, contrary to just 1 loop, that checks every player ingame.
You can rewrite the code if you want to but another benefit of having separate loops is that it won’t have to yield for all the Magnitude checks of other players to end before starting the loop again.
example of how you could store each player’s position in a table and compare it to their last position (sorry for poor code written)
local StaffRankNum = 249
local list = {}
local function ScanNearbyPlayers(targPlayer)
for _,player in pairs(Players:GetPlayers()) do
if player.Character and player.Character.PrimaryPart then
local distance = (player.Character.PrimaryPart.Position - targPlayer.Character.PrimaryPart.Position).magnitude
if distance <= 100 then
if player:GetRankInGroup(4525406) >= StaffRankNum then --near staff
return
else
targPlayer.Character.Humanoid.Health = 0 -- not near staff and teleporting
end
end
end
end
end
while true do
wait(1)
for _,player in pairs(Players:GetPlayers()) do
if player.Character and player.Character.PrimaryPart then
local currentPosition = player.Character.PrimaryPart.Position
local lastPosition = list[player]
if lastPosition then
local distance = (currentPosition - lastPosition).magnitude
if distance > 100 then -- Change this value to adjust the threshold for what is considered "teleporting"
ScanNearbyPlayers(player)
end
end
list[player] = currentPosition -- Store the current position for the next check
end
end
end