
KeylessUniversal

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local StarterGui = game:GetService("StarterGui")
local localPlayer = Players.LocalPlayer
local CONFIG = { -- configurations
FOLLOW_DISTANCE = 1.2, -- how close do you want to be to the protected user
STOP_DISTANCE = 0.45, -- which studs do you want to stop backing up to the protected user's back
MAX_SPEED = 130, -- how fast do you want to follow to the protected user
ACCELERATION = 30, -- speed-up
AUTO_INTERVAL = 20 * 60, -- adjustions
RATE_LIMIT = 1.2, -- limits ig
}
local targetPlayer = nil
local connection = nil
local lastCommandTime = {}
local lastMessageTime = 0
local function serverChat(message)
if not localPlayer.Character then return end
local success = pcall(function()
local chatEvents = ReplicatedStorage:FindFirstChild("DefaultChatSystemChatEvents")
if chatEvents then
local sayRequest = chatEvents:FindFirstChild("SayMessageRequest")
if sayRequest then
sayRequest:FireServer(message, "All")
return
end
end
end)
if success then return end
success = pcall(function()
local tcs = game:GetService("TextChatService")
if tcs.ChatVersion == Enum.ChatVersion.TextChatService then
local channel = tcs:FindFirstChild("TextChannels") and tcs.TextChannels:FindFirstChild("RBXGeneral")
if channel then
channel:SendAsync(message)
return
end
end
end)
if success then return end
pcall(function()
StarterGui:SetCore("ChatMakeSystemMessage", {
Text = "[Protector] " .. message,
Color = Color3.fromRGB(0, 255, 100),
Font = Enum.Font.SourceSansBold
})
end)
end
local function findPlayer(query)
if not query or #query < 1 then return nil end
query = query:lower():gsub("%s+", "")
local best, bestScore = nil, -1
for _, plr in ipairs(Players:GetPlayers()) do
if plr == localPlayer then continue end
local uname = plr.Name:lower()
local dname = plr.DisplayName:lower()
local score = 0
if uname == query or dname == query then return plr end
if uname:find(query, 1, true) then score = 88
elseif dname:find(query, 1, true) then score = 78 end
if uname:sub(1, #query) == query then score += 25
elseif dname:sub(1, #query) == query then score += 20 end
if score > bestScore then
bestScore = score
best = plr
end
end
return best
end
local function stopFollowing()
targetPlayer = nil
if connection then
connection:Disconnect()
connection = nil
end
local char = localPlayer.Character
if char then
local hum = char:FindFirstChild("Humanoid")
local root = char:FindFirstChild("HumanoidRootPart")
if hum then
hum.PlatformStand = false
hum.WalkSpeed = 16
end
if root then
root.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
end
end
end
local function startFollowing(target)
if not target or target == localPlayer then return end
targetPlayer = target
if connection then connection:Disconnect() end
connection = RunService.Heartbeat:Connect(function()
local myChar = localPlayer.Character
local tChar = targetPlayer.Character
if not myChar or not tChar then stopFollowing() return end
local myRoot = myChar:FindFirstChild("HumanoidRootPart")
local tRoot = tChar:FindFirstChild("HumanoidRootPart")
local myHum = myChar:FindFirstChild("Humanoid")
if not myRoot or not tRoot or not myHum then stopFollowing() return end
myHum.PlatformStand = false
myHum.WalkSpeed = 60
local behindPos = (tRoot.CFrame * CFrame.new(0, 0, CONFIG.FOLLOW_DISTANCE)).Position
local dist = (behindPos - myRoot.Position).Magnitude
if dist > CONFIG.STOP_DISTANCE then
local dir = (behindPos - myRoot.Position).Unit
local speed = math.min(dist * CONFIG.ACCELERATION, CONFIG.MAX_SPEED)
myRoot.AssemblyLinearVelocity = Vector3.new(dir.X * speed, myRoot.AssemblyLinearVelocity.Y, dir.Z * speed)
else
myRoot.AssemblyLinearVelocity = Vector3.new(0, myRoot.AssemblyLinearVelocity.Y, 0)
end
if dist > 8 then
myRoot.CFrame = CFrame.lookAt(myRoot.Position, tRoot.Position)
else
local desired = -tRoot.CFrame.LookVector
local current = myRoot.CFrame.LookVector
myRoot.CFrame = CFrame.lookAt(myRoot.Position, myRoot.Position + current:Lerp(desired, 0.25))
end
end)
end
local function canRunCommand(player, cmd)
local key = tostring(player.UserId) .. cmd
local now = tick()
if lastCommandTime[key] and now - lastCommandTime[key] < CONFIG.RATE_LIMIT then
return false
end
lastCommandTime[key] = now
return true
end
local function onPlayerChatted(player, message)
if not message or message:sub(1,1) ~= ";" then return end
if not canRunCommand(player, message) then return end
local args = {}
for word in message:gmatch("%S+") do table.insert(args, word) end
local cmd = args[1]:lower()
if cmd == ";protect" and args[2] then
local target = findPlayer(args[2])
if not target then
serverChat("Player not found: " .. args[2])
return
end
if targetPlayer and targetPlayer ~= player then
serverChat(targetPlayer.DisplayName .. " is currently protected. Only they can change it.")
return
end
if targetPlayer == target then
stopFollowing()
serverChat("Stopped protecting " .. target.DisplayName)
else
startFollowing(target)
serverChat("Now protecting " .. target.DisplayName .. " (" .. target.Name .. ")")
end
elseif cmd == ";unprotect" then
if targetPlayer == player then
stopFollowing()
serverChat("Stopped protecting you.")
else
serverChat("You are not being protected right now.")
end
end
end
local function setupListeners()
for _, plr in Players:GetPlayers() do
if plr ~= localPlayer then
plr.Chatted:Connect(function(msg) onPlayerChatted(plr, msg) end)
end
end
Players.PlayerAdded:Connect(function(plr)
if plr ~= localPlayer then
plr.Chatted:Connect(function(msg) onPlayerChatted(plr, msg) end)
end
end)
end
local function autoMessageLoop()
while true do
task.wait(1)
if tick() - lastMessageTime >= CONFIG.AUTO_INTERVAL then
serverChat("20 minutes passed! Use ;protect [name] to get protected. Protected players: say ;unprotect when done.")
lastMessageTime = tick()
end
end
end
local function onCharacterAdded(char)
task.wait(1)
if targetPlayer then
startFollowing(targetPlayer)
end
end
local function init()
if localPlayer.Character then
onCharacterAdded(localPlayer.Character)
end
localPlayer.CharacterAdded:Connect(onCharacterAdded)
setupListeners()
spawn(autoMessageLoop)
serverChat("Ultimate Protector Script Loaded!")
serverChat("Commands: ;protect [name] | ;unprotect")
end
Players.PlayerRemoving:Connect(function(plr)
if plr == targetPlayer then
stopFollowing()
serverChat("Target left. Protection stopped.")
end
end)
UserInputService.InputBegan:Connect(function(inp, gp)
if gp then return end
if inp.KeyCode == Enum.KeyCode.F then -- STOP PROTECTING MANUALLY!
stopFollowing()
serverChat("Manual stop (F key)")
end
end)
init()No comments yet for this script.



