From 3f6bb4a0e6a4b6e6bdaf373c9ebf5bc77d0532f5 Mon Sep 17 00:00:00 2001 From: Dawson Date: Tue, 27 May 2025 13:13:53 -0400 Subject: [PATCH 1/7] Refactor, code cleanup, sponge impl. BungeeCord still has problems, bad API, not my fault technically. still need to fix though --- .../antivpn/bukkit/BukkitListener.java | 213 +++++--------- .../antivpn/bungee/BungeeListener.java | 175 ++++------- .../java/dev/brighten/antivpn/AntiVPN.java | 63 ++-- .../dev/brighten/antivpn/api/APIPlayer.java | 68 ++++- .../dev/brighten/antivpn/api/CheckResult.java | 6 + .../brighten/antivpn/api/OfflinePlayer.java | 26 ++ .../dev/brighten/antivpn/api/ResultType.java | 18 ++ .../dev/brighten/antivpn/api/VPNExecutor.java | 70 +++++ .../antivpn/database/sql/utils/MySQL.java | 3 + .../dev/brighten/antivpn/utils/MiscUtils.java | 39 ++- .../brighten/antivpn/utils/StringUtil.java | 23 ++ .../dev/brighten/antivpn/utils/Tuple.java | 5 + Sponge/pom.xml | 6 + .../antivpn/sponge/SpongeListener.java | 106 +++++++ .../brighten/antivpn/sponge/SpongePlayer.java | 2 +- .../antivpn/sponge/SpongePlayerExecutor.java | 45 ++- .../brighten/antivpn/sponge/SpongePlugin.java | 26 +- .../antivpn/velocity/VelocityListener.java | 274 ++++++++++-------- .../antivpn/velocity/util/StringUtils.java | 17 -- 19 files changed, 739 insertions(+), 446 deletions(-) create mode 100644 Common/src/main/java/dev/brighten/antivpn/api/CheckResult.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/api/OfflinePlayer.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/api/ResultType.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/utils/Tuple.java create mode 100644 Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java delete mode 100644 Velocity/src/main/java/dev/brighten/antivpn/velocity/util/StringUtils.java diff --git a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java index 1ded919..fe37786 100644 --- a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java +++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java @@ -1,33 +1,27 @@ package dev.brighten.antivpn.bukkit; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; 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.message.VpnString; -import dev.brighten.antivpn.web.objects.VPNResponse; +import dev.brighten.antivpn.utils.StringUtil; +import dev.brighten.antivpn.utils.Tuple; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; -import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.scheduler.BukkitRunnable; -import java.util.UUID; -import java.util.concurrent.TimeUnit; import java.util.logging.Level; @SuppressWarnings("unchecked") public class BukkitListener extends VPNExecutor implements Listener { - private final Cache responseCache = Caffeine.newBuilder() - .expireAfterWrite(5, TimeUnit.MINUTES) - .maximumSize(2000) - .build(); @Override public void registerListeners() { @@ -50,6 +44,12 @@ public class BukkitListener extends VPNExecutor implements Listener { Bukkit.getLogger().log(Level.SEVERE, message, ex); } + @Override + public void runCommand(String command) { + Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), + ChatColor.translateAlternateColorCodes('&', command)); + } + @Override public void disablePlugin() { HandlerList.unregisterAll(this); @@ -57,6 +57,61 @@ public class BukkitListener extends VPNExecutor implements Listener { } @EventHandler(priority = EventPriority.HIGH) + public void onLogin(final PlayerLoginEvent event) { + APIPlayer player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId()) + .orElse(new OfflinePlayer( + event.getPlayer().getUniqueId(), + event.getPlayer().getName(), + event.getRealAddress() + )); + + CheckResult instantResult = player.checkPlayer(result -> { + if(!result.resultType().isShouldBlock()) return; + + AntiVPN.getInstance().getExecutor().log(Level.INFO, "Adding %s to kick", event.getPlayer().getName()); + AntiVPN.getInstance().getExecutor().getToKick().add(new Tuple<>(result, event.getPlayer().getUniqueId())); + }); + + if(!instantResult.resultType().isShouldBlock()) return; + + AntiVPN.getInstance().getExecutor().getToKick() + .add(new Tuple<>(instantResult, event.getPlayer().getUniqueId())); + + if(!AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + return; + } + + event.setResult(PlayerLoginEvent.Result.KICK_BANNED); + switch (instantResult.resultType()) { + case DENIED_COUNTRY -> event.setKickMessage(StringUtil.translateAlternateColorCodes('&', + StringUtil.varReplace( + AntiVPN.getInstance().getVpnConfig().countryVanillaKickReason(), + player, + instantResult.response() + ))); + case DENIED_PROXY -> { + if(AntiVPN.getInstance().getVpnConfig().alertToStaff()) { + AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() + .filter(APIPlayer::isAlertsEnabled) + .forEach(pl -> + pl.sendMessage(StringUtil.varReplace( + ChatColor.translateAlternateColorCodes( + '&', + AntiVPN.getInstance().getVpnConfig().alertMessage()), + player, + instantResult.response()))); + } + event.setKickMessage(StringUtil.translateAlternateColorCodes('&', + StringUtil.varReplace( + AntiVPN.getInstance().getVpnConfig().getKickString(), + player, + instantResult.response() + ))); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR) public void onJoin(final PlayerJoinEvent event) { AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId()) .ifPresent(player -> AntiVPN.getInstance().getDatabase().alertsState(player.getUuid(), enabled -> { @@ -67,142 +122,6 @@ public class BukkitListener extends VPNExecutor implements Listener { .getFormattedMessage(new VpnString.Var<>("state", true))); } })); - - String address; - - if(event.getPlayer().getAddress() != null) { - address = event.getPlayer().getAddress().getAddress().getHostAddress(); - } else { - log(Level.WARNING, "Player %s address is null! This is a bug and should be reported!", event.getPlayer().getName()); - return; - } - - if(event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission - || AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId()) //Is exempt - //Or has a name that starts with a certain prefix. This is for Bedrock exempting. - || AntiVPN.getInstance().getExecutor().isWhitelisted(address) - || AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream() - .anyMatch(prefix -> event.getPlayer().getName().startsWith(prefix))) return; - - if(responseCache.asMap().containsKey(event.getPlayer().getUniqueId())) { - VPNResponse cached = responseCache.getIfPresent(event.getPlayer().getUniqueId()); - - if (cached != null && cached.isProxy()) { - proxyKick(event.getPlayer(), cached); - return; - } - } - - final Player player = event.getPlayer(); - checkIp(address).thenAccept(result -> { - if(result.isSuccess()) { - //We need to run on main thread or kicking and running commands will cause errors - //If the player is whitelisted, we don't want to kick them - if(AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())) { - log("UUID is whitelisted: %s", event.getPlayer().getUniqueId().toString()); - return; - } - - //If the IP is whitelisted, we don't want to kick them - if (AntiVPN.getInstance().getExecutor().isWhitelisted(address)) { - log("IP is whitelisted: %s", - address); - return; - } - - // If the countryList() size is zero, no need to check. - // Running country check first - if(!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty() - // This bit of code will decide whether to kick the player - // If contains the code, and set to whitelist, it will not kick as they are equal - // and vise versa. However, if the contains does not match the state, it will kick. - && AntiVPN.getInstance().getVpnConfig().countryList() - .contains(result.getCountryCode()) - != AntiVPN.getInstance().getVpnConfig().whitelistCountries()) { - countryKick(player, result); - } else if(result.isProxy()) { - proxyKick(player, result); - } - } else { - log(Level.WARNING, - "The API query was not a success! " + - "You may need to upgrade your license on https://funkemunky.cc/shop"); - } - AntiVPN.getInstance().checked++; - }); - } - - private void countryKick(Player player, VPNResponse result) { - final String kickReason = AntiVPN.getInstance().getVpnConfig() - .countryVanillaKickReason(); - //Using our built-in kicking system if no commands are configured - if(AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) { - // Kicking our player - new BukkitRunnable() { - public void run() { - player.kickPlayer(ChatColor - .translateAlternateColorCodes('&', - kickReason - .replace("%player%", player.getName()) - .replace("%country%", result.getCountryName()) - .replace("%code%", result.getCountryCode()))); - } - }.runTask(BukkitPlugin.pluginInstance); - } else { - final String playerName = player.getName(); - - BukkitPlugin.pluginInstance.getPlayerCommandRunner() - .addAction(player.getUniqueId(), () -> { - for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) { - final String formattedCommand = ChatColor.translateAlternateColorCodes('&', - cmd.replace("%player%", playerName) - .replace("%country%", result.getCountryName()) - .replace("%code%", result.getCountryCode())); - - // Runs our command from console - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), formattedCommand); - } - }); - } - } - - private void proxyKick(Player player, VPNResponse result) { - log(Level.INFO, player.getName() - + " joined on a VPN/Proxy (" + result.getMethod() + ")"); - - //Ensuring the user wishes to alert to staff - if(AntiVPN.getInstance().getVpnConfig().alertToStaff()) - AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() - .filter(APIPlayer::isAlertsEnabled) - .forEach(pl -> pl.sendMessage(AntiVPN.getInstance().getVpnConfig().alertMessage() - .replace("%player%", player.getName()) - .replace("%reason%", result.getMethod()) - .replace("%country%", result.getCountryName()) - .replace("%city%", result.getCity()))); - - if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { - new BukkitRunnable() { - public void run() { - player.kickPlayer(org.bukkit.ChatColor.translateAlternateColorCodes('&', - AntiVPN.getInstance().getVpnConfig().getKickString())); - } - }.runTask(BukkitPlugin.pluginInstance); - } else { - //In case the user wants to run their own commands instead of using the built-in kicking - if(AntiVPN.getInstance().getVpnConfig().runCommands()) { - String playerName = player.getName(); - BukkitPlugin.pluginInstance.getPlayerCommandRunner() - .addAction(player.getUniqueId(), () -> { - for (String command : AntiVPN.getInstance().getVpnConfig().commands()) { - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), - ChatColor.translateAlternateColorCodes('&', - command.replace("%player%", - playerName))); - } - }); - } - AntiVPN.getInstance().detections++; - } } @EventHandler diff --git a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java index ea8344b..7d94b55 100644 --- a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -1,34 +1,30 @@ package dev.brighten.antivpn.bungee; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; 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.web.objects.VPNResponse; +import dev.brighten.antivpn.utils.MiscUtils; +import dev.brighten.antivpn.utils.StringUtil; +import dev.brighten.antivpn.utils.Tuple; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.event.PlayerDisconnectEvent; -import net.md_5.bungee.api.event.PostLoginEvent; import net.md_5.bungee.api.event.PreLoginEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.api.scheduler.ScheduledTask; import net.md_5.bungee.event.EventHandler; import net.md_5.bungee.event.EventPriority; +import java.net.InetSocketAddress; import java.util.UUID; -import java.util.concurrent.TimeUnit; import java.util.logging.Level; public class BungeeListener extends VPNExecutor implements Listener { private ScheduledTask cacheResetTask; - private final Cache responseCache = Caffeine.newBuilder() - .expireAfterWrite(5, TimeUnit.MINUTES) - .maximumSize(2000) - .build(); - @Override public void registerListeners() { BungeePlugin.pluginInstance.getProxy().getPluginManager() @@ -50,10 +46,16 @@ public class BungeeListener extends VPNExecutor implements Listener { BungeePlugin.pluginInstance.getProxy().getLogger().log(Level.SEVERE, message, ex); } + @Override + public void runCommand(String command) { + BungeePlugin.pluginInstance.getProxy().getPluginManager() + .dispatchCommand(BungeePlugin.pluginInstance.getProxy().getConsole(), command); + } + @Override public void disablePlugin() { BungeePlugin.pluginInstance.getProxy().getPluginManager().unregisterListeners(BungeePlugin.pluginInstance); - if(cacheResetTask != null) { + if (cacheResetTask != null) { cacheResetTask.cancel(); cacheResetTask = null; } @@ -61,115 +63,56 @@ public class BungeeListener extends VPNExecutor implements Listener { BungeePlugin.pluginInstance.onDisable(); } - @EventHandler(priority = EventPriority.LOWEST) + @EventHandler(priority = EventPriority.HIGH) public void onListener(final PreLoginEvent event) { - if(!responseCache.asMap().containsKey(event.getConnection().getUniqueId())) return; - VPNResponse cached = responseCache.getIfPresent(event.getConnection().getUniqueId()); + APIPlayer player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getConnection().getUniqueId()) + .orElseGet(() -> { + UUID uuid = MiscUtils.lookupUUID(event.getConnection().getName()); + AntiVPN.getInstance().getExecutor().log(Level.INFO, "Getting offline player for %s with name %s", + event.getConnection().getUniqueId(), uuid); - if(cached != null && cached.isProxy()) { - event.setCancelled(true); - event.setReason(TextComponent.fromLegacy(ChatColor - .translateAlternateColorCodes('&', - AntiVPN.getInstance().getVpnConfig().getKickString()))); - AntiVPN.getInstance().getExecutor().log(Level.INFO, - "%s was kicked from pre-login proxy cache.", - event.getConnection().getName()); - } - } - - @EventHandler(priority = EventPriority.LOWEST) - public void onListener(final PostLoginEvent event) { - if(event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission - || AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream() - .anyMatch(prefix -> event.getPlayer().getName().startsWith(prefix))) return; - - String address = event.getPlayer().getSocketAddress().toString(); - - if(AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())) { - AntiVPN.getInstance().getExecutor().log("UUID is whitelisted: %s", - event.getPlayer().getUniqueId().toString()); - return; - } - - //If the IP is whitelisted, we don't want to kick them - if(AntiVPN.getInstance().getExecutor().isWhitelisted(address)) { - AntiVPN.getInstance().getExecutor().log("IP is whitelisted: %s", address); - return; - } - - checkIp(address) - .thenAccept(result -> { - if(result.isSuccess()) { - //If the player is whitelisted, we don't want to kick them - responseCache.put(event.getPlayer().getUniqueId(), result); - if(!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty() - // This bit of code will decide whether or not to kick the player - // If it contains the code and it is set to whitelist, it will not kick as they are equal - // and vise versa. However, if the contains does not match the state, it will kick. - && AntiVPN.getInstance().getVpnConfig().countryList() - .contains(result.getCountryCode()) != AntiVPN.getInstance().getVpnConfig().whitelistCountries()) { - //Using our built in kicking system if no commands are configured - if(AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) { - final String kickReason = AntiVPN.getInstance().getVpnConfig() - .countryVanillaKickReason(); - // Kicking our player - event.getPlayer().disconnect(TextComponent.fromLegacy(ChatColor - .translateAlternateColorCodes('&', - kickReason - .replace("%player%", event.getPlayer().getName()) - .replace("%country%", result.getCountryName()) - .replace("%code%", result.getCountryCode())))); - } else { - for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) { - final String formattedCommand = ChatColor.translateAlternateColorCodes('&', - cmd.replace("%player%", event.getPlayer().getName()) - .replace("%country%", result.getCountryName()) - .replace("%code%", result.getCountryCode())); - - // Runs our command from console - BungeePlugin.pluginInstance.getProxy().getPluginManager().dispatchCommand( - BungeePlugin.pluginInstance.getProxy().getConsole(), formattedCommand); - } - } - } else if(result.isProxy()) { - if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) - event.getPlayer().disconnect(TextComponent.fromLegacy(ChatColor - .translateAlternateColorCodes('&', - AntiVPN.getInstance().getVpnConfig().getKickString()))); - BungeePlugin.pluginInstance.getProxy().getLogger().info(event.getPlayer().getName() - + " joined on a VPN/Proxy (" + result.getMethod() + ")"); - - if(AntiVPN.getInstance().getVpnConfig().alertToStaff()) //Ensuring the user wishes to alert to staff - AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() - .filter(APIPlayer::isAlertsEnabled) - .forEach(pl -> pl.sendMessage(AntiVPN.getInstance().getVpnConfig() - .alertMessage() - .replace("%player%", event.getPlayer().getName()) - .replace("%reason%", result.getMethod()) - .replace("%country%", result.getCountryName()) - .replace("%city%", result.getCity()))); - - //In case the user wants to run their own commands instead of using the built in kicking - if(AntiVPN.getInstance().getVpnConfig().runCommands()) { - for (String command : AntiVPN.getInstance().getVpnConfig().commands()) { - BungeePlugin.pluginInstance.getProxy().getPluginManager() - .dispatchCommand(BungeePlugin.pluginInstance.getProxy().getConsole(), - ChatColor.translateAlternateColorCodes('&', - command.replace("%player%", event.getPlayer().getName()))); - } - } - AntiVPN.getInstance().detections++; - } - - } else { - BungeePlugin.pluginInstance.getProxy().getLogger() - .log(Level.WARNING, - "The API query was not a success! " + - "You may need to upgrade your license on https://funkemunky.cc/shop"); - } - AntiVPN.getInstance().checked++; + return new OfflinePlayer(uuid, event.getConnection().getName(), + ((InetSocketAddress) event.getConnection().getSocketAddress()).getAddress()); }); + + CheckResult instantResult = player.checkPlayer(result -> { + if (!result.resultType().isShouldBlock()) return; + AntiVPN.getInstance().getExecutor().getToKick() + .add(new Tuple<>(result, event.getConnection().getUniqueId())); + }); + + if (!instantResult.resultType().isShouldBlock()) { + return; + } + + AntiVPN.getInstance().getExecutor().getToKick() + .add(new Tuple<>(instantResult, player.getUuid())); + + if (!AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + return; + } + + event.setCancelled(true); + AntiVPN.getInstance().getExecutor().log(Level.INFO, + "%s was kicked from pre-login proxy cache.", + event.getConnection().getName()); + + + switch (instantResult.resultType()) { + case DENIED_PROXY -> event.setReason(TextComponent.fromLegacy(ChatColor + .translateAlternateColorCodes('&', + StringUtil.varReplace( + AntiVPN.getInstance().getVpnConfig().getKickString(), + player, + instantResult.response())))); + case DENIED_COUNTRY -> event.setReason(TextComponent.fromLegacy(ChatColor + .translateAlternateColorCodes('&', + StringUtil.varReplace( + AntiVPN.getInstance().getVpnConfig().countryVanillaKickReason(), + player, + instantResult.response())))); + } } @EventHandler diff --git a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java index 3a24d96..3eb00b2 100644 --- a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -94,34 +94,40 @@ public class AntiVPN { INSTANCE.messageHandler = new MessageHandler(); - switch(INSTANCE.vpnConfig.getDatabaseType().toLowerCase()) { - case "h2": - case "local": - case "flatfile": { - AntiVPN.getInstance().getExecutor().log("Using databaseType H2..."); - INSTANCE.database = new H2VPN(); - INSTANCE.database.init(); - break; - } - case "mysql": - case "sql":{ - AntiVPN.getInstance().getExecutor().log("Using databaseType MySQL..."); - INSTANCE.database = new MySqlVPN(); - INSTANCE.database.init(); - break; - } - case "mongo": - case "mongodb": - case "mongod": { - INSTANCE.database = new MongoVPN(); - INSTANCE.database.init(); - break; - } - default: { - AntiVPN.getInstance().getExecutor().log("Could not find database type \"" + INSTANCE.vpnConfig.getDatabaseType() + "\". " + - "Options: [MySQL]"); - break; + try { + switch(INSTANCE.vpnConfig.getDatabaseType().toLowerCase()) { + case "h2": + case "local": + case "flatfile": { + AntiVPN.getInstance().getExecutor().log("Using databaseType H2..."); + INSTANCE.database = new H2VPN(); + INSTANCE.database.init(); + break; + } + case "mysql": + case "sql":{ + AntiVPN.getInstance().getExecutor().log("Using databaseType MySQL..."); + INSTANCE.database = new MySqlVPN(); + INSTANCE.database.init(); + break; + } + case "mongo": + case "mongodb": + case "mongod": { + INSTANCE.database = new MongoVPN(); + INSTANCE.database.init(); + break; + } + default: { + AntiVPN.getInstance().getExecutor().log("Could not find database type \"" + INSTANCE.vpnConfig.getDatabaseType() + "\". " + + "Options: [MySQL]"); + break; + } } + } catch (Exception e) { + AntiVPN.getInstance().getExecutor().logException("Could not initialize database, plugin disabling...", e); + executor.disablePlugin(); + return; } //Registering commands @@ -141,6 +147,9 @@ public class AntiVPN { (vpnString.getDefaultMessage(), "messages." + vpnString.getKey(), AntiVPN.getInstance()) .get()); AntiVPN.getInstance().getMessageHandler().reloadStrings(); + + // Starting kick checks + AntiVPN.getInstance().getExecutor().startKickChecks(); } public InputStream getResource(String filename) { diff --git a/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java b/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java index 72fa742..1660a73 100644 --- a/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java +++ b/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java @@ -1,18 +1,30 @@ package dev.brighten.antivpn.api; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import dev.brighten.antivpn.AntiVPN; import lombok.Getter; +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 public abstract class APIPlayer { private final UUID uuid; private final String name; private final InetAddress ip; + @Setter private boolean alertsEnabled; + private static final Cache checkResultCache = Caffeine.newBuilder() + .expireAfterWrite(5, TimeUnit.MINUTES) + .maximumSize(2000) + .build(); + public APIPlayer(UUID uuid, String name, InetAddress ip) { this.uuid = uuid; this.name = name; @@ -25,12 +37,60 @@ public abstract class APIPlayer { public abstract boolean hasPermission(String permission); - public void setAlertsEnabled(boolean alertsEnabled) { - this.alertsEnabled = alertsEnabled; - } - public void updateAlertsState() { //Updating into database so its synced across servers and saved on logout. AntiVPN.getInstance().getDatabase().updateAlertsState(uuid, alertsEnabled); } + + public CheckResult checkPlayer(Consumer onKick) { + if (hasPermission("antivpn.bypass") //Has bypass permission + //Is exempt + || (uuid != null && AntiVPN.getInstance().getExecutor().isWhitelisted(uuid)) + //Or has a name that starts with a certain prefix. This is for Bedrock exempting. + || AntiVPN.getInstance().getExecutor().isWhitelisted(ip.getHostAddress()) + || AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream() + .anyMatch(name::startsWith)) return new CheckResult(null, ResultType.WHITELISTED); + + CheckResult cachedResult = checkResultCache.getIfPresent(ip.getHostAddress()); + + if(cachedResult != null) { + return cachedResult; + } + + AntiVPN.getInstance().getExecutor().checkIp(ip.getHostAddress()) + .thenAccept(result -> { + if(!result.isSuccess()) { + 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"); + } + // If the countryList() size is zero, no need to check. + // Running country check first + CheckResult checkResult; + if (!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty() + && !((uuid != null && AntiVPN.getInstance().getExecutor() + .isWhitelisted(uuid)) + //Or has a name that starts with a certain prefix. This is for Bedrock exempting. + || AntiVPN.getInstance().getExecutor().isWhitelisted(ip.getHostAddress())) + // This bit of code will decide whether or not to kick the player + // If it contains the code and it is set to whitelist, it will not kick + // as they are equal and vise versa. However, if the contains does not match + // the state, it will kick. + && AntiVPN.getInstance().getVpnConfig().countryList() + .contains(result.getCountryCode()) + != AntiVPN.getInstance().getVpnConfig().whitelistCountries()) { + //Using our built in kicking system if no commands are configured + checkResult = new CheckResult(result, ResultType.DENIED_COUNTRY); + } else if (result.isProxy()) { + checkResult = new CheckResult(result, ResultType.DENIED_PROXY); + } else { + checkResult = new CheckResult(result, ResultType.ALLOWED); + } + + checkResultCache.put(ip.getHostAddress(), checkResult); + onKick.accept(checkResult); + AntiVPN.getInstance().checked++; + }); + return new CheckResult(null, ResultType.UNKNOWN); + } } diff --git a/Common/src/main/java/dev/brighten/antivpn/api/CheckResult.java b/Common/src/main/java/dev/brighten/antivpn/api/CheckResult.java new file mode 100644 index 0000000..c331961 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/api/CheckResult.java @@ -0,0 +1,6 @@ +package dev.brighten.antivpn.api; + +import dev.brighten.antivpn.web.objects.VPNResponse; + +public record CheckResult(VPNResponse response, ResultType resultType) { +} diff --git a/Common/src/main/java/dev/brighten/antivpn/api/OfflinePlayer.java b/Common/src/main/java/dev/brighten/antivpn/api/OfflinePlayer.java new file mode 100644 index 0000000..27ce5f7 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/api/OfflinePlayer.java @@ -0,0 +1,26 @@ +package dev.brighten.antivpn.api; + +import java.net.InetAddress; +import java.util.UUID; + +public class OfflinePlayer extends APIPlayer { + + public OfflinePlayer(UUID uuid, String name, InetAddress ip) { + super(uuid, name, ip); + } + + @Override + public void sendMessage(String message) { + + } + + @Override + public void kickPlayer(String reason) { + + } + + @Override + public boolean hasPermission(String permission) { + return false; + } +} diff --git a/Common/src/main/java/dev/brighten/antivpn/api/ResultType.java b/Common/src/main/java/dev/brighten/antivpn/api/ResultType.java new file mode 100644 index 0000000..e8dfea4 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/api/ResultType.java @@ -0,0 +1,18 @@ +package dev.brighten.antivpn.api; + +import lombok.Getter; + +public enum ResultType { + ALLOWED(false), + WHITELISTED(false), + DENIED_COUNTRY(true), + DENIED_PROXY(true), + UNKNOWN(false); + + @Getter + private final boolean shouldBlock; + + ResultType(boolean shouldBlock) { + this.shouldBlock = shouldBlock; + } +} diff --git a/Common/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java b/Common/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java index 838e6d8..6635f94 100644 --- a/Common/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -1,6 +1,8 @@ package dev.brighten.antivpn.api; import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.utils.StringUtil; +import dev.brighten.antivpn.utils.Tuple; import dev.brighten.antivpn.utils.json.JSONException; import dev.brighten.antivpn.web.FunkemunkyAPI; import dev.brighten.antivpn.web.objects.VPNResponse; @@ -11,6 +13,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; public abstract class VPNExecutor { @@ -20,6 +23,10 @@ public abstract class VPNExecutor { private final Set whitelisted = Collections.synchronizedSet(new HashSet<>()); @Getter private final Set whitelistedIps = Collections.synchronizedSet(new HashSet<>()); + + @Getter + private final List> toKick = Collections.synchronizedList(new LinkedList<>()); + public abstract void registerListeners(); public abstract void log(Level level, String log, Object... objects); @@ -28,10 +35,73 @@ public abstract class VPNExecutor { public abstract void logException(String message, Throwable ex); + public abstract void runCommand(String command); + public void logException(Throwable ex) { logException("An exception occurred: " + ex.getMessage(), ex); } + public void startKickChecks() { + threadExecutor.scheduleAtFixedRate(() -> { + synchronized (toKick) { + if(toKick.isEmpty()) return; + + Iterator> i = toKick.iterator(); + + while(i.hasNext()) { + var toCheck = i.next(); + + Optional player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(toCheck.second()); + + if(player.isEmpty()) { + continue; + } + + handleKickingOfPlayer(toCheck.first(), player.get()); + + i.remove(); + } + } + }, 8, 2, TimeUnit.SECONDS); + } + + public void handleKickingOfPlayer(CheckResult result, APIPlayer player) { + if (AntiVPN.getInstance().getVpnConfig().alertToStaff()) AntiVPN.getInstance().getPlayerExecutor() + .getOnlinePlayers() + .stream() + .filter(APIPlayer::isAlertsEnabled) + .forEach(pl -> + pl.sendMessage(StringUtil.translateAlternateColorCodes('&', + StringUtil.varReplace(dev.brighten.antivpn.AntiVPN.getInstance().getVpnConfig() + .alertMessage(), player, result.response())))); + + if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + switch (result.resultType()) { + case DENIED_PROXY -> player.kickPlayer(StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() + .getKickString(), player, result.response())); + case DENIED_COUNTRY -> player.kickPlayer(StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() + .countryVanillaKickReason(), player, result.response())); + } + } + + if(!AntiVPN.getInstance().getVpnConfig().runCommands()) return; + + switch (result.resultType()) { + case DENIED_PROXY -> { + for (String command : AntiVPN.getInstance().getVpnConfig().commands()) { + runCommand(StringUtil.translateAlternateColorCodes('&', + StringUtil.varReplace(command, player, result.response()))); + } + } + case DENIED_COUNTRY -> { + for (String command : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) { + runCommand(StringUtil.translateAlternateColorCodes('&', + StringUtil.varReplace(command, player, result.response()))); + } + } + } + } + public boolean isWhitelisted(UUID uuid) { if(AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) { return AntiVPN.getInstance().getDatabase().isWhitelisted(uuid); diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java b/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java index 8355e2a..e8a1530 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java @@ -75,6 +75,9 @@ public class MySQL { } else { AntiVPN.getInstance().getExecutor().logException("Failed to load H2 database: " + ex.getCause().toString(), ex); } + } catch (Exception e) { + AntiVPN.getInstance().getExecutor().logException("Failed to load H2 database: " + e.getMessage(), e); + AntiVPN.getInstance().getExecutor().log(Level.INFO, "TIP: Try deleting the plugin folder and restarting your server!"); } } diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java b/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java index 41c1856..50d7dea 100644 --- a/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java +++ b/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java @@ -1,6 +1,12 @@ package dev.brighten.antivpn.utils; +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.utils.json.JSONException; +import dev.brighten.antivpn.utils.json.JSONObject; +import dev.brighten.antivpn.utils.json.JsonReader; + import java.io.*; +import java.util.UUID; import java.util.concurrent.ThreadFactory; import java.util.regex.Pattern; @@ -12,7 +18,7 @@ public class MiscUtils { try { for (Closeable closeable : closeables) if (closeable != null) closeable.close(); } catch (Exception e) { - e.printStackTrace(); + AntiVPN.getInstance().getExecutor().logException(e); } } @@ -20,7 +26,7 @@ public class MiscUtils { try { for (AutoCloseable closeable : closeables) if (closeable != null) closeable.close(); } catch (Exception e) { - e.printStackTrace(); + AntiVPN.getInstance().getExecutor().logException(e); } } @@ -38,7 +44,7 @@ public class MiscUtils { out.close(); in.close(); } catch (Exception e) { - e.printStackTrace(); + AntiVPN.getInstance().getExecutor().logException(e); } } @@ -50,6 +56,33 @@ public class MiscUtils { }; } + public static UUID formatFromMojangUUID(String mojangUUID) { + StringBuilder uuid = new StringBuilder(); + for(int i = 0; i <= 31; i++) { + uuid.append(mojangUUID.charAt(i)); + if(i == 7 || i == 11 || i == 15 || i == 19) { + uuid.append("-"); + } + } + + return UUID.fromString(uuid.toString()); + } + + public static UUID lookupUUID(String playername) { + try { + JSONObject object = JsonReader + .readJsonFromUrl("https://funkemunky.cc/mojang/uuid?name=" + playername); + + if(object.has("id")) { + return formatFromMojangUUID(object.getString("uuid")); + } + } catch (IOException | JSONException e) { + AntiVPN.getInstance().getExecutor().logException("Error while looking up UUID for " + playername, e); + } + + return null; + } + public static boolean isIpv4(String ip) { return ipv4.matcher(ip).matches(); diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/StringUtil.java b/Common/src/main/java/dev/brighten/antivpn/utils/StringUtil.java index 53ba8af..5081aa3 100644 --- a/Common/src/main/java/dev/brighten/antivpn/utils/StringUtil.java +++ b/Common/src/main/java/dev/brighten/antivpn/utils/StringUtil.java @@ -1,5 +1,8 @@ package dev.brighten.antivpn.utils; +import dev.brighten.antivpn.api.APIPlayer; +import dev.brighten.antivpn.web.objects.VPNResponse; + public class StringUtil { public static String line(String color) { return color + "&m-----------------------------------------------------"; @@ -12,4 +15,24 @@ public class StringUtil { public static String lineNoStrike(String color) { return color + "-----------------------------------------------------"; } + + public static String varReplace(String input, APIPlayer player, VPNResponse result) { + return input.replace("%player%", player.getName()) + .replace("%reason%", result.getMethod()) + .replace("%country%", result.getCountryName()) + .replace("%city%", result.getCity()); + } + + public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) { + char[] b = textToTranslate.toCharArray(); + + for(int i = 0; i < b.length - 1; ++i) { + if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i + 1]) > -1) { + b[i] = 167; + b[i + 1] = Character.toLowerCase(b[i + 1]); + } + } + + return new String(b); + } } diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/Tuple.java b/Common/src/main/java/dev/brighten/antivpn/utils/Tuple.java new file mode 100644 index 0000000..0e54854 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/utils/Tuple.java @@ -0,0 +1,5 @@ +package dev.brighten.antivpn.utils; + +public record Tuple(F first, S second) { + +} diff --git a/Sponge/pom.xml b/Sponge/pom.xml index de32988..98b6cc5 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -31,6 +31,12 @@ 1.9.4-DEV provided + + org.slf4j + slf4j-api + 2.0.17 + compile + diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java new file mode 100644 index 0000000..4519f61 --- /dev/null +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java @@ -0,0 +1,106 @@ +package dev.brighten.antivpn.sponge; + +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.api.*; +import dev.brighten.antivpn.sponge.util.StringUtil; +import dev.brighten.antivpn.utils.Tuple; +import net.kyori.adventure.text.Component; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.command.exception.CommandException; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.Order; +import org.spongepowered.api.event.network.ServerSideConnectionEvent; + +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; + +public class SpongeListener extends VPNExecutor { + + @Listener(order = Order.EARLY) + public void onJoin(ServerSideConnectionEvent.Auth event) { + AtomicReference player = new AtomicReference<>(AntiVPN.getInstance().getPlayerExecutor() + .getPlayer(event.connection().profile().uuid()) + .orElse(new OfflinePlayer( + event.connection().profile().uuid(), + event.connection().profile().name().orElse("Unknown"), + event.connection().address().getAddress() + ))); + + CheckResult instantResult = player.get().checkPlayer(result -> { + if(result.resultType().isShouldBlock()) { + AntiVPN.getInstance().getExecutor().getToKick().add(new Tuple<>(result, player.get().getUuid())); + } + }); + + if(!instantResult.resultType().isShouldBlock()) { + return; + } + + AntiVPN.getInstance().getExecutor().getToKick().add(new Tuple<>(instantResult, player.get().getUuid())); + + if(!AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + return; + } + + event.setCancelled(true); + switch (instantResult.resultType()) { + case DENIED_PROXY -> { + AntiVPN.getInstance().getExecutor().log(Level.INFO, player.get().getName() + + " joined on a VPN/Proxy (" + instantResult.response().getMethod() + ")"); + event.setMessage(Component.text(StringUtil + .translateColorCodes('&', AntiVPN.getInstance().getVpnConfig() + .getKickString() + .replace("%player%", player.get().getName()) + .replace("%country%", instantResult.response().getCountryName()) + .replace("%code%", instantResult.response().getCountryCode())))); + } + case DENIED_COUNTRY -> + event.setMessage(Component.text(StringUtil + .translateColorCodes('&', AntiVPN.getInstance().getVpnConfig() + .countryVanillaKickReason() + .replace("%player%", player.get().getName()) + .replace("%country%", instantResult.response().getCountryName()) + .replace("%code%", instantResult.response().getCountryCode())))); + } + } + + @Override + public void registerListeners() { + Sponge.eventManager().registerListeners(SpongePlugin.INSTANCE.getPlugin(), this); + } + + @Override + public void log(Level level, String log, Object... objects) { + if (level.equals(Level.SEVERE)) { + SpongePlugin.INSTANCE.getLogger().error(String.format(log, objects)); + } else if (level.equals(Level.WARNING)) { + SpongePlugin.INSTANCE.getLogger().warn(String.format(log, objects)); + } else { + SpongePlugin.INSTANCE.getLogger().info(String.format(log, objects)); + } + } + + @Override + public void log(String log, Object... objects) { + log(Level.INFO, String.format(log, objects)); + } + + @Override + public void logException(String message, Throwable ex) { + SpongePlugin.INSTANCE.getLogger().error(message, ex); + } + + @Override + public void runCommand(String command) { + try { + Sponge.server().commandManager().process(Sponge.systemSubject(), command); + } catch (CommandException e) { + logException(e); + } + } + + @Override + public void disablePlugin() { + Sponge.eventManager().unregisterListeners(this); + } +} diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java index 9ce17f9..2052eea 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java @@ -16,7 +16,7 @@ public class SpongePlayer extends APIPlayer { @Override public void sendMessage(String message) { - //player.sendMessage(StringUtil.translateColorCodes('&', message)); + player.sendMessage(Component.text(StringUtil.translateColorCodes('&', message))); } @Override diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java index 414d7b3..be373de 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java @@ -1,31 +1,68 @@ package dev.brighten.antivpn.sponge; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import dev.brighten.antivpn.api.APIPlayer; import dev.brighten.antivpn.api.PlayerExecutor; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; import java.util.List; import java.util.Optional; import java.util.UUID; +import java.util.concurrent.TimeUnit; public class SpongePlayerExecutor implements PlayerExecutor { + + private final Cache playerCache = Caffeine.newBuilder().maximumSize(10000) + .expireAfterAccess(30, TimeUnit.MINUTES) + .build(); + @Override public Optional getPlayer(String name) { + Optional serverPlayer = Sponge.server().player(name); - return Optional.empty(); + return serverPlayer.map(SpongePlayer::new); } @Override public Optional getPlayer(UUID uuid) { - return Optional.empty(); + SpongePlayer cachedPlayer = playerCache.getIfPresent(uuid); + + if(cachedPlayer != null) { + return Optional.of(cachedPlayer); + } + + Optional serverPlayer = Sponge.server().player(uuid); + + Optional player = serverPlayer.map(SpongePlayer::new); + + player.ifPresent(value -> playerCache.put(uuid, (SpongePlayer) value)); + + return player; } @Override public void unloadPlayer(UUID uuid) { - + playerCache.invalidate(uuid); } @Override public List getOnlinePlayers() { - return null; + return Sponge.server().onlinePlayers() + .stream() + .map(pl -> { + SpongePlayer cachedPlayer = playerCache.getIfPresent(pl.uniqueId()); + + if(cachedPlayer != null) { + return cachedPlayer; + } + + SpongePlayer player = new SpongePlayer(pl); + playerCache.put(pl.uniqueId(), player); + + return (APIPlayer) player; + }) + .toList(); } } diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java index 39d9c50..3b68391 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java @@ -1,28 +1,52 @@ package dev.brighten.antivpn.sponge; import com.google.inject.Inject; +import dev.brighten.antivpn.AntiVPN; +import lombok.Getter; import org.spongepowered.api.Server; +import org.spongepowered.api.config.ConfigDir; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.lifecycle.StartedEngineEvent; +import org.spongepowered.api.event.lifecycle.StoppingEngineEvent; +import org.spongepowered.plugin.PluginContainer; import org.spongepowered.plugin.builtin.jvm.Plugin; -import java.util.logging.Logger; +import java.nio.file.Path; +import org.slf4j.Logger; @Plugin("kaurivpn") +@Getter public class SpongePlugin { public static SpongePlugin INSTANCE; + //Plugin init + @Inject + private PluginContainer plugin; @Inject private Logger logger; + @Inject + @ConfigDir(sharedRoot = false) + private Path configDir; + + @Listener public void onServerStart(final StartedEngineEvent event) { INSTANCE = this; logger.info("Starting AntiVPN services..."); //Start AntiVPN + + SpongeListener spongeListener = new SpongeListener(); + + AntiVPN.start(spongeListener, new SpongePlayerExecutor(), configDir.toFile()); + } + + @Listener + public void onServer(final StoppingEngineEvent event) { + AntiVPN.getInstance().getExecutor().disablePlugin(); } } diff --git a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java index 8c6a437..8f79deb 100644 --- a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -5,8 +5,11 @@ 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.velocity.util.StringUtils; +import dev.brighten.antivpn.utils.StringUtil; +import dev.brighten.antivpn.web.objects.VPNResponse; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import java.util.concurrent.TimeUnit; @@ -20,136 +23,146 @@ public class VelocityListener extends VPNExecutor { .register(VelocityPlugin.INSTANCE, this); VelocityPlugin.INSTANCE.getServer().getEventManager().register(VelocityPlugin.INSTANCE, DisconnectEvent.class, - event -> AntiVPN.getInstance().getPlayerExecutor().unloadPlayer(event.getPlayer().getUniqueId())); + event -> AntiVPN.getInstance() + .getPlayerExecutor() + .unloadPlayer(event.getPlayer().getUniqueId())); VelocityPlugin.INSTANCE.getServer().getEventManager().register(VelocityPlugin.INSTANCE, LoginEvent.class, event -> { - if (event.getResult().isAllowed()) { - if (event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission - //Is exempt - || AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId()) - //Or has a name that starts with a certain prefix. This is for Bedrock exempting. - || AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getRemoteAddress() - .getAddress().getHostAddress()) - || AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream() - .anyMatch(prefix -> event.getPlayer().getUsername().startsWith(prefix))) return; - checkIp(event.getPlayer().getRemoteAddress().getAddress().getHostAddress()) - .thenAccept(result -> { - if(!result.isSuccess()) { - VelocityPlugin.INSTANCE.getLogger() - .log(Level.WARNING, - "The API query was not a success! " + - "You may need to upgrade your license on " + - "https://funkemunky.cc/shop"); - } - // If the countryList() size is zero, no need to check. - // Running country check first - if (!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty() - && !(AntiVPN.getInstance().getExecutor() - .isWhitelisted(event.getPlayer().getUniqueId()) //Is exempt - //Or has a name that starts with a certain prefix. This is for Bedrock exempting. - || AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer() - .getRemoteAddress().getAddress().getHostAddress())) - // This bit of code will decide whether or not to kick the player - // If it contains the code and it is set to whitelist, it will not kick - // as they are equal and vise versa. However, if the contains does not match - // the state, it will kick. - && AntiVPN.getInstance().getVpnConfig().countryList() - .contains(result.getCountryCode()) - != AntiVPN.getInstance().getVpnConfig().whitelistCountries()) { - //Using our built in kicking system if no commands are configured - if (AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) { - final String kickReason = AntiVPN.getInstance().getVpnConfig() - .countryVanillaKickReason(); - // Kicking our player - event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder() - .character('&') - .build().deserialize(kickReason - .replace("%player%", event.getPlayer().getUsername()) - .replace("%country%", result.getCountryName()) - .replace("%code%", result.getCountryCode())))); - VelocityPlugin.INSTANCE.getServer().getScheduler() - .buildTask(VelocityPlugin.INSTANCE, () -> - event.getPlayer().disconnect(LegacyComponentSerializer.builder() - .character('&') - .build().deserialize(kickReason - .replace("%player%", event.getPlayer().getUsername()) - .replace("%country%", result.getCountryName()) - .replace("%code%", result.getCountryCode())))); - } else { - for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) { - final String formattedCommand = StringUtils - .translateAlternateColorCodes('&', - cmd.replace("%player%", - event.getPlayer().getUsername()) - .replace("%country%", result.getCountryName()) - .replace("%code%", result.getCountryCode())); - // Running the command from console - VelocityPlugin.INSTANCE.getServer().getCommandManager() - .executeAsync(VelocityPlugin.INSTANCE.getServer() - .getConsoleCommandSource(), - StringUtils.translateAlternateColorCodes('&', - formattedCommand)); - } - } - } else if (result.isProxy()) { - if (AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { - // Delay code execution - event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder() - .character('&') - .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .getKickString() - .replace("%player%", event.getPlayer().getUsername()) - .replace("%country%", result.getCountryName()) - .replace("%code%", result.getCountryCode())))); + APIPlayer player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId()) + .orElse(new OfflinePlayer( + event.getPlayer().getUniqueId(), + event.getPlayer().getUsername(), + event.getPlayer().getRemoteAddress().getAddress() + )); - VelocityPlugin.INSTANCE.getServer().getScheduler() - .buildTask(VelocityPlugin.INSTANCE, () -> - event.getPlayer().disconnect(LegacyComponentSerializer.builder() - .character('&') - .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .getKickString() - .replace("%player%", event.getPlayer().getUsername()) - .replace("%country%", result.getCountryName()) - .replace("%code%", result.getCountryCode())))) - .delay(1, TimeUnit.SECONDS).schedule(); - } - VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername() - + " joined on a VPN/Proxy (" + result.getMethod() + ")"); - //Ensuring the user wishes to alert to staff - if (AntiVPN.getInstance().getVpnConfig().alertToStaff()) - AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() - .filter(APIPlayer::isAlertsEnabled) - .forEach(pl -> - pl.sendMessage(AntiVPN.getInstance().getVpnConfig() - .alertMessage() - .replace("%player%", - event.getPlayer().getUsername()) - .replace("%reason%", - result.getMethod()) - .replace("%country%", - result.getCountryName()) - .replace("%city%", - result.getCity()))); + CheckResult instantResult = player.checkPlayer(result -> { + if(!result.resultType().isShouldBlock()) return; + + handleDeniedTasks(event, result); + }); + + if(!instantResult.resultType().isShouldBlock()) return; + + switch (instantResult.resultType()) { + case DENIED_COUNTRY -> event.setResult(ResultedEvent.ComponentResult.denied( + LegacyComponentSerializer.builder() + .character('&') + .build().deserialize(AntiVPN.getInstance().getVpnConfig() + .countryVanillaKickReason() + .replace("%player%", event.getPlayer().getUsername()) + .replace("%country%", instantResult.response().getCountryName()) + .replace("%code%", instantResult.response().getCountryCode())))); + case DENIED_PROXY -> { + VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername() + + " joined on a VPN/Proxy (" + instantResult.response().getMethod() + ")"); + event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder() + .character('&') + .build().deserialize(AntiVPN.getInstance().getVpnConfig() + .getKickString() + .replace("%player%", event.getPlayer().getUsername()) + .replace("%country%", instantResult.response().getCountryName()) + .replace("%code%", instantResult.response().getCountryCode())))); + } + } + + handleDeniedTasks(event, instantResult, true); + }); + } + + private void handleDeniedTasks(LoginEvent event, CheckResult result) { + handleDeniedTasks(event, result, false); + } + + private void handleDeniedTasks(LoginEvent event, CheckResult checkResult, boolean deniedOnLogin) { + VPNResponse result = checkResult.response(); + //Ensuring the user wishes to alert to staff + if (AntiVPN.getInstance().getVpnConfig().alertToStaff()) + AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() + .filter(APIPlayer::isAlertsEnabled) + .forEach(pl -> + pl.sendMessage(dev.brighten.antivpn.AntiVPN.getInstance().getVpnConfig() + .alertMessage() + .replace("%player%", + event.getPlayer().getUsername()) + .replace("%reason%", + result.getMethod()) + .replace("%country%", + result.getCountryName()) + .replace("%city%", + result.getCity()))); + + if(deniedOnLogin) return; + + //In case the user wants to run their own commands instead of using the + // built in kicking + + if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + switch (checkResult.resultType()) { + case DENIED_PROXY -> VelocityPlugin.INSTANCE.getServer().getScheduler() + .buildTask(VelocityPlugin.INSTANCE, () -> + event.getPlayer().disconnect(LegacyComponentSerializer.builder() + .character('&') + .build().deserialize(AntiVPN.getInstance().getVpnConfig() + .getKickString() + .replace("%player%", event.getPlayer().getUsername()) + .replace("%country%", result.getCountryName()) + .replace("%code%", result.getCountryCode())))) + .delay(1, TimeUnit.SECONDS).schedule(); + case DENIED_COUNTRY -> VelocityPlugin.INSTANCE.getServer().getScheduler() + .buildTask(VelocityPlugin.INSTANCE, () -> + event.getPlayer().disconnect(LegacyComponentSerializer.builder() + .character('&') + .build().deserialize(AntiVPN.getInstance().getVpnConfig() + .countryVanillaKickReason() + .replace("%player%", event.getPlayer().getUsername()) + .replace("%country%", result.getCountryName()) + .replace("%code%", result.getCountryCode())))) + .delay(1, TimeUnit.SECONDS).schedule(); + } + } + + if(!AntiVPN.getInstance().getVpnConfig().runCommands()) return; + + switch (checkResult.resultType()) { + case DENIED_PROXY -> { + for (String command : AntiVPN.getInstance().getVpnConfig().commands()) { + VelocityPlugin.INSTANCE.getServer().getCommandManager() + .executeAsync(VelocityPlugin.INSTANCE.getServer() + .getConsoleCommandSource(), + StringUtil.translateAlternateColorCodes('&', + StringUtil.varReplace( + command, + AntiVPN.getInstance().getPlayerExecutor() + .getPlayer(event.getPlayer().getUniqueId()) + .orElse(new OfflinePlayer( + event.getPlayer().getUniqueId(), + event.getPlayer().getUsername(), + event.getPlayer().getRemoteAddress().getAddress()) + ), + result))); + } + } + case DENIED_COUNTRY -> { + for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) { + final String formattedCommand = StringUtil + .translateAlternateColorCodes('&', + StringUtil.varReplace( + cmd, + AntiVPN.getInstance().getPlayerExecutor() + .getPlayer(event.getPlayer().getUniqueId()) + .orElse(new OfflinePlayer( + event.getPlayer().getUniqueId(), + event.getPlayer().getUsername(), + event.getPlayer().getRemoteAddress().getAddress()) + ), + result)); + // Running the command from console + runCommand(formattedCommand); + } + } + } - //In case the user wants to run their own commands instead of using the - // built in kicking - if (AntiVPN.getInstance().getVpnConfig().runCommands()) { - for (String command : AntiVPN.getInstance().getVpnConfig().commands()) { - VelocityPlugin.INSTANCE.getServer().getCommandManager() - .executeAsync(VelocityPlugin.INSTANCE.getServer() - .getConsoleCommandSource(), - StringUtils.translateAlternateColorCodes('&', - command.replace("%player%", - event.getPlayer().getUsername()))); - } - } - AntiVPN.getInstance().detections++; - } - AntiVPN.getInstance().checked++; - }); - } - }); } @Override @@ -167,6 +180,15 @@ public class VelocityListener extends VPNExecutor { VelocityPlugin.INSTANCE.getLogger().log(Level.SEVERE, message, ex); } + @Override + public void runCommand(String command) { + VelocityPlugin.INSTANCE.getServer().getCommandManager() + .executeAsync(VelocityPlugin.INSTANCE.getServer() + .getConsoleCommandSource(), + StringUtil.translateAlternateColorCodes('&', + command)); + } + @Override public void disablePlugin() { VelocityPlugin.INSTANCE.getServer().getEventManager().unregisterListener(VelocityPlugin.INSTANCE, this); diff --git a/Velocity/src/main/java/dev/brighten/antivpn/velocity/util/StringUtils.java b/Velocity/src/main/java/dev/brighten/antivpn/velocity/util/StringUtils.java deleted file mode 100644 index a4f02fe..0000000 --- a/Velocity/src/main/java/dev/brighten/antivpn/velocity/util/StringUtils.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.brighten.antivpn.velocity.util; - -public class StringUtils { - - public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) { - char[] b = textToTranslate.toCharArray(); - - for(int i = 0; i < b.length - 1; ++i) { - if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i + 1]) > -1) { - b[i] = 167; - b[i + 1] = Character.toLowerCase(b[i + 1]); - } - } - - return new String(b); - } -} From 7247341693a764435c47bbd55710dc81c45ef79a Mon Sep 17 00:00:00 2001 From: Dawson Date: Tue, 27 May 2025 19:39:27 -0400 Subject: [PATCH 2/7] Got initial sponge powered loading working, Im not sure the consequences of it though --- .../antivpn/bungee/BungeeListener.java | 7 +-- Common/pom.xml | 6 ++- .../java/dev/brighten/antivpn/AntiVPN.java | 1 + .../dev/brighten/antivpn/utils/MiscUtils.java | 4 +- Sponge/pom.xml | 49 +++++++++++++++---- .../antivpn/sponge/SpongeListener.java | 16 +++--- .../brighten/antivpn/sponge/SpongePlugin.java | 41 +++++++++------- .../resources/META-INF/sponge_plugins.json | 29 +++++++++++ Universal/pom.xml | 9 ++-- 9 files changed, 115 insertions(+), 47 deletions(-) create mode 100644 Sponge/src/main/resources/META-INF/sponge_plugins.json diff --git a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java index 7d94b55..ae5c12e 100644 --- a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -1,10 +1,7 @@ package dev.brighten.antivpn.bungee; 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.api.*; import dev.brighten.antivpn.utils.MiscUtils; import dev.brighten.antivpn.utils.StringUtil; import dev.brighten.antivpn.utils.Tuple; @@ -79,7 +76,7 @@ public class BungeeListener extends VPNExecutor implements Listener { CheckResult instantResult = player.checkPlayer(result -> { if (!result.resultType().isShouldBlock()) return; AntiVPN.getInstance().getExecutor().getToKick() - .add(new Tuple<>(result, event.getConnection().getUniqueId())); + .add(new Tuple<>(result, player.getUuid())); }); if (!instantResult.resultType().isShouldBlock()) { diff --git a/Common/pom.xml b/Common/pom.xml index 0854ccd..bed828a 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -57,6 +57,10 @@ dev.brighten.antivpn.depends.MavenLibraries + + com.github.benmanes.caffeine + dev.brighten.antivpn.com.github.benmanes.caffeine + org.h2 dev.brighten.antivpn.shaded.org.h2 @@ -159,7 +163,7 @@ com.github.ben-manes.caffeine caffeine 3.1.8 - compile + provided diff --git a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java index 3eb00b2..6382ccb 100644 --- a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -47,6 +47,7 @@ import java.util.List; @Relocate(from = "com.my\\" + "sql.jdbc", to = "dev.brighten.antivpn.shaded.com.mysql.jdbc") } ) +@MavenLibrary(groupId = "com.github.ben-manes.caffeine", artifactId = "caffeine", version = "3.1.8") public class AntiVPN { private static AntiVPN INSTANCE; diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java b/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java index 50d7dea..77cde0b 100644 --- a/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java +++ b/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java @@ -73,8 +73,8 @@ public class MiscUtils { JSONObject object = JsonReader .readJsonFromUrl("https://funkemunky.cc/mojang/uuid?name=" + playername); - if(object.has("id")) { - return formatFromMojangUUID(object.getString("uuid")); + if(object.has("uuid")) { + return UUID.fromString(object.getString("uuid")); } } catch (IOException | JSONException e) { AntiVPN.getInstance().getExecutor().logException("Error while looking up UUID for " + playername, e); diff --git a/Sponge/pom.xml b/Sponge/pom.xml index 98b6cc5..7af842c 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -13,8 +13,8 @@ - sponge - https://repo.spongepowered.org/repository/maven-public/ + spongepowered-repo + https://repo.spongepowered.org/maven/ @@ -22,7 +22,7 @@ org.spongepowered spongeapi - 8.1.0 + 11.0.0 provided @@ -31,12 +31,6 @@ 1.9.4-DEV provided - - org.slf4j - slf4j-api - 2.0.17 - compile - @@ -44,4 +38,41 @@ 17 + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + 17 + 17 + -XDignore.symbol.file + + + + org.apache.maven.plugins + maven-shade-plugin + 3.6.0 + + + package + + shade + + + + + + + + + + + src/main/resources + true + + + + \ No newline at end of file diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java index 4519f61..c996343 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java @@ -19,10 +19,10 @@ public class SpongeListener extends VPNExecutor { @Listener(order = Order.EARLY) public void onJoin(ServerSideConnectionEvent.Auth event) { AtomicReference player = new AtomicReference<>(AntiVPN.getInstance().getPlayerExecutor() - .getPlayer(event.connection().profile().uuid()) + .getPlayer(event.profile().uuid()) .orElse(new OfflinePlayer( - event.connection().profile().uuid(), - event.connection().profile().name().orElse("Unknown"), + event.profile().uuid(), + event.profile().name().orElse("Unknown"), event.connection().address().getAddress() ))); @@ -66,17 +66,17 @@ public class SpongeListener extends VPNExecutor { @Override public void registerListeners() { - Sponge.eventManager().registerListeners(SpongePlugin.INSTANCE.getPlugin(), this); + Sponge.eventManager().registerListeners(SpongePlugin.getInstance().getContainer(), this); } @Override public void log(Level level, String log, Object... objects) { if (level.equals(Level.SEVERE)) { - SpongePlugin.INSTANCE.getLogger().error(String.format(log, objects)); + SpongePlugin.getInstance().getLogger().error(String.format(log, objects)); } else if (level.equals(Level.WARNING)) { - SpongePlugin.INSTANCE.getLogger().warn(String.format(log, objects)); + SpongePlugin.getInstance().getLogger().warn(String.format(log, objects)); } else { - SpongePlugin.INSTANCE.getLogger().info(String.format(log, objects)); + SpongePlugin.getInstance().getLogger().info(String.format(log, objects)); } } @@ -87,7 +87,7 @@ public class SpongeListener extends VPNExecutor { @Override public void logException(String message, Throwable ex) { - SpongePlugin.INSTANCE.getLogger().error(message, ex); + SpongePlugin.getInstance().getLogger().error(message, ex); } @Override diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java index 3b68391..ae9cbb3 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java @@ -4,49 +4,52 @@ import com.google.inject.Inject; import dev.brighten.antivpn.AntiVPN; import lombok.Getter; import org.spongepowered.api.Server; -import org.spongepowered.api.config.ConfigDir; +import org.apache.logging.log4j.Logger; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.config.ConfigManager; import org.spongepowered.api.event.Listener; -import org.spongepowered.api.event.lifecycle.StartedEngineEvent; -import org.spongepowered.api.event.lifecycle.StoppingEngineEvent; +import org.spongepowered.api.event.lifecycle.*; import org.spongepowered.plugin.PluginContainer; import org.spongepowered.plugin.builtin.jvm.Plugin; import java.nio.file.Path; -import org.slf4j.Logger; @Plugin("kaurivpn") @Getter public class SpongePlugin { - public static SpongePlugin INSTANCE; - //Plugin init - @Inject - private PluginContainer plugin; + private final PluginContainer container; + private final Logger logger; @Inject - private Logger logger; - - @Inject - @ConfigDir(sharedRoot = false) - private Path configDir; + SpongePlugin(final PluginContainer container, final Logger logger) { + this.container = container; + this.logger = logger; + } @Listener - public void onServerStart(final StartedEngineEvent event) { - INSTANCE = this; - - logger.info("Starting AntiVPN services..."); + public void onServerStart(final ConstructPluginEvent event) { //Start AntiVPN + ConfigManager configManager = Sponge.game().configManager(); SpongeListener spongeListener = new SpongeListener(); - AntiVPN.start(spongeListener, new SpongePlayerExecutor(), configDir.toFile()); + var path = configManager.sharedConfig(container).directory(); + + logger.info("Fucking path: " + path); + + AntiVPN.start(spongeListener, new SpongePlayerExecutor(), path.toFile()); } @Listener - public void onServer(final StoppingEngineEvent event) { + public void onServer(final StoppingEngineEvent event) { AntiVPN.getInstance().getExecutor().disablePlugin(); } + public static SpongePlugin getInstance() { + return (SpongePlugin) Sponge.pluginManager().plugin("kaurivpn").get(); + } + } diff --git a/Sponge/src/main/resources/META-INF/sponge_plugins.json b/Sponge/src/main/resources/META-INF/sponge_plugins.json new file mode 100644 index 0000000..be21d3b --- /dev/null +++ b/Sponge/src/main/resources/META-INF/sponge_plugins.json @@ -0,0 +1,29 @@ +{ + "loader": { + "name": "java_plain", + "version": "1.0" + }, + "license": "All-Rights-Reserved", + "plugins": [ + { + "id": "kaurivpn", + "name": "Kauri VPN", + "version": "${version}", + "entrypoint": "dev.brighten.antivpn.sponge.SpongePlugin", + "description": "A simple and fast antivpn plugin.", + "branding": {}, + "links": { + }, + "contributors": [ + ], + "dependencies": [ + { + "id": "spongeapi", + "version": "11.0.0", + "load-order": "after", + "optional": false + } + ] + } + ] +} diff --git a/Universal/pom.xml b/Universal/pom.xml index fe9424e..0706963 100644 --- a/Universal/pom.xml +++ b/Universal/pom.xml @@ -42,12 +42,11 @@ ${project.version} compile - - + @@ -77,6 +76,10 @@ org.bstats dev.brighten.antivpn.shaded.org.bstats + + org.objectweb + dev.brighten.antivpn.shaded.org.objectweb + From 68a2acce008e83b5b0b39a3d2a2645edf1ba9cca Mon Sep 17 00:00:00 2001 From: Dawson Date: Wed, 28 May 2025 15:42:43 -0400 Subject: [PATCH 3/7] Got Sponge support working, need to ensure other plugins are still working tho --- .../dev/brighten/antivpn/api/APIPlayer.java | 5 +- .../antivpn/depends/LibraryLoader.java | 10 +- Sponge/pom.xml | 97 ++++++++++++++- .../antivpn/sponge/SpongeListener.java | 2 +- .../antivpn/sponge/SpongePlayerExecutor.java | 2 + .../brighten/antivpn/sponge/SpongePlugin.java | 37 +++--- .../antivpn/sponge/command/SpongeCommand.java | 111 ++++++++++++++++++ .../sponge/command/SpongeCommandExecutor.java | 42 +++++++ Universal/pom.xml | 5 - 9 files changed, 285 insertions(+), 26 deletions(-) create mode 100644 Sponge/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommand.java create mode 100644 Sponge/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommandExecutor.java diff --git a/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java b/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java index 1660a73..086755a 100644 --- a/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java +++ b/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java @@ -54,7 +54,10 @@ public abstract class APIPlayer { CheckResult cachedResult = checkResultCache.getIfPresent(ip.getHostAddress()); if(cachedResult != null) { - return cachedResult; + if(cachedResult.response().getIp().equals(ip.getHostAddress())) { + AntiVPN.getInstance().getExecutor().log(Level.FINE, "Cached result for " + ip.getHostAddress() + " is " + cachedResult.resultType()); + return cachedResult; + } } AntiVPN.getInstance().getExecutor().checkIp(ip.getHostAddress()) diff --git a/Common/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java b/Common/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java index 2ef3bca..8f16b26 100644 --- a/Common/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java +++ b/Common/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java @@ -55,14 +55,20 @@ import java.util.jar.JarOutputStream; public final class LibraryLoader { @SuppressWarnings("Guava") - private static final Supplier URL_INJECTOR = Suppliers.memoize(() -> - URLClassLoaderAccess.create((URLClassLoader) AntiVPN.getInstance().getClass().getClassLoader())); + private static final Supplier URL_INJECTOR = AntiVPN.getInstance().getClass().getClassLoader() instanceof URLClassLoader ? + Suppliers.memoize(() -> + URLClassLoaderAccess.create((URLClassLoader) AntiVPN.getInstance().getClass().getClassLoader())) + : null; public static void loadAll(Object object) { + if(URL_INJECTOR == null) + return; loadAll(object.getClass()); } public static void loadAll(Class clazz) { + if(URL_INJECTOR == null) + return; MavenLibrary[] libs = clazz.getDeclaredAnnotationsByType(MavenLibrary.class); for (MavenLibrary lib : libs) { diff --git a/Sponge/pom.xml b/Sponge/pom.xml index 7af842c..bb8f79a 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -29,7 +29,32 @@ dev.brighten.antivpn Common 1.9.4-DEV - provided + compile + + + com.github.ben-manes.caffeine + caffeine + 3.1.8 + compile + + + org.mongodb + mongo-java-driver + 3.12.14 + compile + + + com.mysql + mysql-connector-j + 9.1.0 + jar + compile + + + com.h2database + h2 + 2.2.220 + compile @@ -61,7 +86,77 @@ shade + + + *:* + + com/google/** + org/objectweb/** + org/checkerframework/** + + + + + + org.yaml.snakeyaml + dev.brighten.antivpn.shaded.org.yaml.snakeyaml + + + dev.brighten.antivpn.depends.Relocate + dev.brighten.antivpn.depends.MavenLibraries + + + + com.github.benmanes.caffeine + dev.brighten.antivpn.com.github.benmanes.caffeine + + + org.h2 + dev.brighten.antivpn.shaded.org.h2 + + + dev.brighten.antivpn.depends.Relocate + dev.brighten.antivpn.depends.MavenLibraries + + + + org.bson + dev.brighten.antivpn.shaded.org.bson + + + dev.brighten.antivpn.depends.Relocate + dev.brighten.antivpn.depends.MavenLibraries + + + + com.mongodb + dev.brighten.antivpn.shaded.com.mongodb + + + dev.brighten.antivpn.depends.Relocate + dev.brighten.antivpn.depends.MavenLibraries + + + + com.mysql.cj + dev.brighten.antivpn.shaded.com.mysql.cj + + + dev.brighten.antivpn.depends.Relocate + dev.brighten.antivpn.depends.MavenLibraries + + + + com.mysql.jdbc + dev.brighten.antivpn.shaded.com.mysql.jdbc + + + dev.brighten.antivpn.depends.Relocate + dev.brighten.antivpn.depends.MavenLibraries + + + diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java index c996343..d059c0b 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java @@ -101,6 +101,6 @@ public class SpongeListener extends VPNExecutor { @Override public void disablePlugin() { - Sponge.eventManager().unregisterListeners(this); + AntiVPN.getInstance().getExecutor().log(Level.INFO, "Disabling listeners for plugin..."); } } diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java index be373de..3904633 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java @@ -7,6 +7,7 @@ import dev.brighten.antivpn.api.PlayerExecutor; import org.spongepowered.api.Sponge; import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -49,6 +50,7 @@ public class SpongePlayerExecutor implements PlayerExecutor { @Override public List getOnlinePlayers() { + if(!Sponge.game().isServerAvailable()) return Collections.emptyList(); return Sponge.server().onlinePlayers() .stream() .map(pl -> { diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java index ae9cbb3..1aa11f2 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java @@ -2,38 +2,35 @@ package dev.brighten.antivpn.sponge; import com.google.inject.Inject; import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.sponge.command.SpongeCommand; import lombok.Getter; import org.spongepowered.api.Server; import org.apache.logging.log4j.Logger; import org.spongepowered.api.Sponge; +import org.spongepowered.api.command.Command; import org.spongepowered.api.config.ConfigManager; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.lifecycle.*; import org.spongepowered.plugin.PluginContainer; import org.spongepowered.plugin.builtin.jvm.Plugin; -import java.nio.file.Path; - @Plugin("kaurivpn") @Getter public class SpongePlugin { //Plugin init - private final PluginContainer container; - private final Logger logger; - @Inject - SpongePlugin(final PluginContainer container, final Logger logger) { - this.container = container; - this.logger = logger; - } - + private PluginContainer container; + @Inject + private Logger logger; + @Getter + private static SpongePlugin instance; @Listener - public void onServerStart(final ConstructPluginEvent event) { - //Start AntiVPN + public void onConstruct(final ConstructPluginEvent event) { + instance = this; - ConfigManager configManager = Sponge.game().configManager(); + ConfigManager configManager = Sponge.configManager(); SpongeListener spongeListener = new SpongeListener(); var path = configManager.sharedConfig(container).directory(); @@ -48,8 +45,16 @@ public class SpongePlugin { AntiVPN.getInstance().getExecutor().disablePlugin(); } - public static SpongePlugin getInstance() { - return (SpongePlugin) Sponge.pluginManager().plugin("kaurivpn").get(); + @Listener + public void onRegisterRawCommands(final RegisterCommandEvent event){ + if(AntiVPN.getInstance() == null) { + for(int i = 0 ; i < 5 ; i++) System.out.println("FUCKING NULL"); + return; + } + AntiVPN.getInstance().getExecutor().log("Registering commands..."); + for (dev.brighten.antivpn.command.Command command : AntiVPN.getInstance().getCommands()) { + AntiVPN.getInstance().getExecutor().log("Registering command %s...", command.name()); + event.register(this.container, new SpongeCommand(command), command.name(), command.aliases()); + } } - } diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommand.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommand.java new file mode 100644 index 0000000..3bccdc2 --- /dev/null +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommand.java @@ -0,0 +1,111 @@ +package dev.brighten.antivpn.sponge.command; + +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.command.Command; +import dev.brighten.antivpn.command.CommandExecutor; +import dev.brighten.antivpn.utils.StringUtil; +import lombok.val; +import net.kyori.adventure.text.Component; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.spongepowered.api.command.CommandCause; +import org.spongepowered.api.command.CommandCompletion; +import org.spongepowered.api.command.CommandResult; +import org.spongepowered.api.command.parameter.ArgumentReader; + +import java.util.*; +import java.util.stream.IntStream; + +public class SpongeCommand implements org.spongepowered.api.command.Command.Raw { + + private final Command command; + + public SpongeCommand(Command command) { + this.command = command; + } + + @Override + public CommandResult process(CommandCause sender, ArgumentReader.Mutable arguments) { + + String[] args = arguments.input().split(" "); + + CommandExecutor commandExecutor = new SpongeCommandExecutor(sender); + + val children = command.children(); + + if(children.length > 0 && args.length > 0) { + for (dev.brighten.antivpn.command.Command child : children) { + if(child.name().equalsIgnoreCase(args[0]) || Arrays.stream(child.aliases()) + .anyMatch(alias -> alias.equalsIgnoreCase(args[0]))) { + if(!sender.hasPermission("antivpn.command.*") + && !sender.hasPermission(child.permission())) { + return CommandResult.error(Component.text(StringUtil.translateAlternateColorCodes('&', + AntiVPN.getInstance().getMessageHandler().getString("no-permission").getMessage()))); + } + + commandExecutor.sendMessage(StringUtil + .translateAlternateColorCodes('&', + child.execute(commandExecutor, IntStream + .range(0, args.length - 1) + .mapToObj(i -> args[i + 1]).toArray(String[]::new)))); + return CommandResult.success(); + } + } + } + + commandExecutor.sendMessage(StringUtil + .translateAlternateColorCodes('&', + command.execute(new SpongeCommandExecutor(sender), args))); + + command.execute(new SpongeCommandExecutor(sender), args); + return CommandResult.success(); + } + + @Override + public List complete(CommandCause sender, ArgumentReader.Mutable arguments) { + val children = command.children(); + String[] args = arguments.input().split(" "); + if(children.length > 0 && args.length > 0) { + for (dev.brighten.antivpn.command.Command child : children) { + if(child.name().equalsIgnoreCase(args[0]) || Arrays.stream(child.aliases()) + .anyMatch(alias2 -> alias2.equalsIgnoreCase(args[0]))) { + return child.tabComplete(new SpongeCommandExecutor(sender), "alias", IntStream + .range(0, args.length - 1) + .mapToObj(i -> args[i + 1]).toArray(String[]::new)) + .stream() + .map(CommandCompletion::of) + .toList(); + } + } + } + return command.tabComplete(new SpongeCommandExecutor(sender), "alias", args) + .stream() + .map(CommandCompletion::of) + .toList(); + } + + @Override + public boolean canExecute(CommandCause cause) { + return cause.hasPermission(command.permission()); + } + + @Override + public Optional shortDescription(CommandCause cause) { + return command.description() != null ? Optional.of(Component.text(command.description())) : Optional.empty(); + } + + @Override + public Optional extendedDescription(CommandCause cause) { + return Optional.empty(); + } + + @Override + public Optional help(@NonNull CommandCause cause) { + return Optional.of(Component.text(StringUtil.translateAlternateColorCodes('&', + command.execute(new SpongeCommandExecutor(cause), new String[0])))); + } + + @Override + public Component usage(CommandCause cause) { + return command.usage() != null ? Component.text(command.usage()) : Component.empty(); + } +} diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommandExecutor.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommandExecutor.java new file mode 100644 index 0000000..de96dd5 --- /dev/null +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommandExecutor.java @@ -0,0 +1,42 @@ +package dev.brighten.antivpn.sponge.command; + +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.api.APIPlayer; +import dev.brighten.antivpn.command.CommandExecutor; +import dev.brighten.antivpn.sponge.util.StringUtil; +import lombok.RequiredArgsConstructor; +import net.kyori.adventure.text.Component; +import org.spongepowered.api.command.CommandCause; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; + +import java.util.Optional; + +@RequiredArgsConstructor +public class SpongeCommandExecutor implements CommandExecutor { + + private final CommandCause cause; + + @Override + public void sendMessage(String message, Object... objects) { + cause.sendMessage(Component.text(StringUtil.translateColorCodes('&', + String.format(message, objects)))); + } + + @Override + public boolean hasPermission(String permission) { + return cause.hasPermission(permission); + } + + @Override + public Optional getPlayer() { + if(cause.subject() instanceof ServerPlayer serverPlayer) { + return AntiVPN.getInstance().getPlayerExecutor().getPlayer(serverPlayer.uniqueId()); + } + return Optional.empty(); + } + + @Override + public boolean isPlayer() { + return cause.subject() instanceof ServerPlayer; + } +} diff --git a/Universal/pom.xml b/Universal/pom.xml index 0706963..b036049 100644 --- a/Universal/pom.xml +++ b/Universal/pom.xml @@ -42,11 +42,6 @@ ${project.version} compile - - dev.brighten.antivpn - Sponge - ${project.version} - From f271275bfae70935aece69dfb25b3139ce53f46c Mon Sep 17 00:00:00 2001 From: Dawson Date: Wed, 28 May 2025 16:33:29 -0400 Subject: [PATCH 4/7] Sponge is loading, other plugins load, fixed some bugs that were introduced, added sponge plugin uploader in maven workflow --- .github/workflows/maven.yml | 7 ++++++- .../dev/brighten/antivpn/bukkit/BukkitListener.java | 4 +++- Common/pom.xml | 2 +- Common/src/main/java/dev/brighten/antivpn/AntiVPN.java | 5 ++++- .../main/java/dev/brighten/antivpn/api/APIPlayer.java | 2 ++ Sponge/pom.xml | 2 +- .../dev/brighten/antivpn/sponge/SpongeListener.java | 10 +++++++++- 7 files changed, 26 insertions(+), 6 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index f4dd1cb..ed7bcd3 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -29,5 +29,10 @@ jobs: - name: Upload AntiVPN uses: actions/upload-artifact@v4 with: - name: AntiVPN + name: AntiVPN-Universal path: Universal/target/AntiVPN-*.jar + - name: Upload Sponge plugin + uses: actions/upload-artifact@v4 + with: + name: AntiVPN-Sponge + path: Sponge/target/Sponge-*.jar diff --git a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java index fe37786..9c51ef6 100644 --- a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java +++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java @@ -62,7 +62,7 @@ public class BukkitListener extends VPNExecutor implements Listener { .orElse(new OfflinePlayer( event.getPlayer().getUniqueId(), event.getPlayer().getName(), - event.getRealAddress() + event.getAddress() )); CheckResult instantResult = player.checkPlayer(result -> { @@ -81,6 +81,8 @@ public class BukkitListener extends VPNExecutor implements Listener { return; } + AntiVPN.getInstance().getExecutor().log(Level.INFO, "%s was kicked from pre-login cache with IP %s", event.getPlayer().getName(), instantResult.response().getIp()); + event.setResult(PlayerLoginEvent.Result.KICK_BANNED); switch (instantResult.resultType()) { case DENIED_COUNTRY -> event.setKickMessage(StringUtil.translateAlternateColorCodes('&', diff --git a/Common/pom.xml b/Common/pom.xml index bed828a..dec5693 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -59,7 +59,7 @@ com.github.benmanes.caffeine - dev.brighten.antivpn.com.github.benmanes.caffeine + dev.brighten.antivpn.shaded.com.github.benmanes.caffeine org.h2 diff --git a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java index 6382ccb..e89821a 100644 --- a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -47,7 +47,10 @@ import java.util.List; @Relocate(from = "com.my\\" + "sql.jdbc", to = "dev.brighten.antivpn.shaded.com.mysql.jdbc") } ) -@MavenLibrary(groupId = "com.github.ben-manes.caffeine", artifactId = "caffeine", version = "3.1.8") +@MavenLibrary(groupId = "com.\\github\\.ben-manes\\.caffeine", artifactId = "caffeine", version = "3.1.8", + relocations = { + @Relocate(from = "com\\.github\\.benmanes\\.caffeine", to = "dev.brighten.antivpn.shaded.com.github.benmanes.caffeine"), + }) public class AntiVPN { private static AntiVPN INSTANCE; diff --git a/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java b/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java index 086755a..1c0f2bc 100644 --- a/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java +++ b/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java @@ -90,6 +90,8 @@ public abstract class APIPlayer { checkResult = new CheckResult(result, ResultType.ALLOWED); } + AntiVPN.getInstance().getExecutor().log(Level.FINE, "Result for " + ip.getHostAddress() + " is " + checkResult.resultType()); + checkResultCache.put(ip.getHostAddress(), checkResult); onKick.accept(checkResult); AntiVPN.getInstance().checked++; diff --git a/Sponge/pom.xml b/Sponge/pom.xml index bb8f79a..075ed54 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -109,7 +109,7 @@ com.github.benmanes.caffeine - dev.brighten.antivpn.com.github.benmanes.caffeine + dev.brighten.antivpn.shaded.com.github.benmanes.caffeine org.h2 diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java index d059c0b..47b6664 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java @@ -17,7 +17,7 @@ import java.util.logging.Level; public class SpongeListener extends VPNExecutor { @Listener(order = Order.EARLY) - public void onJoin(ServerSideConnectionEvent.Auth event) { + public void onJoin(ServerSideConnectionEvent.Login event) { AtomicReference player = new AtomicReference<>(AntiVPN.getInstance().getPlayerExecutor() .getPlayer(event.profile().uuid()) .orElse(new OfflinePlayer( @@ -42,6 +42,8 @@ public class SpongeListener extends VPNExecutor { return; } + AntiVPN.getInstance().getExecutor().log(Level.INFO, "%s was kicked from cache with IP %s", player.get().getName(), instantResult.response().getIp()); + event.setCancelled(true); switch (instantResult.resultType()) { case DENIED_PROXY -> { @@ -64,6 +66,12 @@ public class SpongeListener extends VPNExecutor { } } + @Listener + public void onPlayerDisconnect(ServerSideConnectionEvent.Disconnect event) { + event.profile().ifPresent(profile -> + AntiVPN.getInstance().getPlayerExecutor().unloadPlayer(profile.uuid())); + } + @Override public void registerListeners() { Sponge.eventManager().registerListeners(SpongePlugin.getInstance().getContainer(), this); From 866217ff08873aadf8d3f28e195fb3b6feca479d Mon Sep 17 00:00:00 2001 From: Dawson Date: Wed, 28 May 2025 16:36:28 -0400 Subject: [PATCH 5/7] Fixing repositories --- Sponge/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sponge/pom.xml b/Sponge/pom.xml index 075ed54..468cf97 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -16,6 +16,10 @@ spongepowered-repo https://repo.spongepowered.org/maven/ + + funkemunky-releases + https://nexus.funkemunky.cc/content/repositories/releases/ + From 4f43028ec0076f5fdc1869136f31a2c58ddb88e9 Mon Sep 17 00:00:00 2001 From: Dawson Date: Wed, 28 May 2025 16:38:48 -0400 Subject: [PATCH 6/7] Attempting to fix cache dependency path --- .github/workflows/maven.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index ed7bcd3..c3638cb 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -17,7 +17,8 @@ jobs: with: java-version: '17' distribution: 'zulu' - cache: maven + cache: 'maven' + cache-dependency-path: '**/pom.xml' # Add this line - name: Set up Maven uses: stCarolas/setup-maven@v5 with: From 103fdf74da59439d2320347c3c2bcde7b3d506f8 Mon Sep 17 00:00:00 2001 From: Dawson Date: Wed, 28 May 2025 16:40:28 -0400 Subject: [PATCH 7/7] Using JDK 21 instead --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index c3638cb..ad0d183 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -12,10 +12,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: '17' + java-version: '21' distribution: 'zulu' cache: 'maven' cache-dependency-path: '**/pom.xml' # Add this line