Merge pull request #1517 from AuthMe/642-kick-on-fast-commands

#642 - Quick Command Protection
This commit is contained in:
ljacqu
2018-03-19 22:35:49 +01:00
committed by GitHub
38 changed files with 247 additions and 11 deletions
@@ -0,0 +1,75 @@
package fr.xephi.authme.data;
import fr.xephi.authme.initialization.HasCleanup;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.ProtectionSettings;
import fr.xephi.authme.util.expiring.ExpiringSet;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.concurrent.TimeUnit;
public class QuickCommandsProtectionManager implements SettingsDependent, HasCleanup {
private final PermissionsManager permissionsManager;
private final ExpiringSet<String> latestJoin;
@Inject
public QuickCommandsProtectionManager(Settings settings, PermissionsManager permissionsManager) {
this.permissionsManager = permissionsManager;
long countTimeout = settings.getProperty(ProtectionSettings.QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS);
latestJoin = new ExpiringSet<>(countTimeout, TimeUnit.MILLISECONDS);
reload(settings);
}
/**
* Save the player in the set
* @param name the player's name
*/
private void setJoin(String name) {
latestJoin.add(name);
}
/**
* Returns whether the given player has the permission and should be saved in the set
* @param player the player to check
* @return true if the player has the permission, false otherwise
*/
private boolean shouldSavePlayer(Player player) {
return permissionsManager.hasPermission(player, PlayerPermission.QUICK_COMMANDS_PROTECTION);
}
/**
* Process the player join
* @param player the player to process
*/
public void processJoin(Player player) {
if(shouldSavePlayer(player)) {
setJoin(player.getName());
}
}
/**
* Returns whether the given player is able to perform the command
* @param name the name of the player to check
* @return true if the player is not in the set (so it's allowed to perform the command), false otherwise
*/
public boolean isAllowed(String name) {
return !latestJoin.contains(name);
}
@Override
public void reload(Settings settings) {
long countTimeout = settings.getProperty(ProtectionSettings.QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS);
latestJoin.setExpiration(countTimeout, TimeUnit.MILLISECONDS);
}
@Override
public void performCleanup() {
latestJoin.removeExpiredEntries();
}
}
@@ -1,5 +1,6 @@
package fr.xephi.authme.listener;
import fr.xephi.authme.data.QuickCommandsProtectionManager;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey;
@@ -86,6 +87,8 @@ public class PlayerListener implements Listener {
@Inject
private PermissionsManager permissionsManager;
@Inject
private QuickCommandsProtectionManager quickCommandsProtectionManager;
@Inject
private BungeeSender bungeeSender;
private boolean isAsyncPlayerPreLoginEventCalled = false;
@@ -100,6 +103,11 @@ public class PlayerListener implements Listener {
return;
}
final Player player = event.getPlayer();
if (!quickCommandsProtectionManager.isAllowed(player.getName())) {
event.setCancelled(true);
player.kickPlayer(m.retrieveSingle(player, MessageKey.QUICK_COMMAND_PROTECTION_KICK));
return;
}
if (listenerService.shouldCancelEvent(player)) {
event.setCancelled(true);
m.send(player, MessageKey.DENIED_COMMAND);
@@ -207,6 +215,9 @@ public class PlayerListener implements Listener {
if (!PlayerListener19Spigot.isPlayerSpawnLocationEventCalled()) {
teleportationService.teleportOnJoin(player);
}
quickCommandsProtectionManager.processJoin(player);
management.performJoin(player);
teleportationService.teleportNewPlayerToFirstSpawn(player);
@@ -275,6 +275,9 @@ public enum MessageKey {
/** To verify your identity you need to link an email address with your account! */
VERIFICATION_CODE_EMAIL_NEEDED("verification.email_needed"),
/** You used a command too fast! Please, join the server again and wait more before using any command. */
QUICK_COMMAND_PROTECTION_KICK("on_join_validation.quick_command"),
/** second */
SECOND("time.second"),
@@ -68,7 +68,12 @@ public enum PlayerPermission implements PermissionNode {
/**
* Permission to use the email verification codes feature.
*/
VERIFICATION_CODE("authme.player.security.verificationcode");
VERIFICATION_CODE("authme.player.security.verificationcode"),
/**
* Permission that enables on join quick commands checks for the player.
*/
QUICK_COMMANDS_PROTECTION("authme.player.protection.quickcommandsprotection");
/**
* The permission node.
@@ -55,6 +55,10 @@ public final class ProtectionSettings implements SettingsHolder {
public static final Property<Integer> ANTIBOT_DELAY =
newProperty("Protection.antiBotDelay", 60);
@Comment("Kicks the player that issued a command before the defined time after the join process")
public static final Property<Integer> QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS =
newProperty("Protection.quickCommands.denyCommandsBeforeMilliseconds", 1000);
private ProtectionSettings() {
}