It took me a long time to get somewhere, and I think I was able to create a LocalScript protection so that it could not be deleted/transferred.
Game(Roblox Studio file): Test.rbxl (35.3 KB)
Server script
local SecureScript = script.Parent.LocalScript
local Listok = {} -- List (true - test passed, false - failed)
local ListClone = {} -- List with SecureScript (LocalScript)
local ListPlr = {} -- List with players
local Listdied = {} -- List (true - player dead, false - player not dead)
local playerload = false
local event = game.ReplicatedStorage.RemoteEvent
local HttpS = game:GetService("HttpService")
game.Players.PlayerAdded:Connect(function(Plr)
--Avoiding false kick when a player is dead
task.spawn(function()
Plr.CharacterAdded:Wait()
Plr.Character:WaitForChild("Humanoid")
Plr.Character.Humanoid.Died:Connect(function()
Listdied[table.find(ListPlr,Plr)] = true
task.wait(2)
ListClone[table.find(ListPlr,Plr)].Parent = Plr
Plr.Character.Changed:Wait()
Plr.PlayerGui.ChildAdded:Wait()
ListClone[table.find(ListPlr,Plr)].Parent = Plr.PlayerGui.Script.f1
Listdied[table.find(ListPlr,Plr)] = false
end)
end)
--When a player enters, assign him a script
while not Plr.PlayerGui:FindFirstChild("Script") do
task.wait()
end
local FolderLoad = false
task.spawn(function()
for i = 1, 10 do
while not Plr.PlayerGui.Script:FindFirstChild(string.format("f%.f",i)) do
task.wait()
end
end
FolderLoad = true
end)
while not FolderLoad do
task.wait()
end
task.spawn(function()
if not playerload then playerload = true end
end)
local clone = SecureScript:Clone()
clone.Parent = Plr.PlayerGui.Script.f1
table.insert(ListPlr,Plr) -- [number] = player
table.insert(ListClone,clone) -- [number] = script
table.insert(Listok,true) -- [number] = true
table.insert(Listdied, false) -- [number] = false
end)
--Removal from the list if a player is out
game.Players.PlayerRemoving:Connect(function(Plr)
table.remove(ListClone,table.find(ListPlr,Plr))
table.remove(Listok,table.find(ListPlr,Plr))
table.remove(Listdied,table.find(ListPlr,Plr))
table.remove(ListPlr,table.find(ListPlr,Plr))
end)
event.OnServerEvent:Connect(function(plr,FullName)
-- FullNameServer = the script that this player has
local FullNameServer = ListClone[table.find(ListPlr,plr)]:GetFullName()
--Does the path that came in match the one on the server
if FullName == FullNameServer then
Listok[table.find(ListPlr,plr)] = true
else
print("Script deleted")
plr:Kick()
end
end)
while not playerload do
task.wait(0.1)
end
while task.wait(1) do
--Changes the name (a kind of signal)
code = HttpS:GenerateGUID(false)
for i, obj in pairs(ListClone) do
task.spawn(function()
if Listdied[i] then return end -- If dead = do not perform
obj.Name = code
event.OnServerEvent:Wait()
task.wait(0.1)
obj.Parent = ListPlr[i].PlayerGui.Script:GetChildren()[math.random(1,10)]
obj.Name = code
end)
end
--It is necessary that it is not possible to delete "RemoteEvent"
for i, ok in pairs(Listok) do
task.spawn(function()
if not ok then
print("No response was received")
ListPlr[i]:Kick()
else
if Listdied[table.find(Listok,ok)] then return end -- If dead = do not perform
Listok[i] = false
end
end)
end
end
Local script
--...
--Some kind of script
local event = game.ReplicatedStorage.RemoteEvent
script:GetPropertyChangedSignal("Name"):Connect(function()
event:FireServer(script:GetFullName())
end)
--Some kind of script
--...
Demonstration of how the script works:
Video
Yes, this will not protect the script in general, for it can simply be disabled, and artificially signal with its location.
If make it impossible to disable LocalScript, then it will be a protected local script.
But I spent 25+ hours on this(I tried a lot of different ways, but then I bypassed them myself, but I could not get around this), so I’ll tell you like everyone else - “Never trust the client”, the local script can not be fully protected, do checks on the server, and important things only on the server, the local script should be used at a minimum, only for things that can not be done on the server.
If you tell me that this can be circumvented (and demonstrate how), I will realize that I lost 25+ hours, and I will no longer try to protect what cannot be protected.
(Clarification) You must remove LocalScript, NOT disable it, exactly remove it. As I said above, of course, this protection does not - make sense/apply in the real game.
But the point is that under artificial conditions (condition - LocalScript can only be deleted) make it so that my protection no longer works
So the question is, does my script work, or can it be bypassed?
(Clarification) With the condition that you can not just turn off LocalScript(.Disabled = true – don’t use), you must specifically delete the script, and make sure that the server does not know about it (so you do not get kicked)
Why do I put these conditions?
Because as I said in the beginning, and in the title of topic - is to protect LocalScript from being deleted, but not from being turned off
Edit: I made a clarification, so there would be no misunderstandings