mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-04 23:07:44 +01:00
Bleeding: Put captcha into an own Check. Prepare chat.logins,
chat.relog and chat.commands .
This commit is contained in:
parent
b0be6353e9
commit
7693f25345
@ -62,9 +62,15 @@ public enum CheckType {
|
|||||||
BLOCKPLACE_SPEED(BLOCKPLACE, Permissions.BLOCKPLACE_SPEED),
|
BLOCKPLACE_SPEED(BLOCKPLACE, Permissions.BLOCKPLACE_SPEED),
|
||||||
|
|
||||||
CHAT(ChatConfig.factory, ChatData.factory),
|
CHAT(ChatConfig.factory, ChatData.factory),
|
||||||
|
CHAT_CAPTCHA(CHAT, Permissions.CHAT_CAPTCHA),
|
||||||
CHAT_COLOR(CHAT, Permissions.CHAT_COLOR),
|
CHAT_COLOR(CHAT, Permissions.CHAT_COLOR),
|
||||||
CHAT_NOPWNAGE(CHAT, Permissions.CHAT_NOPWNAGE),
|
CHAT_COMMANDS(CHAT, Permissions.CHAT_COMMANDS),
|
||||||
CHAT_GLOBALCHAT(CHAT, Permissions.CHAT_GLOBALCHAT),
|
CHAT_GLOBALCHAT(CHAT, Permissions.CHAT_GLOBALCHAT),
|
||||||
|
CHAT_LOGINS(CHAT, Permissions.CHAT_LOGINS),
|
||||||
|
CHAT_RELOG(CHAT, Permissions.CHAT_RELOG),
|
||||||
|
// TOOD: remove nopwnage
|
||||||
|
CHAT_NOPWNAGE(CHAT, Permissions.CHAT_NOPWNAGE),
|
||||||
|
|
||||||
|
|
||||||
COMBINED(CombinedConfig.factory, CombinedData.factory),
|
COMBINED(CombinedConfig.factory, CombinedData.factory),
|
||||||
COMBINED_IMPROBABLE(COMBINED, Permissions.COMBINED_IMPROBABLE),
|
COMBINED_IMPROBABLE(COMBINED, Permissions.COMBINED_IMPROBABLE),
|
||||||
|
101
src/fr/neatmonster/nocheatplus/checks/chat/Captcha.java
Normal file
101
src/fr/neatmonster/nocheatplus/checks/chat/Captcha.java
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package fr.neatmonster.nocheatplus.checks.chat;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.checks.AsyncCheck;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
|
import fr.neatmonster.nocheatplus.players.Permissions;
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOTE: EARLY REFACTORING STATE, MOST METHODS NEED SYNC OVER DATA !
|
||||||
|
* @author mc_dev
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Captcha extends AsyncCheck implements ICaptcha{
|
||||||
|
|
||||||
|
public Captcha() {
|
||||||
|
super(CheckType.CHAT_CAPTCHA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The random number generator. */
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkCaptcha(Player player, String message, ChatConfig cc, ChatData data, boolean isMainThread) {
|
||||||
|
// Correct answer to the captcha?
|
||||||
|
if (message.equals(data.captchaGenerated)) {
|
||||||
|
// Yes, clear his data and do not worry anymore about him.
|
||||||
|
data.clearNoPwnageData();
|
||||||
|
data.captchaStarted = false;
|
||||||
|
player.sendMessage(CheckUtils.replaceColors(cc.captchaSuccess));
|
||||||
|
} else {
|
||||||
|
// Increment his tries number counter.
|
||||||
|
data.captchTries++;
|
||||||
|
data.captchaVL ++;
|
||||||
|
// Does he failed too much times?
|
||||||
|
if (data.captchTries > cc.captchaTries) {
|
||||||
|
// Find out if we need to kick the player or not.
|
||||||
|
executeActions(player, data.captchaVL, 1, cc.captchaActions,
|
||||||
|
isMainThread);
|
||||||
|
// (Resetting captcha tries is done on quit/kick).
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display the question again (if not kicked).
|
||||||
|
if (player.isOnline())
|
||||||
|
sendCaptcha(player, cc, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendNewCaptcha(Player player, ChatConfig cc, ChatData data) {
|
||||||
|
// Display a captcha to the player.
|
||||||
|
generateCaptcha(cc, data, true);
|
||||||
|
sendCaptcha(player, cc, data);
|
||||||
|
data.captchaStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateCaptcha(ChatConfig cc, ChatData data, boolean reset) {
|
||||||
|
if (reset) data.captchTries = 0;
|
||||||
|
data.captchaGenerated = "";
|
||||||
|
for (int i = 0; i < cc.captchaLength; i++)
|
||||||
|
data.captchaGenerated += cc.captchaCharacters.charAt(random
|
||||||
|
.nextInt(cc.captchaCharacters.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetCaptcha(Player player){
|
||||||
|
ChatData data = ChatData.getData(player);
|
||||||
|
synchronized (data) {
|
||||||
|
resetCaptcha(ChatConfig.getConfig(player), data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetCaptcha(ChatConfig cc, ChatData data){
|
||||||
|
data.captchTries = 0;
|
||||||
|
if (shouldCheckCaptcha(cc, data) || shouldStartCaptcha(cc, data)){
|
||||||
|
generateCaptcha(cc, data, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendCaptcha(Player player, ChatConfig cc, ChatData data) {
|
||||||
|
player.sendMessage(CheckUtils.replaceColors(cc.captchaQuestion.replace("[captcha]",
|
||||||
|
data.captchaGenerated)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldStartCaptcha(ChatConfig cc, ChatData data) {
|
||||||
|
return cc.captchaCheck && !data.captchaStarted && !data.hasCachedPermission(Permissions.CHAT_CAPTCHA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldCheckCaptcha(ChatConfig cc, ChatData data) {
|
||||||
|
return cc.captchaCheck && data.captchaStarted && !data.hasCachedPermission(Permissions.CHAT_CAPTCHA);
|
||||||
|
}
|
||||||
|
}
|
@ -67,6 +67,14 @@ public class ChatConfig extends AsyncCheckConfig {
|
|||||||
return worldsMap.get(player.getWorld().getName());
|
return worldsMap.get(player.getWorld().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean captchaCheck;
|
||||||
|
public final String captchaCharacters;
|
||||||
|
public final int captchaLength;
|
||||||
|
public final String captchaQuestion;
|
||||||
|
public final String captchaSuccess;
|
||||||
|
public final int captchaTries;
|
||||||
|
public final ActionList captchaActions;
|
||||||
|
|
||||||
public final boolean colorCheck;
|
public final boolean colorCheck;
|
||||||
public final ActionList colorActions;
|
public final ActionList colorActions;
|
||||||
@ -93,14 +101,6 @@ public class ChatConfig extends AsyncCheckConfig {
|
|||||||
public final long noPwnageBannedTimeout;
|
public final long noPwnageBannedTimeout;
|
||||||
public final int noPwnageBannedWeight;
|
public final int noPwnageBannedWeight;
|
||||||
|
|
||||||
public final boolean noPwnageCaptchaCheck;
|
|
||||||
public final String noPwnageCaptchaCharacters;
|
|
||||||
public final int noPwnageCaptchaLength;
|
|
||||||
public final String noPwnageCaptchaQuestion;
|
|
||||||
public final String noPwnageCaptchaSuccess;
|
|
||||||
public final int noPwnageCaptchaTries;
|
|
||||||
public final ActionList noPwnageCaptchaActions;
|
|
||||||
|
|
||||||
public final boolean noPwnageFirstCheck;
|
public final boolean noPwnageFirstCheck;
|
||||||
public final long noPwnageFirstTimeout;
|
public final long noPwnageFirstTimeout;
|
||||||
public final int noPwnageFirstWeight;
|
public final int noPwnageFirstWeight;
|
||||||
@ -152,8 +152,17 @@ public class ChatConfig extends AsyncCheckConfig {
|
|||||||
Permissions.CHAT_COLOR,
|
Permissions.CHAT_COLOR,
|
||||||
Permissions.CHAT_GLOBALCHAT,
|
Permissions.CHAT_GLOBALCHAT,
|
||||||
Permissions.CHAT_NOPWNAGE,
|
Permissions.CHAT_NOPWNAGE,
|
||||||
Permissions.CHAT_NOPWNAGE_CAPTCHA,
|
Permissions.CHAT_CAPTCHA,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
captchaCheck = config.getBoolean(ConfPaths.CHAT_CAPTCHA_CHECK);
|
||||||
|
captchaCharacters = config.getString(ConfPaths.CHAT_CAPTCHA_CHARACTERS);
|
||||||
|
captchaLength = config.getInt(ConfPaths.CHAT_CAPTCHA_LENGTH);
|
||||||
|
captchaQuestion = config.getString(ConfPaths.CHAT_CAPTCHA_QUESTION);
|
||||||
|
captchaSuccess = config.getString(ConfPaths.CHAT_CAPTCHA_SUCCESS);
|
||||||
|
captchaTries = config.getInt(ConfPaths.CHAT_CAPTCHA_TRIES);
|
||||||
|
captchaActions = config.getActionList(ConfPaths.CHAT_CAPTCHA_ACTIONS, Permissions.CHAT_CAPTCHA);
|
||||||
|
|
||||||
colorCheck = config.getBoolean(ConfPaths.CHAT_COLOR_CHECK);
|
colorCheck = config.getBoolean(ConfPaths.CHAT_COLOR_CHECK);
|
||||||
colorActions = config.getActionList(ConfPaths.CHAT_COLOR_ACTIONS, Permissions.CHAT_COLOR);
|
colorActions = config.getActionList(ConfPaths.CHAT_COLOR_ACTIONS, Permissions.CHAT_COLOR);
|
||||||
|
|
||||||
@ -180,14 +189,6 @@ public class ChatConfig extends AsyncCheckConfig {
|
|||||||
noPwnageBannedTimeout = config.getLong(ConfPaths.CHAT_NOPWNAGE_BANNED_TIMEOUT);
|
noPwnageBannedTimeout = config.getLong(ConfPaths.CHAT_NOPWNAGE_BANNED_TIMEOUT);
|
||||||
noPwnageBannedWeight = config.getInt(ConfPaths.CHAT_NOPWNAGE_BANNED_WEIGHT);
|
noPwnageBannedWeight = config.getInt(ConfPaths.CHAT_NOPWNAGE_BANNED_WEIGHT);
|
||||||
|
|
||||||
noPwnageCaptchaCheck = config.getBoolean(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHECK);
|
|
||||||
noPwnageCaptchaCharacters = config.getString(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHARACTERS);
|
|
||||||
noPwnageCaptchaLength = config.getInt(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_LENGTH);
|
|
||||||
noPwnageCaptchaQuestion = config.getString(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_QUESTION);
|
|
||||||
noPwnageCaptchaSuccess = config.getString(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_SUCCESS);
|
|
||||||
noPwnageCaptchaTries = config.getInt(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_TRIES);
|
|
||||||
noPwnageCaptchaActions = config.getActionList(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_ACTIONS, Permissions.CHAT_NOPWNAGE_CAPTCHA);
|
|
||||||
|
|
||||||
noPwnageFirstCheck = config.getBoolean(ConfPaths.CHAT_NOPWNAGE_FIRST_CHECK);
|
noPwnageFirstCheck = config.getBoolean(ConfPaths.CHAT_NOPWNAGE_FIRST_CHECK);
|
||||||
noPwnageFirstTimeout = config.getLong(ConfPaths.CHAT_NOPWNAGE_FIRST_TIMEOUT);
|
noPwnageFirstTimeout = config.getLong(ConfPaths.CHAT_NOPWNAGE_FIRST_TIMEOUT);
|
||||||
noPwnageFirstWeight = config.getInt(ConfPaths.CHAT_NOPWNAGE_FIRST_WEIGHT);
|
noPwnageFirstWeight = config.getInt(ConfPaths.CHAT_NOPWNAGE_FIRST_WEIGHT);
|
||||||
|
@ -70,35 +70,41 @@ public class ChatData extends AsyncCheckData {
|
|||||||
public double captchaVL;
|
public double captchaVL;
|
||||||
public double colorVL;
|
public double colorVL;
|
||||||
public double globalChatVL;
|
public double globalChatVL;
|
||||||
public double noPwnageVL;
|
public double noPwnageVL;
|
||||||
|
|
||||||
|
// Captcha data.
|
||||||
|
public int captchTries;
|
||||||
|
public String captchaGenerated;
|
||||||
|
public boolean captchaStarted;
|
||||||
|
|
||||||
// Data of the globalchat check.
|
// Data of the globalchat check.
|
||||||
public final ActionFrequency globalChatFrequency = new ActionFrequency(10, 3000);
|
public final ActionFrequency globalChatFrequency = new ActionFrequency(10, 3000);
|
||||||
|
|
||||||
// Data of the no pwnage check.
|
// Data of the no pwnage check.
|
||||||
public int noPwnageCaptchTries;
|
|
||||||
public String noPwnageGeneratedCaptcha;
|
|
||||||
public boolean noPwnageHasStartedCaptcha;
|
|
||||||
public long noPwnageJoinTime;
|
public long noPwnageJoinTime;
|
||||||
|
|
||||||
public String noPwnageLastMessage;
|
public String noPwnageLastMessage;
|
||||||
public long noPwnageLastMessageTime;
|
public long noPwnageLastMessageTime;
|
||||||
public long noPwnageLastWarningTime;
|
public long noPwnageLastWarningTime;
|
||||||
public long noPwnageLeaveTime;
|
public long noPwnageLeaveTime;
|
||||||
|
|
||||||
|
|
||||||
public int noPwnageReloginWarnings;
|
public int noPwnageReloginWarnings;
|
||||||
public long noPwnageReloginWarningTime;
|
public long noPwnageReloginWarningTime;
|
||||||
|
|
||||||
public final ActionFrequency noPwnageSpeed = new ActionFrequency(5, 1000);
|
public final ActionFrequency noPwnageSpeed = new ActionFrequency(5, 1000);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the data of the no pwnage check.
|
* Clear the data of the no pwnage check.
|
||||||
*/
|
*/
|
||||||
public synchronized void clearNoPwnageData() {
|
public synchronized void clearNoPwnageData() {
|
||||||
noPwnageCaptchTries = noPwnageReloginWarnings = 0;
|
captchTries = noPwnageReloginWarnings = 0;
|
||||||
captchaVL = 0D;
|
captchaVL = 0D;
|
||||||
// colorVL <- is spared to avoid problems with spam + captcha success.
|
// colorVL <- is spared to avoid problems with spam + captcha success.
|
||||||
noPwnageVL = 0;
|
noPwnageVL = 0;
|
||||||
noPwnageSpeed.clear(System.currentTimeMillis());
|
noPwnageSpeed.clear(System.currentTimeMillis());
|
||||||
noPwnageJoinTime = noPwnageLastMessageTime = noPwnageLastWarningTime = noPwnageLeaveTime = noPwnageReloginWarningTime = 0L;
|
noPwnageJoinTime = noPwnageLastMessageTime = noPwnageLastWarningTime = noPwnageLeaveTime = noPwnageReloginWarningTime = 0L;
|
||||||
noPwnageGeneratedCaptcha = noPwnageLastMessage = "";
|
captchaGenerated = noPwnageLastMessage = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,9 @@ public class ChatListener implements Listener, INotifyReload {
|
|||||||
/** The no pwnage check. */
|
/** The no pwnage check. */
|
||||||
private final NoPwnage noPwnage = new NoPwnage();
|
private final NoPwnage noPwnage = new NoPwnage();
|
||||||
|
|
||||||
|
/** Captcha handler. */
|
||||||
|
private final Captcha captcha = new Captcha();
|
||||||
|
|
||||||
/** Global chat check (experiment: alternative / supplement). */
|
/** Global chat check (experiment: alternative / supplement). */
|
||||||
private final GlobalChat globalChat = new GlobalChat();
|
private final GlobalChat globalChat = new GlobalChat();
|
||||||
|
|
||||||
@ -94,9 +97,9 @@ public class ChatListener implements Listener, INotifyReload {
|
|||||||
if (color.isEnabled(player)) event.setMessage(color.check(player, event.getMessage(), false));
|
if (color.isEnabled(player)) event.setMessage(color.check(player, event.getMessage(), false));
|
||||||
|
|
||||||
// Then the no pwnage check.
|
// Then the no pwnage check.
|
||||||
if (noPwnage.isEnabled(player) && noPwnage.check(player, event.getMessage(), false, false))
|
if (noPwnage.isEnabled(player) && noPwnage.check(player, event.getMessage(), captcha, false, false))
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
else if (globalChat.isEnabled(player) && globalChat.check(player, event.getMessage(), (ICaptcha) noPwnage, false))
|
else if (globalChat.isEnabled(player) && globalChat.check(player, event.getMessage(), captcha, false))
|
||||||
// Only check those that got through.
|
// Only check those that got through.
|
||||||
// (ICaptcha to start captcha if desired.)
|
// (ICaptcha to start captcha if desired.)
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
@ -163,9 +166,9 @@ public class ChatListener implements Listener, INotifyReload {
|
|||||||
final boolean handleAsChat = chatCommands.hasPrefixWords(lcMessage);
|
final boolean handleAsChat = chatCommands.hasPrefixWords(lcMessage);
|
||||||
|
|
||||||
// Then the no pwnage check.
|
// Then the no pwnage check.
|
||||||
if (!commandExclusions.hasPrefixWords(lcMessage) && noPwnage.isEnabled(player) && noPwnage.check(player, event.getMessage(), !handleAsChat, true))
|
if (!commandExclusions.hasPrefixWords(lcMessage) && noPwnage.isEnabled(player) && noPwnage.check(player, event.getMessage(), captcha, !handleAsChat, true))
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
else if (handleAsChat && globalChat.isEnabled(player) && globalChat.check(player, event.getMessage(), noPwnage, true))
|
else if (handleAsChat && globalChat.isEnabled(player) && globalChat.check(player, event.getMessage(), captcha, true))
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +198,7 @@ public class ChatListener implements Listener, INotifyReload {
|
|||||||
TickTask.updatePermissions();
|
TickTask.updatePermissions();
|
||||||
|
|
||||||
// Reset captcha of player if needed.
|
// Reset captcha of player if needed.
|
||||||
noPwnage.resetCaptcha(player);
|
captcha.resetCaptcha(player);
|
||||||
|
|
||||||
// Execute the no pwnage check.
|
// Execute the no pwnage check.
|
||||||
if (noPwnage.isEnabled(player) && noPwnage.checkLogin(player))
|
if (noPwnage.isEnabled(player) && noPwnage.checkLogin(player))
|
||||||
|
11
src/fr/neatmonster/nocheatplus/checks/chat/Commands.java
Normal file
11
src/fr/neatmonster/nocheatplus/checks/chat/Commands.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package fr.neatmonster.nocheatplus.checks.chat;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.checks.Check;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
|
|
||||||
|
public class Commands extends Check {
|
||||||
|
public Commands() {
|
||||||
|
super(CheckType.CHAT_COMMANDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,7 +4,7 @@ import org.bukkit.entity.Player;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Captcha related operations.<br>
|
* Captcha related operations.<br>
|
||||||
* Auxiliary interface to avoid creating a new check type.
|
* Auxiliary interface, most methods should need sync over data, unless stated otherwise.
|
||||||
* @author mc_dev
|
* @author mc_dev
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -59,4 +59,18 @@ public interface ICaptcha {
|
|||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
public void resetCaptcha(ChatConfig cc, ChatData data);
|
public void resetCaptcha(ChatConfig cc, ChatData data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method. Should synchronize over data of player (!).
|
||||||
|
* @param player
|
||||||
|
*/
|
||||||
|
public void resetCaptcha(Player player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a captcha.
|
||||||
|
* @param cc
|
||||||
|
* @param data
|
||||||
|
* @param reset If to reset tries.
|
||||||
|
*/
|
||||||
|
public void generateCaptcha(ChatConfig cc, ChatData data, boolean reset);
|
||||||
}
|
}
|
||||||
|
12
src/fr/neatmonster/nocheatplus/checks/chat/Logins.java
Normal file
12
src/fr/neatmonster/nocheatplus/checks/chat/Logins.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package fr.neatmonster.nocheatplus.checks.chat;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.checks.Check;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
|
|
||||||
|
public class Logins extends Check {
|
||||||
|
|
||||||
|
public Logins() {
|
||||||
|
super(CheckType.CHAT_LOGINS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package fr.neatmonster.nocheatplus.checks.chat;
|
package fr.neatmonster.nocheatplus.checks.chat;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -11,7 +10,6 @@ import fr.neatmonster.nocheatplus.checks.AsyncCheck;
|
|||||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
||||||
import fr.neatmonster.nocheatplus.checks.combined.CombinedData;
|
import fr.neatmonster.nocheatplus.checks.combined.CombinedData;
|
||||||
import fr.neatmonster.nocheatplus.players.Permissions;
|
|
||||||
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -27,7 +25,7 @@ import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
|||||||
/**
|
/**
|
||||||
* The NoPwnage check will try to detect "spambots" (like the ones created by the PWN4G3 software).
|
* The NoPwnage check will try to detect "spambots" (like the ones created by the PWN4G3 software).
|
||||||
*/
|
*/
|
||||||
public class NoPwnage extends AsyncCheck implements ICaptcha{
|
public class NoPwnage extends AsyncCheck{
|
||||||
|
|
||||||
/** The last message which caused ban said. */
|
/** The last message which caused ban said. */
|
||||||
private String lastBanCausingMessage;
|
private String lastBanCausingMessage;
|
||||||
@ -40,10 +38,7 @@ public class NoPwnage extends AsyncCheck implements ICaptcha{
|
|||||||
|
|
||||||
/** The time it was when the last message was said. */
|
/** The time it was when the last message was said. */
|
||||||
private long lastGlobalMessageTime;
|
private long lastGlobalMessageTime;
|
||||||
|
|
||||||
/** The random number generator. */
|
|
||||||
private final Random random = new Random();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new no pwnage check.
|
* Instantiates a new no pwnage check.
|
||||||
*/
|
*/
|
||||||
@ -56,13 +51,14 @@ public class NoPwnage extends AsyncCheck implements ICaptcha{
|
|||||||
*
|
*
|
||||||
* @param player
|
* @param player
|
||||||
* the player
|
* the player
|
||||||
|
* @param captcha
|
||||||
* @param event
|
* @param event
|
||||||
* the event
|
* the event
|
||||||
* @param isMainThread
|
* @param isMainThread
|
||||||
* is the thread the main thread
|
* is the thread the main thread
|
||||||
* @return If to cancel the event.
|
* @return If to cancel the event.
|
||||||
*/
|
*/
|
||||||
public boolean check(final Player player, final String message, final boolean isCommand,
|
public boolean check(final Player player, final String message, final Captcha captcha, final boolean isCommand,
|
||||||
final boolean isMainThread) {
|
final boolean isMainThread) {
|
||||||
|
|
||||||
final ChatConfig cc = ChatConfig.getConfig(player);
|
final ChatConfig cc = ChatConfig.getConfig(player);
|
||||||
@ -70,7 +66,7 @@ public class NoPwnage extends AsyncCheck implements ICaptcha{
|
|||||||
|
|
||||||
// Keep related to ChatData/NoPwnage/Color used lock.
|
// Keep related to ChatData/NoPwnage/Color used lock.
|
||||||
synchronized (data) {
|
synchronized (data) {
|
||||||
return unsafeCheck(player, message, isCommand, isMainThread, cc, data);
|
return unsafeCheck(player, message, captcha, isCommand, isMainThread, cc, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +99,7 @@ public class NoPwnage extends AsyncCheck implements ICaptcha{
|
|||||||
* the player
|
* the player
|
||||||
* @param message
|
* @param message
|
||||||
* the message
|
* the message
|
||||||
|
* @param captcha
|
||||||
* @param isMainThread
|
* @param isMainThread
|
||||||
* the is main thread
|
* the is main thread
|
||||||
* @param cc
|
* @param cc
|
||||||
@ -111,14 +108,14 @@ public class NoPwnage extends AsyncCheck implements ICaptcha{
|
|||||||
* the data
|
* the data
|
||||||
* @return If to cancel the event.
|
* @return If to cancel the event.
|
||||||
*/
|
*/
|
||||||
private boolean unsafeCheck(final Player player, final String message, final boolean isCommand,
|
private boolean unsafeCheck(final Player player, final String message, final Captcha captcha, final boolean isCommand,
|
||||||
final boolean isMainThread, final ChatConfig cc, final ChatData data) {
|
final boolean isMainThread, final ChatConfig cc, final ChatData data) {
|
||||||
boolean cancel = false;
|
boolean cancel = false;
|
||||||
|
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
|
|
||||||
if (shouldCheckCaptcha(cc, data)) {
|
if (captcha.shouldCheckCaptcha(cc, data)) {
|
||||||
checkCaptcha(player, message, cc, data, isMainThread);
|
captcha.checkCaptcha(player, message, cc, data, isMainThread);
|
||||||
// Cancel the event.
|
// Cancel the event.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -177,8 +174,8 @@ public class NoPwnage extends AsyncCheck implements ICaptcha{
|
|||||||
player.sendMessage(CheckUtils.replaceColors(cc.noPwnageWarnPlayerMessage));
|
player.sendMessage(CheckUtils.replaceColors(cc.noPwnageWarnPlayerMessage));
|
||||||
data.noPwnageLastWarningTime = now;
|
data.noPwnageLastWarningTime = now;
|
||||||
} else if (suspicion > cc.noPwnageLevel)
|
} else if (suspicion > cc.noPwnageLevel)
|
||||||
if (shouldStartCaptcha(cc, data)) {
|
if (captcha.shouldStartCaptcha(cc, data)) {
|
||||||
sendNewCaptcha(player, cc, data);
|
captcha.sendNewCaptcha(player, cc, data);
|
||||||
cancel = true;
|
cancel = true;
|
||||||
} else {
|
} else {
|
||||||
lastBanCausingMessage = message;
|
lastBanCausingMessage = message;
|
||||||
@ -212,88 +209,7 @@ public class NoPwnage extends AsyncCheck implements ICaptcha{
|
|||||||
return cancel;
|
return cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkCaptcha(Player player, String message, ChatConfig cc, ChatData data, boolean isMainThread) {
|
|
||||||
// Correct answer to the captcha?
|
|
||||||
if (message.equals(data.noPwnageGeneratedCaptcha)) {
|
|
||||||
// Yes, clear his data and do not worry anymore about him.
|
|
||||||
data.clearNoPwnageData();
|
|
||||||
data.noPwnageHasStartedCaptcha = false;
|
|
||||||
player.sendMessage(CheckUtils.replaceColors(cc.noPwnageCaptchaSuccess));
|
|
||||||
} else {
|
|
||||||
// Increment his tries number counter.
|
|
||||||
data.noPwnageCaptchTries++;
|
|
||||||
data.captchaVL ++;
|
|
||||||
// Does he failed too much times?
|
|
||||||
if (data.noPwnageCaptchTries > cc.noPwnageCaptchaTries) {
|
|
||||||
// Find out if we need to kick the player or not.
|
|
||||||
executeActions(player, data.captchaVL, 1, cc.noPwnageCaptchaActions,
|
|
||||||
isMainThread);
|
|
||||||
// (Resetting captcha tries is done on quit/kick).
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the question again (if not kicked).
|
|
||||||
if (player.isOnline())
|
|
||||||
sendCaptcha(player, cc, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendNewCaptcha(Player player, ChatConfig cc, ChatData data) {
|
|
||||||
// Display a captcha to the player.
|
|
||||||
generateCaptcha(cc, data, true);
|
|
||||||
sendCaptcha(player, cc, data);
|
|
||||||
data.noPwnageHasStartedCaptcha = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Just generate captcha, reset tries if set so.
|
|
||||||
* @param cc
|
|
||||||
* @param data
|
|
||||||
* @param reset
|
|
||||||
*/
|
|
||||||
public void generateCaptcha(ChatConfig cc, ChatData data, boolean reset) {
|
|
||||||
if (reset) data.noPwnageCaptchTries = 0;
|
|
||||||
data.noPwnageGeneratedCaptcha = "";
|
|
||||||
for (int i = 0; i < cc.noPwnageCaptchaLength; i++)
|
|
||||||
data.noPwnageGeneratedCaptcha += cc.noPwnageCaptchaCharacters.charAt(random
|
|
||||||
.nextInt(cc.noPwnageCaptchaCharacters.length()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset captcha, synchronizes over ChatData instance for the player..
|
|
||||||
* @param player
|
|
||||||
*/
|
|
||||||
public void resetCaptcha(Player player){
|
|
||||||
ChatData data = ChatData.getData(player);
|
|
||||||
synchronized (data) {
|
|
||||||
resetCaptcha(ChatConfig.getConfig(player), data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resetCaptcha(ChatConfig cc, ChatData data){
|
|
||||||
data.noPwnageCaptchTries = 0;
|
|
||||||
if (shouldCheckCaptcha(cc, data) || shouldStartCaptcha(cc, data)){
|
|
||||||
generateCaptcha(cc, data, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendCaptcha(Player player, ChatConfig cc, ChatData data) {
|
|
||||||
player.sendMessage(CheckUtils.replaceColors(cc.noPwnageCaptchaQuestion.replace("[captcha]",
|
|
||||||
data.noPwnageGeneratedCaptcha)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldStartCaptcha(ChatConfig cc, ChatData data) {
|
|
||||||
return cc.noPwnageCaptchaCheck && !data.noPwnageHasStartedCaptcha && !data.hasCachedPermission(Permissions.CHAT_NOPWNAGE_CAPTCHA);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldCheckCaptcha(ChatConfig cc, ChatData data) {
|
|
||||||
return cc.noPwnageCaptchaCheck && data.noPwnageHasStartedCaptcha && !data.hasCachedPermission(Permissions.CHAT_NOPWNAGE_CAPTCHA);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check (Join), only call from synchronized code.
|
* Check (Join), only call from synchronized code.
|
||||||
|
12
src/fr/neatmonster/nocheatplus/checks/chat/Relog.java
Normal file
12
src/fr/neatmonster/nocheatplus/checks/chat/Relog.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package fr.neatmonster.nocheatplus.checks.chat;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.checks.Check;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
|
|
||||||
|
public class Relog extends Check {
|
||||||
|
|
||||||
|
public Relog() {
|
||||||
|
super(CheckType.CHAT_RELOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -180,6 +180,15 @@ public abstract class ConfPaths {
|
|||||||
@GlobalConfig
|
@GlobalConfig
|
||||||
public static final String CHAT_HANDLEASCHAT = CHAT + "handleaschat";
|
public static final String CHAT_HANDLEASCHAT = CHAT + "handleaschat";
|
||||||
|
|
||||||
|
private static final String CHAT_CAPTCHA = CHAT + "captcha.";
|
||||||
|
public static final String CHAT_CAPTCHA_CHECK = CHAT_CAPTCHA + "active";
|
||||||
|
public static final String CHAT_CAPTCHA_CHARACTERS = CHAT_CAPTCHA + "characters";
|
||||||
|
public static final String CHAT_CAPTCHA_LENGTH = CHAT_CAPTCHA + "length";
|
||||||
|
public static final String CHAT_CAPTCHA_QUESTION = CHAT_CAPTCHA + "question";
|
||||||
|
public static final String CHAT_CAPTCHA_SUCCESS = CHAT_CAPTCHA + "success";
|
||||||
|
public static final String CHAT_CAPTCHA_TRIES = CHAT_CAPTCHA + "tries";
|
||||||
|
public static final String CHAT_CAPTCHA_ACTIONS = CHAT_CAPTCHA + "actions";
|
||||||
|
|
||||||
private static final String CHAT_COLOR = CHAT + "color.";
|
private static final String CHAT_COLOR = CHAT + "color.";
|
||||||
public static final String CHAT_COLOR_CHECK = CHAT_COLOR + "active";
|
public static final String CHAT_COLOR_CHECK = CHAT_COLOR + "active";
|
||||||
public static final String CHAT_COLOR_ACTIONS = CHAT_COLOR + "actions";
|
public static final String CHAT_COLOR_ACTIONS = CHAT_COLOR + "actions";
|
||||||
@ -236,15 +245,6 @@ public abstract class ConfPaths {
|
|||||||
public static final String CHAT_NOPWNAGE_BANNED_TIMEOUT = CHAT_NOPWNAGE_BANNED + "timeout";
|
public static final String CHAT_NOPWNAGE_BANNED_TIMEOUT = CHAT_NOPWNAGE_BANNED + "timeout";
|
||||||
public static final String CHAT_NOPWNAGE_BANNED_WEIGHT = CHAT_NOPWNAGE_BANNED + "weight";
|
public static final String CHAT_NOPWNAGE_BANNED_WEIGHT = CHAT_NOPWNAGE_BANNED + "weight";
|
||||||
|
|
||||||
private static final String CHAT_NOPWNAGE_CAPTCHA = CHAT_NOPWNAGE + "captcha.";
|
|
||||||
public static final String CHAT_NOPWNAGE_CAPTCHA_CHECK = CHAT_NOPWNAGE_CAPTCHA + "active";
|
|
||||||
public static final String CHAT_NOPWNAGE_CAPTCHA_CHARACTERS = CHAT_NOPWNAGE_CAPTCHA + "characters";
|
|
||||||
public static final String CHAT_NOPWNAGE_CAPTCHA_LENGTH = CHAT_NOPWNAGE_CAPTCHA + "length";
|
|
||||||
public static final String CHAT_NOPWNAGE_CAPTCHA_QUESTION = CHAT_NOPWNAGE_CAPTCHA + "question";
|
|
||||||
public static final String CHAT_NOPWNAGE_CAPTCHA_SUCCESS = CHAT_NOPWNAGE_CAPTCHA + "success";
|
|
||||||
public static final String CHAT_NOPWNAGE_CAPTCHA_TRIES = CHAT_NOPWNAGE_CAPTCHA + "tries";
|
|
||||||
public static final String CHAT_NOPWNAGE_CAPTCHA_ACTIONS = CHAT_NOPWNAGE_CAPTCHA + "actions";
|
|
||||||
|
|
||||||
private static final String CHAT_NOPWNAGE_FIRST = CHAT_NOPWNAGE + "first.";
|
private static final String CHAT_NOPWNAGE_FIRST = CHAT_NOPWNAGE + "first.";
|
||||||
public static final String CHAT_NOPWNAGE_FIRST_CHECK = CHAT_NOPWNAGE_FIRST + "active";
|
public static final String CHAT_NOPWNAGE_FIRST_CHECK = CHAT_NOPWNAGE_FIRST + "active";
|
||||||
public static final String CHAT_NOPWNAGE_FIRST_TIMEOUT = CHAT_NOPWNAGE_FIRST + "timeout";
|
public static final String CHAT_NOPWNAGE_FIRST_TIMEOUT = CHAT_NOPWNAGE_FIRST + "timeout";
|
||||||
|
@ -144,16 +144,28 @@ public class DefaultConfig extends ConfigFile {
|
|||||||
* Y888 ,d 888 888 ,ee 888 888
|
* Y888 ,d 888 888 ,ee 888 888
|
||||||
* "88,d88 888 888 "88 888 888
|
* "88,d88 888 888 "88 888 888
|
||||||
*/
|
*/
|
||||||
|
|
||||||
set(ConfPaths.CHAT_COLOR_CHECK, true);
|
set(ConfPaths.CHAT_COLOR_CHECK, true);
|
||||||
set(ConfPaths.CHAT_COLOR_ACTIONS, "log:color:0:1:if cancel");
|
set(ConfPaths.CHAT_COLOR_ACTIONS, "log:color:0:1:if cancel");
|
||||||
|
|
||||||
|
// Multi purpose.
|
||||||
|
set(ConfPaths.CHAT_HANDLEASCHAT,
|
||||||
|
new LinkedList<String>(Arrays.asList(new String[]{"/me"})));
|
||||||
|
|
||||||
|
// Captcha.
|
||||||
|
set(ConfPaths.CHAT_CAPTCHA_CHECK, false);
|
||||||
|
set(ConfPaths.CHAT_CAPTCHA_CHARACTERS, "abcdefghjkmnpqrtuvwxyzABCDEFGHJKMNPQRTUVWXYZ2346789");
|
||||||
|
set(ConfPaths.CHAT_CAPTCHA_LENGTH, 6);
|
||||||
|
set(ConfPaths.CHAT_CAPTCHA_QUESTION, "&cPlease type '&6[captcha]&c' to continue sending messages/commands.");
|
||||||
|
set(ConfPaths.CHAT_CAPTCHA_SUCCESS, "&aOK, it sounds like you're not a spambot.");
|
||||||
|
set(ConfPaths.CHAT_CAPTCHA_TRIES, 3);
|
||||||
|
set(ConfPaths.CHAT_CAPTCHA_ACTIONS, "cancel cmd:kickcaptcha vl>4 log:captcha:2:5:cf cancel cmd:kickcaptcha");
|
||||||
|
|
||||||
// globalchat (ordering on purpose).
|
// globalchat (ordering on purpose).
|
||||||
set(ConfPaths.CHAT_GLOBALCHAT_CHECK, true);
|
set(ConfPaths.CHAT_GLOBALCHAT_CHECK, true);
|
||||||
set(ConfPaths.CHAT_GLOBALCHAT_LEVEL, 80);
|
set(ConfPaths.CHAT_GLOBALCHAT_LEVEL, 80);
|
||||||
set(ConfPaths.CHAT_GLOBALCHAT_FREQUENCY_FACTOR, 0.9D);
|
set(ConfPaths.CHAT_GLOBALCHAT_FREQUENCY_FACTOR, 0.9D);
|
||||||
set(ConfPaths.CHAT_GLOBALCHAT_FREQUENCY_WEIGHT, 6);
|
set(ConfPaths.CHAT_GLOBALCHAT_FREQUENCY_WEIGHT, 6);
|
||||||
set(ConfPaths.CHAT_HANDLEASCHAT,
|
|
||||||
new LinkedList<String>(Arrays.asList(new String[]{"/me"})));
|
|
||||||
set(ConfPaths.CHAT_GLOBALCHAT_GL_CHECK, true);
|
set(ConfPaths.CHAT_GLOBALCHAT_GL_CHECK, true);
|
||||||
set(ConfPaths.CHAT_GLOBALCHAT_GL_WEIGHT, 0.5);
|
set(ConfPaths.CHAT_GLOBALCHAT_GL_WEIGHT, 0.5);
|
||||||
set(ConfPaths.CHAT_GLOBALCHAT_GL_WORDS_CHECK, false);
|
set(ConfPaths.CHAT_GLOBALCHAT_GL_WORDS_CHECK, false);
|
||||||
@ -176,16 +188,6 @@ public class DefaultConfig extends ConfigFile {
|
|||||||
set(ConfPaths.CHAT_NOPWNAGE_BANNED_TIMEOUT, 5000L);
|
set(ConfPaths.CHAT_NOPWNAGE_BANNED_TIMEOUT, 5000L);
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_BANNED_WEIGHT, 100);
|
set(ConfPaths.CHAT_NOPWNAGE_BANNED_WEIGHT, 100);
|
||||||
|
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHECK, false);
|
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_CHARACTERS,
|
|
||||||
"abcdefghjkmnpqrtuvwxyzABCDEFGHJKMNPQRTUVWXYZ2346789");
|
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_LENGTH, 6);
|
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_QUESTION,
|
|
||||||
"&cPlease type '&6[captcha]&c' to continue sending messages/commands.");
|
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_SUCCESS, "&aOK, it sounds like you're not a spambot.");
|
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_TRIES, 3);
|
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_CAPTCHA_ACTIONS, "cancel cmd:kickcaptcha vl>4 log:captcha:2:5:cf cancel cmd:kickcaptcha");
|
|
||||||
|
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_FIRST_CHECK, true);
|
set(ConfPaths.CHAT_NOPWNAGE_FIRST_CHECK, true);
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_FIRST_TIMEOUT, 3000L);
|
set(ConfPaths.CHAT_NOPWNAGE_FIRST_TIMEOUT, 3000L);
|
||||||
set(ConfPaths.CHAT_NOPWNAGE_FIRST_WEIGHT, 200);
|
set(ConfPaths.CHAT_NOPWNAGE_FIRST_WEIGHT, 200);
|
||||||
|
@ -102,10 +102,14 @@ public class Permissions {
|
|||||||
* "88,d88 888 888 "88 888 888
|
* "88,d88 888 888 "88 888 888
|
||||||
*/
|
*/
|
||||||
private static final String CHAT = CHECKS + ".chat";
|
private static final String CHAT = CHECKS + ".chat";
|
||||||
|
public static final String CHAT_CAPTCHA = CHAT + ".captcha";
|
||||||
public static final String CHAT_COLOR = CHAT + ".color";
|
public static final String CHAT_COLOR = CHAT + ".color";
|
||||||
|
public static final String CHAT_COMMANDS = CHAT + ".commands";
|
||||||
public static final String CHAT_GLOBALCHAT = CHAT + ".globalchat";
|
public static final String CHAT_GLOBALCHAT = CHAT + ".globalchat";
|
||||||
|
public static final String CHAT_LOGINS = CHAT + ".logins";
|
||||||
|
public static final String CHAT_RELOG = CHAT + ".relog";
|
||||||
|
|
||||||
public static final String CHAT_NOPWNAGE = CHAT + ".nopwnage";
|
public static final String CHAT_NOPWNAGE = CHAT + ".nopwnage";
|
||||||
public static final String CHAT_NOPWNAGE_CAPTCHA = CHAT_NOPWNAGE + ".captcha";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Combined !
|
* Combined !
|
||||||
|
Loading…
Reference in New Issue
Block a user