mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-10-06 02:17:25 +02:00
Alter how command lists are interpreted. Might fix some issues.
Details: * Only trim commands from the left side (both on feed and check). * Ensure versions with and without leading '/' are fed into trees. * Move methods to feed CharPrefixTree from configs to CommandUtil. Potentially fixes (untested): * Only deny the sub-commands for a prefix, example: feed 'version ' to consoleonly, in order to allow 'version' but not 'version NoCheatplus'. * Might fix some plugin/server specific prefixes not being detected, example: feed "/version" and expect "/bukkit:version" to be blocked.
This commit is contained in:
parent
878848c4d1
commit
ea5b249197
@ -164,7 +164,7 @@ public class StringUtil {
|
|||||||
|
|
||||||
return p[n];
|
return p[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just return the stack trace as new-line-separated string.
|
* Just return the stack trace as new-line-separated string.
|
||||||
* @param t
|
* @param t
|
||||||
@ -214,7 +214,7 @@ public class StringUtil {
|
|||||||
}
|
}
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method for stackTraceToString(t).
|
* Convenience method for stackTraceToString(t).
|
||||||
* @param t
|
* @param t
|
||||||
@ -223,7 +223,7 @@ public class StringUtil {
|
|||||||
public static final String throwableToString(final Throwable t) {
|
public static final String throwableToString(final Throwable t) {
|
||||||
return stackTraceToString(t, true, true);
|
return stackTraceToString(t, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count number of needles left in a dart board.
|
* Count number of needles left in a dart board.
|
||||||
* @param dartBoard
|
* @param dartBoard
|
||||||
@ -243,4 +243,37 @@ public class StringUtil {
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a version of a String with all leading whitespace removed.
|
||||||
|
*
|
||||||
|
* @param input
|
||||||
|
* @return String with leading whitespace removed. Returns the original
|
||||||
|
* reference, if there is no leading whitespace.
|
||||||
|
*/
|
||||||
|
public static final String leftTrim(final String input) {
|
||||||
|
if (input == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final int len = input.length();
|
||||||
|
int beginIndex = 0;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (Character.isWhitespace(input.charAt(i))) {
|
||||||
|
++beginIndex;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (beginIndex > 0) {
|
||||||
|
if (beginIndex >= len) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return input.substring(beginIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,14 +13,14 @@ import fr.neatmonster.nocheatplus.utilities.StringUtil;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TestStringUtil {
|
public class TestStringUtil {
|
||||||
|
|
||||||
private void assertCount(String data, char searchFor, int num) {
|
private void assertCount(String data, char searchFor, int num) {
|
||||||
int res = StringUtil.count(data, searchFor);
|
int res = StringUtil.count(data, searchFor);
|
||||||
if (res != num) {
|
if (res != num) {
|
||||||
fail("Expect to find '" + searchFor + "' " + num + " times in '" + data + "', got instead: " + res);
|
fail("Expect to find '" + searchFor + "' " + num + " times in '" + data + "', got instead: " + res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCount() {
|
public void testCount() {
|
||||||
assertCount("" , 'x', 0);
|
assertCount("" , 'x', 0);
|
||||||
@ -34,7 +34,7 @@ public class TestStringUtil {
|
|||||||
assertCount("oxx" , 'x', 2);
|
assertCount("oxx" , 'x', 2);
|
||||||
assertCount("230489tuvn1374z1hxk,34htmc1", '3', 3);
|
assertCount("230489tuvn1374z1hxk,34htmc1", '3', 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recursiveFail(int now, int max) {
|
private void recursiveFail(int now, int max) {
|
||||||
now ++;
|
now ++;
|
||||||
if (now >= max) {
|
if (now >= max) {
|
||||||
@ -44,7 +44,7 @@ public class TestStringUtil {
|
|||||||
recursiveFail(now, max);
|
recursiveFail(now, max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indirectly by counting line breaks with StringUtil.
|
* Indirectly by counting line breaks with StringUtil.
|
||||||
* @param recursionDepth
|
* @param recursionDepth
|
||||||
@ -62,7 +62,7 @@ public class TestStringUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indirectly by counting line breaks with StringUtil.
|
* Indirectly by counting line breaks with StringUtil.
|
||||||
* @param recursionDepth
|
* @param recursionDepth
|
||||||
@ -80,15 +80,37 @@ public class TestStringUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStackTraceLinear() {
|
public void testStackTraceLinear() {
|
||||||
assertMinimumStackTraceLength(1000, 1000, false);
|
assertMinimumStackTraceLength(1000, 1000, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStackTraceTrimmed() {
|
public void testStackTraceTrimmed() {
|
||||||
assertMaximumStackTraceLength(1000, 50, true);
|
assertMaximumStackTraceLength(1000, 50, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void testLeftTrim(String input, String expectedResult) {
|
||||||
|
String result = StringUtil.leftTrim(input);
|
||||||
|
if (!expectedResult.equals(result)) {
|
||||||
|
fail("Expect leftTrim for '" + input + "' to return '" + expectedResult + "', got instead: '" + result + "'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLeftTrim() {
|
||||||
|
if (StringUtil.leftTrim(null) != null) {
|
||||||
|
fail("Expect leftTrim to return null for null input, got instead: '" + StringUtil.leftTrim(null) + "'.");
|
||||||
|
}
|
||||||
|
for (String[] spec : new String[][]{
|
||||||
|
{"", ""},
|
||||||
|
{" \t", ""},
|
||||||
|
{" TEST", "TEST"},
|
||||||
|
{"\t\n TEST", "TEST"},
|
||||||
|
{" TEST ", "TEST "}
|
||||||
|
}) {
|
||||||
|
testLeftTrim(spec[0], spec[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package fr.neatmonster.nocheatplus.checks.chat;
|
package fr.neatmonster.nocheatplus.checks.chat;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
@ -22,6 +21,7 @@ import fr.neatmonster.nocheatplus.components.JoinLeaveListener;
|
|||||||
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
||||||
import fr.neatmonster.nocheatplus.config.ConfigFile;
|
import fr.neatmonster.nocheatplus.config.ConfigFile;
|
||||||
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.StringUtil;
|
||||||
import fr.neatmonster.nocheatplus.utilities.TickTask;
|
import fr.neatmonster.nocheatplus.utilities.TickTask;
|
||||||
import fr.neatmonster.nocheatplus.utilities.ds.prefixtree.SimpleCharPrefixTree;
|
import fr.neatmonster.nocheatplus.utilities.ds.prefixtree.SimpleCharPrefixTree;
|
||||||
|
|
||||||
@ -31,81 +31,56 @@ import fr.neatmonster.nocheatplus.utilities.ds.prefixtree.SimpleCharPrefixTree;
|
|||||||
* @see ChatEvent
|
* @see ChatEvent
|
||||||
*/
|
*/
|
||||||
public class ChatListener extends CheckListener implements INotifyReload, JoinLeaveListener {
|
public class ChatListener extends CheckListener implements INotifyReload, JoinLeaveListener {
|
||||||
|
|
||||||
// Checks.
|
// Checks.
|
||||||
|
|
||||||
/** Captcha handler. */
|
/** Captcha handler. */
|
||||||
private final Captcha captcha = addCheck(new Captcha());
|
private final Captcha captcha = addCheck(new Captcha());
|
||||||
|
|
||||||
/** The color check. */
|
/** The color check. */
|
||||||
private final Color color = addCheck(new Color());
|
private final Color color = addCheck(new Color());
|
||||||
|
|
||||||
/** Commands repetition check. */
|
/** Commands repetition check. */
|
||||||
private final Commands commands = addCheck(new Commands());
|
private final Commands commands = addCheck(new Commands());
|
||||||
|
|
||||||
/** Logins check (global) */
|
/** Logins check (global) */
|
||||||
private final Logins logins = addCheck(new Logins());
|
private final Logins logins = addCheck(new Logins());
|
||||||
|
|
||||||
/** Chat message check. */
|
/** Chat message check. */
|
||||||
private final Text text = addCheck(new Text());
|
private final Text text = addCheck(new Text());
|
||||||
|
|
||||||
/** Relogging check. */
|
/** Relogging check. */
|
||||||
private final Relog relog = addCheck(new Relog());
|
private final Relog relog = addCheck(new Relog());
|
||||||
|
|
||||||
// Auxiliary stuff.
|
// Auxiliary stuff.
|
||||||
|
|
||||||
/** Commands to be ignored completely. */
|
/** Commands to be ignored completely. */
|
||||||
private final SimpleCharPrefixTree commandExclusions = new SimpleCharPrefixTree();
|
private final SimpleCharPrefixTree commandExclusions = new SimpleCharPrefixTree();
|
||||||
|
|
||||||
/** Commands to be handled as chat. */
|
/** Commands to be handled as chat. */
|
||||||
private final SimpleCharPrefixTree chatCommands = new SimpleCharPrefixTree();
|
private final SimpleCharPrefixTree chatCommands = new SimpleCharPrefixTree();
|
||||||
|
|
||||||
/** Commands not to be executed in-game. */
|
/** Commands not to be executed in-game. */
|
||||||
private final SimpleCharPrefixTree consoleOnlyCommands = new SimpleCharPrefixTree();
|
private final SimpleCharPrefixTree consoleOnlyCommands = new SimpleCharPrefixTree();
|
||||||
|
|
||||||
public ChatListener(){
|
public ChatListener() {
|
||||||
super(CheckType.CHAT);
|
super(CheckType.CHAT);
|
||||||
ConfigFile config = ConfigManager.getConfigFile();
|
ConfigFile config = ConfigManager.getConfigFile();
|
||||||
initFilters(config);
|
initFilters(config);
|
||||||
// (text inits in constructor.)
|
// (text inits in constructor.)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void initFilters(ConfigFile config) {
|
||||||
* Clear tree and feed lower case. Add versions with "/" if missing.
|
CommandUtil.feedCommands(consoleOnlyCommands, config, ConfPaths.PROTECT_COMMANDS_CONSOLEONLY_CMDS, true);
|
||||||
* @param tree
|
CommandUtil.feedCommands(chatCommands, config, ConfPaths.CHAT_COMMANDS_HANDLEASCHAT, true);
|
||||||
* @param inputs
|
CommandUtil.feedCommands(commandExclusions, config, ConfPaths.CHAT_COMMANDS_EXCLUSIONS, true);
|
||||||
*/
|
|
||||||
private void feedCommands(SimpleCharPrefixTree tree, Collection<String> inputs){
|
|
||||||
tree.clear();
|
|
||||||
tree.feedAll(inputs, false, true);
|
|
||||||
for (String input : inputs){
|
|
||||||
if (!input.trim().startsWith("/")){
|
|
||||||
tree.feed("/" + input.trim().toLowerCase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@EventHandler(priority=EventPriority.MONITOR)
|
||||||
* Read string list from config and call feedCommands(tree, list).
|
public void onPlayerChangedWorld(final PlayerChangedWorldEvent event) {
|
||||||
* @param tree
|
// Tell TickTask to update cached permissions.
|
||||||
* @param config
|
|
||||||
* @param configPath
|
|
||||||
*/
|
|
||||||
private void feedCommands(SimpleCharPrefixTree tree, ConfigFile config, String configPath){
|
|
||||||
feedCommands(tree, config.getStringList(configPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initFilters(ConfigFile config) {
|
|
||||||
feedCommands(consoleOnlyCommands, config, ConfPaths.PROTECT_COMMANDS_CONSOLEONLY_CMDS);
|
|
||||||
feedCommands(chatCommands, config, ConfPaths.CHAT_COMMANDS_HANDLEASCHAT);
|
|
||||||
feedCommands(commandExclusions, config, ConfPaths.CHAT_COMMANDS_EXCLUSIONS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority=EventPriority.MONITOR)
|
|
||||||
public void onPlayerChangedWorld(final PlayerChangedWorldEvent event){
|
|
||||||
// Tell TickTask to update cached permissions.
|
|
||||||
TickTask.requestPermissionUpdate(event.getPlayer().getName(), CheckType.CHAT);
|
TickTask.requestPermissionUpdate(event.getPlayer().getName(), CheckType.CHAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We listen to PlayerChat events for obvious reasons.
|
* We listen to PlayerChat events for obvious reasons.
|
||||||
@ -115,10 +90,10 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
|
|||||||
*/
|
*/
|
||||||
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOWEST)
|
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOWEST)
|
||||||
public void onPlayerChat(final AsyncPlayerChatEvent event) {
|
public void onPlayerChat(final AsyncPlayerChatEvent event) {
|
||||||
|
|
||||||
final Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
final boolean alreadyCancelled = event.isCancelled();
|
final boolean alreadyCancelled = event.isCancelled();
|
||||||
|
|
||||||
// Tell TickTask to update cached permissions.
|
// Tell TickTask to update cached permissions.
|
||||||
// (Might omit this if already cancelled.)
|
// (Might omit this if already cancelled.)
|
||||||
// TODO: Implement to only update on "timeout" or checks being activated at all.
|
// TODO: Implement to only update on "timeout" or checks being activated at all.
|
||||||
@ -126,15 +101,15 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
|
|||||||
|
|
||||||
// First the color check.
|
// First the color check.
|
||||||
if (!alreadyCancelled && color.isEnabled(player)) {
|
if (!alreadyCancelled && color.isEnabled(player)) {
|
||||||
event.setMessage(color.check(player, event.getMessage(), false));
|
event.setMessage(color.check(player, event.getMessage(), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then the no chat check.
|
// Then the no chat check.
|
||||||
// TODO: isMainThread: Could consider event.isAsync ?
|
// TODO: isMainThread: Could consider event.isAsync ?
|
||||||
if (textChecks(player, event.getMessage(), false, alreadyCancelled)) {
|
if (textChecks(player, event.getMessage(), false, alreadyCancelled)) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,71 +121,71 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
|
|||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) {
|
public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) {
|
||||||
final Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
|
|
||||||
// Tell TickTask to update cached permissions.
|
// Tell TickTask to update cached permissions.
|
||||||
TickTask.requestPermissionUpdate(player.getName(), CheckType.CHAT);
|
TickTask.requestPermissionUpdate(player.getName(), CheckType.CHAT);
|
||||||
|
|
||||||
final ChatConfig cc = ChatConfig.getConfig(player);
|
final ChatConfig cc = ChatConfig.getConfig(player);
|
||||||
|
|
||||||
// Checks that replace parts of the message (color).
|
// Checks that replace parts of the message (color).
|
||||||
if (color.isEnabled(player)){
|
if (color.isEnabled(player)) {
|
||||||
event.setMessage(color.check(player, event.getMessage(), true));
|
event.setMessage(color.check(player, event.getMessage(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim is necessary because the server accepts leading spaces with commands.
|
// Left-trim is necessary because the server accepts leading spaces with commands.
|
||||||
final String message = event.getMessage();
|
final String message = event.getMessage();
|
||||||
final String lcMessage = message.trim().toLowerCase();
|
final String lcMessage = StringUtil.leftTrim(message).toLowerCase();
|
||||||
// TODO: Remove bukkit: etc.
|
// TODO: Remove bukkit: etc.
|
||||||
|
|
||||||
final String[] split = lcMessage.split(" ", 2);
|
final String[] split = lcMessage.split(" ", 2);
|
||||||
final String alias = split[0].substring(1);
|
final String alias = split[0].substring(1);
|
||||||
final Command command = CommandUtil.getCommand(alias);
|
final Command command = CommandUtil.getCommand(alias);
|
||||||
|
|
||||||
final List<String> messageVars = new ArrayList<String>(); // Could as well use an array and allow null on input of SimpleCharPrefixTree.
|
final List<String> messageVars = new ArrayList<String>(); // Could as well use an array and allow null on input of SimpleCharPrefixTree.
|
||||||
messageVars.add(lcMessage);
|
messageVars.add(lcMessage);
|
||||||
String checkMessage = message; // Message to run chat checks on.
|
String checkMessage = message; // Message to run chat checks on.
|
||||||
if (command != null){
|
if (command != null) {
|
||||||
messageVars.add("/" + command.getLabel().toLowerCase() + (split.length > 1 ? (" " + split[1]) : ""));
|
messageVars.add("/" + command.getLabel().toLowerCase() + (split.length > 1 ? (" " + split[1]) : ""));
|
||||||
}
|
}
|
||||||
if (alias.indexOf(":") != -1) {
|
if (alias.indexOf(":") != -1) {
|
||||||
final int index = message.indexOf(":") + 1;
|
final int index = message.indexOf(":") + 1;
|
||||||
if (index < message.length()) {
|
if (index < message.length()) {
|
||||||
checkMessage = message.substring(index);
|
checkMessage = message.substring(index);
|
||||||
messageVars.add(checkMessage.toLowerCase());
|
messageVars.add(checkMessage.toLowerCase());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Prevent commands from being used by players (e.g. /op /deop /reload).
|
// Prevent commands from being used by players (e.g. /op /deop /reload).
|
||||||
if (cc.consoleOnlyCheck && consoleOnlyCommands.hasAnyPrefixWords(messageVars)) {
|
if (cc.consoleOnlyCheck && consoleOnlyCommands.hasAnyPrefixWords(messageVars)) {
|
||||||
if (command == null || command.testPermission(player)){
|
if (command == null || command.testPermission(player)) {
|
||||||
player.sendMessage(cc.consoleOnlyMessage);
|
player.sendMessage(cc.consoleOnlyMessage);
|
||||||
}
|
}
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle as chat or command.
|
// Handle as chat or command.
|
||||||
if (chatCommands.hasAnyPrefixWords(messageVars)){
|
if (chatCommands.hasAnyPrefixWords(messageVars)) {
|
||||||
// Treat as chat.
|
// Treat as chat.
|
||||||
// TODO: Consider requesting permission updates on these, for consistency.
|
// TODO: Consider requesting permission updates on these, for consistency.
|
||||||
// TODO: Cut off the command ?.
|
// TODO: Cut off the command ?.
|
||||||
if (textChecks(player, checkMessage, true, false)) {
|
if (textChecks(player, checkMessage, true, false)) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!commandExclusions.hasAnyPrefixWords(messageVars)){
|
else if (!commandExclusions.hasAnyPrefixWords(messageVars)) {
|
||||||
// Treat as command.
|
// Treat as command.
|
||||||
if (commands.isEnabled(player) && commands.check(player, checkMessage, captcha)) {
|
if (commands.isEnabled(player) && commands.check(player, checkMessage, captcha)) {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean textChecks(final Player player, final String message, final boolean isMainThread, final boolean alreadyCancelled) {
|
private boolean textChecks(final Player player, final String message, final boolean isMainThread, final boolean alreadyCancelled) {
|
||||||
return text.isEnabled(player) && text.check(player, message, captcha, isMainThread, alreadyCancelled);
|
return text.isEnabled(player) && text.check(player, message, captcha, isMainThread, alreadyCancelled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We listen to this type of events to prevent spambots from login to the server.
|
* We listen to this type of events to prevent spambots from login to the server.
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
@ -219,54 +194,54 @@ public class ChatListener extends CheckListener implements INotifyReload, JoinLe
|
|||||||
@EventHandler(
|
@EventHandler(
|
||||||
priority = EventPriority.NORMAL)
|
priority = EventPriority.NORMAL)
|
||||||
public void onPlayerLogin(final PlayerLoginEvent event) {
|
public void onPlayerLogin(final PlayerLoginEvent event) {
|
||||||
if (event.getResult() != Result.ALLOWED) return;
|
if (event.getResult() != Result.ALLOWED) return;
|
||||||
final Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
final ChatConfig cc = ChatConfig.getConfig(player);
|
final ChatConfig cc = ChatConfig.getConfig(player);
|
||||||
final ChatData data = ChatData.getData(player);
|
final ChatData data = ChatData.getData(player);
|
||||||
|
|
||||||
// Tell TickTask to update cached permissions.
|
// Tell TickTask to update cached permissions.
|
||||||
TickTask.requestPermissionUpdate(player.getName(), CheckType.CHAT);
|
TickTask.requestPermissionUpdate(player.getName(), CheckType.CHAT);
|
||||||
// Force permission update.
|
// Force permission update.
|
||||||
TickTask.updatePermissions(); // TODO: This updates ALL... something more efficient ?
|
TickTask.updatePermissions(); // TODO: This updates ALL... something more efficient ?
|
||||||
|
|
||||||
// Reset captcha of player if needed.
|
// Reset captcha of player if needed.
|
||||||
synchronized(data){
|
synchronized(data) {
|
||||||
captcha.resetCaptcha(cc, data);
|
captcha.resetCaptcha(cc, data);
|
||||||
}
|
}
|
||||||
// Fast relog check.
|
// Fast relog check.
|
||||||
if (relog.isEnabled(player) && relog.unsafeLoginCheck(player, cc, data)){
|
if (relog.isEnabled(player) && relog.unsafeLoginCheck(player, cc, data)) {
|
||||||
event.disallow(Result.KICK_OTHER, cc.relogKickMessage);
|
event.disallow(Result.KICK_OTHER, cc.relogKickMessage);
|
||||||
}
|
}
|
||||||
else if (logins.isEnabled(player) && logins.check(player, cc, data)){
|
else if (logins.isEnabled(player) && logins.check(player, cc, data)) {
|
||||||
event.disallow(Result.KICK_OTHER, cc.loginsKickMessage);
|
event.disallow(Result.KICK_OTHER, cc.loginsKickMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReload() {
|
public void onReload() {
|
||||||
// Read some things from the global config file.
|
// Read some things from the global config file.
|
||||||
ConfigFile config = ConfigManager.getConfigFile();
|
ConfigFile config = ConfigManager.getConfigFile();
|
||||||
initFilters(config);
|
initFilters(config);
|
||||||
text.onReload();
|
text.onReload();
|
||||||
logins.onReload();
|
logins.onReload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playerJoins(final Player player) {
|
public void playerJoins(final Player player) {
|
||||||
final ChatConfig cc = ChatConfig.getConfig(player);
|
final ChatConfig cc = ChatConfig.getConfig(player);
|
||||||
final ChatData data = ChatData.getData(player);
|
final ChatData data = ChatData.getData(player);
|
||||||
synchronized (data) {
|
synchronized (data) {
|
||||||
if (captcha.isEnabled(player) && captcha.shouldCheckCaptcha(cc, data)){
|
if (captcha.isEnabled(player) && captcha.shouldCheckCaptcha(cc, data)) {
|
||||||
// shouldCheckCaptcha: only if really enabled.
|
// shouldCheckCaptcha: only if really enabled.
|
||||||
// TODO: Later: add check for cc.captchaOnLogin or so (before shouldCheckCaptcha).
|
// TODO: Later: add check for cc.captchaOnLogin or so (before shouldCheckCaptcha).
|
||||||
// TODO: maybe schedule this to come after other plugins messages.
|
// TODO: maybe schedule this to come after other plugins messages.
|
||||||
captcha.sendNewCaptcha(player, cc, data);
|
captcha.sendNewCaptcha(player, cc, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playerLeaves(final Player player) {
|
public void playerLeaves(final Player player) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,10 @@ import org.bukkit.plugin.java.JavaPlugin;
|
|||||||
|
|
||||||
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
|
import fr.neatmonster.nocheatplus.config.ConfigFile;
|
||||||
import fr.neatmonster.nocheatplus.logging.StaticLog;
|
import fr.neatmonster.nocheatplus.logging.StaticLog;
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.StringUtil;
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.ds.prefixtree.SimpleCharPrefixTree;
|
||||||
|
|
||||||
public class CommandUtil {
|
public class CommandUtil {
|
||||||
|
|
||||||
@ -154,4 +157,55 @@ public class CommandUtil {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear tree and feed lower case. Adds versions with "/" if missing, also adds input without the first "/". No trimming is used, except left-trim.
|
||||||
|
* @param tree
|
||||||
|
* @param inputs
|
||||||
|
*/
|
||||||
|
public static void feedCommands(SimpleCharPrefixTree tree, Collection<String> inputs, boolean clear) {
|
||||||
|
if (clear) {
|
||||||
|
tree.clear();
|
||||||
|
}
|
||||||
|
for (String input : inputs) {
|
||||||
|
if (input == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!input.isEmpty()) {
|
||||||
|
// Do feed the original input.
|
||||||
|
tree.feed(input);
|
||||||
|
}
|
||||||
|
input = StringUtil.leftTrim(input).toLowerCase();
|
||||||
|
if (input.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tree.feed(input);
|
||||||
|
if (!input.startsWith("/")) {
|
||||||
|
// Add version with '/'.
|
||||||
|
tree.feed("/" + input);
|
||||||
|
} else {
|
||||||
|
// Add version without the first '/'.
|
||||||
|
// TODO: Consider removing all leading '/' here.
|
||||||
|
input = input.substring(1);
|
||||||
|
if (!input.isEmpty()) {
|
||||||
|
tree.feed(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read string list from config and call feedCommands(tree, list).
|
||||||
|
*
|
||||||
|
* @param tree
|
||||||
|
* @param config
|
||||||
|
* @param configPath
|
||||||
|
* @param clear If to clear the map before inserting anything.
|
||||||
|
*/
|
||||||
|
public static void feedCommands(SimpleCharPrefixTree tree, ConfigFile config, String configPath, boolean clear) {
|
||||||
|
final List<String> prefixes = config.getStringList(configPath);
|
||||||
|
if (prefixes != null) {
|
||||||
|
feedCommands(tree, prefixes, clear);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user