Hi, How can I go about making server side anti fly using humanoid.floormaterial?
Sounds pretty specific, but;
--We'll be using RunService to run code every frame
local RunService = game:GetService("RunService")
--Using Players service to get all players in the server
local Players = game:GetService("Players")
--A list of information about a player; where they were last on the ground and
--how long they've been in the air
local PlayerInfos = {}
--How long someone can be in the air without being rubberbanded (teleported back)
local MaxAirborneTime = 5
--Connect to Heartbeat to run code after every physics step (60 times a second)
RunService.Heartbeat:Connect(function(Delta)
for _, Player in pairs(Players:GetPlayers()) do --Go through each player
local Character = Player.Character
if not Character then --Do they have a character? If not, ignore this player
continue
end
local Humanoid:Humanoid = Character:FindFirstChild("Humanoid")
if not Humanoid then --Do they have a humanoid? If not, ignore this player
continue
end
local Info = PlayerInfos[Player.Name] --Get info
if not Info then --If the server hasn't started monitoring this player
PlayerInfos[Player.Name] = { --Set default info
LastCFrameOnGround = Character:GetPivot(), --Their current location
TimeAirborne = 0
}
continue
end
if Humanoid.FloorMaterial == Enum.Material.Air then --Are they in the air?
--Increase the counter for how long they've been in the air
PlayerInfos[Player.Name].TimeAirborne += Delta
--Have they been in the air for too long (longer than MaxAirboneTime)?
if PlayerInfos[Player.Name].TimeAirborne > MaxAirborneTime then
PlayerInfos[Player.Name].TimeAirborne = 0
--Move them back to when they were last on the ground
Character:PivotTo(Info.LastCFrameOnGround)
end
else --Player is on the ground
PlayerInfos[Player.Name].TimeAirborne = 0
--Set the last on ground location to be their current one
PlayerInfos[Player.Name].LastCFrameOnGround = Character:GetPivot()
end
end
end)
This should be put in a server-script, preferable inside ServerScriptService, and you can test this out by running the following in the command bar in Client view in Studio and holding the jump/space key:
while true do
if not game.Players.LocalPlayer.Character then
task.wait()
continue
end
game.Players.LocalPlayer.Character:WaitForChild("Humanoid"):ChangeState(Enum.HumanoidStateType.Swimming)
task.wait()
end
In this case, 5 seconds is pretty excessive.
Obligatory “This is heavily dependent on your game”.
Hope this is not too much to ask, could you explain every part of the script?
I have added comments to the code.
Might be wrong, but floor material might be exploitable, use raycasts instead if it is
make sure they cant fall off very tall buildings and get twleported
humanoid.floormaterial
doesn’t replicate from client to server, and its only readable, so it’s safe.
humanoid.floormaterial
casts 9 rays to check for material.
udont know , maybe by chance they can use getrawmetatable to change it
woah okay
I think you better make that the antifly works after a few seconds
actually, humanoid.JumpPower/4 i think
Yeah but maybe you better use Humanoid:GetState() if it returns Enum.HumanoidStateType.Flying or Enum.HumanoidStateType.None the client is mostly flying
no because thats exploitable and known
It’s not replicated, as the linked thread shows. It’s like saying the client can access ServerScriptService through some metatable magic, which is completely false since it’s never replicated to the client. Likewise, the client cannot fake FloorMaterial since, when it accessed by a server script, the raycasts are done on the spot by the server, which is also mentioned in the FloorMaterial replication update post.
i guasse this is the best way to fix it