PlayerPing - Get client ping times on the Server

How does making the client return a GUID prevent exploiters from spoofing it? Is there some reason why exploiters can’t just return the GUID passed by the remote function?

It prevents pre-emptive spoofing, since they can’t know the GUID ahead of time. Therefore, they cannot lower their ping. However, they can artificially raise their ping, unfortunately. There really isn’t a good way to prevent this. How can you distinguish an intentionally bad ping from a real bad ping? To the server, they’re identical.

3 Likes

This is a pretty nice module but, I have a few critiques, wouldn’t an exploiter want to increase their ping instead of make it seem really low as I don’t really see much use of faking your ping so it seems lower than what it actually is; on the other hand, increasing their ping would allow them to “trick” lag compensation on a server to register a hit allowing them to shoot players who aren’t in sight (one example).

Ping can be easily increased by an exploiter, one way this could be done is by hooking functions so Remote:Fire(...) will yield for a short amount of time before firing (there’s an example below); using a key will probably prevent most exploiters (script kiddies) but, some exploiters will be able to easily get around. Arguments passed through Remote:Fire(...) will be passed to the hooked function which an exploiter can pass through the original function used to fire remotes, rendering the use of keys useless in most cases.

I’ve considered a few alternatives such as using a players position to determine what their ping is but, if a player is stationary, their ping will seem really high. A part that a player has network ownership could be used but, if an exploiter finds out, it might be even easier for them to fake their “ping”.

local FireServer
FireServer = hookfunction(Instance.new("RemoteEvent").FireServer, newcclosure(function(Event, ...)
    if not checkcaller() then
        if Event == [some event] then
            wait(n)
        end
    end

    return FireServer(Event, ...)
end))
-- Hookfunction: allows you to hook functions
-- newcclosure: prevents some (if not, all) current detection methods (e.g. environment checks)
-- Checkcaller: checks if a Remote was fired by a game script (if so, it'll return false)

Thanks for sharing this module though, I’m sure it’ll have really nice use cases :+1:

3 Likes

Sending os.clock() instead of GUID would be enough and you would also receive a synced up server time reference on the client. os.clock() is a floating point value and guessing the right one for exploiters would be very tedious already.

8 Likes

Awesome module! Thank you!

Accurately grabbing ping of players was always something I would find hard to write myself <3

I was looking into Postie and discovered a major issue with how old listeners are cleaned up. Essentially, if multiple requests are sent around the same time (as they would be with a system like PlayerPing) and are not returned in the correct order, requests can be “lost”. I have described the issue in detail in the reply linked below as well as uploaded a modified version of Postie that addresses the problem. I’d recommend you to either use that or come up with your own solution.

2 Likes

cant exploit just decompile your script and copy and then disable yours and make there script return what ever they need and the value the server send

Yes but that defeats the point of the check.

The check exists to make sure that an exploiter can’t report their ping as lower than actuality.

is there a limit to how long ping can be delay if not i can just delay it till i did what ever bad action then fire it

Why not kick the player instead of discarding the info?

( sorry for the bump :skull: ) didn’t see this was 2 years ago

I already answered that.

2 Likes

Thanks!
Are you thinking about updating this?

No point, Roblox has since added a function that does this. PlayerPing is a pointless old library from the dark ages.

https://create.roblox.com/docs/reference/engine/classes/Player#GetNetworkPing

Wow never knew this function existed.
:+1:
Thanks!

I been using this module for some time and noticed that my memory usage has been going up and saw that this module was the cause of that. I try to debug the code by commenting out the Postie.InvokeClient and putting fake values like, isSuccessful = true and returnGUID = GUID to see if Postie was causing it, but my memory still kept going up. My Memory increases every 3 seconds which is also the time frequency update.


I did requested the module in the server and client.
So I am not sure what is causing it, I think is a memory leak but couldn’t see any. So I wanted to see if you could fix it or tell me if I did something wrong. Thanks in advance.

1 Like

As BoatBomber mentioned Roblox has created there own method for getting player-ping.

I have seen it, but I want to get it from the server that is why I used this module. The problem is that my server memory keeps increasing and don’t know how to fix it.

Player:GetNetworkPing() will always return 0 on Studio during play test
CC: @testentry16

It seems like the module is using an outdated version of Postie you should get the new version here

I also used the new version of postie but still got the same problem.

I don’t get the difference between this and Player:GetNetworkPing()?