diff --git a/build.gradle b/build.gradle index 7475d36..fc5a8a5 100644 --- a/build.gradle +++ b/build.gradle @@ -52,6 +52,7 @@ dependencies { implementation("org.bstats:bstats-velocity:$bstatsVersion") implementation("net.elytrium:pcap:$pcapVersion") + implementation("redis.clients:jedis:4.2.3") compileOnly("com.github.spotbugs:spotbugs-annotations:$spotbugsVersion") } diff --git a/src/main/java/net/elytrium/limbofilter/LimboFilter.java b/src/main/java/net/elytrium/limbofilter/LimboFilter.java index 651c593..6f1ec26 100644 --- a/src/main/java/net/elytrium/limbofilter/LimboFilter.java +++ b/src/main/java/net/elytrium/limbofilter/LimboFilter.java @@ -42,9 +42,12 @@ import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import net.elytrium.commons.kyori.serialization.Serializer; import net.elytrium.commons.kyori.serialization.Serializers; import net.elytrium.commons.utils.updates.UpdatesChecker; +import net.elytrium.limboapi.BuildConstants; import net.elytrium.limboapi.api.Limbo; import net.elytrium.limboapi.api.LimboFactory; import net.elytrium.limboapi.api.chunk.VirtualWorld; @@ -77,11 +80,13 @@ import org.bstats.velocity.Metrics; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.slf4j.Logger; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; @Plugin( id = "limbofilter", name = "LimboFilter", - version = BuildConstants.FILTER_VERSION, + version = BuildConstants.LIMBO_VERSION, url = "https://elytrium.net/", authors = { "Elytrium (https://elytrium.net/)", @@ -118,6 +123,9 @@ public class LimboFilter { private boolean logsDisabled; private TcpListener tcpListener; + private JedisPool jedisPool; + private final Matcher nicknameMatcher = Pattern.compile("[^a-zA-Z0-9_]+").matcher(""); + @Inject public LimboFilter(Logger logger, ProxyServer server, Metrics.Factory metricsFactory, @DataDirectory Path dataDirectory) { setLogger(logger); @@ -168,6 +176,16 @@ public void onProxyInitialization(ProxyInitializeEvent event) { public void reload() { Settings.IMP.reload(this.configFile, Settings.IMP.PREFIX); + if (Settings.IMP.MAIN.REDIS.ENABLE) { + this.jedisPool = new JedisPool(Settings.IMP.MAIN.REDIS.HOST, Settings.IMP.MAIN.REDIS.PORT); + + try (Jedis jedis = this.jedisPool.getResource()) { + if (jedis.ping().equals("PONG")) { + LOGGER.info("Redis connected"); + } + } + } + ComponentSerializer serializer = Settings.IMP.SERIALIZER.getSerializer(); if (serializer == null) { LOGGER.warn("The specified serializer could not be founded, using default. (LEGACY_AMPERSAND)"); @@ -383,6 +401,18 @@ public boolean shouldCheck(Player player) { } public boolean shouldCheck(String nickname, InetAddress ip) { + if (this.jedisPool != null && Settings.IMP.MAIN.CAPTCHA_WHITELIST.ENABLE) { + try (Jedis jedis = this.jedisPool.getResource()) { + String sanitizedNickname = this.nicknameMatcher.reset(nickname).replaceAll(""); // Probably no need, but I did it anyway + if (jedis.exists("captcha_whitelist_nickname:" + sanitizedNickname) + || jedis.exists("captcha_whitelist_ip:" + ip.getHostAddress())) { + return false; + } else if (Settings.IMP.MAIN.CAPTCHA_WHITELIST.OVERRIDE_OTHER_CHECKS) { + return true; + } + } + } + if (this.cachedFilterChecks.containsKey(nickname)) { return !ip.equals(this.cachedFilterChecks.get(nickname).getInetAddress()); } else { diff --git a/src/main/java/net/elytrium/limbofilter/Settings.java b/src/main/java/net/elytrium/limbofilter/Settings.java index 987d1bc..f8c74d2 100644 --- a/src/main/java/net/elytrium/limbofilter/Settings.java +++ b/src/main/java/net/elytrium/limbofilter/Settings.java @@ -21,6 +21,7 @@ import java.util.Map; import net.elytrium.commons.config.YamlConfig; import net.elytrium.commons.kyori.serialization.Serializers; +import net.elytrium.limboapi.BuildConstants; import net.elytrium.limboapi.api.chunk.Dimension; import net.elytrium.limboapi.api.file.BuiltInWorldFileType; import net.elytrium.limboapi.api.player.GameMode; @@ -33,7 +34,7 @@ public class Settings extends YamlConfig { public static final Settings IMP = new Settings(); @Final - public String VERSION = BuildConstants.FILTER_VERSION; + public String VERSION = BuildConstants.LIMBO_VERSION; @Comment({ "Available serializers:", @@ -445,5 +446,27 @@ public static class STRINGS { public String CAPTCHA_NOT_READY_YET = "{PRFX} Captcha is not ready yet. Try again in a few seconds"; } + + @Create + public REDIS REDIS; + + @Comment("Redis connection settings") + public static class REDIS { + + public boolean ENABLE = false; + public String HOST = "localhost"; + public int PORT = 6379; + } + + + @Create + public CAPTCHA_WHITELIST CAPTCHA_WHITELIST; + + @Comment("Whitelist usernames or IP addresses to not show captcha") + public static class CAPTCHA_WHITELIST { + + public boolean ENABLE = false; + public boolean OVERRIDE_OTHER_CHECKS = false; + } } }