diff --git a/.gitignore b/.gitignore index 6189b28..ed8c0eb 100644 --- a/.gitignore +++ b/.gitignore @@ -295,4 +295,5 @@ $RECYCLE.BIN/ # End of https://www.toptal.com/developers/gitignore/api/windows,macos,linux,maven,java,intellij,eclipse,netbeans /.gradle/ -.grade/** \ No newline at end of file +.grade/** +/run/ diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java index a1fb3f3..f0f1ab7 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java @@ -18,6 +18,7 @@ package dev.brighten.antivpn.bukkit; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.api.APIPlayer; +import dev.brighten.antivpn.api.CheckResult; import dev.brighten.antivpn.api.OfflinePlayer; import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.utils.StringUtil; @@ -82,28 +83,28 @@ public class BukkitListener extends VPNExecutor implements Listener { event.getAddress() )); - player.checkPlayer(result -> { - if(!result.resultType().isShouldBlock()) return; + CheckResult result = player.checkPlayer(); - if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { - return; - } + if(!result.resultType().isShouldBlock()) return; - event.setResult(PlayerLoginEvent.Result.KICK_BANNED); - event.setKickMessage(switch (result.resultType()) { - case DENIED_COUNTRY -> StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(), - player, - result.response() - ); - case DENIED_PROXY -> - StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().getKickMessage(), - player, - result.response() - ); - default -> "You were kicked by KauriVPN for an unknown reason!"; - }); + if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { + return; + } + + event.setResult(PlayerLoginEvent.Result.KICK_BANNED); + event.setKickMessage(switch (result.resultType()) { + case DENIED_COUNTRY -> StringUtil.varReplace( + AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(), + player, + result.response() + ); + case DENIED_PROXY -> + StringUtil.varReplace( + AntiVPN.getInstance().getVpnConfig().getKickMessage(), + player, + result.response() + ); + default -> "You were kicked by KauriVPN for an unknown reason!"; }); } diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java index b09cab2..2754a53 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -77,7 +77,6 @@ public class BungeeListener extends VPNExecutor implements Listener { @EventHandler(priority = EventPriority.HIGH) public void onListener(final PreLoginEvent event) { - APIPlayer player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getConnection().getUniqueId()) .orElseGet(() -> { UUID uuid = MiscUtils.lookupUUID(event.getConnection().getName()); @@ -88,22 +87,22 @@ public class BungeeListener extends VPNExecutor implements Listener { ((InetSocketAddress) event.getConnection().getSocketAddress()).getAddress()); }); - player.checkPlayer(result -> { - if (!result.resultType().isShouldBlock()) return; + CheckResult result = player.checkPlayer(); - if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { - return; - } + if (!result.resultType().isShouldBlock()) return; - event.setCancelled(true); - event.setReason(TextComponent.fromLegacy(StringUtil.varReplace(switch (result.resultType()) { - case DENIED_PROXY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() - .getKickMessage(), player, result.response()); - case DENIED_COUNTRY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() - .getCountryVanillaKickReason(), player, result.response()); - default -> "You were kicked by KauriVPN for an unknown reason!"; - }, player, result.response()))); - }); + if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { + return; + } + + event.setCancelled(true); + event.setReason(TextComponent.fromLegacy(StringUtil.varReplace(switch (result.resultType()) { + case DENIED_PROXY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() + .getKickMessage(), player, result.response()); + case DENIED_COUNTRY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() + .getCountryVanillaKickReason(), player, result.response()); + default -> "You were kicked by KauriVPN for an unknown reason!"; + }, player, result.response()))); } @EventHandler(priority = EventPriority.HIGH) diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java index 0bf5200..97554b0 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java @@ -26,7 +26,6 @@ import lombok.Setter; import java.net.InetAddress; import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; import java.util.logging.Level; @Getter @@ -74,7 +73,12 @@ public abstract class APIPlayer { ); } - public void checkPlayer(Consumer onResult) { + /*** + * The result is only returned if it is cached. Otherwise, there is an asynchronous call to the API + * and will handle kicking the player if necessary. + * @return CheckResult - The cached result of the check if it exists. + */ + public CheckResult checkPlayer() { if (hasPermission("antivpn.bypass") //Has bypass permission //Is exempt || (uuid != null && AntiVPN.getInstance().getExecutor().isWhitelisted(uuid)) @@ -82,8 +86,7 @@ public abstract class APIPlayer { || AntiVPN.getInstance().getExecutor().isWhitelisted(ip.getHostAddress() + "/32") || AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream() .anyMatch(name::startsWith)) { - onResult.accept(new CheckResult(null, ResultType.WHITELISTED, false)); - return; + return new CheckResult(null, ResultType.WHITELISTED, false); } CheckResult cachedResult = checkResultCache.getIfPresent(ip.getHostAddress()); @@ -94,8 +97,7 @@ public abstract class APIPlayer { if(cachedResult.resultType().isShouldBlock()) { AntiVPN.getInstance().getExecutor().handleKickingOfPlayer(cachedResult, this); } - onResult.accept(cachedResult); - return; + return cachedResult; } } @@ -105,7 +107,6 @@ public abstract class APIPlayer { AntiVPN.getInstance().getExecutor().log(Level.WARNING, "The API query was not a success! " + "You may need to upgrade your license on " + "https://funkemunky.cc/shop"); - onResult.accept(new CheckResult(null, ResultType.API_FAILURE, false)); return; } // If the countryList() size is zero, no need to check. @@ -137,9 +138,8 @@ public abstract class APIPlayer { if(checkResult.resultType().isShouldBlock()) { AntiVPN.getInstance().getExecutor().handleKickingOfPlayer(checkResult, this); } - onResult.accept(checkResult); AntiVPN.getInstance().checked++; }); - onResult.accept(new CheckResult(null, ResultType.UNKNOWN, false)); + return new CheckResult(null, ResultType.UNKNOWN, false); } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/Suppliers.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/Suppliers.java index 13fef69..531a939 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/Suppliers.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/Suppliers.java @@ -16,6 +16,7 @@ package dev.brighten.antivpn.utils; +import java.io.Serial; import java.io.Serializable; import static dev.brighten.antivpn.utils.NullnessCasts.uncheckedCastNullableTToT; @@ -36,7 +37,7 @@ public final class Suppliers { /** * Returns a supplier which caches the instance retrieved during the first call to {@code get()} - * and returns that value on subsequent calls to {@code get()}. See: memoization * *

The returned supplier is thread-safe. The delegate's {@code get()} method will be invoked at @@ -44,7 +45,7 @@ public final class Suppliers { * form does not contain the cached value, which will be recalculated when {@code get()} is called * on the reserialized instance. * - *

When the underlying delegate throws an exception then this memoizing supplier will keep + *

When the underlying delegate throws an exception then this memorizing supplier will keep * delegating calls until it returns valid data. * *

If {@code delegate} is an instance created by an earlier call to {@code memoize}, it is @@ -95,6 +96,7 @@ public final class Suppliers { + ")"; } + @Serial private static final long serialVersionUID = 0; } diff --git a/README.md b/README.md index 1bd91cc..fa4cf06 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,18 @@ Just a simple plugin using an incredibly fast and accurate API. ## SpigotMC Page Rate and support the project on SpigotMC: https://www.spigotmc.org/resources/kaurivpn-anti-proxy-tor-and-vpn-free-api.93355/ + +## Velocity Debugging +Run a generated local Velocity proxy with the AntiVPN Velocity loader installed: + +```bash +./gradlew runVelocity +``` + +Run the proxy suspended for IDE debugger attach on port `5005`: + +```bash +./gradlew debugVelocity +``` + +In IntelliJ IDEA, use the Gradle `debugVelocity` task and attach a remote JVM debugger to `localhost:5005`. diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java index 6c38d97..7f94f34 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java @@ -41,22 +41,22 @@ public class SpongeListener extends VPNExecutor { event.connection().address().getAddress() ))); - player.get().checkPlayer(result -> { - if(!result.resultType().isShouldBlock()) return; + CheckResult result = player.get().checkPlayer(); - if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { - return; - } + if(!result.resultType().isShouldBlock()) return; - event.setCancelled(true); - event.setMessage(Component.text(switch (result.resultType()) { - case DENIED_PROXY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() - .getKickMessage(), player.get(), result.response()); - case DENIED_COUNTRY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() - .getCountryVanillaKickReason(), player.get(), result.response()); - default -> "You were kicked by KauriVPN for an unknown reason!"; - })); - }); + if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { + return; + } + + event.setCancelled(true); + event.setMessage(Component.text(switch (result.resultType()) { + case DENIED_PROXY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() + .getKickMessage(), player.get(), result.response()); + case DENIED_COUNTRY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() + .getCountryVanillaKickReason(), player.get(), result.response()); + default -> "You were kicked by KauriVPN for an unknown reason!"; + })); } @Listener diff --git a/Velocity/VelocityLoader/build.gradle b/Velocity/VelocityLoader/build.gradle index f3d5e95..1ce3f05 100644 --- a/Velocity/VelocityLoader/build.gradle +++ b/Velocity/VelocityLoader/build.gradle @@ -1,5 +1,6 @@ plugins { id 'com.gradleup.shadow' + id 'xyz.jpenilla.run-velocity' } evaluationDependsOn(':Velocity:VelocityPlugin') @@ -25,16 +26,44 @@ shadowJar { rename { 'antivpn-velocity.jarinjar' } } + // Include the shared shaded source jar required by JarInJarClassLoader. + from(project(':Common:Source').tasks.named('shadowJar')) { + rename { 'antivpn-source.jarinjar' } + } + relocate 'org.bstats', 'dev.brighten.antivpn.velocity.org.bstats' relocate 'org.yaml.snakeyaml', 'dev.brighten.antivpn.shaded.org.yaml.snakeyaml' } tasks.named('shadowJar') { + dependsOn(':Common:Source:shadowJar') dependsOn(':Velocity:VelocityPlugin:shadowJar') } tasks.build.dependsOn shadowJar +tasks.named('runVelocity') { + velocityVersion('3.4.0-SNAPSHOT') + runDirectory.set(rootProject.layout.projectDirectory.dir('run/velocity')) + pluginJars.from(tasks.named('shadowJar')) + dependsOn(tasks.named('shadowJar')) +} + +tasks.register('debugVelocity', xyz.jpenilla.runvelocity.task.RunVelocity) { + group = 'Run Velocity' + description = 'Run a local Velocity proxy for plugin debugging on port 5005.' + velocityVersion('3.4.0-SNAPSHOT') + runDirectory.set(rootProject.layout.projectDirectory.dir('run/velocity')) + pluginJars.from(tasks.named('shadowJar')) + dependsOn(tasks.named('shadowJar')) + debugOptions { + enabled = true + port = 5005 + server = true + suspend = true + } +} + jar { archiveClassifier.set('raw') } diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java index 35d4cab..e0c77f6 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -21,6 +21,7 @@ import com.velocitypowered.api.event.connection.DisconnectEvent; import com.velocitypowered.api.event.connection.LoginEvent; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.api.APIPlayer; +import dev.brighten.antivpn.api.CheckResult; import dev.brighten.antivpn.api.OfflinePlayer; import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.utils.StringUtil; @@ -52,35 +53,35 @@ public class VelocityListener extends VPNExecutor { event.getPlayer().getRemoteAddress().getAddress() )); - player.checkPlayer(result -> { - if(!result.resultType().isShouldBlock()) return; + CheckResult result = player.checkPlayer(); - if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { - return; - } + if(!result.resultType().isShouldBlock()) return; - switch (result.resultType()) { - case DENIED_COUNTRY -> event.setResult(ResultedEvent.ComponentResult.denied( - LegacyComponentSerializer.builder() - .character('&') - .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .getCountryVanillaKickReason() - .replace("%player%", event.getPlayer().getUsername()) - .replace("%country%", result.response().getCountryName()) - .replace("%code%", result.response().getCountryCode())))); - case DENIED_PROXY -> { - VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername() - + " joined on a VPN/Proxy (" + result.response().getMethod() + ")"); - event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder() + if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { + return; + } + + switch (result.resultType()) { + case DENIED_COUNTRY -> event.setResult(ResultedEvent.ComponentResult.denied( + LegacyComponentSerializer.builder() .character('&') .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .getKickMessage() + .getCountryVanillaKickReason() .replace("%player%", event.getPlayer().getUsername()) .replace("%country%", result.response().getCountryName()) .replace("%code%", result.response().getCountryCode())))); - } + case DENIED_PROXY -> { + VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername() + + " joined on a VPN/Proxy (" + result.response().getMethod() + ")"); + event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder() + .character('&') + .build().deserialize(AntiVPN.getInstance().getVpnConfig() + .getKickMessage() + .replace("%player%", event.getPlayer().getUsername()) + .replace("%country%", result.response().getCountryName()) + .replace("%code%", result.response().getCountryCode())))); } - }); + } } @Override diff --git a/build.gradle b/build.gradle index b2e7e9b..9157264 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'com.gradleup.shadow' version '9.4.1' + id 'xyz.jpenilla.run-velocity' version '3.0.2' apply false } def aggregateTestProjects = [ @@ -101,3 +102,15 @@ tasks.named('shadowJar') { } tasks.build.dependsOn shadowJar + +tasks.register('runVelocity') { + group = 'run' + description = 'Starts a local Velocity proxy with the AntiVPN Velocity loader installed.' + dependsOn(':Velocity:VelocityLoader:runVelocity') +} + +tasks.register('debugVelocity') { + group = 'run' + description = 'Starts a local Velocity proxy suspended for debugger attach on port 5005.' + dependsOn(':Velocity:VelocityLoader:debugVelocity') +}