+ Added the SpamJoins check

= Fixed the issue with the fly tracker and ladders
= Fixed the issue with the projectiles check and other entities
This commit is contained in:
NeatMonster 2012-04-09 21:34:19 +02:00
parent 1c649112ae
commit 60802760f5
10 changed files with 143 additions and 15 deletions

View File

@ -961,6 +961,26 @@
number of messages/commands that were sent beyond the specified limits.
It gets increased for every message/command by 1 and reset to zero when
the "timeframe" has passed.
3) SPAMJOINS:
This check limits the number of new players joining every X seconds to
prevent the usage of softwares like PWN4G3.
active:
Should players get checked for that kind of spam.
playerslimit:
The number of new players allowed to join during the interval defined
in the configuration.
timelimit:
The interval in milliseconds during which the number of new players
defined in the configuration are allowed to join.
cooldown:
The number of milliseconds during which new players won't be allowed
to join if too many new players have been detected.
------------------------------ FIGHT Subsection --------------------------------

View File

@ -4,7 +4,7 @@
<!-- Informations -->
<name>NoCheatPlus</name>
<version>3.5.4_1</version>
<version>3.5.5</version>
<description>Detect and fight the exploitation of various flaws/bugs in Minecraft.</description>
<url>http://dev.bukkit.org/server-mods/nocheatplus</url>

View File

@ -56,6 +56,8 @@ public class BlockPlaceCheckListener implements Listener, EventManager {
s.add("blockplace.reach");
if (bp.directionCheck)
s.add("blockplace.direction");
if (bp.projectileCheck)
s.add("blockplace.projectileCheck");
return s;
}
@ -127,8 +129,10 @@ public class BlockPlaceCheckListener implements Listener, EventManager {
public void otherProjectiles(final ProjectileLaunchEvent event) {
// We are only interested by enderpears, endersignals, eggs, snowballs and expbottles
if (event.getEntityType() != EntityType.ENDER_PEARL && event.getEntityType() != EntityType.ENDER_SIGNAL
&& event.getEntityType() != EntityType.EGG && event.getEntityType() != EntityType.SNOWBALL
// of course thrown by a player
if (!(event.getEntity().getShooter() instanceof Player) || event.getEntityType() != EntityType.ENDER_PEARL
&& event.getEntityType() != EntityType.ENDER_SIGNAL && event.getEntityType() != EntityType.EGG
&& event.getEntityType() != EntityType.SNOWBALL
&& event.getEntityType() != EntityType.THROWN_EXP_BOTTLE)
return;

View File

@ -14,6 +14,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
/**
* Central location to listen to events that are
@ -22,16 +23,18 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent;
*/
public class ChatCheckListener implements Listener, EventManager {
private final SpamCheck spamCheck;
private final ColorCheck colorCheck;
private final SpamCheck spamCheck;
private final SpamJoinsCheck spamJoinsCheck;
private final ColorCheck colorCheck;
private final NoCheatPlus plugin;
private final NoCheatPlus plugin;
public ChatCheckListener(final NoCheatPlus plugin) {
this.plugin = plugin;
spamCheck = new SpamCheck(plugin);
spamJoinsCheck = new SpamJoinsCheck(plugin);
colorCheck = new ColorCheck(plugin);
}
@ -95,8 +98,27 @@ public class ChatCheckListener implements Listener, EventManager {
final ChatConfig c = ChatCheck.getConfig(cc);
if (c.spamCheck)
s.add("chat.spam");
if (c.spamJoinsCheck)
s.add("chat.spamjoins");
if (c.colorCheck)
s.add("chat.color");
return s;
}
@EventHandler(
ignoreCancelled = true, priority = EventPriority.LOWEST)
public void join(final PlayerJoinEvent event) {
// Only check new players (who has joined less than 10 minutes ago)
if (System.currentTimeMillis() - event.getPlayer().getFirstPlayed() > 600000L)
return;
final NoCheatPlusPlayer player = plugin.getPlayer(event.getPlayer());
final ChatConfig cc = ChatCheck.getConfig(player);
final ChatData data = ChatCheck.getData(player);
if (cc.spamJoinsCheck && spamJoinsCheck.check(player, data, cc))
// If the player failed the check, kick it
event.getPlayer().kickPlayer(cc.spamJoinsKickMessage);
}
}

View File

@ -24,6 +24,12 @@ public class ChatConfig implements ConfigItem {
public final int spamCommandLimit;
public final ActionList spamActions;
public final boolean spamJoinsCheck;
public final int spamJoinsPlayersLimit;
public final int spamJoinsTimeLimit;
public final int spamJoinsCooldown;
public final String spamJoinsKickMessage;
public final boolean colorCheck;
public final ActionList colorActions;
@ -35,6 +41,11 @@ public class ChatConfig implements ConfigItem {
spamMessageLimit = data.getInt(ConfPaths.CHAT_SPAM_MESSAGELIMIT);
spamCommandLimit = data.getInt(ConfPaths.CHAT_SPAM_COMMANDLIMIT);
spamActions = data.getActionList(ConfPaths.CHAT_SPAM_ACTIONS, Permissions.CHAT_SPAM);
spamJoinsCheck = data.getBoolean(ConfPaths.CHAT_SPAMJOINS_CHECK);
spamJoinsPlayersLimit = data.getInt(ConfPaths.CHAT_SPAMJOINS_PLAYERSLIMIT);
spamJoinsTimeLimit = data.getInt(ConfPaths.CHAT_SPAMJOINS_TIMELIMIT);
spamJoinsCooldown = data.getInt(ConfPaths.CHAT_SPAMJOINS_COOLDOWN);
spamJoinsKickMessage = data.getString(ConfPaths.CHAT_SPAMJOINS_KICKMESSAGE);
colorCheck = data.getBoolean(ConfPaths.CHAT_COLOR_CHECK);
colorActions = data.getActionList(ConfPaths.CHAT_COLOR_ACTIONS, Permissions.CHAT_COLOR);
}

View File

@ -10,6 +10,7 @@ public class ChatData implements DataItem {
// Keep track of the violation levels for the two checks
public int spamVL;
public int spamJoinsVL;
public int colorVL;
// Count messages and commands

View File

@ -0,0 +1,55 @@
package me.neatmonster.nocheatplus.checks.chat;
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;
// Used to remember the latest joins;
private long[] joins = null;
public SpamJoinsCheck(final NoCheatPlus plugin) {
super(plugin, "chat.spamjoins");
}
public boolean check(final NoCheatPlusPlayer player, final ChatData data, final ChatConfig cc) {
// Initialize the joins array
if (joins == null)
joins = new long[cc.spamJoinsPlayersLimit];
boolean kick = false;
// If the new players cooldown is over
if (cooldown && System.currentTimeMillis() - cooldownStartTime > cc.spamJoinsCooldown) {
// Stop the new players cooldown
cooldown = false;
cooldownStartTime = 0L;
}
// If the new players cooldown is active
else if (cooldown)
// Kick the player who joined
kick = true;
// If more than limit new players have joined in less than limit time
else if (System.currentTimeMillis() - joins[0] < cc.spamJoinsTimeLimit) {
// Enable the new players cooldown
cooldown = true;
cooldownStartTime = System.currentTimeMillis();
// Kick the player who joined
kick = true;
}
// 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();
return kick;
}
}

View File

@ -71,19 +71,17 @@ public class MovingCheckListener implements Listener, EventManager {
final MovingData data = MovingCheck.getData(player);
// 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 or if he has the required permission.
// allowed to fly because of its game mode, if he has the required permission,
// if he is in water or in vines.
if (!cc.tracker || cc.allowFlying || bukkitPlayer.getGameMode() == GameMode.CREATIVE
|| bukkitPlayer.getAllowFlight() || bukkitPlayer.hasPermission(Permissions.MOVING_RUNFLY)) {
data.fallingSince = 0;
return;
}
// If the player is in water or in vines, then do not run the check
if (bukkitPlayer.getLocation().getBlock().getType() == Material.WATER
|| bukkitPlayer.getAllowFlight() || bukkitPlayer.hasPermission(Permissions.MOVING_RUNFLY)
|| bukkitPlayer.hasPermission(Permissions.MOVING_FLYING)
|| bukkitPlayer.getLocation().getBlock().getType() == Material.WATER
|| bukkitPlayer.getLocation().getBlock().getType() == Material.STATIONARY_WATER
|| bukkitPlayer.getLocation().getBlock().getType() == Material.LADDER
|| bukkitPlayer.getLocation().getBlock().getType() == Material.VINE) {
data.fallingSince = 0;
return;
continue;
}
// If the player isn't falling or jumping
@ -176,10 +174,14 @@ public class MovingCheckListener implements Listener, EventManager {
s.add("moving.sneaking");
if (m.nofallCheck)
s.add("moving.nofall");
if (m.waterWalkCheck)
s.add("moving.waterwalk");
} else
s.add("moving.flying");
if (m.morePacketsCheck)
s.add("moving.morepackets");
if (m.morePacketsVehicleCheck)
s.add("moving.morepacketsvehicle");
return s;
}

View File

@ -142,6 +142,13 @@ public abstract class ConfPaths {
public final static String CHAT_SPAM_COMMANDLIMIT = CHAT_SPAM + "commandlimit";
public final static String CHAT_SPAM_ACTIONS = CHAT_SPAM + "actions";
private final static String CHAT_SPAMJOINS = CHAT + "spamjoins.";
public final static String CHAT_SPAMJOINS_CHECK = CHAT_SPAMJOINS + "active";
public final static String CHAT_SPAMJOINS_PLAYERSLIMIT = CHAT_SPAMJOINS + "playerslimit";
public final static String CHAT_SPAMJOINS_TIMELIMIT = CHAT_SPAMJOINS + "timelimit";
public final static String CHAT_SPAMJOINS_COOLDOWN = CHAT_SPAMJOINS + "cooldown";
public final static String CHAT_SPAMJOINS_KICKMESSAGE = CHAT_SPAMJOINS + "kickmessage";
private final static String FIGHT = CHECKS + "fight.";
private final static String FIGHT_DIRECTION = FIGHT + "direction.";

View File

@ -125,6 +125,12 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
set(ConfPaths.CHAT_SPAM_COMMANDLIMIT, 12);
set(ConfPaths.CHAT_SPAM_ACTIONS, "log:spam:0:3:if cancel vl>30 log:spam:0:3:cif cancel cmd:kick");
set(ConfPaths.CHAT_SPAMJOINS_CHECK, true);
set(ConfPaths.CHAT_SPAMJOINS_PLAYERSLIMIT, 3);
set(ConfPaths.CHAT_SPAMJOINS_TIMELIMIT, 5000);
set(ConfPaths.CHAT_SPAMJOINS_COOLDOWN, 5000);
set(ConfPaths.CHAT_SPAMJOINS_KICKMESSAGE, "SpamBot?!");
/*** FIGHT ***/
set(ConfPaths.FIGHT_DIRECTION_CHECK, true);