Tutorial Very Simple Reach Check

Discussion in 'Resources' started by Retrooper, Jun 19, 2019.

  1. Offline

    Retrooper

    How to detect reach
    Thanks for coming by, now I assume you are creating an anticheat, right?
    Well, you came to the right place!
    Please let me know if I should continue adding anticheat checks help guides(I'm not the best).

    So, let's get into it.

    Firstly, there are two ways of doing this, we can either use packets(ProtocolLib) or use the API's events!
    It is recommended to use packets, but no big difference!

    PROTOCOLLIB:
    Here is for you packet users.
    So, we will first get the Interaction with Entity packet called Use Entity.
    Code:
    
            ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(plugin, ListenerPriority.NORMAL, PacketType.Play.Client.USE_ENTITY) {
                @Override
                public void onPacketReceiving(PacketEvent event)
                {
              
                }
            });
    
    Now we must store the player's and entity's location in a variable.
    Do this inside the onPacketReceiving method.
    Code:
    Player player = event.getPlayer();
    Entity entity = event.getPacket().getEntityModifier(player.getWorld()).read(0);
    
    Now we will store the locations of the player and entity.
    Code:
    Location loc1 = player.getEyeLocation();
    Location loc2 = entity.getLocation();
    
    After everything is stored, we will make a separate method that will calculate the distance, ofcourse you can use loc1.distance(loc2); which is built into the API to get the distance, but were gonna calculate so you understand what actually happens in loc1.distance(loc2) but the same values should come out!

    This function takes two Locations, it will calculate the distance between them!
    Code:
    public double getDistanceLocations(Location loc1, Location loc2)
    {
        
    }
    
    First we must initialize the distance variable, we will set it to 0 for now, then we setup the coordinates!
    Code:
    public double getDistanceLocations(Location loc1, Location loc2)
    {
        double distance = 0.0; //initialize the distance and set it to 0
    
        //coordinates
        double x1 = loc1.getX();
        double x2 = loc2.getX();
        
        double y1 = loc1.getY();
        double y2 = loc2.getY();
        
        double z1 = loc1.getZ();
        double z2 = loc2.getZ();
    
    }
    
    This is how you calculate the distance!
    Code:
    public double getDistanceLocations(Location loc1, Location loc2)
    {
        double distance = 0.0;
    
        
        double x1 = loc1.getX();
        double x2 = loc2.getX();
        
        double y1 = loc1.getY();
        double y2 = loc2.getY();
        
        double z1 = loc1.getZ();
        double z2 = loc2.getZ();
        distance = Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1) - (z2 - z1) * (z2 - z1));
        return distance;
    }
    
    Get back to your onPacketReceiving method and let's use this!
    Code:
    double distance = getDistanceLocations(loc1, loc2);
    
    We now have a problem, we cannot just say if the distance is over a limit, then we caught them.
    The reach in survival and creative is different so we must check their gamemode.
    First of all let's create some variables that store the creative limit reach and survival limit reach.
    Here are some good values, NoCheatPlus uses these values!
    Code:
    double survivalDistance = 4.4;
    double creativeDistance = 6.0;
    
    Let's create another variable that will do this automatically
    Code:
    //if gaemode is creative, check creative distance, if gamemode is survival, check survival distance
    double distanceLimit = player.getGameMode() == GameMode.CREATIVE ? creativeDistance : survivalDistance;
    
    Good, we are almost done!
    Now we must just use an if statement and check if their reach ever gets over the limit!
    Before doing this make sure to check if distance is equal to null, check for the server's
    TPS if it's not too low and if the player's ping is not too high to avoid lag as much as possible!
    Code:
    if(distance > distanceLimit)
    {
        //CHEATER!!!!!!         
    }
    
    There we go, now make sure you have a violation system.
    Now what that means is, if you get a reach hit detected, don't instantly report or ban or contact staff.
    It should make sure this check is failed consistently, in my violation system, I check if the player failed this 6 times, then the plugin report to staff.
    The reason a violations system is important is because lag exists, and lag can always give you false checks.
    If player is lagging or server is lagging!

    I hope you learned something new, and improved in anticheat making.
    This is how simple a reach check can be, this is the real simple version, now here is the code for it using the spigot api, not protocollib!
    SPIGOT API CODE:
    Code:
    double survivalDist = 4.4;
    
    double creativeDist = 6.0;
    @EventHandler
    public void onDamage(EntityDamageByEntityEvent event)
    {
        if(event.getDamager() instanceof Player)
        {
            Player player = (Player) event.getDamager();
            Entity entity = event.getEntity();
            
            Location loc1 = player.getEyeLocation();
            Location loc2 = entity.getLocation();
            double distance = getDistanceLocations(loc1, loc2);
            double distanceLimit = player.getGameMode() == GameMode.CREATIVE ? creativeDist : survivalDist;
            
            if(distance > distanceLimit)
            {
                //CHEATER!!!
            }
        }
    }
    
    public double getDistanceLocations(Location loc1, Location loc2)
    {
        double distance = 0.0;
    
        
        double x1 = loc1.getX();
        double x2 = loc2.getX();
        
        double y1 = loc1.getY();
        double y2 = loc2.getY();
        
        double z1 = loc1.getZ();
        double z2 = loc2.getZ();
        distance = Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1) - (z2 - z1) * (z2 - z1));
        return distance;
    }
    
    Make sure you let me know if you liked this post, bye!
     
  2. Offline

    bwfcwalshy Retired Staff

    The response on Spigot didn't discourage you eh? While I agree posting things like this can showcas some new resources you also need to understand people will take this as a "100% working NO PATCH" way to make their own "anti-cheat" which... well won't end well.

    This isn't at all a very sure fire way to detect a cheater, it's easy to bypass with 1 simple packet manipulation. I recommend taking a different angle on this kinda thing rather than branding it as a way to find a cheater.

    Keep going on your code adventures though and good luck :)
     
    Zombie_Striker likes this.
  3. Offline

    Retrooper

    Wait what, I'm very confused how do I do it then?
    And I mentioned in the title it's a VERY SIMPLE reach check :/ urgh.

    It's difficult to even find simple tutorials for such checks on the internet so why not?
    Don't try discourage people it is not a good thing, many people look for suvh simple tutorials even and are almost impossible to find online, people just direct you to open source projects which is hard to learn from.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 20, 2019
  4. Offline

    bwfcwalshy Retired Staff

    Yeah, simple reason for that is there isn't a need.


    I don't think you understood what I said. Please re-read what I said, I never once try and discourage you, in fact I encourage you to keep going at the end. All I said was the branding for this was wrong, there's things to learn but people not familiar with Java or Bukkit will come and just think "hey look, I can ban cheaters with this" which... well they can't. I've seen people take code from things like this and literally try and sell it....
    I don't know how much you know this entire scene but I've been in it for many years, if there's one thing you learn is that people will take a simple thing and act like it's fantastic.

    Also, open source projects can be pretty easy to learn from, not all of course but if you're open-sourcing you're usually trying to make it easy to read and contribute to.

    Either way, I don't want to clog up this thread with a discussion of branding and such so feel free to DM me if you disagree still.
     

Share This Page