diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index b2b3197..b63af6a 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -1,6 +1,10 @@ on: push: branches: ["**"] + pull_request: + types: + - opened + - synchronize jobs: build: diff --git a/Assembly/dependency-reduced-pom.xml b/Assembly/dependency-reduced-pom.xml index 1685498..5924f7c 100644 --- a/Assembly/dependency-reduced-pom.xml +++ b/Assembly/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ AntiVPN dev.brighten.antivpn - 1.8.2.2 + 1.9.1 4.0.0 Assembly @@ -18,6 +18,18 @@ shade + + + + org.yaml.snakeyaml + dev.brighten.antivpn.shaded.org.yaml.snakeyaml + + + com.google.common + dev.brighten.antivpn.shaded.com.google.common + + + diff --git a/Assembly/pom.xml b/Assembly/pom.xml index 8356526..97be620 100644 --- a/Assembly/pom.xml +++ b/Assembly/pom.xml @@ -5,7 +5,7 @@ AntiVPN dev.brighten.antivpn - 1.8.2.2 + 1.9.2 4.0.0 @@ -28,6 +28,18 @@ shade + + + + org.yaml.snakeyaml + dev.brighten.antivpn.shaded.org.yaml.snakeyaml + + + com.google.common + dev.brighten.antivpn.shaded.com.google.common + + + diff --git a/Bukkit/dependency-reduced-pom.xml b/Bukkit/dependency-reduced-pom.xml index 0e89eea..d81027d 100644 --- a/Bukkit/dependency-reduced-pom.xml +++ b/Bukkit/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ AntiVPN dev.brighten.antivpn - 1.8.2.2 + 1.9.1 4.0.0 Bukkit @@ -26,23 +26,32 @@ maven-shade-plugin - 3.1.0 + 3.2.4 package shade + + true + + + org.bstats + dev.brighten.antivpn.bukkit.org.bstats + + + org.yaml.snakeyaml + dev.brighten.antivpn.shaded.org.yaml.snakeyaml + + + com.google.common + dev.brighten.antivpn.shaded.com.google.common + + + - - - - org.bstats - dev.brighten.antivpn.bukkit.org.bstats - - - @@ -56,14 +65,8 @@ dev.brighten.antivpn Common - 1.8.2.2 + 1.9.1 provided - - - snakeyaml - org.yaml - - cc.funkemunky.utils @@ -77,4 +80,3 @@ 8 - diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 62da9a9..87ddad2 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,7 +5,7 @@ AntiVPN dev.brighten.antivpn - 1.8.2.2 + 1.9.2 4.0.0 @@ -26,22 +26,31 @@ org.apache.maven.plugins maven-shade-plugin - 3.1.0 - - - - org.bstats - - dev.brighten.antivpn.bukkit.org.bstats - - - + 3.2.4 package shade + + true + + + org.bstats + + dev.brighten.antivpn.bukkit.org.bstats + + + org.yaml.snakeyaml + dev.brighten.antivpn.shaded.org.yaml.snakeyaml + + + com.google.common + dev.brighten.antivpn.shaded.com.google.common + + + @@ -69,7 +78,7 @@ dev.brighten.antivpn Common - 1.8.2.2 + 1.9.2 provided 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 ae9adc1..0977dc7 100644 --- a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java +++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java @@ -1,9 +1,12 @@ package dev.brighten.antivpn.bukkit; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.api.APIPlayer; import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.message.VpnString; +import dev.brighten.antivpn.web.objects.VPNResponse; import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -16,11 +19,20 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.UUID; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; public class BukkitListener extends VPNExecutor implements Listener { private BukkitTask cacheResetTask; + private final Cache responseCache = CacheBuilder.newBuilder() + .expireAfterWrite(5, TimeUnit.MINUTES) + .maximumSize(10000) + .build(); + @Override public void registerListeners() { BukkitPlugin.pluginInstance.getServer().getPluginManager() @@ -29,11 +41,12 @@ public class BukkitListener extends VPNExecutor implements Listener { @Override public void runCacheReset() { + // Reset cache every 20 minutes cacheResetTask = new BukkitRunnable() { public void run() { resetCache(); } - }.runTaskTimerAsynchronously(BukkitPlugin.pluginInstance, 24000, 24000); //Reset cache every 20 minutes + }.runTaskTimerAsynchronously(BukkitPlugin.pluginInstance, 24000, 24000); HandlerList.unregisterAll(this); threadExecutor.shutdown(); @@ -44,9 +57,14 @@ public class BukkitListener extends VPNExecutor implements Listener { if(cacheResetTask != null && !cacheResetTask.isCancelled()) cacheResetTask.cancel(); } + @Override + public void log(Level level, String log, Object... objects) { + Bukkit.getLogger().log(level, String.format(log, objects)); + } + @Override public void log(String log, Object... objects) { - Bukkit.getLogger().log(Level.INFO, String.format(log, objects)); + log(Level.INFO, String.format(log, objects)); } @EventHandler @@ -75,6 +93,18 @@ public class BukkitListener extends VPNExecutor implements Listener { || 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()) { + event.setResult(PlayerLoginEvent.Result.KICK_BANNED); + event.setKickMessage(org.bukkit.ChatColor.translateAlternateColorCodes('&', + AntiVPN.getInstance().getVpnConfig().getKickString())); + return; + } + } + final Player player = event.getPlayer(); checkIp(event.getAddress().getHostAddress(), AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> { @@ -82,15 +112,28 @@ public class BukkitListener extends VPNExecutor implements Listener { //We need to run on main thread or kicking and running commands will cause errors new BukkitRunnable() { public void run() { + //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 + InetSocketAddress address = event.getPlayer().getAddress(); + if (address != null){ + InetAddress address1 = address.getAddress(); + if (address1 != null && AntiVPN.getInstance().getExecutor().isWhitelisted(address1.getHostAddress())) { + log("IP is whitelisted: %s", + address1.getHostAddress()); + return; + } + } + } + // If the countryList() size is zero, no need to check. // Running country check first if(AntiVPN.getInstance().getVpnConfig().countryList().size() > 0 - && !(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() - .getAddress().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. @@ -123,7 +166,7 @@ public class BukkitListener extends VPNExecutor implements Listener { if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) player.kickPlayer(org.bukkit.ChatColor.translateAlternateColorCodes('&', AntiVPN.getInstance().getVpnConfig().getKickString())); - Bukkit.getLogger().info(event.getPlayer().getName() + log(Level.INFO, event.getPlayer().getName() + " joined on a VPN/Proxy (" + result.getMethod() + ")"); //Ensuring the user wishes to alert to staff @@ -150,8 +193,7 @@ public class BukkitListener extends VPNExecutor implements Listener { } }.runTask(BukkitPlugin.pluginInstance); } else { - Bukkit.getLogger() - .log(Level.WARNING, + log(Level.WARNING, "The API query was not a success! " + "You may need to upgrade your license on https://funkemunky.cc/shop"); } diff --git a/Bungee/dependency-reduced-pom.xml b/Bungee/dependency-reduced-pom.xml index f44d6aa..98c91a2 100644 --- a/Bungee/dependency-reduced-pom.xml +++ b/Bungee/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ AntiVPN dev.brighten.antivpn - 1.8.2.2 + 1.9.1 4.0.0 Bungee @@ -41,6 +41,14 @@ org.bstats dev.brighten.antivpn.bungee.org.bstats + + org.yaml.snakeyaml + dev.brighten.antivpn.shaded.org.yaml.snakeyaml + + + com.google + dev.brighten.antivpn.shaded.com.google + @@ -50,13 +58,17 @@ dev.brighten.antivpn Common - 1.8.2.2 + 1.9.1 provided snakeyaml org.yaml + + guava + com.google.guava + diff --git a/Bungee/pom.xml b/Bungee/pom.xml index a5ff714..fb5f8bc 100644 --- a/Bungee/pom.xml +++ b/Bungee/pom.xml @@ -5,7 +5,7 @@ AntiVPN dev.brighten.antivpn - 1.8.2.2 + 1.9.2 4.0.0 @@ -34,6 +34,14 @@ dev.brighten.antivpn.bungee.org.bstats + + org.yaml.snakeyaml + dev.brighten.antivpn.shaded.org.yaml.snakeyaml + + + com.google + dev.brighten.antivpn.shaded.com.google + @@ -63,7 +71,7 @@ dev.brighten.antivpn Common - 1.8.2.2 + 1.9.2 provided 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 82ef549..24aab5d 100644 --- a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -1,17 +1,22 @@ package dev.brighten.antivpn.bungee; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.api.APIPlayer; import dev.brighten.antivpn.api.VPNExecutor; +import dev.brighten.antivpn.web.objects.VPNResponse; import net.md_5.bungee.BungeeCord; 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 java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.logging.Level; @@ -19,6 +24,11 @@ public class BungeeListener extends VPNExecutor implements Listener { private ScheduledTask cacheResetTask; + private final Cache responseCache = CacheBuilder.newBuilder() + .expireAfterWrite(5, TimeUnit.MINUTES) + .maximumSize(10000) + .build(); + @Override public void registerListeners() { BungeePlugin.pluginInstance.getProxy().getPluginManager() @@ -42,10 +52,32 @@ public class BungeeListener extends VPNExecutor implements Listener { } @Override - public void log(String log, Object... objects) { + public void log(Level level, String log, Object... objects) { BungeeCord.getInstance().getLogger().log(Level.INFO, String.format(log, objects)); } + @Override + public void log(String log, Object... objects) { + log(Level.INFO, String.format(log, objects)); + } + + @EventHandler + public void onListener(final PreLoginEvent event) { + if(!responseCache.asMap().containsKey(event.getConnection().getUniqueId())) return; + + VPNResponse cached = responseCache.getIfPresent(event.getConnection().getUniqueId()); + + if(cached != null && cached.isProxy()) { + event.setCancelled(true); + event.setCancelReason(TextComponent.fromLegacyText(ChatColor + .translateAlternateColorCodes('&', + AntiVPN.getInstance().getVpnConfig().getKickString()))); + AntiVPN.getInstance().getExecutor().log(Level.INFO, + "%s was kicked from pre-login proxy cache.", + event.getConnection().getName()); + } + } + @EventHandler public void onListener(final PostLoginEvent event) { if(event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission @@ -55,13 +87,24 @@ public class BungeeListener extends VPNExecutor implements Listener { checkIp(event.getPlayer().getAddress().getAddress().getHostAddress(), AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> { if(result.isSuccess()) { - // If the countryList() size is zero, no need to check. - // Running country check first + //If the player is whitelisted, we don't want to kick them + 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(event.getPlayer().getAddress().getAddress() + .getHostAddress())) { + AntiVPN.getInstance().getExecutor().log("IP is whitelisted: %s", + event.getPlayer().getAddress().getAddress().getHostAddress()); + return; + } + + responseCache.put(event.getPlayer().getUniqueId(), result); + if(AntiVPN.getInstance().getVpnConfig().countryList().size() > 0 - && !(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().getAddress().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. diff --git a/Common/pom.xml b/Common/pom.xml index 15310d4..337c9df 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -5,7 +5,7 @@ AntiVPN dev.brighten.antivpn - 1.8.2.2 + 1.9.2 4.0.0 @@ -45,6 +45,10 @@ org.yaml.snakeyaml dev.brighten.antivpn.shaded.org.yaml.snakeyaml + + com.google.common + dev.brighten.antivpn.shaded.com.google.common + @@ -86,6 +90,11 @@ 2.0 compile + + com.google.guava + guava + 31.1-jre + org.mongodb mongo-java-driver 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 a1c9a82..8a9cbfc 100644 --- a/Common/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -12,6 +12,7 @@ import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Consumer; +import java.util.logging.Level; public abstract class VPNExecutor { public static ExecutorService threadExecutor = Executors.newSingleThreadExecutor(); @@ -32,6 +33,8 @@ public abstract class VPNExecutor { public abstract void shutdown(); + public abstract void log(Level level, String log, Object... objects); + public abstract void log(String log, Object... objects); public boolean isWhitelisted(UUID uuid) { diff --git a/Common/src/main/java/dev/brighten/antivpn/command/impl/PlanCommand.java b/Common/src/main/java/dev/brighten/antivpn/command/impl/PlanCommand.java index 5b193ab..3dbd35a 100644 --- a/Common/src/main/java/dev/brighten/antivpn/command/impl/PlanCommand.java +++ b/Common/src/main/java/dev/brighten/antivpn/command/impl/PlanCommand.java @@ -10,6 +10,7 @@ import dev.brighten.antivpn.web.FunkemunkyAPI; import dev.brighten.antivpn.web.objects.QueryResponse; import java.io.IOException; +import java.util.Collections; import java.util.List; public class PlanCommand extends Command { diff --git a/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java b/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java index ac8a478..2289197 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java @@ -12,6 +12,8 @@ public interface VPNDatabase { void cacheResponse(VPNResponse toCache); + void deleteResponse(String ip); + boolean isWhitelisted(UUID uuid); boolean isWhitelisted(String ip); diff --git a/Common/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java b/Common/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java index 94466a0..6e2ea79 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java @@ -65,7 +65,12 @@ public class H2VPN implements VPNDatabase { rs.getString("method"), rs.getString("isp"), "N/A", rs.getBoolean("proxy"), rs.getBoolean("cached"), true, rs.getDouble("latitude"), rs.getDouble("longitude"), - System.currentTimeMillis(), -1); + rs.getTimestamp("inserted").getTime(), -1); + + if(System.currentTimeMillis() - response.getLastAccess() > TimeUnit.HOURS.toMillis(1)) { + VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip)); + return Optional.empty(); + } return Optional.of(response); } } catch (SQLException throwables) { @@ -98,6 +103,14 @@ public class H2VPN implements VPNDatabase { .append(toCache.getLatitude()).append(toCache.getLongitude()).execute(); } + @Override + public void deleteResponse(String ip) { + if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + return; + + Query.prepare("delete from `responses` where `ip` = ?").append(ip).execute(); + } + @SneakyThrows @Override public boolean isWhitelisted(UUID uuid) { diff --git a/Common/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java b/Common/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java index 20e1098..6ee677c 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java @@ -7,13 +7,16 @@ import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Indexes; +import com.mongodb.client.model.UpdateOptions; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.database.VPNDatabase; import dev.brighten.antivpn.web.objects.VPNResponse; import org.bson.Document; +import org.bson.conversions.Bson; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; public class MongoVPN implements VPNDatabase { @@ -27,6 +30,13 @@ public class MongoVPN implements VPNDatabase { Document rdoc = cacheDocument.find(Filters.eq("ip", ip)).first(); if(rdoc != null) { + long lastUpdate = rdoc.get("lastAccess", 0L); + + if(System.currentTimeMillis() - lastUpdate > TimeUnit.HOURS.toMillis(1)) { + VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip)); + return Optional.empty(); + } + return Optional.of(VPNResponse.builder().asn(rdoc.getString("asn")).ip(ip) .countryName(rdoc.getString("countryName")) .countryCode(rdoc.getString("countryCode")) @@ -39,6 +49,7 @@ public class MongoVPN implements VPNDatabase { .success(true) .latitude(rdoc.getDouble("latitude")) .longitude(rdoc.getDouble("longitude")) + .lastAccess(rdoc.get("lastAccess", 0L)) .build()); } return Optional.empty(); @@ -60,13 +71,20 @@ public class MongoVPN implements VPNDatabase { rdoc.put("success", toCache.isSuccess()); rdoc.put("latitude", toCache.getLatitude()); rdoc.put("longitude", toCache.getLongitude()); + rdoc.put("lastAccess", System.currentTimeMillis()); VPNExecutor.threadExecutor.execute(() -> { - cacheDocument.deleteMany(Filters.eq("ip", toCache.getIp())); - cacheDocument.insertOne(rdoc); + Bson update = new Document("$set", rdoc); + cacheDocument.updateOne(Filters.eq("ip", toCache.getIp()), update, + new UpdateOptions().upsert(true)); }); } + @Override + public void deleteResponse(String ip) { + cacheDocument.deleteMany(Filters.eq("ip", ip)); + } + @Override public boolean isWhitelisted(UUID uuid) { return settingsDocument @@ -100,8 +118,8 @@ public class MongoVPN implements VPNDatabase { @Override public void setWhitelisted(String ip, boolean whitelisted) { if(whitelisted) { - Document wdoc = new Document("setting", "whitelist"); - wdoc.put("ip", ip); + Document wdoc = new Document("setting", "whitelist").append("ip", ip); + AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip); VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc)); } else { diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java b/Common/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java index 9c5d222..b87dff7 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java @@ -52,7 +52,7 @@ public class MySqlVPN implements VPNDatabase { @Override public Optional getStoredResponse(String ip) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()|| MySQL.isClosed()) + if (isDisabled()) return Optional.empty(); ResultSet rs = Query.prepare("select * from `responses` where `ip` = ? limit 1").append(ip).executeQuery(); @@ -65,7 +65,13 @@ public class MySqlVPN implements VPNDatabase { rs.getString("method"), rs.getString("isp"), "N/A", rs.getBoolean("proxy"), rs.getBoolean("cached"), true, rs.getDouble("latitude"), rs.getDouble("longitude"), - System.currentTimeMillis(), -1); + rs.getTimestamp("inserted").getTime(), -1); + + if(System.currentTimeMillis() - response.getLastAccess() > TimeUnit.HOURS.toMillis(1)) { + VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip)); + return Optional.empty(); + } + return Optional.of(response); } } catch (SQLException throwables) { @@ -86,7 +92,7 @@ public class MySqlVPN implements VPNDatabase { */ @Override public void cacheResponse(VPNResponse toCache) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + if (isDisabled()) return; Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`," @@ -98,10 +104,18 @@ public class MySqlVPN implements VPNDatabase { .append(toCache.getLatitude()).append(toCache.getLongitude()).execute(); } + @Override + public void deleteResponse(String ip) { + if(!isDisabled()) + return; + + Query.prepare("delete from `responses` where `ip` = ?").append(ip).execute(); + } + @SneakyThrows @Override public boolean isWhitelisted(UUID uuid) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + if (isDisabled()) return false; ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1") .append(uuid.toString()).executeQuery(); @@ -112,7 +126,7 @@ public class MySqlVPN implements VPNDatabase { @SneakyThrows @Override public boolean isWhitelisted(String ip) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + if (isDisabled()) return false; ResultSet set = Query.prepare("select `ip` from `whitelisted-ips` where `ip` = ? limit 1") .append(ip).executeQuery(); @@ -123,7 +137,7 @@ public class MySqlVPN implements VPNDatabase { @Override public void setWhitelisted(UUID uuid, boolean whitelisted) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + if (isDisabled()) return; if (whitelisted) { @@ -139,7 +153,7 @@ public class MySqlVPN implements VPNDatabase { @Override public void setWhitelisted(String ip, boolean whitelisted) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + if (isDisabled()) return; if(whitelisted) { @@ -333,6 +347,10 @@ public class MySqlVPN implements VPNDatabase { System.err.println("MySQL Excepton created" + e.getMessage()); } } + + private boolean isDisabled() { + return !AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()|| MySQL.isClosed(); + } @Override public void shutdown() { diff --git a/Common/src/main/java/dev/brighten/antivpn/message/MessageHandler.java b/Common/src/main/java/dev/brighten/antivpn/message/MessageHandler.java index b3e2a87..7649a36 100644 --- a/Common/src/main/java/dev/brighten/antivpn/message/MessageHandler.java +++ b/Common/src/main/java/dev/brighten/antivpn/message/MessageHandler.java @@ -30,7 +30,7 @@ public class MessageHandler { public void addString(VpnString string, Function getter) { string.setConfigStringGetter(getter); getter.apply(string); - System.out.println("Added string " + string.getKey()); + AntiVPN.getInstance().getExecutor().log("Added string " + string.getKey()); messages.put(string.getKey(), string); } diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/Suppliers.java b/Common/src/main/java/dev/brighten/antivpn/utils/Suppliers.java index 85d3a0b..44e735c 100644 --- a/Common/src/main/java/dev/brighten/antivpn/utils/Suppliers.java +++ b/Common/src/main/java/dev/brighten/antivpn/utils/Suppliers.java @@ -24,8 +24,6 @@ import static dev.brighten.antivpn.utils.Preconditions.checkNotNull; import static dev.brighten.antivpn.utils.NullnessCasts.uncheckedCastNullableTToT; import static java.util.Objects.requireNonNull; -import jdk.tools.jlink.internal.Platform; - /** * Useful suppliers. * diff --git a/Common/src/main/resources/config.yml b/Common/src/main/resources/config.yml index 134acb4..6098586 100644 --- a/Common/src/main/resources/config.yml +++ b/Common/src/main/resources/config.yml @@ -15,8 +15,8 @@ prefixWhitelists: [] # Configure your database here. database: # Enable to cache queries and save alerts state beyond restarts - enabled: false - useCredentials: true + enabled: true + useCredentials: false #Options Mongo, MySQL, or H2 type: H2 # The database name you would like to use diff --git a/README.md b/README.md index a23cc0f..1bd91cc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Project Map](https://sourcespy.com/shield.svg)](https://sourcespy.com/github/funkemunkyantivpn/) + # AntiVPN An antivpn plugin utilizing the KauriVPN API diff --git a/Sponge/pom.xml b/Sponge/pom.xml index 5491297..4a784e5 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -5,7 +5,7 @@ AntiVPN dev.brighten.antivpn - 1.8.2.2 + 1.9.2 4.0.0 @@ -25,6 +25,12 @@ 8.1.0 provided + + dev.brighten.antivpn + Common + 1.9.2 + provided + diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java new file mode 100644 index 0000000..9ce17f9 --- /dev/null +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java @@ -0,0 +1,31 @@ +package dev.brighten.antivpn.sponge; + +import dev.brighten.antivpn.api.APIPlayer; +import dev.brighten.antivpn.sponge.util.StringUtil; +import net.kyori.adventure.text.Component; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; + +public class SpongePlayer extends APIPlayer { + + private final ServerPlayer player; + + public SpongePlayer(ServerPlayer player) { + super(player.uniqueId(), player.name(), player.connection().address().getAddress()); + this.player = player; + } + + @Override + public void sendMessage(String message) { + //player.sendMessage(StringUtil.translateColorCodes('&', message)); + } + + @Override + public void kickPlayer(String reason) { + player.kick(Component.text(StringUtil.translateColorCodes('&', reason))); + } + + @Override + public boolean hasPermission(String permission) { + return player.hasPermission(permission); + } +} diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java new file mode 100644 index 0000000..414d7b3 --- /dev/null +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java @@ -0,0 +1,31 @@ +package dev.brighten.antivpn.sponge; + +import dev.brighten.antivpn.api.APIPlayer; +import dev.brighten.antivpn.api.PlayerExecutor; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public class SpongePlayerExecutor implements PlayerExecutor { + @Override + public Optional getPlayer(String name) { + + return Optional.empty(); + } + + @Override + public Optional getPlayer(UUID uuid) { + return Optional.empty(); + } + + @Override + public void unloadPlayer(UUID uuid) { + + } + + @Override + public List getOnlinePlayers() { + return null; + } +} 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 7192463..39d9c50 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java @@ -1,4 +1,28 @@ package dev.brighten.antivpn.sponge; +import com.google.inject.Inject; +import org.spongepowered.api.Server; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.lifecycle.StartedEngineEvent; +import org.spongepowered.plugin.builtin.jvm.Plugin; + +import java.util.logging.Logger; + +@Plugin("kaurivpn") public class SpongePlugin { + + public static SpongePlugin INSTANCE; + //Plugin init + + @Inject + private Logger logger; + + @Listener + public void onServerStart(final StartedEngineEvent event) { + INSTANCE = this; + + logger.info("Starting AntiVPN services..."); + //Start AntiVPN + } + } diff --git a/Sponge/src/main/java/dev/brighten/antivpn/sponge/util/StringUtil.java b/Sponge/src/main/java/dev/brighten/antivpn/sponge/util/StringUtil.java new file mode 100644 index 0000000..22d1a5a --- /dev/null +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/util/StringUtil.java @@ -0,0 +1,17 @@ +package dev.brighten.antivpn.sponge.util; + +public class StringUtil { + + public static String translateColorCodes(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/Velocity/pom.xml b/Velocity/pom.xml index d98ab4f..940b04e 100644 --- a/Velocity/pom.xml +++ b/Velocity/pom.xml @@ -5,7 +5,7 @@ AntiVPN dev.brighten.antivpn - 1.8.2.2 + 1.9.2 4.0.0 @@ -33,7 +33,7 @@ dev.brighten.antivpn Common - 1.8.2.2 + 1.9.2 provided @@ -67,6 +67,10 @@ dev.brighten.antivpn.velocity.org.bstats + + org.yaml.snakeyaml + dev.brighten.antivpn.shaded.org.yaml.snakeyaml + 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 eb76e25..e11c2ac 100644 --- a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -1,5 +1,8 @@ package dev.brighten.antivpn.velocity; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.velocitypowered.api.event.ResultedEvent; import com.velocitypowered.api.event.connection.DisconnectEvent; import com.velocitypowered.api.event.connection.LoginEvent; import com.velocitypowered.api.scheduler.ScheduledTask; @@ -7,14 +10,21 @@ import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.api.APIPlayer; import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.velocity.util.StringUtils; +import dev.brighten.antivpn.web.objects.VPNResponse; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.logging.Level; public class VelocityListener extends VPNExecutor { private ScheduledTask cacheResetTask; + private final Cache responseCache = CacheBuilder.newBuilder() + .expireAfterWrite(5, TimeUnit.MINUTES) + .maximumSize(10000) + .build(); + @Override public void registerListeners() { @@ -36,6 +46,18 @@ public class VelocityListener extends VPNExecutor { || AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream() .anyMatch(prefix -> event.getPlayer().getUsername().startsWith(prefix))) return; + if(responseCache.asMap().containsKey(event.getPlayer().getUniqueId())) { + VPNResponse cached = responseCache.getIfPresent(event.getPlayer().getUniqueId()); + + if (cached != null && cached.isProxy()) { + event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder() + .character('&') + .build().deserialize(AntiVPN.getInstance().getVpnConfig() + .getKickString()))); + return; + } + } + checkIp(event.getPlayer().getRemoteAddress().getAddress().getHostAddress(), AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> { if (result.isSuccess()) { @@ -148,8 +170,13 @@ public class VelocityListener extends VPNExecutor { VelocityPlugin.INSTANCE.getServer().getEventManager().unregisterListener(VelocityPlugin.INSTANCE, this); } + @Override + public void log(Level level, String log, Object... objects) { + VelocityPlugin.INSTANCE.getLogger().log(level, String.format(log, objects)); + } + @Override public void log(String log, Object... objects) { - VelocityPlugin.INSTANCE.getLogger().log(Level.INFO, String.format(log, objects)); + log(Level.INFO, String.format(log, objects)); } } diff --git a/Velocity/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommand.java b/Velocity/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommand.java index e00a288..dc49c65 100644 --- a/Velocity/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommand.java +++ b/Velocity/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommand.java @@ -12,6 +12,7 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; import java.util.stream.IntStream; public class VelocityCommand implements SimpleCommand { @@ -78,7 +79,10 @@ public class VelocityCommand implements SimpleCommand { .mapToObj(i -> args[i + 1]).toArray(String[]::new)); } } + }else if (children.length > 0){ // && args.length == 0 is always true here + return Arrays.stream(children).map(Command::name).collect(Collectors.toList()); } + return command.tabComplete(new VelocityCommandExecutor(sender), "alias", args); } diff --git a/pom.xml b/pom.xml index 24b999a..767cdde 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ dev.brighten.antivpn AntiVPN pom - 1.8.2.2 + 1.9.2 Common