Solved Player Mid Eating?

Discussion in 'Plugin Development' started by dlange, Oct 3, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    dlange

    How would you know if a player is in the middle of eating something (so that they are slower than normal)

    I have tried Velocities, but i will admit they aren't my thing. I am trying to see if a player is moving faster than you should when eating food (therefor - noslowdown hacks). I have tried on FoodLevelChangeEvent to see if they are sprinting but this can be positive if the person is lagging, i have made a way to bypass this but it still isnt 100%. Also, if a player has BSM or (i think) is holding down the sprint key while eating, it detects it as they are sprinting.
     
  2. Offline

    RoboticPlayer

    Why don't use use the ItemConsumeEvent?
     
  3. Offline

    dlange

    @henderry2019 That's still fired after they eat. I'm looking for a way to determine how fast they are moving, i can work from there
     
  4. Offline

    teej107

    May we see your code attempt? We may be able to improve on it. The only way I see how to handle this is with the PlayerInteractEvent.
     
  5. Offline

    dlange

    @teej107 Sure
    This is all that is to do with the food tracking:
    Code:
    public static HashMap<String, Integer> playerOffences = new HashMap<>();
        public static HashMap<String, Vector> velocityCache = new HashMap<>();
        public static HashMap<String, Boolean> playerFired = new HashMap<>();
        public ArrayList<UUID> check = new ArrayList<>();
    
        public static int getOffences(Player p) {
            if (playerOffences.get(p.getName()) == null) playerOffences.put(p.getName(), 1);
            return playerOffences.get(p.getName());
        }
    
        public static Vector getVelocity(Player p) {
            if (velocityCache.get(p.getName()) == null) velocityCache.put(p.getName(), p.getVelocity());
            return velocityCache.get(p.getName());
        }
    
        @EventHandler
        public void onEat(FoodLevelChangeEvent e) {
            if (e.getEntity() instanceof Player) {
                Player p = (Player) e.getEntity();
                if (p.hasPotionEffect(PotionEffectType.SATURATION) || e.isCancelled()) return;
                if (e.getFoodLevel() < p.getFoodLevel()) return;
                if (check.contains(p.getUniqueId())) return;
                System.out.println(getVelocity(p).getX()); //------------------
                System.out.println(getVelocity(p).getZ()); // Just debug msgs
                System.out.println(getVelocity(p).length()); //----------------
                if ((p.isOnGround() && (getVelocity(p).getX() > 0.07 || getVelocity(p).getZ() > 1.0)) || (!p.isOnGround() && (getVelocity(p).getX() > 0.4 || getVelocity(p).getZ() > 1.4))) {
                    if (p.isSprinting()) {
                        Bukkit.getPluginManager().callEvent(new PlayerDetectedHackEvent(p, HackType.NO_SLOWDOWN));
                        if (playerOffences.get(p.getName()) == null) playerOffences.put(p.getName(), 0);
                        playerOffences.put(p.getName(), playerOffences.get(p.getName()) + 1);
                    }
                }
            }
        }
    
    // This whole section below is in testing, its meant to fix players with bad ping that could glitch it, but if i could find a way to detect what their speed is when they are mid eating, i would not need it
        @EventHandler
        public void onMove(PlayerMoveEvent e) {
            final Player p = e.getPlayer();
            if (e.getTo().getX() != e.getFrom().getX() || e.getTo().getZ() != e.getFrom().getZ()|| e.getTo().getY() != e.getFrom().getY()) {
                velocityCache.put(p.getName(), p.getVelocity());
                if (((CraftPlayer) p).getHandle().ping >= 200) {
                        if (!check.contains(p.getUniqueId())) {
                            if (!p.isSprinting()) return;
                            check.add(p.getUniqueId());
                            final double fl = p.getFoodLevel();
                            Bukkit.getScheduler().runTaskLater(Core.getInstance(), new Runnable() {
                                @Override
                                public void run() {
                                    check.remove(p.getUniqueId());
                                    if (p.getFoodLevel() > fl) {
                                        Bukkit.getPluginManager().callEvent(new PlayerDetectedHackEvent(p, HackType.NO_SLOWDOWN));
                                    }
                                }
                            }, 30L);
                        } else {
                            if (!p.isSprinting()) check.remove(p.getUniqueId());
                        }
                    }
                }
            }
        }
     
  6. Offline

    teej107

    @dlange So what doesn't make it work 100%? Is it just harder to exploit it or does it seem random?
     
  7. Offline

    dlange

    @teej107 It was harder to exploit, i used PlayerInteractEvent and came up with a solution.

    Ofc it will never be 100%, but there have been no false positives when i tested with someone that had 800ms, and went through 3 stacks of food doing it :p
     
Thread Status:
Not open for further replies.

Share This Page