mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-31 20:01:25 +01:00
+ Patched the disconnect nofall exploit
+ Commands are now hidden (from players) = Fixed the SpamJoin check (2 issues) = Fixed the issue with plugins lists = Fixed the Tracker check's issue with AuthMe = Fixed an issue with boats and moving water
This commit is contained in:
parent
9aa5536fe4
commit
27c79ac30c
@ -3,6 +3,7 @@ version: ${project.version}
|
||||
description: ${project.description}
|
||||
|
||||
author: NeatMonster
|
||||
authors: [Eventprime, Juliui]
|
||||
website: ${project.url}
|
||||
|
||||
main: me.neatmonster.nocheatplus.NoCheatPlus
|
||||
@ -10,7 +11,7 @@ main: me.neatmonster.nocheatplus.NoCheatPlus
|
||||
commands:
|
||||
nocheatplus:
|
||||
description: NoCheatPlus command(s)
|
||||
permission: nocheatplus.admin.commands
|
||||
# permission: nocheatplus.admin.commands
|
||||
usage: |
|
||||
/<command> permlist player [permission]: list NoCheatPlus' permissions of player, optionally only if beginning with [permission]
|
||||
/<command> playerinfo player: show the collected data NoCheatPlus collected about a player
|
||||
|
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
||||
|
||||
<!-- Informations -->
|
||||
<name>NoCheatPlus</name>
|
||||
<version>3.5.5_3</version>
|
||||
<version>3.5.5_4</version>
|
||||
<description>Detect and fight the exploitation of various flaws/bugs in Minecraft.</description>
|
||||
<url>http://dev.bukkit.org/server-mods/nocheatplus</url>
|
||||
|
||||
|
@ -98,7 +98,7 @@ public class ChatCheckListener implements Listener, EventManager {
|
||||
if ((event.getMessage().equalsIgnoreCase("/plugins")
|
||||
|| event.getMessage().toLowerCase().startsWith("/plugins ")
|
||||
|| event.getMessage().equalsIgnoreCase("/pl") || event.getMessage().toLowerCase().startsWith("/pl "))
|
||||
&& cc.hideNoCheatPlus) {
|
||||
&& Bukkit.getPluginManager().getPlugin("PluginList") == null && cc.hideNoCheatPlus) {
|
||||
// If the player isn't allowed to use this command
|
||||
if (!event.getPlayer().hasPermission("bukkit.command.plugins"))
|
||||
// Fake the permissions error message
|
||||
@ -153,8 +153,8 @@ public class ChatCheckListener implements Listener, EventManager {
|
||||
ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void login(final PlayerLoginEvent event) {
|
||||
|
||||
// Only check players who haven't played before
|
||||
if (event.getPlayer().hasPlayedBefore())
|
||||
// Only check new players (who has joined less than 10 minutes ago)
|
||||
if (System.currentTimeMillis() - event.getPlayer().getFirstPlayed() > 600000D)
|
||||
return;
|
||||
|
||||
final NoCheatPlusPlayer player = plugin.getPlayer(event.getPlayer());
|
||||
|
@ -1,16 +1,19 @@
|
||||
package me.neatmonster.nocheatplus.checks.chat;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import me.neatmonster.nocheatplus.NoCheatPlus;
|
||||
import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
|
||||
|
||||
public class SpamJoinsCheck extends ChatCheck {
|
||||
|
||||
// Used to know if the cooldown is enabled and since when
|
||||
private boolean cooldown = false;
|
||||
private long cooldownStartTime = 0L;
|
||||
private boolean cooldown = false;
|
||||
private long cooldownStartTime = 0L;
|
||||
|
||||
// Used to remember the latest joins;
|
||||
private long[] joins = null;
|
||||
private long[] joinsTimes = null;
|
||||
private String[] joinsPlayers = null;
|
||||
|
||||
public SpamJoinsCheck(final NoCheatPlus plugin) {
|
||||
super(plugin, "chat.spamjoins");
|
||||
@ -19,8 +22,10 @@ public class SpamJoinsCheck extends ChatCheck {
|
||||
public boolean check(final NoCheatPlusPlayer player, final ChatData data, final ChatConfig cc) {
|
||||
|
||||
// Initialize the joins array
|
||||
if (joins == null)
|
||||
joins = new long[cc.spamJoinsPlayersLimit];
|
||||
if (joinsTimes == null)
|
||||
joinsTimes = new long[cc.spamJoinsPlayersLimit];
|
||||
if (joinsPlayers == null)
|
||||
joinsPlayers = new String[cc.spamJoinsPlayersLimit];
|
||||
|
||||
boolean kick = false;
|
||||
|
||||
@ -37,7 +42,7 @@ public class SpamJoinsCheck extends ChatCheck {
|
||||
kick = true;
|
||||
|
||||
// If more than limit new players have joined in less than limit time
|
||||
else if (System.currentTimeMillis() - joins[0] < cc.spamJoinsTimeLimit) {
|
||||
else if (System.currentTimeMillis() - joinsTimes[0] < cc.spamJoinsTimeLimit) {
|
||||
// Enable the new players cooldown
|
||||
cooldown = true;
|
||||
cooldownStartTime = System.currentTimeMillis();
|
||||
@ -46,9 +51,14 @@ public class SpamJoinsCheck extends ChatCheck {
|
||||
}
|
||||
|
||||
// Fill the joining times array
|
||||
for (int i = 0; i < cc.spamJoinsPlayersLimit - 1; i++)
|
||||
joins[i] = joins[i + 1];
|
||||
joins[cc.spamJoinsPlayersLimit - 1] = System.currentTimeMillis();
|
||||
if (!Arrays.asList(joinsPlayers).contains(player.getName())) {
|
||||
for (int i = 0; i < cc.spamJoinsPlayersLimit - 1; i++) {
|
||||
joinsTimes[i] = joinsTimes[i + 1];
|
||||
joinsPlayers[i] = joinsPlayers[i + 1];
|
||||
}
|
||||
joinsTimes[cc.spamJoinsPlayersLimit - 1] = System.currentTimeMillis();
|
||||
joinsPlayers[cc.spamJoinsPlayersLimit - 1] = player.getName();
|
||||
}
|
||||
|
||||
return kick;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
@ -135,6 +136,26 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a player tries to place a boat on the ground, the event
|
||||
* will be cancelled.
|
||||
*
|
||||
* @param event
|
||||
* The PlayerInteractEvent
|
||||
*/
|
||||
@EventHandler(
|
||||
ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void boat(final PlayerInteractEvent event) {
|
||||
if (!event.getPlayer().hasPermission(Permissions.MOVING_BOATONGROUND)
|
||||
&& event.getAction() == Action.RIGHT_CLICK_BLOCK
|
||||
&& event.getPlayer().getItemInHand().getType() == Material.BOAT
|
||||
&& event.getClickedBlock().getType() != Material.WATER
|
||||
&& event.getClickedBlock().getType() != Material.STATIONARY_WATER
|
||||
&& event.getClickedBlock().getRelative(event.getBlockFace()).getType() != Material.WATER
|
||||
&& event.getClickedBlock().getRelative(event.getBlockFace()).getType() != Material.STATIONARY_WATER)
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getActiveChecks(final ConfigurationCacheStore cc) {
|
||||
final LinkedList<String> s = new LinkedList<String>();
|
||||
@ -160,6 +181,27 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* This event handler is used to prevent the player from quickly
|
||||
* disconnecting/reconnecting in order to cancel his fall damages.
|
||||
*
|
||||
* @param event
|
||||
* The PlayerJoinEvent
|
||||
*/
|
||||
@EventHandler(
|
||||
ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void join(final PlayerJoinEvent event) {
|
||||
|
||||
final NoCheatPlusPlayer player = plugin.getPlayer(event.getPlayer());
|
||||
final MovingData data = MovingCheck.getData(player);
|
||||
|
||||
// If the player has joined in the air and a safe location is defined...
|
||||
if (player.getPlayer().getLocation().add(0, -1, 0).getBlock().getType() == Material.AIR
|
||||
&& data.lastSafeLocations[0] != null)
|
||||
// ...then teleport him to this location
|
||||
event.getPlayer().teleport(data.lastSafeLocations[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* When a player moves, he will be checked for various
|
||||
* suspicious behaviour.
|
||||
@ -197,6 +239,12 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
final Location to = event.getTo();
|
||||
data.to.set(to);
|
||||
|
||||
// Remember safe locations
|
||||
if (Math.abs(event.getPlayer().getVelocity().getY()) < 0.0785D) {
|
||||
data.lastSafeLocations[0] = data.lastSafeLocations[1];
|
||||
data.lastSafeLocations[1] = event.getFrom();
|
||||
}
|
||||
|
||||
PreciseLocation newTo = null;
|
||||
|
||||
/** RUNFLY CHECK SECTION **/
|
||||
@ -238,24 +286,6 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a player tries to place a boat on the ground, the event
|
||||
* will be cancelled.
|
||||
*
|
||||
* @param event
|
||||
* The PlayerInteractEvent
|
||||
*/
|
||||
@EventHandler(
|
||||
ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerInteract(final PlayerInteractEvent event) {
|
||||
if (!event.getPlayer().hasPermission(Permissions.MOVING_BOATONGROUND)
|
||||
&& event.getAction() == Action.RIGHT_CLICK_BLOCK
|
||||
&& event.getPlayer().getItemInHand().getType() == Material.BOAT
|
||||
&& event.getClickedBlock().getType() != Material.WATER
|
||||
&& event.getClickedBlock().getType() != Material.STATIONARY_WATER)
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* When a player uses a portal, all information related to the
|
||||
* moving checks becomes invalid.
|
||||
@ -278,6 +308,13 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
*/
|
||||
@EventHandler
|
||||
public void quit(final PlayerQuitEvent event) {
|
||||
|
||||
final NoCheatPlusPlayer player = plugin.getPlayer(event.getPlayer());
|
||||
final MovingData data = MovingCheck.getData(player);
|
||||
|
||||
// Reset the variable
|
||||
data.fallingSince = 0L;
|
||||
|
||||
if (!event.getPlayer().hasPermission(Permissions.MOVING_RESPAWNTRICK)
|
||||
&& (event.getPlayer().getLocation().getBlock().getType() == Material.GRAVEL || event.getPlayer()
|
||||
.getLocation().getBlock().getType() == Material.SAND)) {
|
||||
@ -420,6 +457,9 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
|
||||
final MovingData data = MovingCheck.getData(plugin.getPlayer(event.getPlayer()));
|
||||
|
||||
// Reset the tracker's data
|
||||
data.fallingSince = 0L;
|
||||
|
||||
final Vector v = event.getVelocity();
|
||||
|
||||
double newVal = v.getY();
|
||||
|
@ -4,6 +4,8 @@ import me.neatmonster.nocheatplus.DataItem;
|
||||
import me.neatmonster.nocheatplus.data.PreciseLocation;
|
||||
import me.neatmonster.nocheatplus.data.Statistics.Id;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
/**
|
||||
* Player specific data for the moving check group
|
||||
*/
|
||||
@ -28,7 +30,7 @@ public class MovingData implements DataItem {
|
||||
public int onIce;
|
||||
|
||||
// Where should a player be teleported back to when failing the check
|
||||
public final PreciseLocation runflySetBackPoint = new PreciseLocation();
|
||||
public final PreciseLocation runflySetBackPoint = new PreciseLocation();
|
||||
|
||||
// Some values for estimating movement freedom
|
||||
public double vertFreedom;
|
||||
@ -44,39 +46,45 @@ public class MovingData implements DataItem {
|
||||
public float lastAddedFallDistance;
|
||||
|
||||
// Keep in mind since when the player in falling/jumping
|
||||
public long fallingSince = 0L;
|
||||
public long fallingSince = 0L;
|
||||
|
||||
// Remember if the player has already been on the ground
|
||||
public boolean hasAlreadyBeenOnTheGround = false;
|
||||
|
||||
// Keep in mind the player's last safe position
|
||||
public Location[] lastSafeLocations = new Location[] {null, null};
|
||||
|
||||
// Keep track of when "morePackets" last time checked and how much packets
|
||||
// a player sent and may send before failing the check
|
||||
public long morePacketsLastTime;
|
||||
public int packets;
|
||||
public int morePacketsBuffer = 50;
|
||||
public int morePacketsBuffer = 50;
|
||||
|
||||
// Where to teleport the player that fails the "morepackets" check
|
||||
public final PreciseLocation morePacketsSetbackPoint = new PreciseLocation();
|
||||
public final PreciseLocation morePacketsSetbackPoint = new PreciseLocation();
|
||||
|
||||
// Keep track of when "morePacketsVehicle" last time checked an how much
|
||||
// packets a vehicle sent and may send before failing the check
|
||||
public long morePacketsVehicleLastTime;
|
||||
public int packetsVehicle;
|
||||
public int morePacketsVehicleBuffer = 50;
|
||||
public int morePacketsVehicleBuffer = 50;
|
||||
|
||||
// When NoCheatPlus does teleport the player, remember the target location to
|
||||
// be able to distinguish "our" teleports from teleports of others
|
||||
public final PreciseLocation teleportTo = new PreciseLocation();
|
||||
public final PreciseLocation teleportTo = new PreciseLocation();
|
||||
|
||||
// For logging and convenience, make copies of the events locations
|
||||
public final PreciseLocation from = new PreciseLocation();
|
||||
public final PreciseLocation fromVehicle = new PreciseLocation();
|
||||
public final PreciseLocation to = new PreciseLocation();
|
||||
public final PreciseLocation toVehicle = new PreciseLocation();
|
||||
public final PreciseLocation from = new PreciseLocation();
|
||||
public final PreciseLocation fromVehicle = new PreciseLocation();
|
||||
public final PreciseLocation to = new PreciseLocation();
|
||||
public final PreciseLocation toVehicle = new PreciseLocation();
|
||||
|
||||
// For convenience, remember if the locations are considered "on ground"
|
||||
// by NoCheatPlus
|
||||
public boolean fromOnOrInGround;
|
||||
public boolean toOnOrInGround;
|
||||
|
||||
public Id statisticCategory = Id.MOV_RUNNING;
|
||||
public Id statisticCategory = Id.MOV_RUNNING;
|
||||
|
||||
public void clearMorePacketsData() {
|
||||
morePacketsSetbackPoint.reset();
|
||||
|
@ -28,24 +28,32 @@ public class TrackerCheck extends MovingCheck {
|
||||
final int type = CheckUtil.evaluateLocation(player.getPlayer().getWorld(), location);
|
||||
final boolean isLiquid = CheckUtil.isLiquid(type);
|
||||
|
||||
// Check if the player is on the ground
|
||||
if (player.getPlayer().getLocation().add(0, -1, 0).getBlock().getType() != Material.AIR)
|
||||
data.hasAlreadyBeenOnTheGround = true;
|
||||
|
||||
// Do not do the check if it's disabled, if flying is allowed, if the player is
|
||||
// allowed to fly because of its game mode, if he has the required permission,
|
||||
// if he is in water or in vines.
|
||||
// if he is in water, on a ladder or in vines.
|
||||
if (!cc.tracker || cc.allowFlying || player.getPlayer().getGameMode() == GameMode.CREATIVE
|
||||
|| player.getPlayer().getAllowFlight() || player.getPlayer().hasPermission(Permissions.MOVING_RUNFLY)
|
||||
|| player.getPlayer().hasPermission(Permissions.MOVING_FLYING) || isLiquid
|
||||
|| player.getPlayer().getLocation().getBlock().getType() == Material.LADDER
|
||||
|| player.getPlayer().getLocation().getBlock().getType() == Material.VINE
|
||||
|| player.getPlayer().getLocation().getX() < 0D) {
|
||||
data.fallingSince = 0;
|
||||
|| player.getPlayer().getLocation().getY() < 0D) {
|
||||
data.fallingSince = 0L;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the player isn't falling or jumping
|
||||
// If the player isn't static or jumping
|
||||
if (Math.abs(player.getPlayer().getVelocity().getY()) > 0.1D) {
|
||||
|
||||
// The player is falling/jumping, check if he was previously on the ground
|
||||
if (data.fallingSince == 0)
|
||||
// Only do something if the player has already been on the ground
|
||||
if (!data.hasAlreadyBeenOnTheGround)
|
||||
return;
|
||||
|
||||
// The player is static/jumping, check if he was previously on the ground
|
||||
if (data.fallingSince == 0L)
|
||||
data.fallingSince = System.currentTimeMillis();
|
||||
|
||||
// Check if he has stayed too much time in the air (more than 6 seconds)
|
||||
@ -56,11 +64,11 @@ public class TrackerCheck extends MovingCheck {
|
||||
|
||||
// Execute whatever actions are associated with this check and the
|
||||
// violation level and find out if we should cancel the event
|
||||
executeActions(player, cc.nofallActions, data.nofallVL);
|
||||
executeActions(player, cc.trackerActions, data.trackerVL);
|
||||
}
|
||||
} else {
|
||||
// Reset the timer
|
||||
data.fallingSince = 0;
|
||||
data.fallingSince = 0L;
|
||||
|
||||
// Reduce the violation level
|
||||
data.trackerVL *= 0.95;
|
||||
|
@ -63,6 +63,12 @@ public class CommandHandler {
|
||||
public boolean handleCommand(final NoCheatPlus plugin, final CommandSender sender, final Command command,
|
||||
final String label, final String[] args) {
|
||||
|
||||
// Hide NoCheatPlus's commands if the player doesn't have the required permission
|
||||
if (sender instanceof Player && !sender.hasPermission("nocheatplus.admin.commands")) {
|
||||
sender.sendMessage("Unknown command. Type \"help\" for help.");
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean result = false;
|
||||
// Not our command, how did it get here?
|
||||
if (!command.getName().equalsIgnoreCase("nocheatplus") || args.length == 0)
|
||||
|
Loading…
Reference in New Issue
Block a user