From 069142a06b6b466efa2d130e48c53cedcdcafbe1 Mon Sep 17 00:00:00 2001 From: Dawson Date: Sat, 1 Feb 2025 10:45:53 -0500 Subject: [PATCH 01/22] Version 2.0.0-SNAPSHOT: Updated to use SQLLite with versioning. Needed a recode of the database system to allow for future updates. --- Assembly/pom.xml | 8 +- Bukkit/pom.xml | 16 +- .../antivpn/bukkit/BukkitListener.java | 23 +- Bungee/pom.xml | 16 +- .../antivpn/bungee/BungeeListener.java | 2 +- Common/pom.xml | 31 +- .../java/dev/brighten/antivpn/AntiVPN.java | 68 +--- .../dev/brighten/antivpn/api/VPNExecutor.java | 9 +- .../command/impl/AllowlistCommand.java | 12 +- .../antivpn/database/VPNDatabase.java | 22 +- .../antivpn/database/local/H2VPN.java | 276 -------------- .../antivpn/database/mongo/MongoVPN.java | 246 ------------- .../antivpn/database/sql/MySqlVPN.java | 347 ------------------ .../sql/utils/ExecutableStatement.java | 138 ------- .../antivpn/database/sql/utils/MySQL.java | 85 ----- .../sql/utils/NonClosableConnection.java | 122 ------ .../antivpn/database/sql/utils/Query.java | 25 -- .../database/sql/utils/ResultSetIterator.java | 7 - .../database/sqllite/LiteDatabase.java | 238 ++++++++++++ .../database/sqllite/version/Version.java | 18 + .../database/sqllite/version/impl/First.java | 17 + .../dev/brighten/antivpn/utils/CIDRUtils.java | 146 ++++++++ .../dev/brighten/antivpn/utils/IpUtils.java | 93 +++++ .../brighten/antivpn/utils/StringUtil.java | 25 +- Sponge/pom.xml | 4 +- Velocity/pom.xml | 18 +- .../antivpn/velocity/VelocityListener.java | 2 +- pom.xml | 10 +- 28 files changed, 624 insertions(+), 1400 deletions(-) delete mode 100644 Common/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java delete mode 100644 Common/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java delete mode 100644 Common/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java delete mode 100644 Common/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java delete mode 100644 Common/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java delete mode 100644 Common/src/main/java/dev/brighten/antivpn/database/sql/utils/NonClosableConnection.java delete mode 100644 Common/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java delete mode 100644 Common/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/utils/IpUtils.java diff --git a/Assembly/pom.xml b/Assembly/pom.xml index 9e3fa66..22efa46 100644 --- a/Assembly/pom.xml +++ b/Assembly/pom.xml @@ -5,15 +5,15 @@ AntiVPN dev.brighten.antivpn - 1.9.3 + 2.0.0-SNAPSHOT 4.0.0 Assembly - 8 - 8 + 17 + 17 @@ -21,7 +21,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.5.0 package diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 15cd426..aae2a1e 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,7 +5,7 @@ AntiVPN dev.brighten.antivpn - 1.9.3 + 2.0.0-SNAPSHOT 4.0.0 @@ -16,17 +16,17 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.13.0 - 8 - 8 + 17 + 17 -XDignore.symbol.file org.apache.maven.plugins maven-shade-plugin - 3.2.4 + 3.5.0 package @@ -64,8 +64,8 @@ - 8 - 8 + 17 + 17 @@ -78,7 +78,7 @@ dev.brighten.antivpn Common - 1.9.3 + 2.0.0-SNAPSHOT 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 0f2f730..5dbb552 100644 --- a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java +++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java @@ -36,11 +36,6 @@ public class BukkitListener extends VPNExecutor implements Listener { .registerEvents(this, BukkitPlugin.pluginInstance); } - @Override - public void shutdown() { - - } - @Override public void log(Level level, String log, Object... objects) { Bukkit.getLogger().log(level, String.format(log, objects)); @@ -59,14 +54,16 @@ public class BukkitListener extends VPNExecutor implements Listener { @EventHandler public void onJoin(final PlayerJoinEvent event) { AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId()) - .ifPresent(player -> AntiVPN.getInstance().getDatabase().alertsState(player.getUuid(), enabled -> { - if(enabled) { - player.setAlertsEnabled(true); - player.sendMessage(AntiVPN.getInstance().getMessageHandler() - .getString("command-alerts-toggled") - .getFormattedMessage(new VpnString.Var<>("state", true))); - } - })); + .ifPresent(player -> { + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { + if(AntiVPN.getInstance().getDatabase().getAlertsState(player.getUuid())) { + player.setAlertsEnabled(true); + player.sendMessage(AntiVPN.getInstance().getMessageHandler() + .getString("command-alerts-toggled") + .getFormattedMessage(new VpnString.Var<>("state", true))); + } + }); + }); } @EventHandler diff --git a/Bungee/pom.xml b/Bungee/pom.xml index 74b9836..5fedaa4 100644 --- a/Bungee/pom.xml +++ b/Bungee/pom.xml @@ -5,7 +5,7 @@ AntiVPN dev.brighten.antivpn - 1.9.3 + 2.0.0-SNAPSHOT 4.0.0 @@ -16,17 +16,17 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.13.0 - 8 - 8 + 17 + 17 -XDignore.symbol.file org.apache.maven.plugins maven-shade-plugin - 3.1.0 + 3.5.0 @@ -63,15 +63,15 @@ - 8 - 8 + 17 + 17 dev.brighten.antivpn Common - 1.9.3 + 2.0.0-SNAPSHOT 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 826d04e..a602781 100644 --- a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -42,8 +42,8 @@ public class BungeeListener extends VPNExecutor implements Listener { cacheResetTask.cancel(); cacheResetTask = null; } - threadExecutor.shutdown(); BungeePlugin.pluginInstance.getProxy().getPluginManager().unregisterListener(this); + super.shutdown(); } @Override diff --git a/Common/pom.xml b/Common/pom.xml index 3c8ee46..5d8e70a 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -5,15 +5,15 @@ AntiVPN dev.brighten.antivpn - 1.9.3 + 2.0.0-SNAPSHOT 4.0.0 Common - 8 - 8 + 17 + 17 @@ -21,10 +21,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.13.0 - 8 - 8 + 17 + 17 -XDignore.symbol.file @@ -38,7 +38,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.4.1 + 3.5.0 package @@ -83,15 +83,9 @@ - com.mysql - mysql-connector-j - 9.1.0 - - - com.h2database - h2 - 2.2.220 - compile + org.xerial + sqlite-jdbc + 3.48.0.0 org.yaml @@ -110,6 +104,11 @@ 3.12.14 compile + + org.jetbrains + annotations + 24.0.1 + \ No newline at end of file diff --git a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java index 2bc20f4..1d6aaa6 100644 --- a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -6,9 +6,7 @@ import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.command.Command; import dev.brighten.antivpn.command.impl.AntiVPNCommand; import dev.brighten.antivpn.database.VPNDatabase; -import dev.brighten.antivpn.database.local.H2VPN; -import dev.brighten.antivpn.database.mongo.MongoVPN; -import dev.brighten.antivpn.database.sql.MySqlVPN; +import dev.brighten.antivpn.database.sqllite.LiteDatabase; import dev.brighten.antivpn.message.MessageHandler; import dev.brighten.antivpn.utils.ConfigDefault; import dev.brighten.antivpn.utils.MiscUtils; @@ -70,35 +68,8 @@ 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; - } - } + INSTANCE.database = new LiteDatabase(); + INSTANCE.database.init(); //Registering commands INSTANCE.registerCommands(); @@ -109,7 +80,8 @@ public class AntiVPN { //of unnecessary database queries. if(player.hasPermission("antivpn.command.alerts")) { //Running database check for enabled alerts. - INSTANCE.database.alertsState(player.getUuid(), player::setAlertsEnabled); + INSTANCE.database.updateAlertsState(player.getUuid(), true); + player.setAlertsEnabled(true); } }); @@ -146,35 +118,7 @@ public class AntiVPN { public void reloadDatabase() { database.shutdown(); - switch(AntiVPN.getInstance().getVpnConfig().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; - } - } + INSTANCE.database = new LiteDatabase(); } public static AntiVPN getInstance() { 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 84d89f1..5117524 100644 --- a/Common/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -18,10 +18,13 @@ import java.util.function.Consumer; import java.util.logging.Level; public abstract class VPNExecutor { - public static ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2); + + @Getter + private final ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2); @Getter private final Set whitelisted = Collections.synchronizedSet(new HashSet<>()); + @Getter private final Set whitelistedIps = Collections.synchronizedSet(new HashSet<>()); @@ -32,7 +35,9 @@ public abstract class VPNExecutor { public abstract void registerListeners(); - public abstract void shutdown(); + public void shutdown() { + threadExecutor.shutdown(); + } public abstract void log(Level level, String log, Object... objects); diff --git a/Common/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java b/Common/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java index 1a0c297..1b8c16e 100644 --- a/Common/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java +++ b/Common/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java @@ -68,13 +68,13 @@ public class AllowlistCommand extends Command { case "add": case "insert": { AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(args[1]); - AntiVPN.getInstance().getDatabase().setWhitelisted(args[1], true); + AntiVPN.getInstance().getDatabase().removeWhitelist(args[1]); return String.format("&aAdded &6%s &ato the exemption allowlist.", args[1]); } case "remove": case "delete": { AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(args[1]); - AntiVPN.getInstance().getDatabase().setWhitelisted(args[1], false); + AntiVPN.getInstance().getDatabase().removeWhitelist(args[1]); return String.format("&cRemoved &6%s &cfrom the exemption allowlist.", args[1]); } default: { @@ -85,12 +85,12 @@ public class AllowlistCommand extends Command { switch(args[0].toLowerCase()) { case "add": case "insert": { - AntiVPN.getInstance().getDatabase().setWhitelisted(args[1], true); + AntiVPN.getInstance().getDatabase().addWhitelist(args[1]); return String.format("&aAdded &6%s &a to the exemption allowlist.", args[1]); } case "remove": case "delete": { - AntiVPN.getInstance().getDatabase().setWhitelisted(args[1], false); + AntiVPN.getInstance().getDatabase().removeWhitelist(args[1]); return String.format("&cRemoved &6%s &c from the exemption allowlist.", args[1]); } default: { @@ -130,12 +130,12 @@ public class AllowlistCommand extends Command { } else { switch(args[0].toLowerCase()) { case "add": { - AntiVPN.getInstance().getDatabase().setWhitelisted(uuid, true); + AntiVPN.getInstance().getDatabase().addWhitelist(uuid); return String.format("&aAdded &6%s &auuid to the exemption allowlist.", uuid.toString()); } case "remove": case "delete": { - AntiVPN.getInstance().getDatabase().setWhitelisted(uuid, false); + AntiVPN.getInstance().getDatabase().removeWhitelist(uuid); return String.format("&cRemoved &6%s &cuuid from the exemption allowlist.", uuid.toString()); } default: { 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 2289197..59ebf74 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java @@ -2,10 +2,8 @@ package dev.brighten.antivpn.database; import dev.brighten.antivpn.web.objects.VPNResponse; -import java.util.List; import java.util.Optional; import java.util.UUID; -import java.util.function.Consumer; public interface VPNDatabase { Optional getStoredResponse(String ip); @@ -14,30 +12,24 @@ public interface VPNDatabase { void deleteResponse(String ip); + void clearResponses(); + boolean isWhitelisted(UUID uuid); boolean isWhitelisted(String ip); - void setWhitelisted(UUID uuid, boolean whitelisted); + void addWhitelist(UUID uuid); - void setWhitelisted(String ip, boolean whitelisted); + void addWhitelist(String cidr); - List getAllWhitelisted(); + void removeWhitelist(UUID uuid); - List getAllWhitelistedIps(); + void removeWhitelist(String cidr); - void getStoredResponseAsync(String ip, Consumer> result); - - void isWhitelistedAsync(UUID uuid, Consumer result); - - void isWhitelistedAsync(String ip, Consumer result); - - void alertsState(UUID uuid, Consumer result); + boolean getAlertsState(UUID uuid); void updateAlertsState(UUID uuid, boolean state); - void clearResponses(); - void init(); void shutdown(); 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 deleted file mode 100644 index c2cd904..0000000 --- a/Common/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java +++ /dev/null @@ -1,276 +0,0 @@ -package dev.brighten.antivpn.database.local; - -import dev.brighten.antivpn.AntiVPN; -import dev.brighten.antivpn.api.VPNExecutor; -import dev.brighten.antivpn.database.VPNDatabase; -import dev.brighten.antivpn.database.sql.utils.MySQL; -import dev.brighten.antivpn.database.sql.utils.Query; -import dev.brighten.antivpn.web.objects.VPNResponse; -import lombok.SneakyThrows; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; - -public class H2VPN implements VPNDatabase { - - public H2VPN() { - VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> { - if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - - //Refreshing whitelisted players - AntiVPN.getInstance().getExecutor().getWhitelisted().clear(); - AntiVPN.getInstance().getExecutor().getWhitelisted() - .addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted()); - - //Refreshing whitlisted IPs - AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear(); - AntiVPN.getInstance().getExecutor().getWhitelistedIps() - .addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps()); - }, 2, 30, TimeUnit.SECONDS); - } - - @Override - public Optional getStoredResponse(String ip) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()|| MySQL.isClosed()) - return Optional.empty(); - - ResultSet rs = Query.prepare("select * from `responses` where `ip` = ? limit 1").append(ip).executeQuery(); - - try { - if (rs != null && rs.next()) { - VPNResponse response = new VPNResponse(rs.getString("asn"), rs.getString("ip"), - rs.getString("countryName"), rs.getString("countryCode"), - rs.getString("city"), rs.getString("timeZone"), - rs.getString("method"), rs.getString("isp"), "N/A", - rs.getBoolean("proxy"), rs.getBoolean("cached"), true, - rs.getDouble("latitude"), rs.getDouble("longitude"), - 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) { - throwables.printStackTrace(); - } - - return Optional.empty(); - } - - /* - * Query. - * prepare("create table if not exists `responses` (`ip` varchar(45) not null, " - * + - * "`countryName` varchar(64), `countryCode` varchar(10), `city` varchar(64), `timeZone` varchar(64), " - * + - * "`method` varchar(32), `isp` varchar(32), `proxy` boolean, `cached` boolean " - * + "`latitude` double, `longitude` double)"); - */ - @Override - public void cacheResponse(VPNResponse toCache) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) - return; - - Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`," - + "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)") - .append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName()) - .append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone()) - .append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy()) - .append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis())) - .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) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) - return false; - ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1") - .append(uuid.toString()).executeQuery(); - - return set != null && set.next() && set.getString("uuid") != null; - } - - @SneakyThrows - @Override - public boolean isWhitelisted(String ip) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) - return false; - ResultSet set = Query.prepare("select `ip` from `whitelisted-ips` where `ip` = ? limit 1") - .append(ip).executeQuery(); - - - return set != null && set.next() && set.getString("ip") != null; - } - - @Override - public void setWhitelisted(UUID uuid, boolean whitelisted) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) - return; - - if (whitelisted) { - if (!isWhitelisted(uuid)) { - Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString()).execute(); - } - AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); - } else { - Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString()).execute(); - AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); - } - } - - @Override - public void setWhitelisted(String ip, boolean whitelisted) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) - return; - - if(whitelisted) { - if(!isWhitelisted(ip)) { - Query.prepare("insert into `whitelisted-ips` (`ip`) values (?)").append(ip).execute(); - } - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip); - } else { - Query.prepare("delete from `whitelisted-ips` where `ip` = ?").append(ip).execute(); - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip); - } - } - - @Override - public List getAllWhitelisted() { - List uuids = new ArrayList<>(); - - if(!MySQL.isClosed()) Query.prepare("select uuid from `whitelisted`") - .execute(set -> uuids.add(UUID.fromString(set.getString("uuid")))); - - return uuids; - } - - @Override - public List getAllWhitelistedIps() { - List ips = new ArrayList<>(); - - if(!MySQL.isClosed()) Query.prepare("select `ip` from `whitelisted-ips`") - .execute(set -> ips.add(set.getString("ip"))); - - return ips; - } - - @Override - public void getStoredResponseAsync(String ip, Consumer> result) { - if(MySQL.isClosed()) return; - - VPNExecutor.threadExecutor.execute(() -> result.accept(getStoredResponse(ip))); - } - - @Override - public void isWhitelistedAsync(UUID uuid, Consumer result) { - if(MySQL.isClosed()) return; - - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid))); - } - - @Override - public void isWhitelistedAsync(String ip, Consumer result) { - if(MySQL.isClosed()) return; - - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip))); - } - - @Override - public void alertsState(UUID uuid, Consumer result) { - if(MySQL.isClosed()) return; - - VPNExecutor.threadExecutor.execute(() -> { - ResultSet set = Query.prepare("select * from `alerts` where `uuid` = ? limit 1") - .append(uuid.toString()).executeQuery(); - - try { - result.accept(set != null && set.next() && set.getString("uuid") != null); - } catch (SQLException e) { - e.printStackTrace(); - result.accept(false); - } - }); - } - - @Override - public void updateAlertsState(UUID uuid, boolean enabled) { - if(MySQL.isClosed()) return; - - if(enabled) { - //We want to make sure there isn't already a uuid inserted to prevent double insertions - alertsState(uuid, alreadyEnabled -> { //No need to make another thread execute, already async - if(!alreadyEnabled) { - Query.prepare("insert into `alerts` (`uuid`) values (?)").append(uuid.toString()) - .execute(); - } //No need to insert again of already enabled - }); - //Removing any uuid from the alerts table will disable alerts globally. - } else VPNExecutor.threadExecutor.execute(() -> - Query.prepare("delete from `alerts` where `uuid` = ?") - .append(uuid.toString()) - .execute()); - } - - @Override - public void clearResponses() { - if(MySQL.isClosed()) return; - - VPNExecutor.threadExecutor.execute(() -> Query.prepare("delete from `responses`").execute()); - } - - @Override - public void init() { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) - return; - AntiVPN.getInstance().getExecutor().log("Initializing H2..."); - MySQL.initH2(); - - AntiVPN.getInstance().getExecutor().log("Creating tables..."); - - //Running check for old table types to update - - Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute(); - Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute(); - Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12)," - + "`countryName` text, `countryCode` varchar(10), `city` text, `timeZone` varchar(64), " - + "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp," - + "`latitude` double, `longitude` double)").execute(); - Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute(); - - AntiVPN.getInstance().getExecutor().log("Creating indexes..."); - try { - Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)").execute(); - Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)").execute(); - Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)").execute(); - Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)").execute(); - Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute(); - } catch (Exception e) { - System.err.println("MySQL Excepton created" + e.getMessage()); - } - } - - @Override - public void shutdown() { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) - return; - MySQL.shutdown(); - } -} 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 deleted file mode 100644 index 900abd4..0000000 --- a/Common/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java +++ /dev/null @@ -1,246 +0,0 @@ -package dev.brighten.antivpn.database.mongo; - -import com.mongodb.*; -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoClients; -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 { - - private MongoCollection settingsDocument, cacheDocument; - private MongoClient client; - - public MongoVPN() { - VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> { - if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) return; - - //Refreshing whitelisted players - AntiVPN.getInstance().getExecutor().getWhitelisted().clear(); - AntiVPN.getInstance().getExecutor().getWhitelisted() - .addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted()); - - //Refreshing whitlisted IPs - AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear(); - AntiVPN.getInstance().getExecutor().getWhitelistedIps() - .addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps()); - }, 2, 30, TimeUnit.SECONDS); - } - @Override - public Optional getStoredResponse(String ip) { - 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")) - .city(rdoc.getString("city")) - .isp(rdoc.getString("isp")) - .method(rdoc.getString("method")) - .timeZone(rdoc.getString("timeZone")) - .proxy(rdoc.getBoolean("proxy")) - .cached(rdoc.getBoolean("cached")) - .success(true) - .latitude(rdoc.getDouble("latitude")) - .longitude(rdoc.getDouble("longitude")) - .lastAccess(rdoc.get("lastAccess", 0L)) - .build()); - } - return Optional.empty(); - } - - @Override - public void cacheResponse(VPNResponse toCache) { - Document rdoc = new Document("ip", toCache.getIp()); - - rdoc.put("asn", toCache.getAsn()); - rdoc.put("countryName", toCache.getCountryName()); - rdoc.put("countryCode", toCache.getCountryCode()); - rdoc.put("city", toCache.getCity()); - rdoc.put("isp", toCache.getIsp()); - rdoc.put("method", toCache.getMethod()); - rdoc.put("timeZone", toCache.getTimeZone()); - rdoc.put("proxy", toCache.isProxy()); - rdoc.put("cached", toCache.isCached()); - rdoc.put("success", toCache.isSuccess()); - rdoc.put("latitude", toCache.getLatitude()); - rdoc.put("longitude", toCache.getLongitude()); - rdoc.put("lastAccess", System.currentTimeMillis()); - - VPNExecutor.threadExecutor.execute(() -> { - 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 - .find(Filters.and(Filters.eq("setting", "whitelist"), - Filters.eq("uuid", uuid.toString()))).first() != null; - } - - @Override - public boolean isWhitelisted(String ip) { - return settingsDocument - .find(Filters.and(Filters.eq("setting", "whitelist"), - Filters.eq("ip", ip))).first() != null; - } - - @Override - public void setWhitelisted(UUID uuid, boolean whitelisted) { - if(whitelisted) { - Document wdoc = new Document("setting", "whitelist"); - wdoc.put("uuid", uuid.toString()); - AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); - VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc)); - } else { - AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); - VPNExecutor.threadExecutor.execute(() -> settingsDocument.deleteMany(Filters - .and( - Filters.eq("setting", "whitelist"), - Filters.eq("uuid", uuid.toString())))); - } - } - - @Override - public void setWhitelisted(String ip, boolean whitelisted) { - if(whitelisted) { - Document wdoc = new Document("setting", "whitelist").append("ip", ip); - - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip); - VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc)); - } else { - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip); - VPNExecutor.threadExecutor.execute(() -> settingsDocument.deleteMany(Filters - .and( - Filters.eq("setting", "whitelist"), - Filters.eq("ip", ip)))); - } - } - - @Override - public List getAllWhitelisted() { - List uuids = new ArrayList<>(); - settingsDocument.find(Filters.and(Filters.eq("setting", "whitelist"), - Filters.exists("uuid"))) - .forEach((Consumer) doc -> uuids.add(UUID.fromString(doc.getString("uuid")))); - return uuids; - } - - @Override - public List getAllWhitelistedIps() { - List ips = new ArrayList<>(); - settingsDocument.find(Filters.and(Filters.eq("setting", "whitelist"), - Filters.exists("ip"))) - .forEach((Consumer) doc -> ips.add(doc.getString("ip"))); - return ips; - } - - @Override - public void getStoredResponseAsync(String ip, Consumer> result) { - VPNExecutor.threadExecutor.execute(() -> result.accept(getStoredResponse(ip))); - } - - @Override - public void isWhitelistedAsync(UUID uuid, Consumer result) { - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid))); - } - - @Override - public void isWhitelistedAsync(String ip, Consumer result) { - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip))); - } - - @Override - public void alertsState(UUID uuid, Consumer result) { - VPNExecutor.threadExecutor.execute(() -> result.accept(settingsDocument - .find(Filters.and(Filters.eq("setting", "alerts"), - Filters.eq("uuid", uuid.toString()))).first() != null)); - } - - @Override - public void updateAlertsState(UUID uuid, boolean state) { - VPNExecutor.threadExecutor.execute(() -> { - settingsDocument.deleteMany(Filters.and(Filters.eq("setting", "alerts"), - Filters.eq("uuid", uuid.toString()))); - if(state) { - Document adoc = new Document("setting", "alerts"); - - adoc.put("uuid", uuid.toString()); - settingsDocument.insertOne(adoc); - } - }); - } - - @Override - public void clearResponses() { - cacheDocument.deleteMany(Filters.exists("ip")); - } - - @Override - public void init() { - if(!AntiVPN.getInstance().getVpnConfig().mongoDatabaseURL().isEmpty()) { //URL - ConnectionString cs = new ConnectionString(AntiVPN.getInstance().getVpnConfig().mongoDatabaseURL()); - MongoClientSettings settings = MongoClientSettings.builder().applyConnectionString(cs).build(); - client = MongoClients.create(settings); - } else { - MongoClientSettings.Builder settingsBld = MongoClientSettings.builder().readPreference(ReadPreference.nearest()) - .applyToClusterSettings(builder -> builder. - hosts(Collections.singletonList( - new ServerAddress( - AntiVPN.getInstance().getVpnConfig().getIp(), - AntiVPN.getInstance().getVpnConfig().getPort()) - ))); - if(AntiVPN.getInstance().getVpnConfig().useDatabaseCreds()) { - settingsBld.credential(MongoCredential - .createCredential(AntiVPN.getInstance().getVpnConfig().getUsername(), - AntiVPN.getInstance().getVpnConfig().getDatabaseName(), - AntiVPN.getInstance().getVpnConfig().getPassword().toCharArray())); - } - - client = MongoClients.create(settingsBld.build()); - } - MongoDatabase antivpnDatabase = client.getDatabase(AntiVPN.getInstance().getVpnConfig().getDatabaseName()); - - settingsDocument = antivpnDatabase.getCollection("settings"); - if(settingsDocument.listIndexes().first() == null) { - AntiVPN.getInstance().getExecutor().log("Created index for settings collection!"); - settingsDocument.createIndex(Indexes.ascending("ip")); - } - cacheDocument = antivpnDatabase.getCollection("cache"); - } - - @Override - public void shutdown() { - settingsDocument = null; - cacheDocument = null; - client.close(); - } -} 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 deleted file mode 100644 index 1b3babd..0000000 --- a/Common/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java +++ /dev/null @@ -1,347 +0,0 @@ -package dev.brighten.antivpn.database.sql; - -import dev.brighten.antivpn.AntiVPN; -import dev.brighten.antivpn.api.VPNExecutor; -import dev.brighten.antivpn.database.VPNDatabase; -import dev.brighten.antivpn.database.sql.utils.MySQL; -import dev.brighten.antivpn.database.sql.utils.Query; -import dev.brighten.antivpn.web.objects.VPNResponse; -import lombok.SneakyThrows; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; - -public class MySqlVPN implements VPNDatabase { - - public MySqlVPN() { - VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> { - if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - - //Refreshing whitelisted players - AntiVPN.getInstance().getExecutor().getWhitelisted().clear(); - AntiVPN.getInstance().getExecutor().getWhitelisted() - .addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted()); - - //Refreshing whitlisted IPs - AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear(); - AntiVPN.getInstance().getExecutor().getWhitelistedIps() - .addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps()); - }, 2, 30, TimeUnit.SECONDS); - } - - @Override - public Optional getStoredResponse(String ip) { - if (isDisabled()) - return Optional.empty(); - - ResultSet rs = Query.prepare("select * from `responses` where `ip` = ? limit 1").append(ip).executeQuery(); - - try { - if (rs != null && rs.next()) { - VPNResponse response = new VPNResponse(rs.getString("asn"), rs.getString("ip"), - rs.getString("countryName"), rs.getString("countryCode"), - rs.getString("city"), rs.getString("timeZone"), - rs.getString("method"), rs.getString("isp"), "N/A", - rs.getBoolean("proxy"), rs.getBoolean("cached"), true, - rs.getDouble("latitude"), rs.getDouble("longitude"), - 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) { - throwables.printStackTrace(); - } - - return Optional.empty(); - } - - /* - * Query. - * prepare("create table if not exists `responses` (`ip` varchar(45) not null, " - * + - * "`countryName` varchar(64), `countryCode` varchar(10), `city` varchar(64), `timeZone` varchar(64), " - * + - * "`method` varchar(32), `isp` varchar(32), `proxy` boolean, `cached` boolean " - * + "`latitude` double, `longitude` double)"); - */ - @Override - public void cacheResponse(VPNResponse toCache) { - if (isDisabled()) - return; - - Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`," - + "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)") - .append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName()) - .append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone()) - .append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy()) - .append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis())) - .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 (isDisabled()) - return false; - ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1") - .append(uuid.toString()).executeQuery(); - - return set != null && set.next() && set.getString("uuid") != null; - } - - @SneakyThrows - @Override - public boolean isWhitelisted(String ip) { - if (isDisabled()) - return false; - ResultSet set = Query.prepare("select `ip` from `whitelisted-ips` where `ip` = ? limit 1") - .append(ip).executeQuery(); - - - return set != null && set.next() && set.getString("ip") != null; - } - - @Override - public void setWhitelisted(UUID uuid, boolean whitelisted) { - if (isDisabled()) - return; - - if (whitelisted) { - if (!isWhitelisted(uuid)) { - Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString()).execute(); - } - AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); - } else { - Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString()).execute(); - AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); - } - } - - @Override - public void setWhitelisted(String ip, boolean whitelisted) { - if (isDisabled()) - return; - - if(whitelisted) { - if(!isWhitelisted(ip)) { - Query.prepare("insert into `whitelisted-ips` (`ip`) values (?)").append(ip).execute(); - } - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip); - } else { - Query.prepare("delete from `whitelisted-ips` where `ip` = ?").append(ip).execute(); - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip); - } - } - - @Override - public List getAllWhitelisted() { - List uuids = new ArrayList<>(); - - if(!MySQL.isClosed()) Query.prepare("select uuid from `whitelisted`") - .execute(set -> uuids.add(UUID.fromString(set.getString("uuid")))); - - return uuids; - } - - @Override - public List getAllWhitelistedIps() { - List ips = new ArrayList<>(); - - if(!MySQL.isClosed()) Query.prepare("select `ip` from `whitelisted-ips`") - .execute(set -> ips.add(set.getString("ip"))); - - return ips; - } - - @Override - public void getStoredResponseAsync(String ip, Consumer> result) { - if(MySQL.isClosed()) return; - - VPNExecutor.threadExecutor.execute(() -> result.accept(getStoredResponse(ip))); - } - - @Override - public void isWhitelistedAsync(UUID uuid, Consumer result) { - if(MySQL.isClosed()) return; - - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid))); - } - - @Override - public void isWhitelistedAsync(String ip, Consumer result) { - if(MySQL.isClosed()) return; - - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip))); - } - - @Override - public void alertsState(UUID uuid, Consumer result) { - if(MySQL.isClosed()) return; - - VPNExecutor.threadExecutor.execute(() -> { - ResultSet set = Query.prepare("select * from `alerts` where `uuid` = ? limit 1") - .append(uuid.toString()).executeQuery(); - - try { - result.accept(set != null && set.next() && set.getString("uuid") != null); - } catch (SQLException e) { - e.printStackTrace(); - result.accept(false); - } - }); - } - - @Override - public void updateAlertsState(UUID uuid, boolean enabled) { - if(MySQL.isClosed()) return; - - if(enabled) { - //We want to make sure there isn't already a uuid inserted to prevent double insertions - alertsState(uuid, alreadyEnabled -> { //No need to make another thread execute, already async - if(!alreadyEnabled) { - Query.prepare("insert into `alerts` (`uuid`) values (?)").append(uuid.toString()) - .execute(); - } //No need to insert again of already enabled - }); - //Removing any uuid from the alerts table will disable alerts globally. - } else VPNExecutor.threadExecutor.execute(() -> - Query.prepare("delete from `alerts` where `uuid` = ?") - .append(uuid.toString()) - .execute()); - } - - @Override - public void clearResponses() { - if(MySQL.isClosed()) return; - - VPNExecutor.threadExecutor.execute(() -> Query.prepare("delete from `responses`").execute()); - } - - @Override - public void init() { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) - return; - AntiVPN.getInstance().getExecutor().log("Initializing MySQL..."); - MySQL.init(); - - AntiVPN.getInstance().getExecutor().log("Creating tables..."); - - //Running check for old table types to update - oldTableCheck: { - Query.prepare("select `DATA_TYPE` from INFORMATION_SCHEMA.COLUMNS " + - "WHERE table_name = 'responses' AND COLUMN_NAME = 'isp';").execute(set -> { - if(set.getObject("DATA_TYPE").toString().contains("varchar")) { - AntiVPN.getInstance().getExecutor().log("Using old database format for storing responses! " + - "Dropping table and creating a new one..."); - if(Query.prepare("drop table `responses`").execute() > 0) { - AntiVPN.getInstance().getExecutor().log("Successfully dropped table!"); - } - } - }); - } - - Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute(); - Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute(); - Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12)," - + "`countryName` text, `countryCode` varchar(10), `city` text, `timeZone` varchar(64), " - + "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp," - + "`latitude` double, `longitude` double)").execute(); - Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute(); - - AntiVPN.getInstance().getExecutor().log("Creating indexes..."); - try { - // Ref: - // https://dba.stackexchange.com/questions/24531/mysql-create-index-if-not-exists - - String query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE()" + - " AND table_name='whitelisted' AND index_name='uuid_1';"; - ResultSet rs = Query.prepare(query).executeQuery(); - int id = 0; - whitelistedIndex: { - while (rs.next()) { - id = rs.getInt("IndexExists"); - } - if (id == 0) { - Query.prepare("create index `uuid_1` on `whitelisted` (`uuid`)").execute(); - } - id = 0; - } - responsesIndex: { - query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() " + - "AND table_name='responses' AND index_name='ip_1';"; - rs = Query.prepare(query).executeQuery(); - while (rs.next()) { - id = rs.getInt("IndexExists"); - } - if (id == 0) { - Query.prepare("create index `ip_1` on `responses` (`ip`)").execute(); - } - id = 0; - query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() " + - "AND table_name='responses' AND index_name='proxy_1';"; - rs = Query.prepare(query).executeQuery(); - while (rs.next()) { - id = rs.getInt("IndexExists"); - } - if (id == 0) { - Query.prepare("create index `proxy_1` on `responses` (`proxy`)").execute(); - } - id = 0; - query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE()" + - " AND table_name='responses' AND index_name='inserted_1';"; - rs = Query.prepare(query).executeQuery(); - while (rs.next()) { - id = rs.getInt("IndexExists"); - } - if (id == 0) { - Query.prepare("create index `inserted_1` on `responses` (`inserted`)").execute(); - } - id = 0; - } - whitelistedIpsIndex: { - query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE()" + - " AND table_name='whitelisted-ips' AND index_name='ip_1';"; - rs = Query.prepare(query).executeQuery(); - while (rs.next()) { - id = rs.getInt("IndexExists"); - } - if (id == 0) { - Query.prepare("create index `ip_1` on `whitelisted-ips` (`ip`)").execute(); - } - } - } catch (Exception e) { - System.err.println("MySQL Excepton created" + e.getMessage()); - } - } - - private boolean isDisabled() { - return !AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()|| MySQL.isClosed(); - } - - @Override - public void shutdown() { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) - return; - MySQL.shutdown(); - } -} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java b/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java deleted file mode 100644 index f226fd0..0000000 --- a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java +++ /dev/null @@ -1,138 +0,0 @@ -package dev.brighten.antivpn.database.sql.utils; - -import dev.brighten.antivpn.utils.MiscUtils; -import lombok.SneakyThrows; - -import java.sql.*; -import java.util.UUID; - -public class ExecutableStatement { - private PreparedStatement statement; - private int pos = 1; - - public ExecutableStatement(PreparedStatement statement) { - this.statement = statement; - } - - @SneakyThrows - public Integer execute() { - try { - return statement.executeUpdate(); - } finally { - MiscUtils.close(statement); - } - } - - @SneakyThrows - public void execute(ResultSetIterator iterator) { - ResultSet rs = null; - try { - rs = statement.executeQuery(); - while (rs.next()) iterator.next(rs); - } finally { - MiscUtils.close(statement, rs); - } - } - - @SneakyThrows - public void executeSingle(ResultSetIterator iterator) { - ResultSet rs = null; - try { - rs = statement.executeQuery(); - if (rs.next()) iterator.next(rs); - else iterator.next(null); - } finally { - MiscUtils.close(statement, rs); - } - } - - @SneakyThrows - public ResultSet executeQuery() { - return statement.executeQuery(); - } - - @SneakyThrows - public ExecutableStatement append(Object obj) { - statement.setObject(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(String obj) { - statement.setString(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(UUID uuid) { - if (uuid != null) statement.setString(pos++, uuid.toString().replace("-", "")); - else statement.setString(pos++, null); - return this; - } - - @SneakyThrows - public ExecutableStatement append(Array obj) { - statement.setArray(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(Integer obj) { - statement.setInt(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(Short obj) { - statement.setShort(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(Long obj) { - statement.setLong(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(Float obj) { - statement.setFloat(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(Double obj) { - statement.setDouble(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(Date obj) { - statement.setDate(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(Timestamp obj) { - statement.setTimestamp(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(Time obj) { - statement.setTime(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(Blob obj) { - statement.setBlob(pos++, obj); - return this; - } - - @SneakyThrows - public ExecutableStatement append(byte[] obj) { - statement.setBytes(pos++, obj); - return this; - } -} 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 deleted file mode 100644 index 5184ef4..0000000 --- a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java +++ /dev/null @@ -1,85 +0,0 @@ -package dev.brighten.antivpn.database.sql.utils; - -import com.mysql.cj.jdbc.Driver; -import dev.brighten.antivpn.AntiVPN; -import org.h2.jdbc.JdbcConnection; - -import java.io.File; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Properties; - -public class MySQL { - private static Connection conn; - - public static void init() { - try { - if (conn == null || conn.isClosed()) { - DriverManager.registerDriver(new Driver()); - conn = DriverManager.getConnection("jdbc:mysql://" + AntiVPN.getInstance().getVpnConfig().getIp() - + ":" + AntiVPN.getInstance().getVpnConfig().getPort() - + "/?useSSL=true&autoReconnect=true", - AntiVPN.getInstance().getVpnConfig().getUsername(), - AntiVPN.getInstance().getVpnConfig().getPassword()); - conn.setAutoCommit(true); - Query.use(conn); - Query.prepare("CREATE DATABASE IF NOT EXISTS `" - + AntiVPN.getInstance().getVpnConfig().getDatabaseName() + "`").execute(); - Query.prepare("USE `" + AntiVPN.getInstance().getVpnConfig().getDatabaseName() + "`").execute(); - AntiVPN.getInstance().getExecutor().log("Connection to MySQL has been established."); - } - } catch (Exception e) { - AntiVPN.getInstance().getExecutor().logException("Failed to load mysql: " + e.getMessage(), e); - } - } - - public static void initH2() { - File dataFolder = new File(AntiVPN.getInstance().getPluginFolder(), "databases"); - File databaseFile = new File(dataFolder, "database"); - try { - conn = new NonClosableConnection(new JdbcConnection("jdbc:h2:file:" + - databaseFile.getAbsolutePath(), - new Properties(), AntiVPN.getInstance().getVpnConfig().getUsername(), - AntiVPN.getInstance().getVpnConfig().getPassword(), false)); - conn.setAutoCommit(true); - Query.use(conn); - AntiVPN.getInstance().getExecutor().log("Connection to H2 has been established."); - } catch (SQLException ex) { - AntiVPN.getInstance().getExecutor().logException("H2 exception on initialize: " + ex.getMessage(), ex); - } - } - - public static void use() { - try { - init(); - } catch (Exception e) { - AntiVPN.getInstance().getExecutor().logException(e); - } - } - - public static void shutdown() { - try { - if(conn != null && !conn.isClosed()) { - if(conn instanceof NonClosableConnection) { - ((NonClosableConnection)conn).shutdown(); - } else conn.close(); - conn = null; - } - } catch (Exception e) { - AntiVPN.getInstance().getExecutor().logException(e); - } - } - - public static boolean isClosed() { - if(conn == null) - return true; - - try { - return conn.isClosed(); - } catch (SQLException e) { - AntiVPN.getInstance().getExecutor().logException(e); - return true; - } - } -} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/NonClosableConnection.java b/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/NonClosableConnection.java deleted file mode 100644 index 38668af..0000000 --- a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/NonClosableConnection.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package dev.brighten.antivpn.database.sql.utils; - -import java.sql.*; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.Executor; - -/** - * A wrapper around a {@link Connection} which blocks usage of the default {@link #close()} method. - */ -public class NonClosableConnection implements Connection { - private final Connection delegate; - - public NonClosableConnection(Connection delegate) { - this.delegate = delegate; - } - - /** - * Actually {@link #close() closes} the underlying connection. - */ - public final void shutdown() throws SQLException { - this.delegate.close(); - } - - @Override - public final void close() throws SQLException { - // do nothing - } - - @Override - public final boolean isWrapperFor(Class iface) throws SQLException { - return iface.isInstance(this.delegate) || this.delegate.isWrapperFor(iface); - } - - @SuppressWarnings("unchecked") - @Override - public final T unwrap(Class iface) throws SQLException { - if (iface.isInstance(this.delegate)) { - return (T) this.delegate; - } - return this.delegate.unwrap(iface); - } - - // Forward to the delegate connection - @Override public Statement createStatement() throws SQLException { return this.delegate.createStatement(); } - @Override public PreparedStatement prepareStatement(String sql) throws SQLException { return this.delegate.prepareStatement(sql); } - @Override public CallableStatement prepareCall(String sql) throws SQLException { return this.delegate.prepareCall(sql); } - @Override public String nativeSQL(String sql) throws SQLException { return this.delegate.nativeSQL(sql); } - @Override public void setAutoCommit(boolean autoCommit) throws SQLException { this.delegate.setAutoCommit(autoCommit); } - @Override public boolean getAutoCommit() throws SQLException { return this.delegate.getAutoCommit(); } - @Override public void commit() throws SQLException { this.delegate.commit(); } - @Override public void rollback() throws SQLException { this.delegate.rollback(); } - @Override public boolean isClosed() throws SQLException { return this.delegate.isClosed(); } - @Override public DatabaseMetaData getMetaData() throws SQLException { return this.delegate.getMetaData(); } - @Override public void setReadOnly(boolean readOnly) throws SQLException { this.delegate.setReadOnly(readOnly); } - @Override public boolean isReadOnly() throws SQLException { return this.delegate.isReadOnly(); } - @Override public void setCatalog(String catalog) throws SQLException { this.delegate.setCatalog(catalog); } - @Override public String getCatalog() throws SQLException { return this.delegate.getCatalog(); } - @Override public void setTransactionIsolation(int level) throws SQLException { this.delegate.setTransactionIsolation(level); } - @Override public int getTransactionIsolation() throws SQLException { return this.delegate.getTransactionIsolation(); } - @Override public SQLWarning getWarnings() throws SQLException { return this.delegate.getWarnings(); } - @Override public void clearWarnings() throws SQLException { this.delegate.clearWarnings(); } - @Override public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { return this.delegate.createStatement(resultSetType, resultSetConcurrency); } - @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return this.delegate.prepareStatement(sql, resultSetType, resultSetConcurrency); } - @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return this.delegate.prepareCall(sql, resultSetType, resultSetConcurrency); } - @Override public Map> getTypeMap() throws SQLException { return this.delegate.getTypeMap(); } - @Override public void setTypeMap(Map> map) throws SQLException { this.delegate.setTypeMap(map); } - @Override public void setHoldability(int holdability) throws SQLException { this.delegate.setHoldability(holdability); } - @Override public int getHoldability() throws SQLException { return this.delegate.getHoldability(); } - @Override public Savepoint setSavepoint() throws SQLException { return this.delegate.setSavepoint(); } - @Override public Savepoint setSavepoint(String name) throws SQLException { return this.delegate.setSavepoint(name); } - @Override public void rollback(Savepoint savepoint) throws SQLException { this.delegate.rollback(savepoint); } - @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException { this.delegate.releaseSavepoint(savepoint); } - @Override public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return this.delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); } - @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return this.delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); } - @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return this.delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); } - @Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { return this.delegate.prepareStatement(sql, autoGeneratedKeys); } - @Override public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { return this.delegate.prepareStatement(sql, columnIndexes); } - @Override public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { return this.delegate.prepareStatement(sql, columnNames); } - @Override public Clob createClob() throws SQLException { return this.delegate.createClob(); } - @Override public Blob createBlob() throws SQLException { return this.delegate.createBlob(); } - @Override public NClob createNClob() throws SQLException { return this.delegate.createNClob(); } - @Override public SQLXML createSQLXML() throws SQLException { return this.delegate.createSQLXML(); } - @Override public boolean isValid(int timeout) throws SQLException { return this.delegate.isValid(timeout); } - @Override public void setClientInfo(String name, String value) throws SQLClientInfoException { this.delegate.setClientInfo(name, value); } - @Override public void setClientInfo(Properties properties) throws SQLClientInfoException { this.delegate.setClientInfo(properties); } - @Override public String getClientInfo(String name) throws SQLException { return this.delegate.getClientInfo(name); } - @Override public Properties getClientInfo() throws SQLException { return this.delegate.getClientInfo(); } - @Override public Array createArrayOf(String typeName, Object[] elements) throws SQLException { return this.delegate.createArrayOf(typeName, elements); } - @Override public Struct createStruct(String typeName, Object[] attributes) throws SQLException { return this.delegate.createStruct(typeName, attributes); } - @Override public void setSchema(String schema) throws SQLException { this.delegate.setSchema(schema); } - @Override public String getSchema() throws SQLException { return this.delegate.getSchema(); } - @Override public void abort(Executor executor) throws SQLException { this.delegate.abort(executor); } - @Override public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { this.delegate.setNetworkTimeout(executor, milliseconds); } - @Override public int getNetworkTimeout() throws SQLException { return this.delegate.getNetworkTimeout(); } - -} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java b/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java deleted file mode 100644 index f2f86fe..0000000 --- a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java +++ /dev/null @@ -1,25 +0,0 @@ -package dev.brighten.antivpn.database.sql.utils; - -import lombok.SneakyThrows; - -import java.sql.Connection; - -public class Query { - private static Connection conn; - - public static void use(Connection conn) { - Query.conn = conn; - } - - @SneakyThrows - public static ExecutableStatement prepare(String query) { - return new ExecutableStatement(conn.prepareStatement(query)); - } - - - - @SneakyThrows - public static ExecutableStatement prepare(String query, Connection con) { - return new ExecutableStatement(con.prepareStatement(query)); - } -} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java b/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java deleted file mode 100644 index e99cd7c..0000000 --- a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java +++ /dev/null @@ -1,7 +0,0 @@ -package dev.brighten.antivpn.database.sql.utils; - -import java.sql.ResultSet; - -public interface ResultSetIterator { - void next(ResultSet rs) throws Exception; -} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java new file mode 100644 index 0000000..40d9ef2 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java @@ -0,0 +1,238 @@ +package dev.brighten.antivpn.database.sqllite; + +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.sqllite.version.Version; +import dev.brighten.antivpn.utils.CIDRUtils; +import dev.brighten.antivpn.utils.IpUtils; +import dev.brighten.antivpn.utils.StringUtil; +import dev.brighten.antivpn.utils.json.JSONException; +import dev.brighten.antivpn.web.objects.VPNResponse; +import org.intellij.lang.annotations.Language; + +import java.math.BigDecimal; +import java.net.UnknownHostException; +import java.sql.*; +import java.util.Optional; +import java.util.UUID; + +public class LiteDatabase implements VPNDatabase { + + private Connection connection; + + @Override + public Optional getStoredResponse(String ip) { + return Optional.empty(); + } + + @Override + public void cacheResponse(VPNResponse toCache) { + String jsonResponse; + try { + jsonResponse = toCache.toJson().toString(); + } catch (JSONException e) { + AntiVPN.getInstance().getExecutor().logException(e); + return; + } + + String hashedIp = StringUtil.getHash(toCache.getIp()); + + try { + statement("INSERT INTO vpn_responses (ip, response) VALUES (?, ?)", hashedIp, jsonResponse); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + + @Override + public void deleteResponse(String ip) { + String hashedIp = StringUtil.getHash(ip); + + try { + statement("DELETE FROM vpn_responses WHERE ip = ?", hashedIp); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + + @Override + public void clearResponses() { + try { + statement("DELETE FROM vpn_responses"); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + + @Override + public boolean isWhitelisted(UUID uuid) { + try(ResultSet result = query("SELECT * FROM whitelist WHERE uuid = ?", uuid.toString())) { + return result.next(); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + return false; + } + + @Override + public boolean isWhitelisted(String ip) { + CIDRUtils cidr; + BigDecimal start, end; + try { + cidr = new CIDRUtils(ip); + + start = IpUtils.getIpDecimal(cidr.getStartAddress().getHostAddress()).orElseThrow(); + end = IpUtils.getIpDecimal(cidr.getEndAddress().getHostAddress()).orElseThrow(); + } catch (UnknownHostException e) { + AntiVPN.getInstance().getExecutor().logException(e); + return false; + } + + try(ResultSet result = query("SELECT * FROM whitelist " + + "WHERE minimum >= ? AND maximum <= ?", start, end)) { + return result.next(); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + return false; + } + + @Override + public void addWhitelist(UUID uuid) { + try { + statement("INSERT INTO whitelist (uuid) VALUES (?)", uuid.toString()); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + + @Override + public void addWhitelist(String cidr) { + CIDRUtils cidrUtils; + BigDecimal start, end; + try { + cidrUtils = new CIDRUtils(cidr); + + start = IpUtils.getIpDecimal(cidrUtils.getStartAddress().getHostAddress()).orElseThrow(); + end = IpUtils.getIpDecimal(cidrUtils.getEndAddress().getHostAddress()).orElseThrow(); + } catch (UnknownHostException e) { + AntiVPN.getInstance().getExecutor().logException(e); + return; + } + + try { + statement("INSERT INTO whitelist (minimum, maximum) VALUES (?, ?)", start, end); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + + @Override + public void removeWhitelist(UUID uuid) { + try { + statement("DELETE FROM whitelist WHERE uuid = ?", uuid.toString()); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + + @Override + public void removeWhitelist(String cidr) { + CIDRUtils cidrUtils; + BigDecimal start, end; + try { + cidrUtils = new CIDRUtils(cidr); + + start = IpUtils.getIpDecimal(cidrUtils.getStartAddress().getHostAddress()).orElseThrow(); + end = IpUtils.getIpDecimal(cidrUtils.getEndAddress().getHostAddress()).orElseThrow(); + } catch (UnknownHostException e) { + AntiVPN.getInstance().getExecutor().logException(e); + return; + } + + try { + statement("DELETE FROM whitelist WHERE minimum = ? AND maximum = ?", start, end); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + + @Override + public boolean getAlertsState(UUID uuid) { + try(ResultSet result = query("SELECT * FROM alerts WHERE uuid = ?", uuid.toString())) { + return result.next(); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + return false; + } + + @Override + public void updateAlertsState(UUID uuid, boolean state) { + try { + statement("INSERT INTO alerts (uuid, STATE) VALUES (?, ?) ON CONFLICT(uuid) DO UPDATE SET STATE = ?", + uuid.toString(), state, state); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + + @Override + public void init() { + String url = "jdbc:sqlite:./plugins/AntiVPN/database.db"; + + try { + Connection connection = DriverManager.getConnection(url); + Statement statement = connection.createStatement(); + statement.execute("CREATE TABLE IF NOT EXISTS vpn_responses (ip TEXT, response TEXT)"); + statement.execute("CREATE TABLE IF NOT EXISTS whitelist (uuid TEXT, NUMBER minimum, NUMBER maximum)"); + statement.execute("CREATE TABLE IF NOT EXISTS alerts (uuid TEXT)"); + statement.execute("CREATE TABLE IF NOT EXISTS version (PRIMARY KEY(version) NUMBER, updated STATE)"); + + this.connection = connection; + + // Run through updates + for (Version version : Version.versions) { + try(ResultSet result = query("SELECT * FROM version WHERE version = ?", + version.versionNumber())) { + if(!result.next()) { + version.update(this); + statement("INSERT INTO version (version, updated) VALUES (?, ?)", + version.versionNumber(), true); + } + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + + @Override + public void shutdown() { + try { + connection.close(); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + + private ResultSet query(@Language("SQL") String query, Object... args) throws SQLException { + PreparedStatement pstmt = connection.prepareStatement(query); + for (int i = 0; i < args.length; i++) { + pstmt.setObject(i + 1, args[i]); + } + + return pstmt.executeQuery(); + } + + public void statement(@Language("SQL") String query, Object... args) throws SQLException { + PreparedStatement pstmt = connection.prepareStatement(query); + for (int i = 0; i < args.length; i++) { + pstmt.setObject(i + 1, args[i]); + } + + pstmt.execute(); + } +} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java new file mode 100644 index 0000000..392a2e4 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java @@ -0,0 +1,18 @@ +package dev.brighten.antivpn.database.sqllite.version; + +import dev.brighten.antivpn.database.sqllite.LiteDatabase; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public interface Version { + void update(LiteDatabase database) throws SQLException; + int versionNumber(); + + List versions = new ArrayList<>(); + + static void register(Version version) { + versions.add(version); + } +} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java new file mode 100644 index 0000000..69ff011 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java @@ -0,0 +1,17 @@ +package dev.brighten.antivpn.database.sqllite.version.impl; + +import dev.brighten.antivpn.database.sqllite.LiteDatabase; +import dev.brighten.antivpn.database.sqllite.version.Version; + +public class First implements Version { + + @Override + public void update(LiteDatabase database) { + + } + + @Override + public int versionNumber() { + return 1; + } +} diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java b/Common/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java new file mode 100644 index 0000000..26b3ca9 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java @@ -0,0 +1,146 @@ +/* +* The MIT License +* +* Copyright (c) 2013 Edin Dazdarevic (edin.dazdarevic@gmail.com) + +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: + +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. + +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +* */ + +package dev.brighten.antivpn.utils; + +import lombok.Getter; + +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +/** + * A class that enables to get an IP range from CIDR specification. It supports + * both IPv4 and IPv6. + */ +@Getter +public class CIDRUtils { + private final String cidr; + + private final InetAddress inetAddress; + + private InetAddress startAddress; + private InetAddress endAddress; + private final int prefixLength; + + + public CIDRUtils(String cidr) throws UnknownHostException { + + this.cidr = cidr; + + /* split CIDR to address and prefix part */ + if (this.cidr.contains("/")) { + int index = this.cidr.indexOf("/"); + String addressPart = this.cidr.substring(0, index); + String networkPart = this.cidr.substring(index + 1); + + inetAddress = InetAddress.getByName(addressPart); + prefixLength = Integer.parseInt(networkPart); + + calculate(); + } else { + throw new IllegalArgumentException("not an valid CIDR format!"); + } + } + + + private void calculate() throws UnknownHostException { + + ByteBuffer maskBuffer; + int targetSize; + if (inetAddress.getAddress().length == 4) { + maskBuffer = + ByteBuffer + .allocate(4) + .putInt(-1); + targetSize = 4; + } else { + maskBuffer = ByteBuffer.allocate(16) + .putLong(-1L) + .putLong(-1L); + targetSize = 16; + } + + BigInteger mask = (new BigInteger(1, maskBuffer.array())).not().shiftRight(prefixLength); + + ByteBuffer buffer = ByteBuffer.wrap(inetAddress.getAddress()); + BigInteger ipVal = new BigInteger(1, buffer.array()); + + BigInteger startIp = ipVal.and(mask); + BigInteger endIp = startIp.add(mask.not()); + + byte[] startIpArr = toBytes(startIp.toByteArray(), targetSize); + byte[] endIpArr = toBytes(endIp.toByteArray(), targetSize); + + this.startAddress = InetAddress.getByAddress(startIpArr); + this.endAddress = InetAddress.getByAddress(endIpArr); + + } + + private byte[] toBytes(byte[] array, int targetSize) { + int counter = 0; + List newArr = new ArrayList(); + while (counter < targetSize && (array.length - 1 - counter >= 0)) { + newArr.add(0, array[array.length - 1 - counter]); + counter++; + } + + int size = newArr.size(); + for (int i = 0; i < (targetSize - size); i++) { + + newArr.add(0, (byte) 0); + } + + byte[] ret = new byte[newArr.size()]; + for (int i = 0; i < newArr.size(); i++) { + ret[i] = newArr.get(i); + } + return ret; + } + + public String getNetworkAddress() { + + return this.startAddress.getHostAddress(); + } + + public String getBroadcastAddress() { + return this.endAddress.getHostAddress(); + } + + public boolean isInRange(String ipAddress) throws UnknownHostException { + InetAddress address = InetAddress.getByName(ipAddress); + BigInteger start = new BigInteger(1, this.startAddress.getAddress()); + BigInteger end = new BigInteger(1, this.endAddress.getAddress()); + BigInteger target = new BigInteger(1, address.getAddress()); + + int st = start.compareTo(target); + int te = target.compareTo(end); + + return (st == -1 || st == 0) && (te == -1 || te == 0); + } +} diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/IpUtils.java b/Common/src/main/java/dev/brighten/antivpn/utils/IpUtils.java new file mode 100644 index 0000000..2ead854 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/utils/IpUtils.java @@ -0,0 +1,93 @@ +package dev.brighten.antivpn.utils; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Optional; + +public class IpUtils { + public static Optional getIpDecimal(String address) { + try { + InetAddress inet = InetAddress.getByName(address); + + if(inet instanceof Inet4Address) { + return Optional.of(BigDecimal.valueOf(ipv4ToLong(address))); + } return Optional.of(new BigDecimal(ipv6ToDecimalFormat(address))); + } catch(Exception e) { + return Optional.empty(); + } + } + + public static long ipv4ToLong(String address) { + String[] addrArray = address.split("\\."); + + long ipDecimal = 0; + + for (int i = 0; i < addrArray.length; i++) { + + int power = 3 - i; + ipDecimal += ((Integer.parseInt(addrArray[i]) % 256 * Math.pow(256, power))); + } + + return ipDecimal; + } + + public static String getIpv4(long ip) { + StringBuilder sb = new StringBuilder(15); + + for (int i = 0; i < 4; i++) { + sb.insert(0, ip & 0xff); + + if (i < 3) { + sb.insert(0, '.'); + } + + ip >>= 8; + } + + return sb.toString(); + } + + public static boolean isIpv4(BigDecimal ip) { + return ip.compareTo(BigDecimal.valueOf(4294967295L)) <= 0; + } + + public static boolean isIpv6(BigDecimal ip) { + return ip.compareTo(BigDecimal.valueOf(4294967295L)) > 0; + } + public static boolean isIpv4(String ip) { + return ip.matches("^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$"); + } + + public static boolean isNotIp(String ip) { + return !isIpv4(ip) && !isIpv6(ip); + } + + public static boolean isIpv6(String ip) { + return ip.matches("^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)$|^(([0-9a-fA-F]{1,4}:){0,6}([0-9a-fA-F]{1,4}|:))?(::([0-9a-fA-F]{1,4}:){0,5}([0-9a-fA-F]{1,4}|:))?$"); + } + + public static String getIpv4(BigDecimal ip) { + try { + return Inet4Address.getByAddress(ip.toBigInteger().toByteArray()).getHostAddress(); + } catch (UnknownHostException e) { + return "Error"; + } + } + + public static String getIpv6(BigDecimal ip) { + try { + return Inet6Address.getByAddress(ip.toBigInteger().toByteArray()).getHostAddress(); + } catch (UnknownHostException e) { + return "Error"; + } + } + + public static BigInteger ipv6ToDecimalFormat(String ipAddress) throws UnknownHostException { + return new BigInteger(1, Inet6Address.getByName(ipAddress).getAddress()); + } + +} 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..b47e5b4 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,11 @@ package dev.brighten.antivpn.utils; +import dev.brighten.antivpn.AntiVPN; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + public class StringUtil { public static String line(String color) { return color + "&m-----------------------------------------------------"; @@ -9,7 +15,22 @@ public class StringUtil { return "&m-----------------------------------------------------"; } - public static String lineNoStrike(String color) { - return color + "-----------------------------------------------------"; + public static String getHash(String input) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-128"); + byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8)); + StringBuilder hexString = new StringBuilder(2 * hash.length); + for (byte b : hash) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + return null; } } diff --git a/Sponge/pom.xml b/Sponge/pom.xml index 51be0b0..62be928 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -5,7 +5,7 @@ AntiVPN dev.brighten.antivpn - 1.9.3 + 2.0.0-SNAPSHOT 4.0.0 @@ -28,7 +28,7 @@ dev.brighten.antivpn Common - 1.9.3 + 2.0.0-SNAPSHOT provided diff --git a/Velocity/pom.xml b/Velocity/pom.xml index 93d2f38..bd501ef 100644 --- a/Velocity/pom.xml +++ b/Velocity/pom.xml @@ -5,15 +5,15 @@ AntiVPN dev.brighten.antivpn - 1.9.3 + 2.0.0-SNAPSHOT 4.0.0 Velocity - 8 - 8 + 17 + 17 @@ -27,13 +27,13 @@ com.velocitypowered velocity-api - 3.1.1 + 3.4.0-SNAPSHOT provided dev.brighten.antivpn Common - 1.9.3 + 2.0.0-SNAPSHOT provided @@ -49,17 +49,17 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.13.0 - 8 - 8 + 17 + 17 -XDignore.symbol.file org.apache.maven.plugins maven-shade-plugin - 3.1.0 + 3.5.0 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 ea8b57a..ff22744 100644 --- a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -182,8 +182,8 @@ public class VelocityListener extends VPNExecutor { cacheResetTask.cancel(); cacheResetTask = null; } - threadExecutor.shutdown(); VelocityPlugin.INSTANCE.getServer().getEventManager().unregisterListener(VelocityPlugin.INSTANCE, this); + super.shutdown(); } @Override diff --git a/pom.xml b/pom.xml index eacb2aa..67ea6c4 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ dev.brighten.antivpn AntiVPN pom - 1.9.3 + 2.0.0-SNAPSHOT Common @@ -19,8 +19,8 @@ - 8 - 8 + 17 + 17 @@ -30,8 +30,8 @@ maven-compiler-plugin 3.7.0 - 8 - 8 + 17 + 17 -XDignore.symbol.file false From 247b3292809846ff419ada646de79861618eef01 Mon Sep 17 00:00:00 2001 From: Dawson Date: Sat, 1 Feb 2025 10:46:35 -0500 Subject: [PATCH 02/22] Added test workflow --- .github/workflows/test.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..7515e19 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,19 @@ +on: + push: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 17.0.2 + uses: actions/setup-java@v4 + with: + java-version: 17.0 + distribution: 'zulu' + cache: 'maven' + - name: Compile + run: mvn -B package --file pom.xml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From bb3a31e100235fb4c4d98d3a5087ef57732c6244 Mon Sep 17 00:00:00 2001 From: Dawson Date: Fri, 30 May 2025 18:10:08 -0400 Subject: [PATCH 03/22] CIDR Support setup and implemeneted for adding/removing via command, and checking updates for CIDR implemented. Also fixed problem with SHA-algor not being present --- .../brighten/antivpn/bukkit/BukkitPlugin.java | 16 +- Bungee/pom.xml | 7 +- .../brighten/antivpn/bungee/BungeePlugin.java | 16 +- Common/pom.xml | 12 -- .../java/dev/brighten/antivpn/AntiVPN.java | 33 +--- .../dev/brighten/antivpn/api/APIPlayer.java | 4 +- .../command/impl/AllowlistCommand.java | 149 ++++++++++-------- .../antivpn/command/impl/PlanCommand.java | 2 +- .../database/sqllite/LiteDatabase.java | 9 +- .../brighten/antivpn/utils/StringUtil.java | 2 +- Sponge/pom.xml | 21 +-- .../antivpn/velocity/VelocityListener.java | 47 +++--- .../antivpn/velocity/VelocityPlugin.java | 16 +- 13 files changed, 133 insertions(+), 201 deletions(-) diff --git a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java index fcd48a0..5cb3e69 100644 --- a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java +++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java @@ -4,9 +4,7 @@ import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.bukkit.command.BukkitCommand; import dev.brighten.antivpn.command.Command; import dev.brighten.antivpn.database.VPNDatabase; -import dev.brighten.antivpn.database.local.H2VPN; -import dev.brighten.antivpn.database.mongo.MongoVPN; -import dev.brighten.antivpn.database.sql.MySqlVPN; +import dev.brighten.antivpn.database.sqllite.LiteDatabase; import lombok.Getter; import org.bstats.bukkit.Metrics; import org.bstats.charts.SimplePie; @@ -118,14 +116,8 @@ public class BukkitPlugin extends JavaPlugin { private String getDatabaseType() { VPNDatabase database = AntiVPN.getInstance().getDatabase(); - if(database instanceof H2VPN) { - return "H2"; - } else if(database instanceof MySqlVPN) { - return "MySQL"; - } else if(database instanceof MongoVPN) { - return "MongoDB"; - } else { - return "No-Database"; - } + if(database instanceof LiteDatabase) { + return "SQLLite"; + } return "No-Database"; } } diff --git a/Bungee/pom.xml b/Bungee/pom.xml index dc90784..cf03290 100644 --- a/Bungee/pom.xml +++ b/Bungee/pom.xml @@ -26,18 +26,13 @@ org.apache.maven.plugins maven-shade-plugin - 3.1.0 + 3.6.0 org.bstats - dev.brighten.antivpn.bungee.org.bstats - - org.yaml.snakeyaml - dev.brighten.antivpn.shaded.org.yaml.snakeyaml - diff --git a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java index 15e29bc..79d2486 100644 --- a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java +++ b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java @@ -4,9 +4,7 @@ import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.bungee.command.BungeeCommand; import dev.brighten.antivpn.command.Command; import dev.brighten.antivpn.database.VPNDatabase; -import dev.brighten.antivpn.database.local.H2VPN; -import dev.brighten.antivpn.database.mongo.MongoVPN; -import dev.brighten.antivpn.database.sql.MySqlVPN; +import dev.brighten.antivpn.database.sqllite.LiteDatabase; import net.md_5.bungee.api.plugin.Plugin; import org.bstats.bungeecord.Metrics; import org.bstats.charts.SimplePie; @@ -51,14 +49,8 @@ public class BungeePlugin extends Plugin { private String getDatabaseType() { VPNDatabase database = AntiVPN.getInstance().getDatabase(); - if(database instanceof H2VPN) { - return "H2"; - } else if(database instanceof MySqlVPN) { - return "MySQL"; - } else if(database instanceof MongoVPN) { - return "MongoDB"; - } else { - return "No-Database"; - } + if(database instanceof LiteDatabase) { + return "SQLLite"; + } return "No-Database"; } } diff --git a/Common/pom.xml b/Common/pom.xml index eb861d9..5bd0b15 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -132,11 +132,6 @@ org.xerial sqlite-jdbc 3.48.0.0 - - - com.h2database - h2 - 2.2.220 provided @@ -163,13 +158,6 @@ 3.1.8 provided - - - org.mongodb - mongo-java-driver - 3.12.14 - compile - org.jetbrains annotations diff --git a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java index 05d32ce..d13c7e2 100644 --- a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -30,21 +30,8 @@ import java.util.List; @Getter @Setter(AccessLevel.PRIVATE) -@MavenLibrary(groupId = "com.h2database", artifactId ="h2", version = "2.2.220", relocations = { - @Relocate(from ="org" + ".\\h2", to ="dev.brighten.antivpn.shaded.org.h2")}) -@MavenLibrary(groupId = "org.mongodb", artifactId = "mongo-java-driver", version = "3.12.14", relocations = { - @Relocate(from = "com." + "\\mongodb", to = "dev.brighten.antivpn.shaded.com.mongodb"), - @Relocate(from = "org" + "\\.bson", to = "dev.brighten.antivpn.shaded.org.bson") -}) -@MavenLibrary( - groupId = "com.mysql", - artifactId = "mysql-connector-j", - version = "9.1.0", - relocations = { - @Relocate(from = "com.my\\" + "sql.cj", to = "dev.brighten.antivpn.shaded.com.mysql.cj"), - @Relocate(from = "com.my\\" + "sql.jdbc", to = "dev.brighten.antivpn.shaded.com.mysql.jdbc") - } -) +@MavenLibrary(groupId = "org\\.sqlite", artifactId ="sqlite-jdbc", version = "3.48.0.0", relocations = { + @Relocate(from ="org" + ".\\sqlite", to ="dev.brighten.antivpn.shaded.org.sqlite")}) @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"), @@ -142,21 +129,7 @@ public class AntiVPN { } public void stop() { - if (database instanceof H2VPN) { - database.shutdown(); - - // Try to deregister driver - try { - java.sql.Driver driver = java.sql.DriverManager.getDriver("jdbc:h2:"); - if (driver != null) { - java.sql.DriverManager.deregisterDriver(driver); - } - } catch (Exception e) { - // Log but don't throw - executor.log("Failed to deregister H2 driver: " + e.getMessage()); - } - } - VPNExecutor.threadExecutor.shutdown(); + executor.shutdown(); if(database != null) database.shutdown(); } 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 1c0f2bc..6af17e7 100644 --- a/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java +++ b/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java @@ -47,7 +47,7 @@ public abstract class APIPlayer { //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().getExecutor().isWhitelisted(ip.getHostAddress() + "/32") || AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream() .anyMatch(name::startsWith)) return new CheckResult(null, ResultType.WHITELISTED); @@ -74,7 +74,7 @@ public abstract class APIPlayer { && !((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().getExecutor().isWhitelisted(ip.getHostAddress() + "/32")) // 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 diff --git a/Common/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java b/Common/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java index 1b8c16e..30c308f 100644 --- a/Common/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java +++ b/Common/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java @@ -4,8 +4,10 @@ import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.api.APIPlayer; import dev.brighten.antivpn.command.Command; import dev.brighten.antivpn.command.CommandExecutor; +import dev.brighten.antivpn.utils.CIDRUtils; import dev.brighten.antivpn.utils.MiscUtils; +import java.net.UnknownHostException; import java.util.*; import java.util.stream.Collectors; @@ -62,50 +64,75 @@ public class AllowlistCommand extends Command { if(!databaseEnabled) executor.sendMessage("&cThe database is currently not setup, " + "so any changes here will disappear after a restart."); + CIDRUtils cidrUtils; + + try { + cidrUtils = new CIDRUtils(args[1]); + } catch(IllegalArgumentException | UnknownHostException e) { + cidrUtils = null; + } + + if(cidrUtils != null) { + if(!databaseEnabled) { + return switch (args[0].toLowerCase()) { + case "add", "insert" -> { + AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(cidrUtils.getCidr()); + yield String.format("&aAdded &6%s &ato exemption allowlist.", cidrUtils.getCidr()); + } + case "remove", "delete" -> { + AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(cidrUtils.getCidr()); + yield String.format("&cRemoved &%s &cfrom the exemption allowlist.", cidrUtils.getCidr()); + } + default -> "&c\"" + args[0] + "\" is not a valid argument"; + }; + } else return switch (args[0].toLowerCase()) { + case "add", "insert" -> { + AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(cidrUtils.getCidr()); + AntiVPN.getInstance().getDatabase().addWhitelist(cidrUtils.getCidr()); + yield String.format("&aAdded &6%s &ato exemption allowlist.", cidrUtils.getCidr()); + } + case "remove", "delete" -> { + AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(cidrUtils.getCidr()); + AntiVPN.getInstance().getDatabase().removeWhitelist(cidrUtils.getCidr()); + yield String.format("&cRemoved &6%s &cfrom the exemption allowlist.", cidrUtils.getCidr()); + } + default -> "&c\"" + args[0] + "\" is not a valid argument"; + }; + } if(MiscUtils.isIpv4(args[1])) { if(!databaseEnabled) { - switch(args[0].toLowerCase()) { - case "add": - case "insert": { - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(args[1]); - AntiVPN.getInstance().getDatabase().removeWhitelist(args[1]); - return String.format("&aAdded &6%s &ato the exemption allowlist.", args[1]); + return switch(args[0].toLowerCase()) { + case "add", "insert" -> { + AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(args[1] + "/32"); + AntiVPN.getInstance().getDatabase().addWhitelist(args[1] + "/32"); + yield String.format("&aAdded &6%s &ato the exemption allowlist.", args[1] + "/32"); } - case "remove": - case "delete": { - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(args[1]); - AntiVPN.getInstance().getDatabase().removeWhitelist(args[1]); - return String.format("&cRemoved &6%s &cfrom the exemption allowlist.", args[1]); + case "remove", "delete" -> { + AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(args[1] + "/32"); + AntiVPN.getInstance().getDatabase().removeWhitelist(args[1] + "/32"); + yield String.format("&cRemoved &6%s &cfrom the exemption allowlist.", args[1] + "/32"); } - default: { - return "&c\"" + args[0] + "\" is not a valid argument"; + default -> "&c\"" + args[0] + "\" is not a valid argument"; + }; + } else return switch (args[0].toLowerCase()) { + case "add", "insert" -> { + AntiVPN.getInstance().getDatabase().addWhitelist(args[1] + "/32"); + yield String.format("&aAdded &6%s &a to the exemption allowlist.", args[1] + "/32"); } - } - } else { - switch(args[0].toLowerCase()) { - case "add": - case "insert": { - AntiVPN.getInstance().getDatabase().addWhitelist(args[1]); - return String.format("&aAdded &6%s &a to the exemption allowlist.", args[1]); + case "remove", "delete" -> { + AntiVPN.getInstance().getDatabase().removeWhitelist(args[1] + "/32"); + yield String.format("&cRemoved &6%s &c from the exemption allowlist.", args[1] + "/32"); } - case "remove": - case "delete": { - AntiVPN.getInstance().getDatabase().removeWhitelist(args[1]); - return String.format("&cRemoved &6%s &c from the exemption allowlist.", args[1]); - } - default: { - return "&c\"" + args[0] + "\" is not a valid argument"; - } - } - } + default -> "&c\"" + args[0] + "\" is not a valid argument"; + }; } else { - UUID uuid = null; + UUID uuid; try { uuid = UUID.fromString(args[1]); } catch(IllegalArgumentException e) { Optional player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(args[1]); - if(!player.isPresent()) { + if(player.isEmpty()) { return "&cThe player \"" + args[1] + "\" is not online, so please provide a UUID."; } @@ -113,54 +140,44 @@ public class AllowlistCommand extends Command { } if(!databaseEnabled) { - switch(args[0].toLowerCase()) { - case "add": { + return switch (args[0].toLowerCase()) { + case "add" -> { AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); - return String.format("&aAdded &6%s &auuid to the exemption allowlist.", uuid.toString()); + yield String.format("&aAdded &6%s &auuid to the exemption allowlist.", uuid.toString()); } - case "remove": - case "delete": { + case "remove", "delete" -> { AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); - return String.format("&cRemoved &6%s &cuuid from the exemption allowlist.", uuid.toString()); + yield String.format("&cRemoved &6%s &cuuid from the exemption allowlist.", uuid.toString()); } - default: { - return "&c\"" + args[0] + "\" is not a valid argument"; - } - } + default -> "&c\"" + args[0] + "\" is not a valid argument"; + }; } else { - switch(args[0].toLowerCase()) { - case "add": { + return switch (args[0].toLowerCase()) { + case "add" -> { AntiVPN.getInstance().getDatabase().addWhitelist(uuid); - return String.format("&aAdded &6%s &auuid to the exemption allowlist.", uuid.toString()); + yield String.format("&aAdded &6%s &auuid to the exemption allowlist.", uuid.toString()); } - case "remove": - case "delete": { + case "remove", "delete" -> { AntiVPN.getInstance().getDatabase().removeWhitelist(uuid); - return String.format("&cRemoved &6%s &cuuid from the exemption allowlist.", uuid.toString()); + yield String.format("&cRemoved &6%s &cuuid from the exemption allowlist.", uuid.toString()); } - default: { - return "&c\"" + args[0] + "\" is not a valid argument"; - } - } + default -> "&c\"" + args[0] + "\" is not a valid argument"; + }; } } } @Override public List tabComplete(CommandExecutor executor, String alias, String[] args) { - switch(args.length) { - case 1: { - return Arrays.stream(secondArgs) - .filter(narg -> narg.toLowerCase().startsWith(args[0].toLowerCase())) - .collect(Collectors.toList()); - } - case 2: { - return AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() - .map(APIPlayer::getName) - .filter(name -> name.toLowerCase().startsWith(args[1].toLowerCase())) - .collect(Collectors.toList()); - } - } - return Collections.emptyList(); + return switch (args.length) { + case 1 -> Arrays.stream(secondArgs) + .filter(narg -> narg.toLowerCase().startsWith(args[0].toLowerCase())) + .collect(Collectors.toList()); + case 2 -> AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() + .map(APIPlayer::getName) + .filter(name -> name.toLowerCase().startsWith(args[1].toLowerCase())) + .collect(Collectors.toList()); + default -> Collections.emptyList(); + }; } } 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 3d4ae8f..dc0f065 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 @@ -51,7 +51,7 @@ public class PlanCommand extends Command { @Override public String execute(CommandExecutor executor, String[] args) { - VPNExecutor.threadExecutor.execute(() -> { + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { QueryResponse result; try { if(AntiVPN.getInstance().getVpnConfig().getLicense().isEmpty()) { diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java index 40d9ef2..a184ed8 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java @@ -179,15 +179,16 @@ public class LiteDatabase implements VPNDatabase { @Override public void init() { - String url = "jdbc:sqlite:./plugins/AntiVPN/database.db"; + String url = "jdbc:sqlite:" + AntiVPN.getInstance().getPluginFolder().toPath() + "/database.db"; try { + Class.forName("org.sqlite.JDBC"); Connection connection = DriverManager.getConnection(url); Statement statement = connection.createStatement(); statement.execute("CREATE TABLE IF NOT EXISTS vpn_responses (ip TEXT, response TEXT)"); - statement.execute("CREATE TABLE IF NOT EXISTS whitelist (uuid TEXT, NUMBER minimum, NUMBER maximum)"); + statement.execute("CREATE TABLE IF NOT EXISTS whitelist (uuid TEXT, minimum NUMERIC, maximum NUMERIC)"); statement.execute("CREATE TABLE IF NOT EXISTS alerts (uuid TEXT)"); - statement.execute("CREATE TABLE IF NOT EXISTS version (PRIMARY KEY(version) NUMBER, updated STATE)"); + statement.execute("CREATE TABLE IF NOT EXISTS version (version INTEGER PRIMARY KEY, updated BOOLEAN)"); this.connection = connection; @@ -204,7 +205,7 @@ public class LiteDatabase implements VPNDatabase { AntiVPN.getInstance().getExecutor().logException(e); } } - } catch (SQLException e) { + } catch (SQLException | ClassNotFoundException e) { AntiVPN.getInstance().getExecutor().logException(e); } } 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 7ef61cb..0af6cf4 100644 --- a/Common/src/main/java/dev/brighten/antivpn/utils/StringUtil.java +++ b/Common/src/main/java/dev/brighten/antivpn/utils/StringUtil.java @@ -20,7 +20,7 @@ public class StringUtil { public static String getHash(String input) { try { - MessageDigest digest = MessageDigest.getInstance("SHA-128"); + MessageDigest digest = MessageDigest.getInstance("SHA1"); byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8)); StringBuilder hexString = new StringBuilder(2 * hash.length); for (byte b : hash) { diff --git a/Sponge/pom.xml b/Sponge/pom.xml index 27e5520..120eeff 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -42,26 +42,11 @@ compile - org.mongodb - mongo-java-driver - 3.12.14 + org.xerial + sqlite-jdbc + 3.48.0.0 compile - - com.mysql - mysql-connector-j - 9.1.0 - jar - compile - - - com.h2database - h2 - 2.2.220 - compile - 2.0.0-SNAPSHOT - provided - 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 98d2d6b..1aca72a 100644 --- a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -92,37 +92,37 @@ public class VelocityListener extends VPNExecutor { .replace("%city%", result.getCity()))); - if(deniedOnLogin) return; + 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()) { + 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(); + .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(); + .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; + if (!AntiVPN.getInstance().getVpnConfig().runCommands()) return; switch (checkResult.resultType()) { case DENIED_PROXY -> { @@ -162,13 +162,10 @@ public class VelocityListener extends VPNExecutor { } } } + } @Override public void shutdown() { - if (cacheResetTask != null) { - cacheResetTask.cancel(); - cacheResetTask = null; - } VelocityPlugin.INSTANCE.getServer().getEventManager().unregisterListener(VelocityPlugin.INSTANCE, this); super.shutdown(); } diff --git a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java index da0de33..2fc4d36 100644 --- a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java +++ b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java @@ -10,9 +10,7 @@ import com.velocitypowered.api.proxy.ProxyServer; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.command.Command; import dev.brighten.antivpn.database.VPNDatabase; -import dev.brighten.antivpn.database.local.H2VPN; -import dev.brighten.antivpn.database.mongo.MongoVPN; -import dev.brighten.antivpn.database.sql.MySqlVPN; +import dev.brighten.antivpn.database.sqllite.LiteDatabase; import dev.brighten.antivpn.velocity.command.VelocityCommand; import lombok.Getter; import org.bstats.charts.SimplePie; @@ -88,14 +86,8 @@ public class VelocityPlugin { private String getDatabaseType() { VPNDatabase database = AntiVPN.getInstance().getDatabase(); - if(database instanceof H2VPN) { - return "H2"; - } else if(database instanceof MySqlVPN) { - return "MySQL"; - } else if(database instanceof MongoVPN) { - return "MongoDB"; - } else { - return "No-Database"; - } + if(database instanceof LiteDatabase) { + return "SQLLite"; + } return "No-Database"; } } From a5ea502f17dc1d3e32b62d5870378cdcdda5f2e6 Mon Sep 17 00:00:00 2001 From: Dawson Date: Thu, 5 Jun 2025 09:50:30 -0400 Subject: [PATCH 04/22] Added postgres --- Common/pom.xml | 6 ++++++ Common/src/main/java/dev/brighten/antivpn/AntiVPN.java | 1 + 2 files changed, 7 insertions(+) diff --git a/Common/pom.xml b/Common/pom.xml index 5bd0b15..56fb33a 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -163,6 +163,12 @@ annotations 24.0.1 + + org.postgresql + postgresql + 42.7.6 + provided + \ No newline at end of file diff --git a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java index d13c7e2..674944b 100644 --- a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -36,6 +36,7 @@ import java.util.List; relocations = { @Relocate(from = "com\\.github\\.benmanes\\.caffeine", to = "dev.brighten.antivpn.shaded.com.github.benmanes.caffeine"), }) +@MavenLibrary(groupId = "org\\.postgresql", artifactId = "postgresql", version = "42.7.6") public class AntiVPN { private static AntiVPN INSTANCE; From 9697150465b928b8815ff68e42c4e82eed0b0108 Mon Sep 17 00:00:00 2001 From: Dawson Date: Thu, 5 Jun 2025 10:24:45 -0400 Subject: [PATCH 05/22] Added postgresql --- .../antivpn/bukkit/BukkitListener.java | 28 ++- .../brighten/antivpn/bukkit/BukkitPlugin.java | 2 +- .../antivpn/bungee/BungeeListener.java | 6 +- .../brighten/antivpn/bungee/BungeePlugin.java | 2 +- Common/pom.xml | 13 +- .../java/dev/brighten/antivpn/AntiVPN.java | 18 +- .../dev/brighten/antivpn/api/APIPlayer.java | 6 +- .../dev/brighten/antivpn/api/VPNConfig.java | 216 ++---------------- .../dev/brighten/antivpn/api/VPNExecutor.java | 16 +- .../antivpn/database/VPNDatabase.java | 52 +++++ .../database/postgres/PostgresDatabase.java | 42 ++++ .../database/sqllite/LiteDatabase.java | 62 ++--- .../database/sqllite/version/Version.java | 9 +- .../database/sqllite/version/impl/First.java | 4 +- .../antivpn/sponge/SpongeListener.java | 6 +- .../antivpn/velocity/VelocityListener.java | 20 +- .../antivpn/velocity/VelocityPlugin.java | 2 +- 17 files changed, 195 insertions(+), 309 deletions(-) create mode 100644 Common/src/main/java/dev/brighten/antivpn/database/postgres/PostgresDatabase.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 7f036c3..a4686aa 100644 --- a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java +++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java @@ -77,7 +77,7 @@ public class BukkitListener extends VPNExecutor implements Listener { AntiVPN.getInstance().getExecutor().getToKick() .add(new Tuple<>(instantResult, event.getPlayer().getUniqueId())); - if(!AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { return; } @@ -87,25 +87,25 @@ public class BukkitListener extends VPNExecutor implements Listener { switch (instantResult.resultType()) { case DENIED_COUNTRY -> event.setKickMessage(StringUtil.translateAlternateColorCodes('&', StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().countryVanillaKickReason(), + AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(), player, instantResult.response() ))); case DENIED_PROXY -> { - if(AntiVPN.getInstance().getVpnConfig().alertToStaff()) { + if(AntiVPN.getInstance().getVpnConfig().isAlertToStaff()) { AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() .filter(APIPlayer::isAlertsEnabled) .forEach(pl -> pl.sendMessage(StringUtil.varReplace( ChatColor.translateAlternateColorCodes( '&', - AntiVPN.getInstance().getVpnConfig().alertMessage()), + AntiVPN.getInstance().getVpnConfig().getAlertMsg()), player, instantResult.response()))); } event.setKickMessage(StringUtil.translateAlternateColorCodes('&', StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().getKickString(), + AntiVPN.getInstance().getVpnConfig().getKickMessage(), player, instantResult.response() ))); @@ -116,16 +116,14 @@ public class BukkitListener extends VPNExecutor implements Listener { @EventHandler(priority = EventPriority.MONITOR) public void onJoin(final PlayerJoinEvent event) { AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId()) - .ifPresent(player -> { - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { - if(AntiVPN.getInstance().getDatabase().getAlertsState(player.getUuid())) { - player.setAlertsEnabled(true); - player.sendMessage(AntiVPN.getInstance().getMessageHandler() - .getString("command-alerts-toggled") - .getFormattedMessage(new VpnString.Var<>("state", true))); - } - }); - }); + .ifPresent(player -> AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { + if(AntiVPN.getInstance().getDatabase().getAlertsState(player.getUuid())) { + player.setAlertsEnabled(true); + player.sendMessage(AntiVPN.getInstance().getMessageHandler() + .getString("command-alerts-toggled") + .getFormattedMessage(new VpnString.Var<>("state", true))); + } + })); } @EventHandler diff --git a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java index 5cb3e69..72e9852 100644 --- a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java +++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java @@ -39,7 +39,7 @@ public class BukkitPlugin extends JavaPlugin { playerCommandRunner.start(); // Loading our bStats metrics to be pushed to https://bstats.org - if(AntiVPN.getInstance().getVpnConfig().metrics()) { + if(AntiVPN.getInstance().getVpnConfig().isMetrics()) { Bukkit.getLogger().info("Starting bStats metrics..."); Metrics metrics = new Metrics(this, 12615); metrics.addCustomChart(new SimplePie("database_used", this::getDatabaseType)); 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 2ecf55d..7f3aad0 100644 --- a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -96,7 +96,7 @@ public class BungeeListener extends VPNExecutor implements Listener { AntiVPN.getInstance().getExecutor().getToKick() .add(new Tuple<>(instantResult, player.getUuid())); - if (!AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + if (!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { return; } @@ -110,13 +110,13 @@ public class BungeeListener extends VPNExecutor implements Listener { case DENIED_PROXY -> event.setReason(TextComponent.fromLegacy(ChatColor .translateAlternateColorCodes('&', StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().getKickString(), + AntiVPN.getInstance().getVpnConfig().getKickMessage(), player, instantResult.response())))); case DENIED_COUNTRY -> event.setReason(TextComponent.fromLegacy(ChatColor .translateAlternateColorCodes('&', StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().countryVanillaKickReason(), + AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(), player, instantResult.response())))); } diff --git a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java index 79d2486..c435bfd 100644 --- a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java +++ b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java @@ -27,7 +27,7 @@ public class BungeePlugin extends Plugin { getProxy().getLogger().info("Starting AntiVPN services..."); AntiVPN.start(new BungeeListener(), new BungeePlayerExecutor(), getDataFolder()); - if(AntiVPN.getInstance().getVpnConfig().metrics()) { + if(AntiVPN.getInstance().getVpnConfig().isMetrics()) { getProxy().getLogger().info("Starting bStats metrics..."); Metrics metrics = new Metrics(this, 12616); metrics.addCustomChart(new SimplePie("database_used", this::getDatabaseType)); diff --git a/Common/pom.xml b/Common/pom.xml index 56fb33a..618aebb 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -89,17 +89,8 @@ - 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 + org.postgresql + dev.brighten.antivpn.shaded.org.postgresql dev.brighten.antivpn.depends.Relocate diff --git a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java index 674944b..b663865 100644 --- a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -6,7 +6,9 @@ import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.command.Command; import dev.brighten.antivpn.command.impl.AntiVPNCommand; import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.postgres.PostgresDatabase; import dev.brighten.antivpn.database.sqllite.LiteDatabase; +import dev.brighten.antivpn.database.sqllite.version.Version; import dev.brighten.antivpn.depends.LibraryLoader; import dev.brighten.antivpn.depends.MavenLibrary; import dev.brighten.antivpn.depends.Relocate; @@ -36,7 +38,10 @@ import java.util.List; relocations = { @Relocate(from = "com\\.github\\.benmanes\\.caffeine", to = "dev.brighten.antivpn.shaded.com.github.benmanes.caffeine"), }) -@MavenLibrary(groupId = "org\\.postgresql", artifactId = "postgresql", version = "42.7.6") +@MavenLibrary(groupId = "org\\.postgresql", artifactId = "postgresql", version = "42.7.6", + relocations = { + @Relocate(from = "org\\.postgresql", to = "dev.brighten.antivpn.shaded.org.postgresql") + }) public class AntiVPN { private static AntiVPN INSTANCE; @@ -61,6 +66,8 @@ public class AntiVPN { LibraryLoader.loadAll(INSTANCE); + Version.register(); + try { File configFile = new File(pluginFolder, "config.yml"); if(!configFile.exists()){ @@ -84,7 +91,14 @@ public class AntiVPN { INSTANCE.messageHandler = new MessageHandler(); - INSTANCE.database = new LiteDatabase(); + INSTANCE.database = switch (INSTANCE.vpnConfig.getDatabaseType().toLowerCase()) { + case "sqlite", "sqllite" -> new LiteDatabase(); + case "postgresql", "postgres" -> new PostgresDatabase(); + default -> + throw new IllegalStateException("Unexpected database type set at config.yml 'database.type': \"" + + INSTANCE.vpnConfig.getDatabaseType().toLowerCase() + "\"!" + + "Available types: 'sqlite', 'postgresql', 'mongodb'"); + }; INSTANCE.database.init(); //Registering commands 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 6af17e7..6397f05 100644 --- a/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java +++ b/Common/src/main/java/dev/brighten/antivpn/api/APIPlayer.java @@ -70,7 +70,7 @@ public abstract class APIPlayer { // If the countryList() size is zero, no need to check. // Running country check first CheckResult checkResult; - if (!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty() + if (!AntiVPN.getInstance().getVpnConfig().getCountryList().isEmpty() && !((uuid != null && AntiVPN.getInstance().getExecutor() .isWhitelisted(uuid)) //Or has a name that starts with a certain prefix. This is for Bedrock exempting. @@ -79,9 +79,9 @@ public abstract class APIPlayer { // 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() + && AntiVPN.getInstance().getVpnConfig().getCountryList() .contains(result.getCountryCode()) - != AntiVPN.getInstance().getVpnConfig().whitelistCountries()) { + != AntiVPN.getInstance().getVpnConfig().isWhitelistCountries()) { //Using our built in kicking system if no commands are configured checkResult = new CheckResult(result, ResultType.DENIED_COUNTRY); } else if (result.isProxy()) { diff --git a/Common/src/main/java/dev/brighten/antivpn/api/VPNConfig.java b/Common/src/main/java/dev/brighten/antivpn/api/VPNConfig.java index 6549945..64e8a13 100644 --- a/Common/src/main/java/dev/brighten/antivpn/api/VPNConfig.java +++ b/Common/src/main/java/dev/brighten/antivpn/api/VPNConfig.java @@ -2,17 +2,19 @@ package dev.brighten.antivpn.api; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.utils.ConfigDefault; +import lombok.Getter; import java.util.ArrayList; import java.util.Collections; import java.util.List; + public class VPNConfig { private final ConfigDefault licenseDefault = new ConfigDefault<>("", "license", AntiVPN.getInstance()), kickStringDefault = new ConfigDefault<>("Proxies are not allowed on our server", "kickMessage", AntiVPN.getInstance()), - defaultDatabaseType = new ConfigDefault<>("H2", + defaultDatabaseType = new ConfigDefault<>("SQLite", "database.type", AntiVPN.getInstance()), defaultDatabaseName = new ConfigDefault<>("kaurivpn", "database.database", AntiVPN.getInstance()), @@ -52,212 +54,22 @@ public class VPNConfig { defCountrylist = new ConfigDefault<>(new ArrayList<>(), "countries.list", AntiVPN.getInstance()); - private String license, kickMessage, databaseType, databaseName, mongoURL, username, password, ip, alertMsg, - countryVanillaKickReason; + /** + * -- GETTER -- + * License from ... to be used for more queries. + * + */ + @Getter + private String license, kickMessage, databaseType, databaseName, mongoURL, username, password, + ip, alertMsg, countryVanillaKickReason; + @Getter private List prefixWhitelists, commands, countryList, countryKickCommands; + @Getter private int port; + @Getter private boolean cacheResults, databaseEnabled, useCredentials, commandsEnabled, kickPlayers, alertToStaff, metrics, whitelistCountries; - /** - * License from https://funkemunky.cc/shop to be used for more queries. - * @return String - */ - public String getLicense() { - return license; - } - - /** - * If true, results will be cached to reduce queries to https://funkemunky.cc - * @return boolean - */ - public boolean cachedResults() { - return cacheResults; - } - - /** - * Will be used for vanilla kick message when {@link VPNConfig#runCommands()} is true. - * @return String - */ - public String getKickString() { - return kickMessage; - } - - /** - * Message to send staff on proxy detection. - * @return String - */ - public String alertMessage() { - return alertMsg; - } - - /** - * If true, staff will be alerted on proxy detection. - * @return boolean - */ - public boolean alertToStaff() { - return alertToStaff; - } - - /** - * If true, will run {@link VPNConfig#commands()} on detect. If not, it will use vanilla kicking methods. - * @return boolean - */ - public boolean runCommands() { - return commandsEnabled; - } - - /** - * Commands to run on proxy detection. - * @return List - */ - public List commands() { - return commands; - } - - /** - * If false, no commands nor kick will be run on proxy detection. - * @return boolean - */ - public boolean kickPlayersOnDetect() { - return kickPlayers; - } - - /** - * Returns Strings of which are checked against the beginning of player names. Used to - * allow Geyser-connected players to join. - * @return List - */ - public List getPrefixWhitelists() { - return prefixWhitelists; - } - - /** - * Returns true if we want to use a database - * @return boolean - */ - public boolean isDatabaseEnabled() { - return databaseEnabled; - } - - /** - * Whether or not the database we want to connect to requires credentials. - * @return boolean - */ - public boolean useDatabaseCreds() { - return useCredentials; - } - - /** - * Only for Mongo only. URL used for connecting to database. Overrides other fields - * @return String - */ - public String mongoDatabaseURL() { - return mongoURL; - } - - /** - * Database type. Either MySQL and Mongo. - * @return String - */ - public String getDatabaseType() { - return databaseType; - } - - /** - * Database name - * @return String - */ - public String getDatabaseName() { - return databaseName; - } - - /** - * Database username - * @return String - */ - public String getUsername() { - return username; - } - - /** - * Database Password - * @return String - */ - public String getPassword() { - return password; - } - - /** - * Database IP - * @return String - */ - public String getIp() { - return ip; - } - - /** - * Returns the list of ISO country codes we need to check. - * @return List - */ - public List countryList() { - return countryList; - } - - /** - * If true, we only allow the {@link VPNConfig#countryKickCommands()}. If false, we blacklist them. - * @return boolean - */ - public boolean whitelistCountries() { - return whitelistCountries; - } - - /** - * Returns our configured commands to run on player country detection. - * @return List - */ - public List countryKickCommands() { - return countryKickCommands; - } - - /** - * Returns the vanilla kick reason for bad country locations - * @return String - */ - public String countryVanillaKickReason() { - return countryVanillaKickReason; - } - - /** - * Gets the port based on configuration. If {@link VPNConfig#port} is -1, will get default port - * based on {@link VPNConfig#getDatabaseType()} lowerCase(). - * @return int - */ - public int getPort() { - if(port == -1) { - switch (getDatabaseType().toLowerCase()) { - case "mongodb": - case "mongo": - case "mongod": - return 27017; - case "sql": - case "mysql": - return 3306; - } - } - - return port; - } - - - /** - * If true, https://bstats.org metrics will be collected to improve KauriVPN. - * @return boolean - */ - public boolean metrics() { - return metrics; - } - /** * Grabs all information from the config.yml */ 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 e979581..01b2a06 100644 --- a/Common/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -73,35 +73,35 @@ public abstract class VPNExecutor { } public void handleKickingOfPlayer(CheckResult result, APIPlayer player) { - if (AntiVPN.getInstance().getVpnConfig().alertToStaff()) AntiVPN.getInstance().getPlayerExecutor() + if (AntiVPN.getInstance().getVpnConfig().isAlertToStaff()) 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())))); + .getAlertMsg(), player, result.response())))); - if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + if(AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { switch (result.resultType()) { case DENIED_PROXY -> player.kickPlayer(StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() - .getKickString(), player, result.response())); + .getKickMessage(), player, result.response())); case DENIED_COUNTRY -> player.kickPlayer(StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() - .countryVanillaKickReason(), player, result.response())); + .getCountryVanillaKickReason(), player, result.response())); } } - if(!AntiVPN.getInstance().getVpnConfig().runCommands()) return; + if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) return; switch (result.resultType()) { case DENIED_PROXY -> { - for (String command : AntiVPN.getInstance().getVpnConfig().commands()) { + for (String command : AntiVPN.getInstance().getVpnConfig().getCommands()) { runCommand(StringUtil.translateAlternateColorCodes('&', StringUtil.varReplace(command, player, result.response()))); } } case DENIED_COUNTRY -> { - for (String command : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) { + for (String command : AntiVPN.getInstance().getVpnConfig().getCountryKickCommands()) { runCommand(StringUtil.translateAlternateColorCodes('&', StringUtil.varReplace(command, player, result.response()))); } 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 59ebf74..b2378d6 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java @@ -1,10 +1,15 @@ package dev.brighten.antivpn.database; +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.sqllite.version.Version; import dev.brighten.antivpn.web.objects.VPNResponse; +import org.intellij.lang.annotations.Language; +import java.sql.*; import java.util.Optional; import java.util.UUID; +@SuppressWarnings({"unused", "SqlSourceToSinkFlow"}) public interface VPNDatabase { Optional getStoredResponse(String ip); @@ -32,5 +37,52 @@ public interface VPNDatabase { void init(); + default void setupTable() throws SQLException { + try(Connection connection = connection()) { + Statement statement = connection.createStatement(); + statement.execute("CREATE TABLE IF NOT EXISTS vpn_responses (ip TEXT, response TEXT)"); + statement.execute("CREATE TABLE IF NOT EXISTS whitelist (uuid TEXT, minimum NUMERIC, maximum NUMERIC)"); + statement.execute("CREATE TABLE IF NOT EXISTS alerts (uuid TEXT)"); + statement.execute("CREATE TABLE IF NOT EXISTS version (version INTEGER PRIMARY KEY, updated BOOLEAN)"); + + // Run through updates + for (Version version : Version.versions) { + try(ResultSet result = query("SELECT * FROM version WHERE version = ?", + version.versionNumber())) { + if(!result.next()) { + version.update(this); + statement("INSERT INTO version (version, updated) VALUES (?, ?)", + version.versionNumber(), true); + } + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + } + } + + default ResultSet query(@Language("SQL") String query, Object... args) throws SQLException { + try(Connection connection = connection()) { + PreparedStatement pstmt = connection.prepareStatement(query); + for (int i = 0; i < args.length; i++) { + pstmt.setObject(i + 1, args[i]); + } + + return pstmt.executeQuery(); + } + } + + default void statement(@Language("SQL") String query, Object... args) throws SQLException { + try(Connection connection = connection()) { + PreparedStatement pstmt = connection.prepareStatement(query); + for (int i = 0; i < args.length; i++) { + pstmt.setObject(i + 1, args[i]); + } + + pstmt.execute(); + } + } + Connection connection(); + void shutdown(); } diff --git a/Common/src/main/java/dev/brighten/antivpn/database/postgres/PostgresDatabase.java b/Common/src/main/java/dev/brighten/antivpn/database/postgres/PostgresDatabase.java new file mode 100644 index 0000000..e21a3e0 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/database/postgres/PostgresDatabase.java @@ -0,0 +1,42 @@ +package dev.brighten.antivpn.database.postgres; + +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.sqllite.LiteDatabase; + +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; + +public class PostgresDatabase extends LiteDatabase { + + @Override + public void init() { + + try { + Class.forName("org.postgresql.Driver"); + } catch (ClassNotFoundException e) { + AntiVPN.getInstance().getExecutor().logException(e); + return; + } + String databaseName = AntiVPN.getInstance().getVpnConfig().getDatabaseName(); + String ipAddress = AntiVPN.getInstance().getVpnConfig().getIp(); + int port = AntiVPN.getInstance().getVpnConfig().getPort(); + String username = AntiVPN.getInstance().getVpnConfig().getUsername(); + String password = AntiVPN.getInstance().getVpnConfig().getPassword(); + + String url = String.format("jdbc:postgresql://%s:%s/%s", ipAddress, port, databaseName); + + Properties properties = new Properties(); + + properties.setProperty("user", username); + properties.setProperty("password", password); + properties.setProperty("ssl", "true"); + + try { + connection = DriverManager.getConnection(url, properties); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + + } +} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java index a184ed8..148b5ca 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java @@ -2,13 +2,11 @@ package dev.brighten.antivpn.database.sqllite; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.database.VPNDatabase; -import dev.brighten.antivpn.database.sqllite.version.Version; import dev.brighten.antivpn.utils.CIDRUtils; import dev.brighten.antivpn.utils.IpUtils; import dev.brighten.antivpn.utils.StringUtil; import dev.brighten.antivpn.utils.json.JSONException; import dev.brighten.antivpn.web.objects.VPNResponse; -import org.intellij.lang.annotations.Language; import java.math.BigDecimal; import java.net.UnknownHostException; @@ -18,7 +16,7 @@ import java.util.UUID; public class LiteDatabase implements VPNDatabase { - private Connection connection; + protected Connection connection; @Override public Optional getStoredResponse(String ip) { @@ -55,6 +53,7 @@ public class LiteDatabase implements VPNDatabase { } } + @SuppressWarnings("SqlWithoutWhere") @Override public void clearResponses() { try { @@ -170,8 +169,11 @@ public class LiteDatabase implements VPNDatabase { @Override public void updateAlertsState(UUID uuid, boolean state) { try { - statement("INSERT INTO alerts (uuid, STATE) VALUES (?, ?) ON CONFLICT(uuid) DO UPDATE SET STATE = ?", - uuid.toString(), state, state); + statement("DELETE FROM alerts WHERE uuid = ?", uuid.toString()); + if(state) { + statement("INSERT INTO alerts (uuid) VALUES (?)", + uuid.toString()); + } } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException(e); } @@ -183,33 +185,25 @@ public class LiteDatabase implements VPNDatabase { try { Class.forName("org.sqlite.JDBC"); - Connection connection = DriverManager.getConnection(url); - Statement statement = connection.createStatement(); - statement.execute("CREATE TABLE IF NOT EXISTS vpn_responses (ip TEXT, response TEXT)"); - statement.execute("CREATE TABLE IF NOT EXISTS whitelist (uuid TEXT, minimum NUMERIC, maximum NUMERIC)"); - statement.execute("CREATE TABLE IF NOT EXISTS alerts (uuid TEXT)"); - statement.execute("CREATE TABLE IF NOT EXISTS version (version INTEGER PRIMARY KEY, updated BOOLEAN)"); - this.connection = connection; + this.connection = DriverManager.getConnection(url); - // Run through updates - for (Version version : Version.versions) { - try(ResultSet result = query("SELECT * FROM version WHERE version = ?", - version.versionNumber())) { - if(!result.next()) { - version.update(this); - statement("INSERT INTO version (version, updated) VALUES (?, ?)", - version.versionNumber(), true); - } - } catch (SQLException e) { - AntiVPN.getInstance().getExecutor().logException(e); - } - } + setupTable(); } catch (SQLException | ClassNotFoundException e) { AntiVPN.getInstance().getExecutor().logException(e); } } + @Override + public void setupTable() throws SQLException { + VPNDatabase.super.setupTable(); + } + + @Override + public Connection connection() { + return connection; + } + @Override public void shutdown() { try { @@ -218,22 +212,4 @@ public class LiteDatabase implements VPNDatabase { AntiVPN.getInstance().getExecutor().logException(e); } } - - private ResultSet query(@Language("SQL") String query, Object... args) throws SQLException { - PreparedStatement pstmt = connection.prepareStatement(query); - for (int i = 0; i < args.length; i++) { - pstmt.setObject(i + 1, args[i]); - } - - return pstmt.executeQuery(); - } - - public void statement(@Language("SQL") String query, Object... args) throws SQLException { - PreparedStatement pstmt = connection.prepareStatement(query); - for (int i = 0; i < args.length; i++) { - pstmt.setObject(i + 1, args[i]); - } - - pstmt.execute(); - } } diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java index 392a2e4..f01202c 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java @@ -1,18 +1,19 @@ package dev.brighten.antivpn.database.sqllite.version; -import dev.brighten.antivpn.database.sqllite.LiteDatabase; +import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.sqllite.version.impl.First; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public interface Version { - void update(LiteDatabase database) throws SQLException; + void update(VPNDatabase database) throws SQLException; int versionNumber(); List versions = new ArrayList<>(); - static void register(Version version) { - versions.add(version); + static void register() { + versions.add(new First()); } } diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java index 69ff011..fd95bf1 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java @@ -1,12 +1,12 @@ package dev.brighten.antivpn.database.sqllite.version.impl; -import dev.brighten.antivpn.database.sqllite.LiteDatabase; +import dev.brighten.antivpn.database.VPNDatabase; import dev.brighten.antivpn.database.sqllite.version.Version; public class First implements Version { @Override - public void update(LiteDatabase database) { + public void update(VPNDatabase database) { } 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 47b6664..c26fab1 100644 --- a/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java +++ b/Sponge/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java @@ -38,7 +38,7 @@ public class SpongeListener extends VPNExecutor { AntiVPN.getInstance().getExecutor().getToKick().add(new Tuple<>(instantResult, player.get().getUuid())); - if(!AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { return; } @@ -51,7 +51,7 @@ public class SpongeListener extends VPNExecutor { + " joined on a VPN/Proxy (" + instantResult.response().getMethod() + ")"); event.setMessage(Component.text(StringUtil .translateColorCodes('&', AntiVPN.getInstance().getVpnConfig() - .getKickString() + .getKickMessage() .replace("%player%", player.get().getName()) .replace("%country%", instantResult.response().getCountryName()) .replace("%code%", instantResult.response().getCountryCode())))); @@ -59,7 +59,7 @@ public class SpongeListener extends VPNExecutor { case DENIED_COUNTRY -> event.setMessage(Component.text(StringUtil .translateColorCodes('&', AntiVPN.getInstance().getVpnConfig() - .countryVanillaKickReason() + .getCountryVanillaKickReason() .replace("%player%", player.get().getName()) .replace("%country%", instantResult.response().getCountryName()) .replace("%code%", instantResult.response().getCountryCode())))); 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 1aca72a..d88f731 100644 --- a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -49,7 +49,7 @@ public class VelocityListener extends VPNExecutor { LegacyComponentSerializer.builder() .character('&') .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .countryVanillaKickReason() + .getCountryVanillaKickReason() .replace("%player%", event.getPlayer().getUsername()) .replace("%country%", instantResult.response().getCountryName()) .replace("%code%", instantResult.response().getCountryCode())))); @@ -59,7 +59,7 @@ public class VelocityListener extends VPNExecutor { event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder() .character('&') .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .getKickString() + .getKickMessage() .replace("%player%", event.getPlayer().getUsername()) .replace("%country%", instantResult.response().getCountryName()) .replace("%code%", instantResult.response().getCountryCode())))); @@ -77,12 +77,12 @@ public class VelocityListener extends VPNExecutor { 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()) + if (AntiVPN.getInstance().getVpnConfig().isAlertToStaff()) AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() .filter(APIPlayer::isAlertsEnabled) .forEach(pl -> pl.sendMessage(dev.brighten.antivpn.AntiVPN.getInstance().getVpnConfig() - .alertMessage() + .getAlertMsg() .replace("%player%", event.getPlayer().getUsername()) .replace("%reason%", @@ -97,14 +97,14 @@ public class VelocityListener extends VPNExecutor { //In case the user wants to run their own commands instead of using the // built in kicking - if (AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + if (AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { 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() + .getKickMessage() .replace("%player%", event.getPlayer().getUsername()) .replace("%country%", result.getCountryName()) .replace("%code%", result.getCountryCode())))) @@ -114,7 +114,7 @@ public class VelocityListener extends VPNExecutor { event.getPlayer().disconnect(LegacyComponentSerializer.builder() .character('&') .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .countryVanillaKickReason() + .getCountryVanillaKickReason() .replace("%player%", event.getPlayer().getUsername()) .replace("%country%", result.getCountryName()) .replace("%code%", result.getCountryCode())))) @@ -122,11 +122,11 @@ public class VelocityListener extends VPNExecutor { } } - if (!AntiVPN.getInstance().getVpnConfig().runCommands()) return; + if (!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) return; switch (checkResult.resultType()) { case DENIED_PROXY -> { - for (String command : AntiVPN.getInstance().getVpnConfig().commands()) { + for (String command : AntiVPN.getInstance().getVpnConfig().getCommands()) { VelocityPlugin.INSTANCE.getServer().getCommandManager() .executeAsync(VelocityPlugin.INSTANCE.getServer() .getConsoleCommandSource(), @@ -144,7 +144,7 @@ public class VelocityListener extends VPNExecutor { } } case DENIED_COUNTRY -> { - for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) { + for (String cmd : AntiVPN.getInstance().getVpnConfig().getCountryKickCommands()) { final String formattedCommand = StringUtil .translateAlternateColorCodes('&', StringUtil.varReplace( diff --git a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java index 2fc4d36..2252ee9 100644 --- a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java +++ b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java @@ -52,7 +52,7 @@ public class VelocityPlugin { logger.info("Starting AntiVPN services..."); AntiVPN.start(new VelocityListener(), new VelocityPlayerExecutor(), configDir.toFile()); - if(AntiVPN.getInstance().getVpnConfig().metrics()) { + if(AntiVPN.getInstance().getVpnConfig().isMetrics()) { logger.info("Starting metrics..."); metrics = metricsFactory.make(this, 12791); From c191fbccfab618cdeabde6d92d8de7724aad16d8 Mon Sep 17 00:00:00 2001 From: Dawson Date: Thu, 5 Jun 2025 10:33:16 -0400 Subject: [PATCH 06/22] Correcting sponge compile --- Sponge/pom.xml | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/Sponge/pom.xml b/Sponge/pom.xml index 120eeff..3b89136 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -47,6 +47,12 @@ 3.48.0.0 compile + + org.postgresql + postgresql + 42.7.6 + compile + @@ -121,26 +127,8 @@ - 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 + org.postgresql + dev.brighten.antivpn.shaded.org.postgresql dev.brighten.antivpn.depends.Relocate From edd255e29db8ae36f646591f1a92a9c166fd2dc1 Mon Sep 17 00:00:00 2001 From: Dawson Date: Thu, 5 Jun 2025 11:35:15 -0400 Subject: [PATCH 07/22] Added mongodb and option to remove spoiled cached responses --- .../brighten/antivpn/bukkit/BukkitPlugin.java | 4 +- .../brighten/antivpn/bungee/BungeePlugin.java | 4 +- Common/pom.xml | 10 +- .../java/dev/brighten/antivpn/AntiVPN.java | 10 +- .../brighten/antivpn/database/Database.java | 39 +++ .../antivpn/database/VPNDatabase.java | 88 ------- .../database/mongodb/MongoDatabase.java | 229 ++++++++++++++++++ .../database/mongodb/records/AlertsUser.java | 6 + .../mongodb/records/CidrWhitelist.java | 6 + .../mongodb/records/UserIpResponse.java | 13 + .../mongodb/records/UserWhitelist.java | 6 + .../database/sqllite/LiteDatabase.java | 58 ++++- .../database/sqllite/version/Version.java | 4 +- .../database/sqllite/version/impl/First.java | 18 +- .../antivpn/velocity/VelocityPlugin.java | 4 +- 15 files changed, 390 insertions(+), 109 deletions(-) create mode 100644 Common/src/main/java/dev/brighten/antivpn/database/Database.java delete mode 100644 Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/database/mongodb/MongoDatabase.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/AlertsUser.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/CidrWhitelist.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/UserIpResponse.java create mode 100644 Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/UserWhitelist.java diff --git a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java index 72e9852..dfce1b9 100644 --- a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java +++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java @@ -3,7 +3,7 @@ package dev.brighten.antivpn.bukkit; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.bukkit.command.BukkitCommand; import dev.brighten.antivpn.command.Command; -import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.Database; import dev.brighten.antivpn.database.sqllite.LiteDatabase; import lombok.Getter; import org.bstats.bukkit.Metrics; @@ -114,7 +114,7 @@ public class BukkitPlugin extends JavaPlugin { } private String getDatabaseType() { - VPNDatabase database = AntiVPN.getInstance().getDatabase(); + Database database = AntiVPN.getInstance().getDatabase(); if(database instanceof LiteDatabase) { return "SQLLite"; diff --git a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java index c435bfd..c8672b7 100644 --- a/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java +++ b/Bungee/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java @@ -3,7 +3,7 @@ package dev.brighten.antivpn.bungee; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.bungee.command.BungeeCommand; import dev.brighten.antivpn.command.Command; -import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.Database; import dev.brighten.antivpn.database.sqllite.LiteDatabase; import net.md_5.bungee.api.plugin.Plugin; import org.bstats.bungeecord.Metrics; @@ -47,7 +47,7 @@ public class BungeePlugin extends Plugin { } private String getDatabaseType() { - VPNDatabase database = AntiVPN.getInstance().getDatabase(); + Database database = AntiVPN.getInstance().getDatabase(); if(database instanceof LiteDatabase) { return "SQLLite"; diff --git a/Common/pom.xml b/Common/pom.xml index 618aebb..cca88e4 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -80,8 +80,8 @@ - com.mongodb - dev.brighten.antivpn.shaded.com.mongodb + com.mongodb.client + dev.brighten.antivpn.shaded.com.mongodb.client dev.brighten.antivpn.depends.Relocate @@ -154,6 +154,12 @@ annotations 24.0.1 + + org.mongodb + mongodb-driver-sync + 5.5.0 + provided + org.postgresql postgresql diff --git a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java index b663865..fca642e 100644 --- a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -5,7 +5,8 @@ import dev.brighten.antivpn.api.VPNConfig; import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.command.Command; import dev.brighten.antivpn.command.impl.AntiVPNCommand; -import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.Database; +import dev.brighten.antivpn.database.mongodb.MongoDatabase; import dev.brighten.antivpn.database.postgres.PostgresDatabase; import dev.brighten.antivpn.database.sqllite.LiteDatabase; import dev.brighten.antivpn.database.sqllite.version.Version; @@ -42,13 +43,17 @@ import java.util.List; relocations = { @Relocate(from = "org\\.postgresql", to = "dev.brighten.antivpn.shaded.org.postgresql") }) +@MavenLibrary(groupId = "com\\.mongodb", artifactId = "driver-sync", version = "5.5.0", + relocations = { + @Relocate(from = "com\\.mongodb.client", to = "dev.brighten.antivpn.shaded.com.mongodb.client") + }) public class AntiVPN { private static AntiVPN INSTANCE; private VPNConfig vpnConfig; private VPNExecutor executor; private PlayerExecutor playerExecutor; - private VPNDatabase database; + private Database database; private MessageHandler messageHandler; private Configuration config; private List commands = new ArrayList<>(); @@ -94,6 +99,7 @@ public class AntiVPN { INSTANCE.database = switch (INSTANCE.vpnConfig.getDatabaseType().toLowerCase()) { case "sqlite", "sqllite" -> new LiteDatabase(); case "postgresql", "postgres" -> new PostgresDatabase(); + case "mongo", "mongodb" -> new MongoDatabase(); default -> throw new IllegalStateException("Unexpected database type set at config.yml 'database.type': \"" + INSTANCE.vpnConfig.getDatabaseType().toLowerCase() + "\"!" + diff --git a/Common/src/main/java/dev/brighten/antivpn/database/Database.java b/Common/src/main/java/dev/brighten/antivpn/database/Database.java new file mode 100644 index 0000000..3d5514a --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/database/Database.java @@ -0,0 +1,39 @@ +package dev.brighten.antivpn.database; + +import dev.brighten.antivpn.web.objects.VPNResponse; + +import java.util.Optional; +import java.util.UUID; + +@SuppressWarnings({"unused"}) +public interface Database { + Optional getStoredResponse(String ip); + + void cacheResponse(VPNResponse toCache); + + void deleteResponse(String ip); + + void clearResponses(); + + void clearOutdatedResponses(); + + boolean isWhitelisted(UUID uuid); + + boolean isWhitelisted(String ip); + + void addWhitelist(UUID uuid); + + void addWhitelist(String cidr); + + void removeWhitelist(UUID uuid); + + void removeWhitelist(String cidr); + + boolean getAlertsState(UUID uuid); + + void updateAlertsState(UUID uuid, boolean state); + + void init(); + + void shutdown(); +} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java b/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java deleted file mode 100644 index b2378d6..0000000 --- a/Common/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java +++ /dev/null @@ -1,88 +0,0 @@ -package dev.brighten.antivpn.database; - -import dev.brighten.antivpn.AntiVPN; -import dev.brighten.antivpn.database.sqllite.version.Version; -import dev.brighten.antivpn.web.objects.VPNResponse; -import org.intellij.lang.annotations.Language; - -import java.sql.*; -import java.util.Optional; -import java.util.UUID; - -@SuppressWarnings({"unused", "SqlSourceToSinkFlow"}) -public interface VPNDatabase { - Optional getStoredResponse(String ip); - - void cacheResponse(VPNResponse toCache); - - void deleteResponse(String ip); - - void clearResponses(); - - boolean isWhitelisted(UUID uuid); - - boolean isWhitelisted(String ip); - - void addWhitelist(UUID uuid); - - void addWhitelist(String cidr); - - void removeWhitelist(UUID uuid); - - void removeWhitelist(String cidr); - - boolean getAlertsState(UUID uuid); - - void updateAlertsState(UUID uuid, boolean state); - - void init(); - - default void setupTable() throws SQLException { - try(Connection connection = connection()) { - Statement statement = connection.createStatement(); - statement.execute("CREATE TABLE IF NOT EXISTS vpn_responses (ip TEXT, response TEXT)"); - statement.execute("CREATE TABLE IF NOT EXISTS whitelist (uuid TEXT, minimum NUMERIC, maximum NUMERIC)"); - statement.execute("CREATE TABLE IF NOT EXISTS alerts (uuid TEXT)"); - statement.execute("CREATE TABLE IF NOT EXISTS version (version INTEGER PRIMARY KEY, updated BOOLEAN)"); - - // Run through updates - for (Version version : Version.versions) { - try(ResultSet result = query("SELECT * FROM version WHERE version = ?", - version.versionNumber())) { - if(!result.next()) { - version.update(this); - statement("INSERT INTO version (version, updated) VALUES (?, ?)", - version.versionNumber(), true); - } - } catch (SQLException e) { - AntiVPN.getInstance().getExecutor().logException(e); - } - } - } - } - - default ResultSet query(@Language("SQL") String query, Object... args) throws SQLException { - try(Connection connection = connection()) { - PreparedStatement pstmt = connection.prepareStatement(query); - for (int i = 0; i < args.length; i++) { - pstmt.setObject(i + 1, args[i]); - } - - return pstmt.executeQuery(); - } - } - - default void statement(@Language("SQL") String query, Object... args) throws SQLException { - try(Connection connection = connection()) { - PreparedStatement pstmt = connection.prepareStatement(query); - for (int i = 0; i < args.length; i++) { - pstmt.setObject(i + 1, args[i]); - } - - pstmt.execute(); - } - } - Connection connection(); - - void shutdown(); -} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/mongodb/MongoDatabase.java b/Common/src/main/java/dev/brighten/antivpn/database/mongodb/MongoDatabase.java new file mode 100644 index 0000000..0cdf156 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/database/mongodb/MongoDatabase.java @@ -0,0 +1,229 @@ +package dev.brighten.antivpn.database.mongodb; + +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.UpdateOptions; +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.Database; +import dev.brighten.antivpn.database.mongodb.records.AlertsUser; +import dev.brighten.antivpn.database.mongodb.records.CidrWhitelist; +import dev.brighten.antivpn.database.mongodb.records.UserIpResponse; +import dev.brighten.antivpn.database.mongodb.records.UserWhitelist; +import dev.brighten.antivpn.utils.CIDRUtils; +import dev.brighten.antivpn.utils.IpUtils; +import dev.brighten.antivpn.utils.json.JSONException; +import dev.brighten.antivpn.web.objects.VPNResponse; +import org.bson.Document; + +import java.math.BigDecimal; +import java.net.UnknownHostException; +import java.util.Date; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; + +public class MongoDatabase implements Database { + + private MongoCollection alertsCollection; + private MongoCollection cidrWhitelistCollection; + private MongoCollection userWhitelistCollection; + private MongoCollection vpnResponseCollection; + + @Override + public Optional getStoredResponse(String ip) { + UserIpResponse response = vpnResponseCollection.find(Filters.eq("ip", ip)).first(); + + if(response == null) { + return Optional.empty(); + } + + try { + return Optional.of(response.getVpnResponse()); + } catch (JSONException e) { + AntiVPN.getInstance().getExecutor().logException("Could not convert vpn response from JSON String to DTO " + + "for address: " + ip, e); + return Optional.empty(); + } + } + + @Override + public void cacheResponse(VPNResponse toCache) { + try { + UserIpResponse response = new UserIpResponse(toCache.getIp(), new Date(), toCache.toJson().toString()); + + vpnResponseCollection.updateOne(Filters.eq("ip", toCache.getIp()), + new Document("$set", response), + new UpdateOptions().upsert(true)); + } catch (JSONException e) { + AntiVPN.getInstance().getExecutor().log(Level.SEVERE, "An error occurred while caching response", e); + } + } + + @Override + public void deleteResponse(String ip) { + vpnResponseCollection.deleteOne(Filters.eq("ip", ip)); + } + + @Override + public void clearResponses() { + //Clears all documents within the collection + var result = vpnResponseCollection.deleteMany(new Document()); + + AntiVPN.getInstance().getExecutor().log(Level.INFO, "VPN responses have been cleared (count=%s)", result.getDeletedCount()); + } + + @Override + public void clearOutdatedResponses() { + var result = vpnResponseCollection.deleteMany(Filters.lte("date", + new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMicros(7)))); + + AntiVPN.getInstance().getExecutor().log(Level.INFO, "Cleared outdated responses (count=%s)", + result.getDeletedCount()); + } + + @Override + public boolean isWhitelisted(UUID uuid) { + UserWhitelist whitelist = userWhitelistCollection.find(Filters.eq("uuid", uuid)).first(); + + return whitelist != null; + } + + @Override + public boolean isWhitelisted(String ip) { + Optional ipDec = IpUtils.getIpDecimal(ip); + + if(ipDec.isEmpty()) { + AntiVPN.getInstance().getExecutor().log(Level.WARNING, "Could not check for whitelist on IP %s since" + + " it cannot be converted to decimal!", ip); + return false; + } + + BigDecimal decimal = ipDec.get(); + + CidrWhitelist whitelist = cidrWhitelistCollection.find(Filters.and( + Filters.lte("start", decimal), + Filters.gte("end", decimal) + + )).first(); + + return whitelist != null; + } + + @Override + public void addWhitelist(UUID uuid) { + UserWhitelist whitelist = new UserWhitelist(uuid); + + userWhitelistCollection.insertOne(whitelist); + } + + @Override + public void addWhitelist(String cidr) { + try { + var cidrObj = new CIDRUtils(cidr); + + Optional start = IpUtils.getIpDecimal(cidrObj.getStartAddress().getHostAddress()), + end = IpUtils.getIpDecimal(cidrObj.getEndAddress().getHostAddress()); + + if(start.isEmpty() || end.isEmpty()) { + AntiVPN.getInstance().getExecutor().log(Level.WARNING, "Could not whitelist cidr %s since " + + "it is missing either a start or end address", cidr); + return; + } + + CidrWhitelist whitelist = new CidrWhitelist(start.get(), end.get()); + + cidrWhitelistCollection.insertOne(whitelist); + } catch (UnknownHostException e) { + AntiVPN.getInstance().getExecutor().logException("Could not whitelist cidr: " + cidr, e); + } + } + + @Override + public void removeWhitelist(UUID uuid) { + var result = userWhitelistCollection.deleteMany(Filters.eq("uuid", uuid.toString())); + + AntiVPN.getInstance().getExecutor().log(Level.INFO, "Removed whitelist for uuid %s (count=%s)", + uuid, result.getDeletedCount()); + } + + @Override + public void removeWhitelist(String cidr) { + try { + var cidrObj = new CIDRUtils(cidr); + + Optional start = IpUtils.getIpDecimal(cidrObj.getStartAddress().getHostAddress()); + Optional end = IpUtils.getIpDecimal(cidrObj.getEndAddress().getHostAddress()); + + if(start.isEmpty() || end.isEmpty()) { + AntiVPN.getInstance().getExecutor().log(Level.WARNING, "Could not remove cidr %s from whitelist" + + " since it is missing either a start or end address.", cidr); + return; + } + + var result = cidrWhitelistCollection.deleteMany(Filters.and(Filters.eq("start", start.get()), + Filters.eq("end", end.get()))); + + AntiVPN.getInstance().getExecutor().log(Level.INFO, "Removed cidr %s from whitelist (count=%s).", + cidr, result.getDeletedCount()); + } catch (UnknownHostException e) { + AntiVPN.getInstance().getExecutor().logException("Could not remove whitelist for CIDR: " + cidr, e); + } + } + + @Override + public boolean getAlertsState(UUID uuid) { + AlertsUser alertsUser = alertsCollection.find(Filters.eq("uuid", uuid)).first(); + + if(alertsUser == null) { + return false; + } + + return alertsUser.state(); + } + + @Override + public void updateAlertsState(UUID uuid, boolean state) { + alertsCollection.updateOne(Filters.eq("uuid", uuid), + new Document("$set", new AlertsUser(uuid, state)), + new UpdateOptions().upsert(true)); + } + + @Override + public void init() { + String connectionUrl; + if(AntiVPN.getInstance().getVpnConfig().getMongoURL().isEmpty()) { + String databaseName = AntiVPN.getInstance().getVpnConfig().getDatabaseName(); + String username = AntiVPN.getInstance().getVpnConfig().getUsername(); + String password = AntiVPN.getInstance().getVpnConfig().getPassword(); + String ip = AntiVPN.getInstance().getVpnConfig().getIp(); + int port = AntiVPN.getInstance().getVpnConfig().getPort(); + + connectionUrl = String.format("mongodb+srv://" + + "%s:%s>@%s:%s/%s?connectTimeoutMS=2000", + username, password, ip, port, databaseName); + } else { + connectionUrl = AntiVPN.getInstance() + .getVpnConfig().getMongoURL(); + } + + try(MongoClient mongoClient = MongoClients.create(connectionUrl)) { + var database = mongoClient.getDatabase(AntiVPN.getInstance().getVpnConfig().getDatabaseName()); + + userWhitelistCollection = database.getCollection("whitelist", UserWhitelist.class); + cidrWhitelistCollection = database.getCollection("cidrWhitelist", CidrWhitelist.class); + alertsCollection = database.getCollection("alerts", AlertsUser.class); + vpnResponseCollection = database.getCollection("responses", UserIpResponse.class); + } + } + + @Override + public void shutdown() { + userWhitelistCollection = null; + cidrWhitelistCollection = null; + alertsCollection = null; + vpnResponseCollection = null; + } +} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/AlertsUser.java b/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/AlertsUser.java new file mode 100644 index 0000000..7fe29f8 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/AlertsUser.java @@ -0,0 +1,6 @@ +package dev.brighten.antivpn.database.mongodb.records; + +import java.util.UUID; + +public record AlertsUser(UUID uuid, boolean state) { +} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/CidrWhitelist.java b/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/CidrWhitelist.java new file mode 100644 index 0000000..eb24bb5 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/CidrWhitelist.java @@ -0,0 +1,6 @@ +package dev.brighten.antivpn.database.mongodb.records; + +import java.math.BigDecimal; + +public record CidrWhitelist(BigDecimal start, BigDecimal end) { +} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/UserIpResponse.java b/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/UserIpResponse.java new file mode 100644 index 0000000..cc81709 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/UserIpResponse.java @@ -0,0 +1,13 @@ +package dev.brighten.antivpn.database.mongodb.records; + +import dev.brighten.antivpn.utils.json.JSONException; +import dev.brighten.antivpn.web.objects.VPNResponse; + +import java.util.Date; + +public record UserIpResponse(String ip, Date queried, String response) { + + public VPNResponse getVpnResponse() throws JSONException { + return VPNResponse.fromJson(response); + } +} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/UserWhitelist.java b/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/UserWhitelist.java new file mode 100644 index 0000000..e2e01c4 --- /dev/null +++ b/Common/src/main/java/dev/brighten/antivpn/database/mongodb/records/UserWhitelist.java @@ -0,0 +1,6 @@ +package dev.brighten.antivpn.database.mongodb.records; + +import java.util.UUID; + +public record UserWhitelist(UUID uuid) { +} diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java index 148b5ca..da2e8e7 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/LiteDatabase.java @@ -1,20 +1,23 @@ package dev.brighten.antivpn.database.sqllite; import dev.brighten.antivpn.AntiVPN; -import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.sqllite.version.Version; import dev.brighten.antivpn.utils.CIDRUtils; import dev.brighten.antivpn.utils.IpUtils; import dev.brighten.antivpn.utils.StringUtil; import dev.brighten.antivpn.utils.json.JSONException; import dev.brighten.antivpn.web.objects.VPNResponse; +import org.intellij.lang.annotations.Language; import java.math.BigDecimal; import java.net.UnknownHostException; import java.sql.*; import java.util.Optional; import java.util.UUID; +import java.util.concurrent.TimeUnit; -public class LiteDatabase implements VPNDatabase { +@SuppressWarnings("SqlSourceToSinkFlow") +public class LiteDatabase implements dev.brighten.antivpn.database.Database { protected Connection connection; @@ -36,7 +39,7 @@ public class LiteDatabase implements VPNDatabase { String hashedIp = StringUtil.getHash(toCache.getIp()); try { - statement("INSERT INTO vpn_responses (ip, response) VALUES (?, ?)", hashedIp, jsonResponse); + statement("INSERT INTO vpn_responses (ip, date, response) VALUES (?, ?, ?)", hashedIp, System.currentTimeMillis(), jsonResponse); } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException(e); } @@ -63,6 +66,17 @@ public class LiteDatabase implements VPNDatabase { } } + @Override + public void clearOutdatedResponses() { + long cutoffTime = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7); + + try { + statement("DELETE FROM vpn_responses WHERE date < ?", cutoffTime); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + @Override public boolean isWhitelisted(UUID uuid) { try(ResultSet result = query("SELECT * FROM whitelist WHERE uuid = ?", uuid.toString())) { @@ -194,12 +208,44 @@ public class LiteDatabase implements VPNDatabase { } } - @Override public void setupTable() throws SQLException { - VPNDatabase.super.setupTable(); + // Run through updates + for (Version version : Version.versions) { + try(ResultSet result = query("SELECT * FROM version WHERE version = ?", + version.versionNumber())) { + if(!result.next()) { + version.update(this); + statement("INSERT INTO version (version, updated) VALUES (?, ?)", + version.versionNumber(), true); + } + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException(e); + } + } + } + + protected ResultSet query(@Language("SQL") String query, Object... args) throws SQLException { + try(Connection connection = connection()) { + PreparedStatement pstmt = connection.prepareStatement(query); + for (int i = 0; i < args.length; i++) { + pstmt.setObject(i + 1, args[i]); + } + + return pstmt.executeQuery(); + } + } + + protected void statement(@Language("SQL") String query, Object... args) throws SQLException { + try(Connection connection = connection()) { + PreparedStatement pstmt = connection.prepareStatement(query); + for (int i = 0; i < args.length; i++) { + pstmt.setObject(i + 1, args[i]); + } + + pstmt.execute(); + } } - @Override public Connection connection() { return connection; } diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java index f01202c..eb0b561 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/Version.java @@ -1,6 +1,6 @@ package dev.brighten.antivpn.database.sqllite.version; -import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.sqllite.LiteDatabase; import dev.brighten.antivpn.database.sqllite.version.impl.First; import java.sql.SQLException; @@ -8,7 +8,7 @@ import java.util.ArrayList; import java.util.List; public interface Version { - void update(VPNDatabase database) throws SQLException; + void update(LiteDatabase database) throws SQLException; int versionNumber(); List versions = new ArrayList<>(); diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java index fd95bf1..508ad62 100644 --- a/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java +++ b/Common/src/main/java/dev/brighten/antivpn/database/sqllite/version/impl/First.java @@ -1,13 +1,25 @@ package dev.brighten.antivpn.database.sqllite.version.impl; -import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.sqllite.LiteDatabase; import dev.brighten.antivpn.database.sqllite.version.Version; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + public class First implements Version { @Override - public void update(VPNDatabase database) { - + public void update(LiteDatabase database) { + try(Connection connection = database.connection()) { + Statement statement = connection.createStatement(); + statement.execute("CREATE TABLE IF NOT EXISTS vpn_responses (ip TEXT, date INTEGER, response TEXT)"); + statement.execute("CREATE TABLE IF NOT EXISTS whitelist (uuid TEXT, minimum NUMERIC, maximum NUMERIC)"); + statement.execute("CREATE TABLE IF NOT EXISTS alerts (uuid TEXT)"); + statement.execute("CREATE TABLE IF NOT EXISTS version (version INTEGER PRIMARY KEY, updated BOOLEAN)"); + } catch (SQLException e) { + throw new RuntimeException(e); + } } @Override diff --git a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java index 2252ee9..926b35d 100644 --- a/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java +++ b/Velocity/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java @@ -9,7 +9,7 @@ import com.velocitypowered.api.plugin.annotation.DataDirectory; import com.velocitypowered.api.proxy.ProxyServer; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.command.Command; -import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.Database; import dev.brighten.antivpn.database.sqllite.LiteDatabase; import dev.brighten.antivpn.velocity.command.VelocityCommand; import lombok.Getter; @@ -84,7 +84,7 @@ public class VelocityPlugin { } private String getDatabaseType() { - VPNDatabase database = AntiVPN.getInstance().getDatabase(); + Database database = AntiVPN.getInstance().getDatabase(); if(database instanceof LiteDatabase) { return "SQLLite"; From 1930a86a0d22d090ad7518478753c94fda2baaf1 Mon Sep 17 00:00:00 2001 From: Dawson Date: Thu, 5 Jun 2025 11:37:13 -0400 Subject: [PATCH 08/22] Added task for clearing outdated database responses --- .../src/main/java/dev/brighten/antivpn/AntiVPN.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java index fca642e..c168747 100644 --- a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -30,6 +30,7 @@ import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; @Getter @Setter(AccessLevel.PRIVATE) @@ -128,6 +129,8 @@ public class AntiVPN { // Starting kick checks AntiVPN.getInstance().getExecutor().startKickChecks(); + + AntiVPN.getInstance().runSpoiledResponseChecks(); } public InputStream getResource(String filename) { @@ -154,6 +157,15 @@ public class AntiVPN { if(database != null) database.shutdown(); } + private void runSpoiledResponseChecks() { + if(database == null) return; + + AntiVPN.getInstance().getExecutor().getThreadExecutor().scheduleAtFixedRate( + () -> database.clearOutdatedResponses(), + 0, 30, TimeUnit.MINUTES + ); + } + public void reloadDatabase() { database.shutdown(); From 1c3e653dda4e04820a035d2b233f95432eb1b89e Mon Sep 17 00:00:00 2001 From: Dawson Date: Thu, 5 Jun 2025 11:38:45 -0400 Subject: [PATCH 09/22] Updating test workflow jdk version to Java 21 --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7515e19..a7de87b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,10 +7,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up JDK 17.0.2 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: - java-version: 17.0 + java-version: 21.0 distribution: 'zulu' cache: 'maven' - name: Compile From 791367632380968a0647d6ea37fb19bd39bfdde2 Mon Sep 17 00:00:00 2001 From: funkemunky Date: Tue, 30 Dec 2025 07:24:35 -0800 Subject: [PATCH 10/22] Start of versioning database functions and handling errors --- Common/Source/pom.xml | 6 + .../java/dev/brighten/antivpn/AntiVPN.java | 146 ++++++++---- .../dev/brighten/antivpn/api/VPNConfig.java | 218 ++++++++++++++++-- .../dev/brighten/antivpn/api/VPNExecutor.java | 25 +- .../antivpn/database/VPNDatabase.java | 2 +- .../antivpn/database/local/H2VPN.java | 56 ++--- .../antivpn/database/local/version/First.java | 40 ++++ .../antivpn/database/sql/utils/Query.java | 12 +- .../antivpn/database/version/H2Version.java | 15 ++ .../antivpn/database/version/Version.java | 7 + .../dev/brighten/antivpn/utils/CIDRUtils.java | 146 ++++++++++++ 11 files changed, 558 insertions(+), 115 deletions(-) create mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java create mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java create mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java create mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java diff --git a/Common/Source/pom.xml b/Common/Source/pom.xml index 44fe127..a829d1e 100644 --- a/Common/Source/pom.xml +++ b/Common/Source/pom.xml @@ -173,6 +173,12 @@ 3.12.14 provided + + org.jetbrains + annotations + 26.0.2 + compile + \ No newline at end of file diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java index c168747..6fe3cdb 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -5,11 +5,10 @@ import dev.brighten.antivpn.api.VPNConfig; import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.command.Command; import dev.brighten.antivpn.command.impl.AntiVPNCommand; -import dev.brighten.antivpn.database.Database; -import dev.brighten.antivpn.database.mongodb.MongoDatabase; -import dev.brighten.antivpn.database.postgres.PostgresDatabase; -import dev.brighten.antivpn.database.sqllite.LiteDatabase; -import dev.brighten.antivpn.database.sqllite.version.Version; +import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.local.H2VPN; +import dev.brighten.antivpn.database.mongo.MongoVPN; +import dev.brighten.antivpn.database.sql.MySqlVPN; import dev.brighten.antivpn.depends.LibraryLoader; import dev.brighten.antivpn.depends.MavenLibrary; import dev.brighten.antivpn.depends.Relocate; @@ -30,31 +29,35 @@ import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.TimeUnit; @Getter @Setter(AccessLevel.PRIVATE) -@MavenLibrary(groupId = "org\\.sqlite", artifactId ="sqlite-jdbc", version = "3.48.0.0", relocations = { - @Relocate(from ="org" + ".\\sqlite", to ="dev.brighten.antivpn.shaded.org.sqlite")}) +@MavenLibrary(groupId = "com.h2database", artifactId ="h2", version = "2.2.220", relocations = { + @Relocate(from ="org" + ".\\h2", to ="dev.brighten.antivpn.shaded.org.h2")}) +@MavenLibrary(groupId = "org.mongodb", artifactId = "mongo-java-driver", version = "3.12.14", relocations = { + @Relocate(from = "com." + "\\mongodb", to = "dev.brighten.antivpn.shaded.com.mongodb"), + @Relocate(from = "org" + "\\.bson", to = "dev.brighten.antivpn.shaded.org.bson") +}) +@MavenLibrary( + groupId = "com.mysql", + artifactId = "mysql-connector-j", + version = "9.1.0", + relocations = { + @Relocate(from = "com.my\\" + "sql.cj", to = "dev.brighten.antivpn.shaded.com.mysql.cj"), + @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", relocations = { @Relocate(from = "com\\.github\\.benmanes\\.caffeine", to = "dev.brighten.antivpn.shaded.com.github.benmanes.caffeine"), }) -@MavenLibrary(groupId = "org\\.postgresql", artifactId = "postgresql", version = "42.7.6", - relocations = { - @Relocate(from = "org\\.postgresql", to = "dev.brighten.antivpn.shaded.org.postgresql") - }) -@MavenLibrary(groupId = "com\\.mongodb", artifactId = "driver-sync", version = "5.5.0", - relocations = { - @Relocate(from = "com\\.mongodb.client", to = "dev.brighten.antivpn.shaded.com.mongodb.client") - }) public class AntiVPN { private static AntiVPN INSTANCE; private VPNConfig vpnConfig; private VPNExecutor executor; private PlayerExecutor playerExecutor; - private Database database; + private VPNDatabase database; private MessageHandler messageHandler; private Configuration config; private List commands = new ArrayList<>(); @@ -72,8 +75,6 @@ public class AntiVPN { LibraryLoader.loadAll(INSTANCE); - Version.register(); - try { File configFile = new File(pluginFolder, "config.yml"); if(!configFile.exists()){ @@ -97,16 +98,41 @@ public class AntiVPN { INSTANCE.messageHandler = new MessageHandler(); - INSTANCE.database = switch (INSTANCE.vpnConfig.getDatabaseType().toLowerCase()) { - case "sqlite", "sqllite" -> new LiteDatabase(); - case "postgresql", "postgres" -> new PostgresDatabase(); - case "mongo", "mongodb" -> new MongoDatabase(); - default -> - throw new IllegalStateException("Unexpected database type set at config.yml 'database.type': \"" - + INSTANCE.vpnConfig.getDatabaseType().toLowerCase() + "\"!" + - "Available types: 'sqlite', 'postgresql', 'mongodb'"); - }; - INSTANCE.database.init(); + 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 INSTANCE.registerCommands(); @@ -117,8 +143,7 @@ public class AntiVPN { //of unnecessary database queries. if(player.hasPermission("antivpn.command.alerts")) { //Running database check for enabled alerts. - INSTANCE.database.updateAlertsState(player.getUuid(), true); - player.setAlertsEnabled(true); + INSTANCE.database.alertsState(player.getUuid(), player::setAlertsEnabled); } }); @@ -129,8 +154,6 @@ public class AntiVPN { // Starting kick checks AntiVPN.getInstance().getExecutor().startKickChecks(); - - AntiVPN.getInstance().runSpoiledResponseChecks(); } public InputStream getResource(String filename) { @@ -153,23 +176,56 @@ public class AntiVPN { } public void stop() { - executor.shutdown(); + if (database instanceof H2VPN) { + database.shutdown(); + + // Try to deregister driver + try { + java.sql.Driver driver = java.sql.DriverManager.getDriver("jdbc:h2:"); + if (driver != null) { + java.sql.DriverManager.deregisterDriver(driver); + } + } catch (Exception e) { + // Log but don't throw + executor.log("Failed to deregister H2 driver: " + e.getMessage()); + } + } + VPNExecutor.threadExecutor.shutdown(); if(database != null) database.shutdown(); } - private void runSpoiledResponseChecks() { - if(database == null) return; - - AntiVPN.getInstance().getExecutor().getThreadExecutor().scheduleAtFixedRate( - () -> database.clearOutdatedResponses(), - 0, 30, TimeUnit.MINUTES - ); - } - public void reloadDatabase() { database.shutdown(); - INSTANCE.database = new LiteDatabase(); + switch(AntiVPN.getInstance().getVpnConfig().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; + } + } } public static AntiVPN getInstance() { @@ -200,4 +256,4 @@ public class AntiVPN { private void registerCommands() { commands.add(new AntiVPNCommand()); } -} +} \ No newline at end of file diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java index 64e8a13..18ebd6d 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java @@ -2,19 +2,17 @@ package dev.brighten.antivpn.api; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.utils.ConfigDefault; -import lombok.Getter; import java.util.ArrayList; import java.util.Collections; import java.util.List; - public class VPNConfig { private final ConfigDefault licenseDefault = new ConfigDefault<>("", "license", AntiVPN.getInstance()), kickStringDefault = new ConfigDefault<>("Proxies are not allowed on our server", "kickMessage", AntiVPN.getInstance()), - defaultDatabaseType = new ConfigDefault<>("SQLite", + defaultDatabaseType = new ConfigDefault<>("H2", "database.type", AntiVPN.getInstance()), defaultDatabaseName = new ConfigDefault<>("kaurivpn", "database.database", AntiVPN.getInstance()), @@ -54,22 +52,212 @@ public class VPNConfig { defCountrylist = new ConfigDefault<>(new ArrayList<>(), "countries.list", AntiVPN.getInstance()); - /** - * -- GETTER -- - * License from ... to be used for more queries. - * - */ - @Getter - private String license, kickMessage, databaseType, databaseName, mongoURL, username, password, - ip, alertMsg, countryVanillaKickReason; - @Getter + private String license, kickMessage, databaseType, databaseName, mongoURL, username, password, ip, alertMsg, + countryVanillaKickReason; private List prefixWhitelists, commands, countryList, countryKickCommands; - @Getter private int port; - @Getter private boolean cacheResults, databaseEnabled, useCredentials, commandsEnabled, kickPlayers, alertToStaff, metrics, whitelistCountries; + /** + * License from https://funkemunky.cc/shop to be used for more queries. + * @return String + */ + public String getLicense() { + return license; + } + + /** + * If true, results will be cached to reduce queries to https://funkemunky.cc + * @return boolean + */ + public boolean cachedResults() { + return cacheResults; + } + + /** + * Will be used for vanilla kick message when {@link VPNConfig#runCommands()} is true. + * @return String + */ + public String getKickString() { + return kickMessage; + } + + /** + * Message to send staff on proxy detection. + * @return String + */ + public String alertMessage() { + return alertMsg; + } + + /** + * If true, staff will be alerted on proxy detection. + * @return boolean + */ + public boolean alertToStaff() { + return alertToStaff; + } + + /** + * If true, will run {@link VPNConfig#commands()} on detect. If not, it will use vanilla kicking methods. + * @return boolean + */ + public boolean runCommands() { + return commandsEnabled; + } + + /** + * Commands to run on proxy detection. + * @return List + */ + public List commands() { + return commands; + } + + /** + * If false, no commands nor kick will be run on proxy detection. + * @return boolean + */ + public boolean kickPlayersOnDetect() { + return kickPlayers; + } + + /** + * Returns Strings of which are checked against the beginning of player names. Used to + * allow Geyser-connected players to join. + * @return List + */ + public List getPrefixWhitelists() { + return prefixWhitelists; + } + + /** + * Returns true if we want to use a database + * @return boolean + */ + public boolean isDatabaseEnabled() { + return databaseEnabled; + } + + /** + * Whether or not the database we want to connect to requires credentials. + * @return boolean + */ + public boolean useDatabaseCreds() { + return useCredentials; + } + + /** + * Only for Mongo only. URL used for connecting to database. Overrides other fields + * @return String + */ + public String mongoDatabaseURL() { + return mongoURL; + } + + /** + * Database type. Either MySQL and Mongo. + * @return String + */ + public String getDatabaseType() { + return databaseType; + } + + /** + * Database name + * @return String + */ + public String getDatabaseName() { + return databaseName; + } + + /** + * Database username + * @return String + */ + public String getUsername() { + return username; + } + + /** + * Database Password + * @return String + */ + public String getPassword() { + return password; + } + + /** + * Database IP + * @return String + */ + public String getIp() { + return ip; + } + + /** + * Returns the list of ISO country codes we need to check. + * @return List + */ + public List countryList() { + return countryList; + } + + /** + * If true, we only allow the {@link VPNConfig#countryKickCommands()}. If false, we blacklist them. + * @return boolean + */ + public boolean whitelistCountries() { + return whitelistCountries; + } + + /** + * Returns our configured commands to run on player country detection. + * @return List + */ + public List countryKickCommands() { + return countryKickCommands; + } + + /** + * Returns the vanilla kick reason for bad country locations + * @return String + */ + public String countryVanillaKickReason() { + return countryVanillaKickReason; + } + + /** + * Gets the port based on configuration. If {@link VPNConfig#port} is -1, will get default port + * based on {@link VPNConfig#getDatabaseType()} lowerCase(). + * @return int + */ + public int getPort() { + if(port == -1) { + switch (getDatabaseType().toLowerCase()) { + case "mongodb": + case "mongo": + case "mongod": + return 27017; + case "sql": + case "mysql": + return 3306; + } + } + + return port; + } + + + /** + * If true, https://bstats.org metrics will be collected to improve KauriVPN. + * @return boolean + */ + public boolean metrics() { + return metrics; + } + /** * Grabs all information from the config.yml */ @@ -99,4 +287,4 @@ public class VPNConfig { countryVanillaKickReason = defaultCountryKickReason.get(); } -} +} \ No newline at end of file diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java index 01b2a06..6635f94 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -17,13 +17,10 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; public abstract class VPNExecutor { - - @Getter - private final ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2); + public static ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2); @Getter private final Set whitelisted = Collections.synchronizedSet(new HashSet<>()); - @Getter private final Set whitelistedIps = Collections.synchronizedSet(new HashSet<>()); @@ -32,10 +29,6 @@ public abstract class VPNExecutor { public abstract void registerListeners(); - public void shutdown() { - threadExecutor.shutdown(); - } - public abstract void log(Level level, String log, Object... objects); public abstract void log(String log, Object... objects); @@ -73,35 +66,35 @@ public abstract class VPNExecutor { } public void handleKickingOfPlayer(CheckResult result, APIPlayer player) { - if (AntiVPN.getInstance().getVpnConfig().isAlertToStaff()) AntiVPN.getInstance().getPlayerExecutor() + 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() - .getAlertMsg(), player, result.response())))); + .alertMessage(), player, result.response())))); - if(AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { + if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { switch (result.resultType()) { case DENIED_PROXY -> player.kickPlayer(StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() - .getKickMessage(), player, result.response())); + .getKickString(), player, result.response())); case DENIED_COUNTRY -> player.kickPlayer(StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() - .getCountryVanillaKickReason(), player, result.response())); + .countryVanillaKickReason(), player, result.response())); } } - if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) return; + if(!AntiVPN.getInstance().getVpnConfig().runCommands()) return; switch (result.resultType()) { case DENIED_PROXY -> { - for (String command : AntiVPN.getInstance().getVpnConfig().getCommands()) { + 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().getCountryKickCommands()) { + for (String command : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) { runCommand(StringUtil.translateAlternateColorCodes('&', StringUtil.varReplace(command, player, result.response()))); } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java index 2289197..1a4fe30 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java @@ -41,4 +41,4 @@ public interface VPNDatabase { void init(); void shutdown(); -} +} \ No newline at end of file diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java index 4dfcdf9..59a75ea 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java @@ -9,6 +9,7 @@ import dev.brighten.antivpn.database.sql.utils.MySQL; import dev.brighten.antivpn.database.sql.utils.Query; import dev.brighten.antivpn.web.objects.VPNResponse; import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import java.sql.ResultSet; import java.sql.SQLException; @@ -87,13 +88,17 @@ public class H2VPN implements VPNDatabase { cachedResponses.put(toCache.getIp(), toCache); - Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`," - + "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)") - .append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName()) - .append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone()) - .append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy()) - .append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis())) - .append(toCache.getLatitude()).append(toCache.getLongitude()).execute(); + try { + Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`," + + "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)") + .append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName()) + .append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone()) + .append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy()) + .append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis())) + .append(toCache.getLatitude()).append(toCache.getLongitude()).execute(); + } catch(SQLException e) { + + } } @Override @@ -101,18 +106,24 @@ public class H2VPN implements VPNDatabase { if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - Query.prepare("delete from `responses` where `ip` = ?").append(ip).execute(); + try { + Query.prepare("delete from `responses` where `ip` = ?").append(ip).execute(); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("Could not delete response from IP: " + ip, e); + } } - @SneakyThrows @Override public boolean isWhitelisted(UUID uuid) { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return false; - ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1") - .append(uuid.toString()).executeQuery(); - - return set != null && set.next() && set.getString("uuid") != null; + try(ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1") + .append(uuid.toString()).executeQuery()) { + return set != null && set.next() && set.getString("uuid") != null; + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("Could not check whitelist for uuid '" + uuid + "' due to SQL error.", e); + return false; + } } @SneakyThrows @@ -252,25 +263,6 @@ public class H2VPN implements VPNDatabase { AntiVPN.getInstance().getExecutor().log("Creating tables..."); //Running check for old table types to update - - Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute(); - Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute(); - Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12)," - + "`countryName` text, `countryCode` varchar(10), `city` text, `timeZone` varchar(64), " - + "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp," - + "`latitude` double, `longitude` double)").execute(); - Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute(); - - AntiVPN.getInstance().getExecutor().log("Creating indexes..."); - try { - Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)").execute(); - Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)").execute(); - Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)").execute(); - Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)").execute(); - Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute(); - } catch (Exception e) { - System.err.println("MySQL Excepton created" + e.getMessage()); - } } @Override diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java new file mode 100644 index 0000000..de04173 --- /dev/null +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java @@ -0,0 +1,40 @@ +package dev.brighten.antivpn.database.local.version; + +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.local.H2VPN; +import dev.brighten.antivpn.database.sql.utils.Query; +import dev.brighten.antivpn.database.version.H2Version; + +public class First implements H2Version { + @Override + public void update(H2VPN database) throws Exception { + Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute(); + Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute(); + Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12)," + + "`countryName` text, `countryCode` varchar(10), `city` text, `timeZone` varchar(64), " + + "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp," + + "`latitude` double, `longitude` double)").execute(); + Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute(); + + AntiVPN.getInstance().getExecutor().log("Creating indexes..."); + try { + Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)").execute(); + Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)").execute(); + Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)").execute(); + Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)").execute(); + Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute(); + } catch (Exception e) { + System.err.println("MySQL Excepton created" + e.getMessage()); + } + } + + @Override + public int versionNumber() { + return 0; + } + + @Override + public boolean needsUpdate(H2VPN database) { + return false; + } +} diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java index ac57c27..35cc5cf 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java @@ -1,20 +1,20 @@ package dev.brighten.antivpn.database.sql.utils; +import lombok.Getter; +import org.intellij.lang.annotations.Language; + import java.sql.Connection; import java.sql.SQLException; public class Query { + @Getter private static Connection conn; public static void use(Connection conn) { Query.conn = conn; } - public static ExecutableStatement prepare(String query) { - try { - return new ExecutableStatement(conn.prepareStatement(query)); - } catch (SQLException e) { - throw new RuntimeException(e); - } + public static ExecutableStatement prepare(@Language("SQL") String sql) throws SQLException { + return new ExecutableStatement(conn.prepareStatement(sql)); } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java new file mode 100644 index 0000000..653b9a1 --- /dev/null +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java @@ -0,0 +1,15 @@ +package dev.brighten.antivpn.database.version; + +import dev.brighten.antivpn.database.local.H2VPN; + +import java.util.ArrayList; +import java.util.List; + +public interface H2Version extends Version { + + List versions = new ArrayList<>(); + + static void registerVersions() { + + } +} diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java new file mode 100644 index 0000000..11b9217 --- /dev/null +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java @@ -0,0 +1,7 @@ +package dev.brighten.antivpn.database.version; + +public interface Version { + void update(DB database) throws Exception; + int versionNumber(); + boolean needsUpdate(DB database); +} \ No newline at end of file diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java new file mode 100644 index 0000000..1fc9518 --- /dev/null +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java @@ -0,0 +1,146 @@ +/* +* The MIT License +* +* Copyright (c) 2013 Edin Dazdarevic (edin.dazdarevic@gmail.com) + +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: + +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. + +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +* */ + +package dev.brighten.antivpn.utils; + +import lombok.Getter; + +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +/** + * A class that enables to get an IP range from CIDR specification. It supports + * both IPv4 and IPv6. + */ +@Getter +public class CIDRUtils { + private final String cidr; + + private final InetAddress inetAddress; + + private InetAddress startAddress; + private InetAddress endAddress; + private final int prefixLength; + + + public CIDRUtils(String cidr) throws UnknownHostException { + + this.cidr = cidr; + + /* split CIDR to address and prefix part */ + if (this.cidr.contains("/")) { + int index = this.cidr.indexOf("/"); + String addressPart = this.cidr.substring(0, index); + String networkPart = this.cidr.substring(index + 1); + + inetAddress = InetAddress.getByName(addressPart); + prefixLength = Integer.parseInt(networkPart); + + calculate(); + } else { + throw new IllegalArgumentException("not an valid CIDR format!"); + } + } + + + private void calculate() throws UnknownHostException { + + ByteBuffer maskBuffer; + int targetSize; + if (inetAddress.getAddress().length == 4) { + maskBuffer = + ByteBuffer + .allocate(4) + .putInt(-1); + targetSize = 4; + } else { + maskBuffer = ByteBuffer.allocate(16) + .putLong(-1L) + .putLong(-1L); + targetSize = 16; + } + + BigInteger mask = (new BigInteger(1, maskBuffer.array())).not().shiftRight(prefixLength); + + ByteBuffer buffer = ByteBuffer.wrap(inetAddress.getAddress()); + BigInteger ipVal = new BigInteger(1, buffer.array()); + + BigInteger startIp = ipVal.and(mask); + BigInteger endIp = startIp.add(mask.not()); + + byte[] startIpArr = toBytes(startIp.toByteArray(), targetSize); + byte[] endIpArr = toBytes(endIp.toByteArray(), targetSize); + + this.startAddress = InetAddress.getByAddress(startIpArr); + this.endAddress = InetAddress.getByAddress(endIpArr); + + } + + private byte[] toBytes(byte[] array, int targetSize) { + int counter = 0; + List newArr = new ArrayList(); + while (counter < targetSize && (array.length - 1 - counter >= 0)) { + newArr.add(0, array[array.length - 1 - counter]); + counter++; + } + + int size = newArr.size(); + for (int i = 0; i < (targetSize - size); i++) { + + newArr.add(0, (byte) 0); + } + + byte[] ret = new byte[newArr.size()]; + for (int i = 0; i < newArr.size(); i++) { + ret[i] = newArr.get(i); + } + return ret; + } + + public String getNetworkAddress() { + + return this.startAddress.getHostAddress(); + } + + public String getBroadcastAddress() { + return this.endAddress.getHostAddress(); + } + + public boolean isInRange(String ipAddress) throws UnknownHostException { + InetAddress address = InetAddress.getByName(ipAddress); + BigInteger start = new BigInteger(1, this.startAddress.getAddress()); + BigInteger end = new BigInteger(1, this.endAddress.getAddress()); + BigInteger target = new BigInteger(1, address.getAddress()); + + int st = start.compareTo(target); + int te = target.compareTo(end); + + return (st == -1 || st == 0) && (te == -1 || te == 0); + } +} \ No newline at end of file From 9f7f4b40f0e82e6218aa35403c766008c72425fb Mon Sep 17 00:00:00 2001 From: Dawson Date: Mon, 5 Jan 2026 09:21:32 -0500 Subject: [PATCH 11/22] Implementing database versioning for CIDR whitelisting --- .../antivpn/bungee/BungeeListener.java | 10 -- .../java/dev/brighten/antivpn/AntiVPN.java | 2 +- .../dev/brighten/antivpn/api/APIPlayer.java | 20 ++- .../dev/brighten/antivpn/api/VPNConfig.java | 159 ++++++------------ .../dev/brighten/antivpn/api/VPNExecutor.java | 9 +- .../command/impl/ClearCacheCommand.java | 19 ++- .../antivpn/database/local/H2VPN.java | 109 +++++++++--- .../antivpn/database/local/version/First.java | 44 +++-- .../database/local/version/Second.java | 122 ++++++++++++++ .../antivpn/database/mongo/MongoVPN.java | 24 +-- .../antivpn/database/sql/MySqlVPN.java | 16 +- .../sql/utils/ExecutableStatement.java | 43 ++--- .../antivpn/database/sql/utils/MySQL.java | 4 +- .../antivpn/database/sql/utils/Query.java | 3 + .../database/sql/utils/ResultSetIterator.java | 3 +- .../antivpn/database/version/H2Version.java | 38 ++++- .../antivpn/database/version/Version.java | 20 ++- .../dev/brighten/antivpn/utils/IpUtils.java | 109 ++++++++++++ .../antivpn/velocity/VelocityListener.java | 10 +- 19 files changed, 551 insertions(+), 213 deletions(-) create mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java create mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/utils/IpUtils.java diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java index 116322c..7a11eea 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -28,16 +28,6 @@ public class BungeeListener extends VPNExecutor implements Listener { .registerListener(BungeePlugin.pluginInstance.getPlugin(), this); } - @Override - public void shutdown() { - if(cacheResetTask != null) { - cacheResetTask.cancel(); - cacheResetTask = null; - } - BungeePlugin.pluginInstance.getProxy().getPluginManager().unregisterListener(this); - super.shutdown(); - } - @Override public void log(Level level, String log, Object... objects) { BungeePlugin.pluginInstance.getProxy().getLogger().log(Level.INFO, String.format(log, objects)); diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java index 6fe3cdb..c1f2c16 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -190,7 +190,7 @@ public class AntiVPN { executor.log("Failed to deregister H2 driver: " + e.getMessage()); } } - VPNExecutor.threadExecutor.shutdown(); + AntiVPN.getInstance().getExecutor().getThreadExecutor().shutdown(); if(database != null) database.shutdown(); } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java index 6397f05..3f4a35a 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.api; import com.github.benmanes.caffeine.cache.Cache; @@ -39,7 +55,7 @@ public abstract class APIPlayer { public void updateAlertsState() { //Updating into database so its synced across servers and saved on logout. - AntiVPN.getInstance().getDatabase().updateAlertsState(uuid, alertsEnabled); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> AntiVPN.getInstance().getDatabase().updateAlertsState(uuid, alertsEnabled)); } public CheckResult checkPlayer(Consumer onKick) { @@ -81,7 +97,7 @@ public abstract class APIPlayer { // the state, it will kick. && AntiVPN.getInstance().getVpnConfig().getCountryList() .contains(result.getCountryCode()) - != AntiVPN.getInstance().getVpnConfig().isWhitelistCountries()) { + != AntiVPN.getInstance().getVpnConfig().getWhitelistCountries()) { //Using our built in kicking system if no commands are configured checkResult = new CheckResult(result, ResultType.DENIED_COUNTRY); } else if (result.isProxy()) { diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java index 18ebd6d..c8c584b 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java @@ -1,7 +1,24 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.api; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.utils.ConfigDefault; +import lombok.Getter; import java.util.ArrayList; import java.util.Collections; @@ -52,37 +69,50 @@ public class VPNConfig { defCountrylist = new ConfigDefault<>(new ArrayList<>(), "countries.list", AntiVPN.getInstance()); - private String license, kickMessage, databaseType, databaseName, mongoURL, username, password, ip, alertMsg, - countryVanillaKickReason; - private List prefixWhitelists, commands, countryList, countryKickCommands; + @Getter + private String license; + @Getter + private String kickMessage; + @Getter + private String databaseType; + @Getter + private String databaseName; + private String mongoURL; + @Getter + private String username; + @Getter + private String password; + @Getter + private String ip; + private String alertMsg; + @Getter + private String countryVanillaKickReason; + @Getter + private List prefixWhitelists; + private List commands; + @Getter + private List countryList; + private List countryKickCommands; private int port; - private boolean cacheResults, databaseEnabled, useCredentials, commandsEnabled, kickPlayers, alertToStaff, - metrics, whitelistCountries; + private boolean cacheResults; + @Getter + private boolean databaseEnabled; + private boolean useCredentials; + private boolean commandsEnabled; + @Getter + private boolean kickPlayers; + private boolean alertToStaff; + private boolean metrics; + private boolean whitelistCountries; /** - * License from https://funkemunky.cc/shop to be used for more queries. - * @return String - */ - public String getLicense() { - return license; - } - - /** - * If true, results will be cached to reduce queries to https://funkemunky.cc + * If true, results will be cached to reduce queries to ... * @return boolean */ public boolean cachedResults() { return cacheResults; } - /** - * Will be used for vanilla kick message when {@link VPNConfig#runCommands()} is true. - * @return String - */ - public String getKickString() { - return kickMessage; - } - /** * Message to send staff on proxy detection. * @return String @@ -115,31 +145,6 @@ public class VPNConfig { return commands; } - /** - * If false, no commands nor kick will be run on proxy detection. - * @return boolean - */ - public boolean kickPlayersOnDetect() { - return kickPlayers; - } - - /** - * Returns Strings of which are checked against the beginning of player names. Used to - * allow Geyser-connected players to join. - * @return List - */ - public List getPrefixWhitelists() { - return prefixWhitelists; - } - - /** - * Returns true if we want to use a database - * @return boolean - */ - public boolean isDatabaseEnabled() { - return databaseEnabled; - } - /** * Whether or not the database we want to connect to requires credentials. * @return boolean @@ -156,59 +161,11 @@ public class VPNConfig { return mongoURL; } - /** - * Database type. Either MySQL and Mongo. - * @return String - */ - public String getDatabaseType() { - return databaseType; - } - - /** - * Database name - * @return String - */ - public String getDatabaseName() { - return databaseName; - } - - /** - * Database username - * @return String - */ - public String getUsername() { - return username; - } - - /** - * Database Password - * @return String - */ - public String getPassword() { - return password; - } - - /** - * Database IP - * @return String - */ - public String getIp() { - return ip; - } - - /** - * Returns the list of ISO country codes we need to check. - * @return List - */ - public List countryList() { - return countryList; - } - /** * If true, we only allow the {@link VPNConfig#countryKickCommands()}. If false, we blacklist them. * @return boolean */ - public boolean whitelistCountries() { + public boolean getWhitelistCountries() { return whitelistCountries; } @@ -220,14 +177,6 @@ public class VPNConfig { return countryKickCommands; } - /** - * Returns the vanilla kick reason for bad country locations - * @return String - */ - public String countryVanillaKickReason() { - return countryVanillaKickReason; - } - /** * Gets the port based on configuration. If {@link VPNConfig#port} is -1, will get default port * based on {@link VPNConfig#getDatabaseType()} lowerCase(). @@ -251,7 +200,7 @@ public class VPNConfig { /** - * If true, https://bstats.org metrics will be collected to improve KauriVPN. + * If true, ... metrics will be collected to improve KauriVPN. * @return boolean */ public boolean metrics() { diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java index 6635f94..a2f8fe0 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -17,7 +17,8 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; public abstract class VPNExecutor { - public static ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2); + @Getter + private ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2); @Getter private final Set whitelisted = Collections.synchronizedSet(new HashSet<>()); @@ -75,12 +76,12 @@ public abstract class VPNExecutor { StringUtil.varReplace(dev.brighten.antivpn.AntiVPN.getInstance().getVpnConfig() .alertMessage(), player, result.response())))); - if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + if(AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { switch (result.resultType()) { case DENIED_PROXY -> player.kickPlayer(StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() - .getKickString(), player, result.response())); + .getKickMessage(), player, result.response())); case DENIED_COUNTRY -> player.kickPlayer(StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() - .countryVanillaKickReason(), player, result.response())); + .getCountryVanillaKickReason(), player, result.response())); } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/ClearCacheCommand.java b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/ClearCacheCommand.java index 3ff5971..01ec9a5 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/ClearCacheCommand.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/ClearCacheCommand.java @@ -1,6 +1,23 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.command.impl; import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.command.Command; import dev.brighten.antivpn.command.CommandExecutor; @@ -45,7 +62,7 @@ public class ClearCacheCommand extends Command { @Override public String execute(CommandExecutor executor, String[] args) { - AntiVPN.getInstance().getDatabase().clearResponses(); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> AntiVPN.getInstance().getDatabase().clearResponses()); return "&aCleared all cached API response information!"; } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java index 59a75ea..6498a22 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database.local; import com.github.benmanes.caffeine.cache.Cache; @@ -7,6 +23,7 @@ import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.database.VPNDatabase; import dev.brighten.antivpn.database.sql.utils.MySQL; import dev.brighten.antivpn.database.sql.utils.Query; +import dev.brighten.antivpn.database.version.H2Version; import dev.brighten.antivpn.web.objects.VPNResponse; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -30,7 +47,7 @@ public class H2VPN implements VPNDatabase { public H2VPN() { - VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> { + AntiVPN.getInstance().getExecutor().getThreadExecutor().scheduleAtFixedRate(() -> { if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; //Refreshing whitelisted players @@ -143,14 +160,18 @@ public class H2VPN implements VPNDatabase { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - if (whitelisted) { - if (!isWhitelisted(uuid)) { - Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString()).execute(); + try { + if (whitelisted) { + if (!isWhitelisted(uuid)) { + Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString()).execute(); + } + AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); + } else { + Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString()).execute(); + AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); } - AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); - } else { - Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString()).execute(); - AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("Could not set whitelist for uuid '" + uuid + "' due to SQL error.", e); } } @@ -159,14 +180,18 @@ public class H2VPN implements VPNDatabase { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - if(whitelisted) { - if(!isWhitelisted(ip)) { - Query.prepare("insert into `whitelisted-ips` (`ip`) values (?)").append(ip).execute(); + try { + if(whitelisted) { + if(!isWhitelisted(ip)) { + Query.prepare("insert into `whitelisted-ips` (`ip`) values (?)").append(ip).execute(); + } + AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip); + } else { + Query.prepare("delete from `whitelisted-ips` where `ip` = ?").append(ip).execute(); + AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip); } - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip); - } else { - Query.prepare("delete from `whitelisted-ips` where `ip` = ?").append(ip).execute(); - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("Could not set whitelist for ip '" + ip + "' due to SQL error.", e); } } @@ -174,8 +199,12 @@ public class H2VPN implements VPNDatabase { public List getAllWhitelisted() { List uuids = new ArrayList<>(); - if(!MySQL.isClosed()) Query.prepare("select uuid from `whitelisted`") - .execute(set -> uuids.add(UUID.fromString(set.getString("uuid")))); + try { + if(!MySQL.isClosed()) Query.prepare("select uuid from `whitelisted`") + .execute(set -> uuids.add(UUID.fromString(set.getString("uuid")))); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("Could not get all whitelisted players due to SQL error.", e); + } return uuids; } @@ -184,8 +213,12 @@ public class H2VPN implements VPNDatabase { public List getAllWhitelistedIps() { List ips = new ArrayList<>(); - if(!MySQL.isClosed()) Query.prepare("select `ip` from `whitelisted-ips`") + try { + if(!MySQL.isClosed()) Query.prepare("select `ip` from `whitelisted-ips`") .execute(set -> ips.add(set.getString("ip"))); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("Could not get all whitelisted ips due to SQL error.", e); + } return ips; } @@ -194,28 +227,28 @@ public class H2VPN implements VPNDatabase { public void getStoredResponseAsync(String ip, Consumer> result) { if(MySQL.isClosed()) return; - VPNExecutor.threadExecutor.execute(() -> result.accept(getStoredResponse(ip))); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(getStoredResponse(ip))); } @Override public void isWhitelistedAsync(UUID uuid, Consumer result) { if(MySQL.isClosed()) return; - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid))); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(uuid))); } @Override public void isWhitelistedAsync(String ip, Consumer result) { if(MySQL.isClosed()) return; - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip))); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(ip))); } @Override public void alertsState(UUID uuid, Consumer result) { if(MySQL.isClosed()) return; - VPNExecutor.threadExecutor.execute(() -> { + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { try(ResultSet set = Query.prepare("select * from `alerts` where `uuid` = ? limit 1") .append(uuid.toString()).executeQuery()) { @@ -235,22 +268,35 @@ public class H2VPN implements VPNDatabase { //We want to make sure there isn't already a uuid inserted to prevent double insertions alertsState(uuid, alreadyEnabled -> { //No need to make another thread execute, already async if(!alreadyEnabled) { - Query.prepare("insert into `alerts` (`uuid`) values (?)").append(uuid.toString()) - .execute(); + try { + Query.prepare("insert into `alerts` (`uuid`) values (?)").append(uuid.toString()) + .execute(); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("There was a problem updating alerts state for " + uuid, e); + } } //No need to insert again of already enabled }); //Removing any uuid from the alerts table will disable alerts globally. - } else VPNExecutor.threadExecutor.execute(() -> + } else { + try { Query.prepare("delete from `alerts` where `uuid` = ?") .append(uuid.toString()) - .execute()); + .execute(); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("There was a problem updating alerts state for " + uuid, e); + } + } } @Override public void clearResponses() { if(MySQL.isClosed()) return; - VPNExecutor.threadExecutor.execute(() -> Query.prepare("delete from `responses`").execute()); + try { + Query.prepare("delete from `responses`").execute(); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("There was a problem clearing responses.", e); + } } @Override @@ -259,6 +305,15 @@ public class H2VPN implements VPNDatabase { return; AntiVPN.getInstance().getExecutor().log("Initializing H2..."); MySQL.initH2(); + try { + for (H2Version version : H2Version.versions) { + if(version.needsUpdate(this)) { + version.update(this); + } + } + } catch (Exception e) { + throw new RuntimeException("Could not complete version setup due to SQL error", e); + } AntiVPN.getInstance().getExecutor().log("Creating tables..."); diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java index de04173..e2fa481 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database.local.version; import dev.brighten.antivpn.AntiVPN; @@ -5,9 +21,13 @@ import dev.brighten.antivpn.database.local.H2VPN; import dev.brighten.antivpn.database.sql.utils.Query; import dev.brighten.antivpn.database.version.H2Version; +import java.sql.ResultSet; +import java.sql.SQLException; + public class First implements H2Version { @Override - public void update(H2VPN database) throws Exception { + public void update(H2VPN database) throws SQLException { + backupDatabase(); Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute(); Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute(); Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12)," @@ -15,17 +35,15 @@ public class First implements H2Version { + "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp," + "`latitude` double, `longitude` double)").execute(); Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute(); + Query.prepare("create table if not exists `database_version` (`version` int)").execute(); + Query.prepare("insert into `database_version` (`version`) values (?)").append(versionNumber()).execute(); AntiVPN.getInstance().getExecutor().log("Creating indexes..."); - try { - Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)").execute(); - Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)").execute(); - Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)").execute(); - Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)").execute(); - Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute(); - } catch (Exception e) { - System.err.println("MySQL Excepton created" + e.getMessage()); - } + Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)").execute(); + Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)").execute(); + Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)").execute(); + Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)").execute(); + Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute(); } @Override @@ -35,6 +53,10 @@ public class First implements H2Version { @Override public boolean needsUpdate(H2VPN database) { - return false; + try(ResultSet set = Query.prepare("select * from `database_version` where version = 0").executeQuery()) { + return set.getFetchSize() == 0; + } catch (SQLException e) { + return true; + } } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java new file mode 100644 index 0000000..348ee39 --- /dev/null +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java @@ -0,0 +1,122 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.brighten.antivpn.database.local.version; + +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.local.H2VPN; +import dev.brighten.antivpn.database.sql.utils.Query; +import dev.brighten.antivpn.database.version.H2Version; +import dev.brighten.antivpn.utils.CIDRUtils; +import dev.brighten.antivpn.utils.IpUtils; + +import java.net.UnknownHostException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class Second implements H2Version { + @Override + public void update(H2VPN database) throws SQLException { + backupDatabase(); + List whitelistedIps = new ArrayList<>(); + + try (var set = Query.prepare("SELECT * FROM `whitelisted-ips`").executeQuery()) { + while (set.next()) { + whitelistedIps.add(set.getString("ip")); + } + } + + try { + Query.prepare("CREATE TABLE IF NOT EXISTS `whitelisted-ranges` " + + "(id INT AUTO_INCREMENT PRIMARY KEY, " + + "cidr_string VARCHAR(45), " + + "ip_start BIGINT NOT NULL, " + + "ip_end BIGINT NOT NULL") + .execute(); + Query.prepare("CREATE INDEX idx_ip_range ON `whitelisted-ranges` (ip_start, ip_end)").execute(); + + var cidrs = whitelistedIps.stream().map(ip -> { + try { + return new CIDRUtils(ip + "/32"); + } catch (UnknownHostException e) { + throw new RuntimeException("Could not format ip " + ip + " into a CIDR!", e); + } + }).toList(); + var insertStatement = Query.prepare("INSERT INTO `whitelisted-ranges` (`cidr_string`, `ip_start`, `ip_end`) VALUES (?, ?, ?)"); + for (CIDRUtils cidr : cidrs) { + insertStatement = insertStatement + .append(cidr.toString()). + append(IpUtils.getIpDecimal(cidr.getStartAddress().getHostAddress()).orElseThrow()) + .append(IpUtils.getIpDecimal(cidr.getEndAddress().getHostAddress()).orElseThrow()) + .addBatch(); + } + + int[] updateCounts = insertStatement.executeBatch(); + + for (int updateCount : updateCounts) { + if(updateCount == 0) { + throw new RuntimeException("Could not insert a CIDR from previous whitelisted lists, attempted to restore previous database!"); + } + } + + Query.prepare("DROP INDEX ip_1 on `whitelisted-ips`").execute(); + Query.prepare("DROP TABLE `whitelisted-ips`").execute(); + Query.prepare("INSERT INTO `database_version` (`version`) VALUES (?)").append(versionNumber()).execute(); + } catch (Throwable e) { + AntiVPN.getInstance().getExecutor().log("Failed to update database to version 1: " + e.getMessage()); + rollback(whitelistedIps); + throw e; + } + + } + + private void rollback(List ipAddresses) throws SQLException { + AntiVPN.getInstance().getExecutor().log("Rolling back to version 0..."); + Query.prepare("DROP INDEX idx_ip_range ON `whitelisted-ranges`").execute(); + Query.prepare("DROP TABLE `whitelisted-ranges`").execute(); + Query.prepare("DELETE FROM `database_version` WHERE version = ?").append(versionNumber()).execute(); + + Query.prepare("CREATE TABLE IF NOT EXISTS `whitelisted-ips` (`ip` VARCHAR(45) NOT NULL)") + .execute(); + Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute(); + + Query.prepare("DELETE FROM `whitelisted-ips`").execute(); + + var statement = Query.prepare("INSERT INTO `whitelisted-ips` (`ip`) VALUES (?)"); + for (String ip : ipAddresses) { + statement.append(ip); + statement.addBatch(); + } + + statement.executeBatch(); + } + + @Override + public int versionNumber() { + return 1; + } + + @Override + public boolean needsUpdate(H2VPN database) { + try (ResultSet set = Query.prepare("select * from `database_version` where version = 1").executeQuery()) { + return set.getFetchSize() == 0; + } catch (SQLException e) { + return true; + } + } +} diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java index 2e7c4eb..c317fd8 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java @@ -32,7 +32,7 @@ public class MongoVPN implements VPNDatabase { .build(); public MongoVPN() { - VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> { + AntiVPN.getInstance().getExecutor().getThreadExecutor().scheduleAtFixedRate(() -> { if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) return; //Refreshing whitelisted players @@ -55,7 +55,7 @@ public class MongoVPN implements VPNDatabase { long lastUpdate = rdoc.get("lastAccess", 0L); if(System.currentTimeMillis() - lastUpdate > TimeUnit.HOURS.toMillis(1)) { - VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip)); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> deleteResponse(ip)); return null; } @@ -101,7 +101,7 @@ public class MongoVPN implements VPNDatabase { cachedResponses.put(toCache.getIp(), toCache); - VPNExecutor.threadExecutor.execute(() -> { + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { Bson update = new Document("$set", rdoc); cacheDocument.updateOne(Filters.eq("ip", toCache.getIp()), update, new UpdateOptions().upsert(true)); @@ -133,10 +133,10 @@ public class MongoVPN implements VPNDatabase { Document wdoc = new Document("setting", "whitelist"); wdoc.put("uuid", uuid.toString()); AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); - VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc)); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> settingsDocument.insertOne(wdoc)); } else { AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); - VPNExecutor.threadExecutor.execute(() -> settingsDocument.deleteMany(Filters + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> settingsDocument.deleteMany(Filters .and( Filters.eq("setting", "whitelist"), Filters.eq("uuid", uuid.toString())))); @@ -149,10 +149,10 @@ public class MongoVPN implements VPNDatabase { Document wdoc = new Document("setting", "whitelist").append("ip", ip); AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip); - VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc)); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> settingsDocument.insertOne(wdoc)); } else { AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip); - VPNExecutor.threadExecutor.execute(() -> settingsDocument.deleteMany(Filters + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> settingsDocument.deleteMany(Filters .and( Filters.eq("setting", "whitelist"), Filters.eq("ip", ip)))); @@ -179,29 +179,29 @@ public class MongoVPN implements VPNDatabase { @Override public void getStoredResponseAsync(String ip, Consumer> result) { - VPNExecutor.threadExecutor.execute(() -> result.accept(getStoredResponse(ip))); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(getStoredResponse(ip))); } @Override public void isWhitelistedAsync(UUID uuid, Consumer result) { - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid))); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(uuid))); } @Override public void isWhitelistedAsync(String ip, Consumer result) { - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip))); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(ip))); } @Override public void alertsState(UUID uuid, Consumer result) { - VPNExecutor.threadExecutor.execute(() -> result.accept(settingsDocument + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(settingsDocument .find(Filters.and(Filters.eq("setting", "alerts"), Filters.eq("uuid", uuid.toString()))).first() != null)); } @Override public void updateAlertsState(UUID uuid, boolean state) { - VPNExecutor.threadExecutor.execute(() -> { + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { settingsDocument.deleteMany(Filters.and(Filters.eq("setting", "alerts"), Filters.eq("uuid", uuid.toString()))); if(state) { diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java index 148f0c8..e51654f 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java @@ -29,7 +29,7 @@ public class MySqlVPN implements VPNDatabase { public MySqlVPN() { - VPNExecutor.threadExecutor.scheduleAtFixedRate(() -> { + AntiVPN.getInstance().getExecutor().getThreadExecutor().scheduleAtFixedRate(() -> { if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; //Refreshing whitelisted players @@ -63,7 +63,7 @@ public class MySqlVPN implements VPNDatabase { rs.getTimestamp("inserted").getTime(), -1); if(System.currentTimeMillis() - responseFromDoc.getLastAccess() > TimeUnit.HOURS.toMillis(1)) { - VPNExecutor.threadExecutor.execute(() -> deleteResponse(ip)); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> deleteResponse(ip)); return null; } @@ -190,28 +190,28 @@ public class MySqlVPN implements VPNDatabase { public void getStoredResponseAsync(String ip, Consumer> result) { if(MySQL.isClosed()) return; - VPNExecutor.threadExecutor.execute(() -> result.accept(getStoredResponse(ip))); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(getStoredResponse(ip))); } @Override public void isWhitelistedAsync(UUID uuid, Consumer result) { if(MySQL.isClosed()) return; - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid))); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(uuid))); } @Override public void isWhitelistedAsync(String ip, Consumer result) { if(MySQL.isClosed()) return; - VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip))); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(ip))); } @Override public void alertsState(UUID uuid, Consumer result) { if(MySQL.isClosed()) return; - VPNExecutor.threadExecutor.execute(() -> { + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { try(ResultSet set = Query.prepare("select * from `alerts` where `uuid` = ? limit 1") .append(uuid.toString()).executeQuery()) { @@ -237,7 +237,7 @@ public class MySqlVPN implements VPNDatabase { } //No need to insert again of already enabled }); //Removing any uuid from the alerts table will disable alerts globally. - } else VPNExecutor.threadExecutor.execute(() -> + } else AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> Query.prepare("delete from `alerts` where `uuid` = ?") .append(uuid.toString()) .execute()); @@ -247,7 +247,7 @@ public class MySqlVPN implements VPNDatabase { public void clearResponses() { if(MySQL.isClosed()) return; - VPNExecutor.threadExecutor.execute(() -> Query.prepare("delete from `responses`").execute()); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> Query.prepare("delete from `responses`").execute()); } @Override diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java index f226fd0..00c8df5 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java @@ -7,15 +7,14 @@ import java.sql.*; import java.util.UUID; public class ExecutableStatement { - private PreparedStatement statement; + private final PreparedStatement statement; private int pos = 1; public ExecutableStatement(PreparedStatement statement) { this.statement = statement; } - @SneakyThrows - public Integer execute() { + public int execute() throws SQLException { try { return statement.executeUpdate(); } finally { @@ -23,34 +22,30 @@ public class ExecutableStatement { } } - @SneakyThrows - public void execute(ResultSetIterator iterator) { - ResultSet rs = null; - try { - rs = statement.executeQuery(); + public void execute(ResultSetIterator iterator) throws SQLException { + try(var rs = statement.executeQuery()) { while (rs.next()) iterator.next(rs); } finally { - MiscUtils.close(statement, rs); + MiscUtils.close(statement); } } - @SneakyThrows - public void executeSingle(ResultSetIterator iterator) { - ResultSet rs = null; + public int[] executeBatch() throws SQLException { + try { + return statement.executeBatch(); + } finally { + MiscUtils.close(statement); + } + } + + public ResultSet executeQuery() throws SQLException { try { - rs = statement.executeQuery(); - if (rs.next()) iterator.next(rs); - else iterator.next(null); + return statement.executeQuery(); } finally { - MiscUtils.close(statement, rs); + MiscUtils.close(statement); } } - @SneakyThrows - public ResultSet executeQuery() { - return statement.executeQuery(); - } - @SneakyThrows public ExecutableStatement append(Object obj) { statement.setObject(pos++, obj); @@ -135,4 +130,10 @@ public class ExecutableStatement { statement.setBytes(pos++, obj); return this; } + + @SneakyThrows + public ExecutableStatement addBatch() { + statement.addBatch(); + return this; + } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java index e8a1530..f1e366a 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java @@ -81,7 +81,7 @@ public class MySQL { } } - private static void backupOldDB(File dbFile, File dataFolder) { + public static void backupOldDB(File dbFile, File dataFolder) { if (dbFile.exists()) { try { // Optional: Make backup first @@ -91,7 +91,7 @@ public class MySQL { } else { AntiVPN.getInstance().getExecutor().log("Backup directory already exists"); } - File backupFile = new File(backupDir, "database.mv.db.backup_" + System.currentTimeMillis()); + File backupFile = new File(backupDir, dbFile.getName() + ".backup_" + System.currentTimeMillis()); Files.copy(dbFile.toPath(), backupFile.toPath()); // Actually delete the file diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java index 35cc5cf..7806524 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java @@ -14,7 +14,10 @@ public class Query { Query.conn = conn; } + @SuppressWarnings("SqlSourceToSinkFlow") public static ExecutableStatement prepare(@Language("SQL") String sql) throws SQLException { return new ExecutableStatement(conn.prepareStatement(sql)); } + + } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java index e99cd7c..4e2f911 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java @@ -1,7 +1,8 @@ package dev.brighten.antivpn.database.sql.utils; import java.sql.ResultSet; +import java.sql.SQLException; public interface ResultSetIterator { - void next(ResultSet rs) throws Exception; + void next(ResultSet rs) throws SQLException; } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java index 653b9a1..e13ce3c 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java @@ -1,15 +1,49 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database.version; +import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.database.local.H2VPN; +import dev.brighten.antivpn.database.local.version.First; +import dev.brighten.antivpn.database.local.version.Second; +import dev.brighten.antivpn.database.sql.utils.MySQL; +import java.io.File; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.Optional; public interface H2Version extends Version { - List versions = new ArrayList<>(); + H2Version[] versions = new H2Version[] {new First(), new Second()}; - static void registerVersions() { + default void backupDatabase() { + File dataFolder = new File(AntiVPN.getInstance().getPluginFolder(), "databases"); + if(!dataFolder.exists()) { + return; + } + + List files = new ArrayList<>(List.of(Optional.ofNullable(dataFolder.listFiles()).orElse(new File[0]))); + files.sort(Comparator.comparingLong(File::lastModified)); + + for (File file : files) { + MySQL.backupOldDB(file, dataFolder); + } } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java index 11b9217..b3b9876 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java @@ -1,7 +1,25 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database.version; +import java.sql.SQLException; + public interface Version { - void update(DB database) throws Exception; + void update(DB database) throws SQLException; int versionNumber(); boolean needsUpdate(DB database); } \ No newline at end of file diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/IpUtils.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/IpUtils.java new file mode 100644 index 0000000..bb982ec --- /dev/null +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/IpUtils.java @@ -0,0 +1,109 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.brighten.antivpn.utils; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Optional; + +public class IpUtils { + public static Optional getIpDecimal(String address) { + try { + InetAddress inet = InetAddress.getByName(address); + + if(inet instanceof Inet4Address) { + return Optional.of(BigDecimal.valueOf(ipv4ToLong(address))); + } return Optional.of(new BigDecimal(ipv6ToDecimalFormat(address))); + } catch(Exception e) { + return Optional.empty(); + } + } + + public static long ipv4ToLong(String address) { + String[] addrArray = address.split("\\."); + + long ipDecimal = 0; + + for (int i = 0; i < addrArray.length; i++) { + + int power = 3 - i; + ipDecimal += ((Integer.parseInt(addrArray[i]) % 256 * Math.pow(256, power))); + } + + return ipDecimal; + } + + public static String getIpv4(long ip) { + StringBuilder sb = new StringBuilder(15); + + for (int i = 0; i < 4; i++) { + sb.insert(0, ip & 0xff); + + if (i < 3) { + sb.insert(0, '.'); + } + + ip >>= 8; + } + + return sb.toString(); + } + + public static boolean isIpv4(BigDecimal ip) { + return ip.compareTo(BigDecimal.valueOf(4294967295L)) <= 0; + } + + public static boolean isIpv6(BigDecimal ip) { + return ip.compareTo(BigDecimal.valueOf(4294967295L)) > 0; + } + public static boolean isIpv4(String ip) { + return ip.matches("^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$"); + } + + public static boolean isNotIp(String ip) { + return !isIpv4(ip) && !isIpv6(ip); + } + + public static boolean isIpv6(String ip) { + return ip.matches("^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)$|^(([0-9a-fA-F]{1,4}:){0,6}([0-9a-fA-F]{1,4}|:))?(::([0-9a-fA-F]{1,4}:){0,5}([0-9a-fA-F]{1,4}|:))?$"); + } + + public static String getIpv4(BigDecimal ip) { + try { + return Inet4Address.getByAddress(ip.toBigInteger().toByteArray()).getHostAddress(); + } catch (UnknownHostException e) { + return "Error"; + } + } + + public static String getIpv6(BigDecimal ip) { + try { + return Inet6Address.getByAddress(ip.toBigInteger().toByteArray()).getHostAddress(); + } catch (UnknownHostException e) { + return "Error"; + } + } + + public static BigInteger ipv6ToDecimalFormat(String ipAddress) throws UnknownHostException { + return new BigInteger(1, Inet6Address.getByName(ipAddress).getAddress()); + } + +} diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java index 242379b..af4c80a 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -49,7 +49,7 @@ public class VelocityListener extends VPNExecutor { LegacyComponentSerializer.builder() .character('&') .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .countryVanillaKickReason() + .getCountryVanillaKickReason() .replace("%player%", event.getPlayer().getUsername()) .replace("%country%", instantResult.response().getCountryName()) .replace("%code%", instantResult.response().getCountryCode())))); @@ -59,7 +59,7 @@ public class VelocityListener extends VPNExecutor { event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder() .character('&') .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .getKickString() + .getKickMessage() .replace("%player%", event.getPlayer().getUsername()) .replace("%country%", instantResult.response().getCountryName()) .replace("%code%", instantResult.response().getCountryCode())))); @@ -97,14 +97,14 @@ public class VelocityListener extends VPNExecutor { //In case the user wants to run their own commands instead of using the // built in kicking - if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) { + if(AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { switch (checkResult.resultType()) { case DENIED_PROXY -> VelocityPlugin.INSTANCE.getServer().getScheduler() .buildTask(VelocityPlugin.INSTANCE.getPluginInstance(), () -> event.getPlayer().disconnect(LegacyComponentSerializer.builder() .character('&') .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .getKickString() + .getKickMessage() .replace("%player%", event.getPlayer().getUsername()) .replace("%country%", result.getCountryName()) .replace("%code%", result.getCountryCode())))) @@ -114,7 +114,7 @@ public class VelocityListener extends VPNExecutor { event.getPlayer().disconnect(LegacyComponentSerializer.builder() .character('&') .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .countryVanillaKickReason() + .getCountryVanillaKickReason() .replace("%player%", event.getPlayer().getUsername()) .replace("%country%", result.getCountryName()) .replace("%code%", result.getCountryCode())))) From 18d9bcea390b59c6a551fe6090ec6fb842d76899 Mon Sep 17 00:00:00 2001 From: Dawson Date: Mon, 5 Jan 2026 10:27:20 -0500 Subject: [PATCH 12/22] Implemented MongoDB version and cleared compile errors --- .../antivpn/bukkit/BukkitListener.java | 19 +- .../dev/brighten/antivpn/api/VPNConfig.java | 20 +- .../dev/brighten/antivpn/api/VPNExecutor.java | 18 +- .../command/impl/AllowlistCommand.java | 72 ++-- .../antivpn/database/DatabaseException.java | 23 ++ .../antivpn/database/VPNDatabase.java | 19 +- .../antivpn/database/local/H2VPN.java | 176 ++++++---- .../antivpn/database/local/version/First.java | 48 +-- .../database/local/version/Second.java | 31 +- .../antivpn/database/mongo/MongoVPN.java | 169 +++++---- .../database/mongo/version/MongoFirst.java | 52 +++ .../database/mongo/version/MongoSecond.java | 84 +++++ .../antivpn/database/sql/MySqlVPN.java | 330 +----------------- .../database/sql/version/MySQLFirst.java | 47 +++ .../antivpn/database/version/H2Version.java | 49 --- .../antivpn/database/version/Version.java | 17 +- .../dev/brighten/antivpn/utils/CIDRUtils.java | 14 +- .../antivpn/velocity/VelocityListener.java | 6 +- 18 files changed, 556 insertions(+), 638 deletions(-) create mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/database/DatabaseException.java create mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/version/MongoFirst.java create mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/version/MongoSecond.java create mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/database/sql/version/MySQLFirst.java delete mode 100644 Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java index 176e63a..2489ca6 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java @@ -92,7 +92,7 @@ public class BukkitListener extends VPNExecutor implements Listener { instantResult.response() ))); case DENIED_PROXY -> { - if(AntiVPN.getInstance().getVpnConfig().isAlertToStaff()) { + if(AntiVPN.getInstance().getVpnConfig().isAlertToSTaff()) { AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() .filter(APIPlayer::isAlertsEnabled) .forEach(pl -> @@ -116,14 +116,15 @@ public class BukkitListener extends VPNExecutor implements Listener { @EventHandler(priority = EventPriority.MONITOR) public void onJoin(final PlayerJoinEvent event) { AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId()) - .ifPresent(player -> AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { - if(AntiVPN.getInstance().getDatabase().getAlertsState(player.getUuid())) { - player.setAlertsEnabled(true); - player.sendMessage(AntiVPN.getInstance().getMessageHandler() - .getString("command-alerts-toggled") - .getFormattedMessage(new VpnString.Var<>("state", true))); - } - })); + .ifPresent(player -> AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> + AntiVPN.getInstance().getDatabase().alertsState(player.getUuid(), state -> { + if(state) { + player.setAlertsEnabled(true); + player.sendMessage(AntiVPN.getInstance().getMessageHandler() + .getString("command-alerts-toggled") + .getFormattedMessage(new VpnString.Var<>("state", true))); + } + }))); } @EventHandler diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java index c8c584b..86e84e0 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNConfig.java @@ -84,6 +84,7 @@ public class VPNConfig { private String password; @Getter private String ip; + @Getter private String alertMsg; @Getter private String countryVanillaKickReason; @@ -98,6 +99,7 @@ public class VPNConfig { @Getter private boolean databaseEnabled; private boolean useCredentials; + @Getter private boolean commandsEnabled; @Getter private boolean kickPlayers; @@ -113,30 +115,14 @@ public class VPNConfig { return cacheResults; } - /** - * Message to send staff on proxy detection. - * @return String - */ - public String alertMessage() { - return alertMsg; - } - /** * If true, staff will be alerted on proxy detection. * @return boolean */ - public boolean alertToStaff() { + public boolean isAlertToSTaff() { return alertToStaff; } - /** - * If true, will run {@link VPNConfig#commands()} on detect. If not, it will use vanilla kicking methods. - * @return boolean - */ - public boolean runCommands() { - return commandsEnabled; - } - /** * Commands to run on proxy detection. * @return List diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java index a2f8fe0..657293a 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -1,6 +1,7 @@ package dev.brighten.antivpn.api; import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.utils.CIDRUtils; import dev.brighten.antivpn.utils.StringUtil; import dev.brighten.antivpn.utils.Tuple; import dev.brighten.antivpn.utils.json.JSONException; @@ -9,6 +10,7 @@ import dev.brighten.antivpn.web.objects.VPNResponse; import lombok.Getter; import java.io.IOException; +import java.net.UnknownHostException; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executors; @@ -18,12 +20,12 @@ import java.util.logging.Level; public abstract class VPNExecutor { @Getter - private ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2); + private final ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2); @Getter private final Set whitelisted = Collections.synchronizedSet(new HashSet<>()); @Getter - private final Set whitelistedIps = Collections.synchronizedSet(new HashSet<>()); + private final Set whitelistedIps = Collections.synchronizedSet(new HashSet<>()); @Getter private final List> toKick = Collections.synchronizedList(new LinkedList<>()); @@ -67,14 +69,14 @@ public abstract class VPNExecutor { } public void handleKickingOfPlayer(CheckResult result, APIPlayer player) { - if (AntiVPN.getInstance().getVpnConfig().alertToStaff()) AntiVPN.getInstance().getPlayerExecutor() + if (AntiVPN.getInstance().getVpnConfig().isAlertToSTaff()) 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())))); + .getAlertMsg(), player, result.response())))); if(AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { switch (result.resultType()) { @@ -85,7 +87,7 @@ public abstract class VPNExecutor { } } - if(!AntiVPN.getInstance().getVpnConfig().runCommands()) return; + if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) return; switch (result.resultType()) { case DENIED_PROXY -> { @@ -114,7 +116,11 @@ public abstract class VPNExecutor { if(AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) { return AntiVPN.getInstance().getDatabase().isWhitelisted(ip); } - return whitelistedIps.contains(ip); + try { + return whitelistedIps.contains(new CIDRUtils(ip + "/32")); + } catch (UnknownHostException e) { + throw new RuntimeException(e); + } } public CompletableFuture checkIp(String ip) { diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java index 30c308f..ce99f79 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java @@ -76,24 +76,24 @@ public class AllowlistCommand extends Command { if(!databaseEnabled) { return switch (args[0].toLowerCase()) { case "add", "insert" -> { - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(cidrUtils.getCidr()); + AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(cidrUtils); yield String.format("&aAdded &6%s &ato exemption allowlist.", cidrUtils.getCidr()); } case "remove", "delete" -> { - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(cidrUtils.getCidr()); + AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(cidrUtils); yield String.format("&cRemoved &%s &cfrom the exemption allowlist.", cidrUtils.getCidr()); } default -> "&c\"" + args[0] + "\" is not a valid argument"; }; } else return switch (args[0].toLowerCase()) { case "add", "insert" -> { - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(cidrUtils.getCidr()); - AntiVPN.getInstance().getDatabase().addWhitelist(cidrUtils.getCidr()); + AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(cidrUtils); + AntiVPN.getInstance().getDatabase().addWhitelist(cidrUtils); yield String.format("&aAdded &6%s &ato exemption allowlist.", cidrUtils.getCidr()); } case "remove", "delete" -> { - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(cidrUtils.getCidr()); - AntiVPN.getInstance().getDatabase().removeWhitelist(cidrUtils.getCidr()); + AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(cidrUtils); + AntiVPN.getInstance().getDatabase().removeWhitelist(cidrUtils); yield String.format("&cRemoved &6%s &cfrom the exemption allowlist.", cidrUtils.getCidr()); } default -> "&c\"" + args[0] + "\" is not a valid argument"; @@ -101,30 +101,42 @@ public class AllowlistCommand extends Command { } if(MiscUtils.isIpv4(args[1])) { if(!databaseEnabled) { - return switch(args[0].toLowerCase()) { - case "add", "insert" -> { - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(args[1] + "/32"); - AntiVPN.getInstance().getDatabase().addWhitelist(args[1] + "/32"); - yield String.format("&aAdded &6%s &ato the exemption allowlist.", args[1] + "/32"); - } - case "remove", "delete" -> { - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(args[1] + "/32"); - AntiVPN.getInstance().getDatabase().removeWhitelist(args[1] + "/32"); - yield String.format("&cRemoved &6%s &cfrom the exemption allowlist.", args[1] + "/32"); - } - default -> "&c\"" + args[0] + "\" is not a valid argument"; - }; - } else return switch (args[0].toLowerCase()) { - case "add", "insert" -> { - AntiVPN.getInstance().getDatabase().addWhitelist(args[1] + "/32"); - yield String.format("&aAdded &6%s &a to the exemption allowlist.", args[1] + "/32"); - } - case "remove", "delete" -> { - AntiVPN.getInstance().getDatabase().removeWhitelist(args[1] + "/32"); - yield String.format("&cRemoved &6%s &c from the exemption allowlist.", args[1] + "/32"); - } - default -> "&c\"" + args[0] + "\" is not a valid argument"; - }; + try { + return switch(args[0].toLowerCase()) { + case "add", "insert" -> { + AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(new CIDRUtils(args[1] + "/32")); + AntiVPN.getInstance().getDatabase().addWhitelist(new CIDRUtils(args[1] + "/32")); + yield String.format("&aAdded &6%s &ato the exemption allowlist.", args[1] + "/32"); + } + case "remove", "delete" -> { + AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(new CIDRUtils(args[1] + "/32")); + AntiVPN.getInstance().getDatabase().removeWhitelist(new CIDRUtils(args[1] + "/32")); + yield String.format("&cRemoved &6%s &cfrom the exemption allowlist.", args[1] + "/32"); + } + default -> "&c\"" + args[0] + "\" is not a valid argument"; + }; + } catch (UnknownHostException e) { + AntiVPN.getInstance().getExecutor().logException("Invalid IP format for allowlist command", e); + return "&cInvalid IP format for allowlist command"; + } + } else { + try { + return switch (args[0].toLowerCase()) { + case "add", "insert" -> { + AntiVPN.getInstance().getDatabase().addWhitelist(new CIDRUtils(args[1] + "/32")); + yield String.format("&aAdded &6%s &a to the exemption allowlist.", args[1] + "/32"); + } + case "remove", "delete" -> { + AntiVPN.getInstance().getDatabase().removeWhitelist(new CIDRUtils(args[1] + "/32")); + yield String.format("&cRemoved &6%s &c from the exemption allowlist.", args[1] + "/32"); + } + default -> "&c\"" + args[0] + "\" is not a valid argument"; + }; + } catch (UnknownHostException e) { + AntiVPN.getInstance().getExecutor().logException("Invalid IP format for allowlist command", e); + return "&cInvalid IP format for allowlist command"; + } + } } else { UUID uuid; try { diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/DatabaseException.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/DatabaseException.java new file mode 100644 index 0000000..53c62ef --- /dev/null +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/DatabaseException.java @@ -0,0 +1,23 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.brighten.antivpn.database; + +public class DatabaseException extends RuntimeException { + public DatabaseException(String message, Throwable e) { + super(message, e); + } +} diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java index 1a4fe30..3ad1ee4 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java @@ -1,5 +1,6 @@ package dev.brighten.antivpn.database; +import dev.brighten.antivpn.utils.CIDRUtils; import dev.brighten.antivpn.web.objects.VPNResponse; import java.util.List; @@ -18,19 +19,19 @@ public interface VPNDatabase { boolean isWhitelisted(String ip); - void setWhitelisted(UUID uuid, boolean whitelisted); + boolean isWhitelisted(CIDRUtils cidr); - void setWhitelisted(String ip, boolean whitelisted); + void addWhitelist(UUID uuid); + + void removeWhitelist(UUID uuid); + + void addWhitelist(CIDRUtils cidr); + + void removeWhitelist(CIDRUtils cidr); List getAllWhitelisted(); - List getAllWhitelistedIps(); - - void getStoredResponseAsync(String ip, Consumer> result); - - void isWhitelistedAsync(UUID uuid, Consumer result); - - void isWhitelistedAsync(String ip, Consumer result); + List getAllWhitelistedIps(); void alertsState(UUID uuid, Consumer result); diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java index 6498a22..990cc49 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java @@ -19,22 +19,21 @@ package dev.brighten.antivpn.database.local; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import dev.brighten.antivpn.AntiVPN; -import dev.brighten.antivpn.api.VPNExecutor; import dev.brighten.antivpn.database.VPNDatabase; import dev.brighten.antivpn.database.sql.utils.MySQL; import dev.brighten.antivpn.database.sql.utils.Query; -import dev.brighten.antivpn.database.version.H2Version; +import dev.brighten.antivpn.database.version.Version; +import dev.brighten.antivpn.utils.CIDRUtils; import dev.brighten.antivpn.web.objects.VPNResponse; import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; +import java.io.File; +import java.math.BigInteger; +import java.net.UnknownHostException; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -103,18 +102,20 @@ public class H2VPN implements VPNDatabase { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - cachedResponses.put(toCache.getIp(), toCache); - - try { - Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`," - + "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)") - .append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName()) - .append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone()) - .append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy()) - .append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis())) - .append(toCache.getLatitude()).append(toCache.getLongitude()).execute(); - } catch(SQLException e) { + if(AntiVPN.getInstance().getVpnConfig().cachedResults()) { + cachedResponses.put(toCache.getIp(), toCache); + try { + Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`," + + "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)") + .append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName()) + .append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone()) + .append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy()) + .append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis())) + .append(toCache.getLatitude()).append(toCache.getLongitude()).execute(); + } catch(SQLException e) { + AntiVPN.getInstance().getExecutor().logException("Could not cache response for IP: " + toCache.getIp(), e); + } } } @@ -146,52 +147,76 @@ public class H2VPN implements VPNDatabase { @SneakyThrows @Override public boolean isWhitelisted(String ip) { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) - return false; - ResultSet set = Query.prepare("select `ip` from `whitelisted-ips` where `ip` = ? limit 1") - .append(ip).executeQuery(); - - - return set != null && set.next() && set.getString("ip") != null; + return isWhitelisted(new CIDRUtils(ip + "/32")); } @Override - public void setWhitelisted(UUID uuid, boolean whitelisted) { + public boolean isWhitelisted(CIDRUtils cidr) { + if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + return false; + + BigInteger start = cidr.getStartIpInt(); + BigInteger end = cidr.getEndIpInt(); + + try(var result = Query.prepare("SELECT * FROM `whitelisted-ranges` WHERE ip_start <= ? AND ip_end >= ?") + .append(start).append(end).executeQuery()) { + + return result.next(); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("Could not check whitelist for cidr '" + cidr + "' due to SQL error.", e); + } + return false; + } + + @Override + public void addWhitelist(UUID uuid) { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; try { - if (whitelisted) { - if (!isWhitelisted(uuid)) { - Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString()).execute(); - } - AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); - } else { - Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString()).execute(); - AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); - } + Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString()).execute(); + AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); } catch (SQLException e) { - AntiVPN.getInstance().getExecutor().logException("Could not set whitelist for uuid '" + uuid + "' due to SQL error.", e); + AntiVPN.getInstance().getExecutor().logException("Could not add uuid '" + uuid + "' to whitelist due to SQL error.", e); } } @Override - public void setWhitelisted(String ip, boolean whitelisted) { + public void removeWhitelist(UUID uuid) { + if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + return; + try { + Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString()).execute(); + AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("Could not remove uuid '" + uuid + "' from whitelist due to SQL error.", e); + } + } + + @Override + public void addWhitelist(CIDRUtils cidr) { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; try { - if(whitelisted) { - if(!isWhitelisted(ip)) { - Query.prepare("insert into `whitelisted-ips` (`ip`) values (?)").append(ip).execute(); - } - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip); - } else { - Query.prepare("delete from `whitelisted-ips` where `ip` = ?").append(ip).execute(); - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip); - } + Query.prepare("insert into `whitelisted-ranges` (`cidr_string`, `ip_start`, `ip_end`) values (?, ?, ?)") + .append(cidr.toString()).append(cidr.getStartIpInt()).append(cidr.getEndIpInt()).execute(); + } catch (SQLException e) { - AntiVPN.getInstance().getExecutor().logException("Could not set whitelist for ip '" + ip + "' due to SQL error.", e); + AntiVPN.getInstance().getExecutor().logException("Could not add cidr '" + cidr + "' to whitelist due to SQL error.", e); + } + } + + @Override + public void removeWhitelist(CIDRUtils cidr) { + if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + return; + + try { + Query.prepare("delete from `whitelisted-ranges` where `cidr_string` = ?").append(cidr.toString()).execute(); + + } catch (SQLException e) { + AntiVPN.getInstance().getExecutor().logException("Could not remove cidr '" + cidr + "' from whitelist due to SQL error.", e); } } @@ -199,6 +224,9 @@ public class H2VPN implements VPNDatabase { public List getAllWhitelisted() { List uuids = new ArrayList<>(); + if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + return uuids; + try { if(!MySQL.isClosed()) Query.prepare("select uuid from `whitelisted`") .execute(set -> uuids.add(UUID.fromString(set.getString("uuid")))); @@ -210,12 +238,20 @@ public class H2VPN implements VPNDatabase { } @Override - public List getAllWhitelistedIps() { - List ips = new ArrayList<>(); + public List getAllWhitelistedIps() { + List ips = new ArrayList<>(); + if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) + return ips; try { - if(!MySQL.isClosed()) Query.prepare("select `ip` from `whitelisted-ips`") - .execute(set -> ips.add(set.getString("ip"))); + if(!MySQL.isClosed()) Query.prepare("select `cidr_string`, `ip_start`, `ip_end` from `whitelisted-ranges`") + .execute(set -> { + try { + ips.add(new CIDRUtils(set.getString("cidr_string"))); + } catch (UnknownHostException e) { + AntiVPN.getInstance().getExecutor().logException("Could not format ip " + set.getString("cidr_string") + " into a CIDR!", e); + } + }); } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("Could not get all whitelisted ips due to SQL error.", e); } @@ -223,27 +259,6 @@ public class H2VPN implements VPNDatabase { return ips; } - @Override - public void getStoredResponseAsync(String ip, Consumer> result) { - if(MySQL.isClosed()) return; - - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(getStoredResponse(ip))); - } - - @Override - public void isWhitelistedAsync(UUID uuid, Consumer result) { - if(MySQL.isClosed()) return; - - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(uuid))); - } - - @Override - public void isWhitelistedAsync(String ip, Consumer result) { - if(MySQL.isClosed()) return; - - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(ip))); - } - @Override public void alertsState(UUID uuid, Consumer result) { if(MySQL.isClosed()) return; @@ -306,7 +321,7 @@ public class H2VPN implements VPNDatabase { AntiVPN.getInstance().getExecutor().log("Initializing H2..."); MySQL.initH2(); try { - for (H2Version version : H2Version.versions) { + for (Version version : Version.h2Versions) { if(version.needsUpdate(this)) { version.update(this); } @@ -327,4 +342,19 @@ public class H2VPN implements VPNDatabase { MySQL.shutdown(); } + + public void backupDatabase() { + File dataFolder = new File(AntiVPN.getInstance().getPluginFolder(), "databases"); + + if(!dataFolder.exists()) { + return; + } + + List files = new ArrayList<>(List.of(Optional.ofNullable(dataFolder.listFiles()).orElse(new File[0]))); + files.sort(Comparator.comparingLong(File::lastModified)); + + for (File file : files) { + MySQL.backupOldDB(file, dataFolder); + } + } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java index e2fa481..3b88541 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java @@ -17,33 +17,41 @@ package dev.brighten.antivpn.database.local.version; import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.DatabaseException; +import dev.brighten.antivpn.database.VPNDatabase; import dev.brighten.antivpn.database.local.H2VPN; import dev.brighten.antivpn.database.sql.utils.Query; -import dev.brighten.antivpn.database.version.H2Version; +import dev.brighten.antivpn.database.version.Version; import java.sql.ResultSet; import java.sql.SQLException; -public class First implements H2Version { +public class First implements Version { @Override - public void update(H2VPN database) throws SQLException { - backupDatabase(); - Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute(); - Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute(); - Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12)," - + "`countryName` text, `countryCode` varchar(10), `city` text, `timeZone` varchar(64), " - + "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp," - + "`latitude` double, `longitude` double)").execute(); - Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute(); - Query.prepare("create table if not exists `database_version` (`version` int)").execute(); - Query.prepare("insert into `database_version` (`version`) values (?)").append(versionNumber()).execute(); + public void update(VPNDatabase database) throws DatabaseException { + if(database instanceof H2VPN h2VPN) { + h2VPN.backupDatabase(); + } + try { + Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute(); + Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute(); + Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12)," + + "`countryName` text, `countryCode` varchar(10), `city` text, `timeZone` varchar(64), " + + "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp," + + "`latitude` double, `longitude` double)").execute(); + Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute(); + Query.prepare("create table if not exists `database_version` (`version` int)").execute(); + Query.prepare("insert into `database_version` (`version`) values (?)").append(versionNumber()).execute(); - AntiVPN.getInstance().getExecutor().log("Creating indexes..."); - Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)").execute(); - Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)").execute(); - Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)").execute(); - Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)").execute(); - Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute(); + AntiVPN.getInstance().getExecutor().log("Creating indexes..."); + Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)").execute(); + Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)").execute(); + Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)").execute(); + Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)").execute(); + Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute(); + } catch (SQLException e) { + throw new DatabaseException("Failed to update database", e); + } } @Override @@ -52,7 +60,7 @@ public class First implements H2Version { } @Override - public boolean needsUpdate(H2VPN database) { + public boolean needsUpdate(VPNDatabase database) { try(ResultSet set = Query.prepare("select * from `database_version` where version = 0").executeQuery()) { return set.getFetchSize() == 0; } catch (SQLException e) { diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java index 348ee39..2e2ddc4 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java @@ -17,11 +17,12 @@ package dev.brighten.antivpn.database.local.version; import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.DatabaseException; +import dev.brighten.antivpn.database.VPNDatabase; import dev.brighten.antivpn.database.local.H2VPN; import dev.brighten.antivpn.database.sql.utils.Query; -import dev.brighten.antivpn.database.version.H2Version; +import dev.brighten.antivpn.database.version.Version; import dev.brighten.antivpn.utils.CIDRUtils; -import dev.brighten.antivpn.utils.IpUtils; import java.net.UnknownHostException; import java.sql.ResultSet; @@ -29,16 +30,20 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -public class Second implements H2Version { +public class Second implements Version { @Override - public void update(H2VPN database) throws SQLException { - backupDatabase(); + public void update(VPNDatabase database) throws DatabaseException { + if(database instanceof H2VPN h2VPN) { + h2VPN.backupDatabase(); + } List whitelistedIps = new ArrayList<>(); try (var set = Query.prepare("SELECT * FROM `whitelisted-ips`").executeQuery()) { while (set.next()) { whitelistedIps.add(set.getString("ip")); } + } catch (SQLException e) { + throw new DatabaseException("Could not get whitelisted ips from database!", e); } try { @@ -60,9 +65,9 @@ public class Second implements H2Version { var insertStatement = Query.prepare("INSERT INTO `whitelisted-ranges` (`cidr_string`, `ip_start`, `ip_end`) VALUES (?, ?, ?)"); for (CIDRUtils cidr : cidrs) { insertStatement = insertStatement - .append(cidr.toString()). - append(IpUtils.getIpDecimal(cidr.getStartAddress().getHostAddress()).orElseThrow()) - .append(IpUtils.getIpDecimal(cidr.getEndAddress().getHostAddress()).orElseThrow()) + .append(cidr.toString()) + .append(cidr.getStartIpInt()) + .append(cidr.getEndIpInt()) .addBatch(); } @@ -79,8 +84,12 @@ public class Second implements H2Version { Query.prepare("INSERT INTO `database_version` (`version`) VALUES (?)").append(versionNumber()).execute(); } catch (Throwable e) { AntiVPN.getInstance().getExecutor().log("Failed to update database to version 1: " + e.getMessage()); - rollback(whitelistedIps); - throw e; + try { + rollback(whitelistedIps); + } catch (SQLException ex) { + throw new DatabaseException("Failed to rollback database!", e); + } + throw new DatabaseException("Failed to update to version one, rolling back database!", e); } } @@ -112,7 +121,7 @@ public class Second implements H2Version { } @Override - public boolean needsUpdate(H2VPN database) { + public boolean needsUpdate(VPNDatabase database) { try (ResultSet set = Query.prepare("select * from `database_version` where version = 1").executeQuery()) { return set.getFetchSize() == 0; } catch (SQLException e) { diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java index c317fd8..daa23f2 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java @@ -8,23 +8,28 @@ import com.mongodb.client.MongoClients; 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.database.version.Version; +import dev.brighten.antivpn.utils.CIDRUtils; import dev.brighten.antivpn.web.objects.VPNResponse; import org.bson.Document; import org.bson.conversions.Bson; +import org.bson.types.Decimal128; +import java.math.BigDecimal; +import java.net.UnknownHostException; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; public class MongoVPN implements VPNDatabase { - private MongoCollection settingsDocument, cacheDocument; + public MongoCollection settingsDocument; + MongoCollection cacheDocument; private MongoClient client; + public MongoDatabase antivpnDatabase; private final Cache cachedResponses = Caffeine.newBuilder() .expireAfterWrite(20, TimeUnit.MINUTES) @@ -83,29 +88,31 @@ public class MongoVPN implements VPNDatabase { @Override public void cacheResponse(VPNResponse toCache) { - Document rdoc = new Document("ip", toCache.getIp()); + if(AntiVPN.getInstance().getVpnConfig().cachedResults()) { + Document rdoc = new Document("ip", toCache.getIp()); - rdoc.put("asn", toCache.getAsn()); - rdoc.put("countryName", toCache.getCountryName()); - rdoc.put("countryCode", toCache.getCountryCode()); - rdoc.put("city", toCache.getCity()); - rdoc.put("isp", toCache.getIsp()); - rdoc.put("method", toCache.getMethod()); - rdoc.put("timeZone", toCache.getTimeZone()); - rdoc.put("proxy", toCache.isProxy()); - rdoc.put("cached", toCache.isCached()); - rdoc.put("success", toCache.isSuccess()); - rdoc.put("latitude", toCache.getLatitude()); - rdoc.put("longitude", toCache.getLongitude()); - rdoc.put("lastAccess", System.currentTimeMillis()); + rdoc.put("asn", toCache.getAsn()); + rdoc.put("countryName", toCache.getCountryName()); + rdoc.put("countryCode", toCache.getCountryCode()); + rdoc.put("city", toCache.getCity()); + rdoc.put("isp", toCache.getIsp()); + rdoc.put("method", toCache.getMethod()); + rdoc.put("timeZone", toCache.getTimeZone()); + rdoc.put("proxy", toCache.isProxy()); + rdoc.put("cached", toCache.isCached()); + rdoc.put("success", toCache.isSuccess()); + rdoc.put("latitude", toCache.getLatitude()); + rdoc.put("longitude", toCache.getLongitude()); + rdoc.put("lastAccess", System.currentTimeMillis()); - cachedResponses.put(toCache.getIp(), toCache); + cachedResponses.put(toCache.getIp(), toCache); - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { - Bson update = new Document("$set", rdoc); - cacheDocument.updateOne(Filters.eq("ip", toCache.getIp()), update, - new UpdateOptions().upsert(true)); - }); + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { + Bson update = new Document("$set", rdoc); + cacheDocument.updateOne(Filters.eq("ip", toCache.getIp()), update, + new UpdateOptions().upsert(true)); + }); + } } @Override @@ -122,41 +129,55 @@ public class MongoVPN implements VPNDatabase { @Override public boolean isWhitelisted(String ip) { - return settingsDocument - .find(Filters.and(Filters.eq("setting", "whitelist"), - Filters.eq("ip", ip))).first() != null; - } - - @Override - public void setWhitelisted(UUID uuid, boolean whitelisted) { - if(whitelisted) { - Document wdoc = new Document("setting", "whitelist"); - wdoc.put("uuid", uuid.toString()); - AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> settingsDocument.insertOne(wdoc)); - } else { - AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> settingsDocument.deleteMany(Filters - .and( - Filters.eq("setting", "whitelist"), - Filters.eq("uuid", uuid.toString())))); + try { + return isWhitelisted(new CIDRUtils(ip + "/32")); + } catch (UnknownHostException e) { + AntiVPN.getInstance().getExecutor().log("Failed to check whitelist for IP: " + ip, e); + return false; } } @Override - public void setWhitelisted(String ip, boolean whitelisted) { - if(whitelisted) { - Document wdoc = new Document("setting", "whitelist").append("ip", ip); + public boolean isWhitelisted(CIDRUtils cidr) { + var start = new Decimal128(new BigDecimal(cidr.getStartIpInt())); + var end = new Decimal128(new BigDecimal(cidr.getEndIpInt())); + return settingsDocument.find(Filters.and(Filters.eq("setting", "whitelisted"), + Filters.lte("ip_start", start), Filters.gte("ip_end", end))).first() != null; + } - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip); - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> settingsDocument.insertOne(wdoc)); - } else { - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip); - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> settingsDocument.deleteMany(Filters - .and( - Filters.eq("setting", "whitelist"), - Filters.eq("ip", ip)))); - } + @Override + public void addWhitelist(UUID uuid) { + Document wdoc = new Document("setting", "whitelist"); + wdoc.put("uuid", uuid.toString()); + AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); + settingsDocument.insertOne(wdoc); + } + + @Override + public void removeWhitelist(UUID uuid) { + AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); + settingsDocument.deleteMany(Filters + .and( + Filters.eq("setting", "whitelist"), + Filters.eq("uuid", uuid.toString()))); + } + + @Override + public void addWhitelist(CIDRUtils cidr) { + Document doc = new Document("setting", "whitelist"); + doc.append("ip_start", new Decimal128(new BigDecimal(cidr.getStartIpInt()))); + doc.append("ip_end", new Decimal128(new BigDecimal(cidr.getEndIpInt()))); + doc.append("cidr_string", cidr.toString()); + + settingsDocument.insertOne(doc); + } + + @Override + public void removeWhitelist(CIDRUtils cidr) { + settingsDocument.deleteMany(Filters + .and( + Filters.eq("setting", "whitelist"), + Filters.eq("cidr_string", cidr.toString()))); } @Override @@ -169,29 +190,20 @@ public class MongoVPN implements VPNDatabase { } @Override - public List getAllWhitelistedIps() { - List ips = new ArrayList<>(); + public List getAllWhitelistedIps() { + List ips = new ArrayList<>(); settingsDocument.find(Filters.and(Filters.eq("setting", "whitelist"), - Filters.exists("ip"))) - .forEach((Consumer) doc -> ips.add(doc.getString("ip"))); + Filters.exists("ip"))).forEach((Consumer) doc -> { + try { + var cidr = new CIDRUtils(doc.getString("cidr_string")); + ips.add(cidr); + } catch (UnknownHostException e) { + AntiVPN.getInstance().getExecutor().logException("Could not format ip " + doc.getString("cidr_string") + " into a CIDR!", e); + } + }); return ips; } - @Override - public void getStoredResponseAsync(String ip, Consumer> result) { - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(getStoredResponse(ip))); - } - - @Override - public void isWhitelistedAsync(UUID uuid, Consumer result) { - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(uuid))); - } - - @Override - public void isWhitelistedAsync(String ip, Consumer result) { - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(ip))); - } - @Override public void alertsState(UUID uuid, Consumer result) { AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(settingsDocument @@ -241,14 +253,17 @@ public class MongoVPN implements VPNDatabase { client = MongoClients.create(settingsBld.build()); } - MongoDatabase antivpnDatabase = client.getDatabase(AntiVPN.getInstance().getVpnConfig().getDatabaseName()); + antivpnDatabase = client.getDatabase(AntiVPN.getInstance().getVpnConfig().getDatabaseName()); settingsDocument = antivpnDatabase.getCollection("settings"); - if(settingsDocument.listIndexes().first() == null) { - AntiVPN.getInstance().getExecutor().log("Created index for settings collection!"); - settingsDocument.createIndex(Indexes.ascending("ip")); - } + cacheDocument = antivpnDatabase.getCollection("cache"); + + for (Version mongoDbVersion : Version.mongoDbVersions) { + if(mongoDbVersion.needsUpdate(this)) { + mongoDbVersion.update(this); + } + } } @Override diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/version/MongoFirst.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/version/MongoFirst.java new file mode 100644 index 0000000..8bf7203 --- /dev/null +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/version/MongoFirst.java @@ -0,0 +1,52 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.brighten.antivpn.database.mongo.version; + +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Indexes; +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.DatabaseException; +import dev.brighten.antivpn.database.mongo.MongoVPN; +import dev.brighten.antivpn.database.version.Version; +import org.bson.Document; + +public class MongoFirst implements Version { + + @Override + public void update(MongoVPN database) throws DatabaseException { + if(database.settingsDocument.listIndexes().first() == null) { + AntiVPN.getInstance().getExecutor().log("Created index for settings collection!"); + database.settingsDocument.createIndex(Indexes.ascending("ip")); + database.settingsDocument.createIndex(Indexes.ascending("setting")); + } + var versionCollect = database.antivpnDatabase.getCollection("version"); + + versionCollect.insertOne(new Document("version", versionNumber())); + } + + @Override + public int versionNumber() { + return 0; + } + + @Override + public boolean needsUpdate(MongoVPN database) { + var versionCollect = database.antivpnDatabase.getCollection("version"); + + return versionCollect.find(Filters.eq("version", versionNumber())).first() == null; + } +} diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/version/MongoSecond.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/version/MongoSecond.java new file mode 100644 index 0000000..c6faccc --- /dev/null +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/version/MongoSecond.java @@ -0,0 +1,84 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.brighten.antivpn.database.mongo.version; + +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Indexes; +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.DatabaseException; +import dev.brighten.antivpn.database.mongo.MongoVPN; +import dev.brighten.antivpn.database.version.Version; +import dev.brighten.antivpn.utils.CIDRUtils; +import org.bson.Document; +import org.bson.types.Decimal128; + +import java.math.BigDecimal; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +public class MongoSecond implements Version { + @Override + public void update(MongoVPN database) throws DatabaseException { + List backup = new ArrayList<>(); + database.settingsDocument.find(Filters.and(Filters.eq("setting", "whitelist"), + Filters.exists("ip"))) + .forEach((Consumer) doc -> { + backup.add(new Document(doc)); + + String ip = doc.getString("ip"); + + try { + var cidr = new CIDRUtils(ip + "/32"); + + doc.append("ip_start", new Decimal128(new BigDecimal(cidr.getStartIpInt()))); + doc.append("ip_end", new Decimal128(new BigDecimal(cidr.getEndIpInt()))); + doc.append("cidr_string", cidr.toString()); + doc.remove("ip"); + + database.settingsDocument.replaceOne(Filters.eq("_id", doc.getObjectId("_id")), doc); + } catch (UnknownHostException e) { + rollback(backup, database); + throw new RuntimeException(e); + } + }); + + database.settingsDocument.createIndex(Indexes.compoundIndex(Indexes.ascending("ip_start"), Indexes.ascending("ip_end"))); + database.settingsDocument.createIndex(Indexes.ascending("cidr_string")); + var versionCollect = database.antivpnDatabase.getCollection("version"); + versionCollect.insertOne(new Document("version", versionNumber())); + } + + private void rollback(List toRollback, MongoVPN database) { + AntiVPN.getInstance().getExecutor().log("Rolling back to version 0..."); + toRollback.forEach(doc -> database.settingsDocument.replaceOne(Filters.eq("_id", doc.getObjectId("_id")), doc)); + toRollback.clear(); + } + + @Override + public int versionNumber() { + return 1; + } + + @Override + public boolean needsUpdate(MongoVPN database) { + var versionCollect = database.antivpnDatabase.getCollection("version"); + + return versionCollect.find(Filters.eq("version", versionNumber())).first() == null; + } +} diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java index e51654f..f7aa25e 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java @@ -1,32 +1,13 @@ package dev.brighten.antivpn.database.sql; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; import dev.brighten.antivpn.AntiVPN; -import dev.brighten.antivpn.api.VPNExecutor; -import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.local.H2VPN; import dev.brighten.antivpn.database.sql.utils.MySQL; -import dev.brighten.antivpn.database.sql.utils.Query; -import dev.brighten.antivpn.web.objects.VPNResponse; -import lombok.SneakyThrows; +import dev.brighten.antivpn.database.version.Version; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; - -public class MySqlVPN implements VPNDatabase { - - private final Cache cachedResponses = Caffeine.newBuilder() - .expireAfterWrite(20, TimeUnit.MINUTES) - .maximumSize(4000) - .build(); +public class MySqlVPN extends H2VPN { public MySqlVPN() { AntiVPN.getInstance().getExecutor().getThreadExecutor().scheduleAtFixedRate(() -> { @@ -44,212 +25,6 @@ public class MySqlVPN implements VPNDatabase { }, 2, 30, TimeUnit.SECONDS); } - @Override - public Optional getStoredResponse(String ip) { - if (isDisabled()) - return Optional.empty(); - - VPNResponse response = cachedResponses.get(ip, ip2 -> { - try(ResultSet rs = Query.prepare("select * from `responses` where `ip` = ? limit 1").append(ip) - .executeQuery()) { - if (rs != null && rs.next()) { - VPNResponse responseFromDoc = new VPNResponse(rs.getString("asn"), - rs.getString("ip"), - rs.getString("countryName"), rs.getString("countryCode"), - rs.getString("city"), rs.getString("timeZone"), - rs.getString("method"), rs.getString("isp"), "N/A", - rs.getBoolean("proxy"), rs.getBoolean("cached"), true, - rs.getDouble("latitude"), rs.getDouble("longitude"), - rs.getTimestamp("inserted").getTime(), -1); - - if(System.currentTimeMillis() - responseFromDoc.getLastAccess() > TimeUnit.HOURS.toMillis(1)) { - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> deleteResponse(ip)); - return null; - } - - return responseFromDoc; - } - } catch (SQLException e) { - AntiVPN.getInstance().getExecutor() - .logException("Failed to get response from cache due to SQL error for: " + ip, e); - } - return null; - }); - - return Optional.ofNullable(response); - } - - /* - * Query. - * prepare("create table if not exists `responses` (`ip` varchar(45) not null, " - * + - * "`countryName` varchar(64), `countryCode` varchar(10), `city` varchar(64), `timeZone` varchar(64), " - * + - * "`method` varchar(32), `isp` varchar(32), `proxy` boolean, `cached` boolean " - * + "`latitude` double, `longitude` double)"); - */ - @Override - public void cacheResponse(VPNResponse toCache) { - if (isDisabled()) - return; - - cachedResponses.put(toCache.getIp(), toCache); - - Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`," - + "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)") - .append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName()) - .append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone()) - .append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy()) - .append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis())) - .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 (isDisabled()) - return false; - try(ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1") - .append(uuid.toString()).executeQuery()) { - return set != null && set.next() && set.getString("uuid") != null; - } - } - - @SneakyThrows - @Override - public boolean isWhitelisted(String ip) { - if (isDisabled()) - return false; - try(ResultSet set = Query.prepare("select `ip` from `whitelisted-ips` where `ip` = ? limit 1") - .append(ip).executeQuery()) { - return set != null && set.next() && set.getString("ip") != null; - } - } - - @Override - public void setWhitelisted(UUID uuid, boolean whitelisted) { - if (isDisabled()) - return; - - if (whitelisted) { - if (!isWhitelisted(uuid)) { - Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString()).execute(); - } - AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); - } else { - Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString()).execute(); - AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); - } - } - - @Override - public void setWhitelisted(String ip, boolean whitelisted) { - if (isDisabled()) - return; - - if(whitelisted) { - if(!isWhitelisted(ip)) { - Query.prepare("insert into `whitelisted-ips` (`ip`) values (?)").append(ip).execute(); - } - AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(ip); - } else { - Query.prepare("delete from `whitelisted-ips` where `ip` = ?").append(ip).execute(); - AntiVPN.getInstance().getExecutor().getWhitelistedIps().remove(ip); - } - } - - @Override - public List getAllWhitelisted() { - List uuids = new ArrayList<>(); - - if(!MySQL.isClosed()) Query.prepare("select uuid from `whitelisted`") - .execute(set -> uuids.add(UUID.fromString(set.getString("uuid")))); - - return uuids; - } - - @Override - public List getAllWhitelistedIps() { - List ips = new ArrayList<>(); - - if(!MySQL.isClosed()) Query.prepare("select `ip` from `whitelisted-ips`") - .execute(set -> ips.add(set.getString("ip"))); - - return ips; - } - - @Override - public void getStoredResponseAsync(String ip, Consumer> result) { - if(MySQL.isClosed()) return; - - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(getStoredResponse(ip))); - } - - @Override - public void isWhitelistedAsync(UUID uuid, Consumer result) { - if(MySQL.isClosed()) return; - - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(uuid))); - } - - @Override - public void isWhitelistedAsync(String ip, Consumer result) { - if(MySQL.isClosed()) return; - - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> result.accept(isWhitelisted(ip))); - } - - @Override - public void alertsState(UUID uuid, Consumer result) { - if(MySQL.isClosed()) return; - - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { - - try(ResultSet set = Query.prepare("select * from `alerts` where `uuid` = ? limit 1") - .append(uuid.toString()).executeQuery()) { - result.accept(set != null && set.next() && set.getString("uuid") != null); - } catch (SQLException e) { - AntiVPN.getInstance().getExecutor() - .logException("Failed to get alerts state from database for: " + uuid, e); - result.accept(false); - } - }); - } - - @Override - public void updateAlertsState(UUID uuid, boolean enabled) { - if(MySQL.isClosed()) return; - - if(enabled) { - //We want to make sure there isn't already a uuid inserted to prevent double insertions - alertsState(uuid, alreadyEnabled -> { //No need to make another thread execute, already async - if(!alreadyEnabled) { - Query.prepare("insert into `alerts` (`uuid`) values (?)").append(uuid.toString()) - .execute(); - } //No need to insert again of already enabled - }); - //Removing any uuid from the alerts table will disable alerts globally. - } else AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> - Query.prepare("delete from `alerts` where `uuid` = ?") - .append(uuid.toString()) - .execute()); - } - - @Override - public void clearResponses() { - if(MySQL.isClosed()) return; - - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> Query.prepare("delete from `responses`").execute()); - } - @Override public void init() { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) @@ -257,106 +32,17 @@ public class MySqlVPN implements VPNDatabase { AntiVPN.getInstance().getExecutor().log("Initializing MySQL..."); MySQL.init(); - AntiVPN.getInstance().getExecutor().log("Creating tables..."); + AntiVPN.getInstance().getExecutor().log("Checking for updates..."); //Running check for old table types to update - Query.prepare("select `DATA_TYPE` from INFORMATION_SCHEMA.COLUMNS " + - "WHERE table_name = 'responses' AND COLUMN_NAME = 'isp';").execute(set -> { - if(set.getObject("DATA_TYPE").toString().contains("varchar")) { - AntiVPN.getInstance().getExecutor().log("Using old database format for storing responses! " + - "Dropping table and creating a new one..."); - if(Query.prepare("drop table `responses`").execute() > 0) { - AntiVPN.getInstance().getExecutor().log("Successfully dropped table!"); - } - } - }); - - Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute(); - Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute(); - Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12)," - + "`countryName` text, `countryCode` varchar(10), `city` text, `timeZone` varchar(64), " - + "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp," - + "`latitude` double, `longitude` double)").execute(); - Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute(); - - AntiVPN.getInstance().getExecutor().log("Creating indexes..."); try { - // Ref: - // https://dba.stackexchange.com/questions/24531/mysql-create-index-if-not-exists - - String query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE()" + - " AND table_name='whitelisted' AND index_name='uuid_1';"; - int id = 0; - try(ResultSet rs = Query.prepare(query).executeQuery()) { - while (rs.next()) { - id = rs.getInt("IndexExists"); - } - if (id == 0) { - Query.prepare("create index `uuid_1` on `whitelisted` (`uuid`)").execute(); - } - } - id = 0; - - // Responses index - query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() " + - "AND table_name='responses' AND index_name='ip_1';"; - try(ResultSet rs = Query.prepare(query).executeQuery()) { - while (rs.next()) { - id = rs.getInt("IndexExists"); - } - if (id == 0) { - Query.prepare("create index `ip_1` on `responses` (`ip`)").execute(); - } - id = 0; - } - - query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() " + - "AND table_name='responses' AND index_name='proxy_1';"; - try(ResultSet rs = Query.prepare(query).executeQuery()) { - while (rs.next()) { - id = rs.getInt("IndexExists"); - } - if (id == 0) { - Query.prepare("create index `proxy_1` on `responses` (`proxy`)").execute(); - } - id = 0; - } - query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE()" + - " AND table_name='responses' AND index_name='inserted_1';"; - try(ResultSet rs = Query.prepare(query).executeQuery()) { - while (rs.next()) { - id = rs.getInt("IndexExists"); - } - if (id == 0) { - Query.prepare("create index `inserted_1` on `responses` (`inserted`)").execute(); - } - id = 0; - } - - //Whitelisted IPs index - query = "SELECT COUNT(1) IndexExists FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE()" + - " AND table_name='whitelisted-ips' AND index_name='ip_1';"; - try(ResultSet rs = Query.prepare(query).executeQuery()) { - while (rs.next()) { - id = rs.getInt("IndexExists"); - } - if (id == 0) { - Query.prepare("create index `ip_1` on `whitelisted-ips` (`ip`)").execute(); + for (Version version : Version.mysqlVersions) { + if(version.needsUpdate(this)) { + version.update(this); } } } catch (Exception e) { - System.err.println("MySQL Excepton created" + e.getMessage()); + throw new RuntimeException("Could not complete version setup due to SQL error", e); } } - - private boolean isDisabled() { - return !AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()|| MySQL.isClosed(); - } - - @Override - public void shutdown() { - if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) - return; - MySQL.shutdown(); - } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/version/MySQLFirst.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/version/MySQLFirst.java new file mode 100644 index 0000000..0a5a3c8 --- /dev/null +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/version/MySQLFirst.java @@ -0,0 +1,47 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.brighten.antivpn.database.sql.version; + +import dev.brighten.antivpn.AntiVPN; +import dev.brighten.antivpn.database.DatabaseException; +import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.local.version.First; +import dev.brighten.antivpn.database.sql.utils.Query; + +import java.sql.SQLException; + +public class MySQLFirst extends First { + + @Override + public void update(VPNDatabase database) throws DatabaseException { + try { + Query.prepare("select `DATA_TYPE` from INFORMATION_SCHEMA.COLUMNS " + + "WHERE table_name = 'responses' AND COLUMN_NAME = 'isp';").execute(set -> { + if(set.getObject("DATA_TYPE").toString().contains("varchar")) { + AntiVPN.getInstance().getExecutor().log("Using old database format for storing responses! " + + "Dropping table and creating a new one..."); + if(Query.prepare("drop table `responses`").execute() > 0) { + AntiVPN.getInstance().getExecutor().log("Successfully dropped table!"); + } + } + }); + } catch (SQLException e) { + throw new DatabaseException("Could not update MySQL database", e); + } + super.update(database); + } +} diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java deleted file mode 100644 index e13ce3c..0000000 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/version/H2Version.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2026 Dawson Hessler - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package dev.brighten.antivpn.database.version; - -import dev.brighten.antivpn.AntiVPN; -import dev.brighten.antivpn.database.local.H2VPN; -import dev.brighten.antivpn.database.local.version.First; -import dev.brighten.antivpn.database.local.version.Second; -import dev.brighten.antivpn.database.sql.utils.MySQL; - -import java.io.File; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; - -public interface H2Version extends Version { - - H2Version[] versions = new H2Version[] {new First(), new Second()}; - - default void backupDatabase() { - File dataFolder = new File(AntiVPN.getInstance().getPluginFolder(), "databases"); - - if(!dataFolder.exists()) { - return; - } - - List files = new ArrayList<>(List.of(Optional.ofNullable(dataFolder.listFiles()).orElse(new File[0]))); - files.sort(Comparator.comparingLong(File::lastModified)); - - for (File file : files) { - MySQL.backupOldDB(file, dataFolder); - } - } -} diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java index b3b9876..f9340b9 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/version/Version.java @@ -16,10 +16,23 @@ package dev.brighten.antivpn.database.version; -import java.sql.SQLException; +import dev.brighten.antivpn.database.DatabaseException; +import dev.brighten.antivpn.database.local.H2VPN; +import dev.brighten.antivpn.database.local.version.First; +import dev.brighten.antivpn.database.local.version.Second; +import dev.brighten.antivpn.database.mongo.MongoVPN; +import dev.brighten.antivpn.database.mongo.version.MongoFirst; +import dev.brighten.antivpn.database.mongo.version.MongoSecond; +import dev.brighten.antivpn.database.sql.MySqlVPN; +import dev.brighten.antivpn.database.sql.version.MySQLFirst; + public interface Version { - void update(DB database) throws SQLException; + void update(DB database) throws DatabaseException; int versionNumber(); boolean needsUpdate(DB database); + + Version[] mongoDbVersions = new Version[] {new MongoFirst(), new MongoSecond()}; + Version[] mysqlVersions = new Version[] {new MySQLFirst(), new Second()}; + Version[] h2Versions = new Version[] {new First(), new Second()}; } \ No newline at end of file diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java index 1fc9518..4742431 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java @@ -45,6 +45,7 @@ public class CIDRUtils { private final InetAddress inetAddress; private InetAddress startAddress; + private BigInteger startIpInt, endIpInt; private InetAddress endAddress; private final int prefixLength; @@ -92,7 +93,9 @@ public class CIDRUtils { BigInteger ipVal = new BigInteger(1, buffer.array()); BigInteger startIp = ipVal.and(mask); + this.startIpInt = startIp; BigInteger endIp = startIp.add(mask.not()); + this.endIpInt = endIp; byte[] startIpArr = toBytes(startIp.toByteArray(), targetSize); byte[] endIpArr = toBytes(endIp.toByteArray(), targetSize); @@ -123,15 +126,6 @@ public class CIDRUtils { return ret; } - public String getNetworkAddress() { - - return this.startAddress.getHostAddress(); - } - - public String getBroadcastAddress() { - return this.endAddress.getHostAddress(); - } - public boolean isInRange(String ipAddress) throws UnknownHostException { InetAddress address = InetAddress.getByName(ipAddress); BigInteger start = new BigInteger(1, this.startAddress.getAddress()); @@ -141,6 +135,6 @@ public class CIDRUtils { int st = start.compareTo(target); int te = target.compareTo(end); - return (st == -1 || st == 0) && (te == -1 || te == 0); + return (st < 0 || st == 0) && (te < 0 || te == 0); } } \ No newline at end of file diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java index af4c80a..3825b47 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -77,12 +77,12 @@ public class VelocityListener extends VPNExecutor { 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()) + if (AntiVPN.getInstance().getVpnConfig().isAlertToSTaff()) AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() .filter(APIPlayer::isAlertsEnabled) .forEach(pl -> pl.sendMessage(dev.brighten.antivpn.AntiVPN.getInstance().getVpnConfig() - .alertMessage() + .getAlertMsg() .replace("%player%", event.getPlayer().getUsername()) .replace("%reason%", @@ -122,7 +122,7 @@ public class VelocityListener extends VPNExecutor { } } - if(!AntiVPN.getInstance().getVpnConfig().runCommands()) return; + if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) return; switch (checkResult.resultType()) { case DENIED_PROXY -> { From ac57a540c2a7d73e5cbdc3dd5afd91af61abb26e Mon Sep 17 00:00:00 2001 From: Dawson Date: Mon, 5 Jan 2026 10:27:59 -0500 Subject: [PATCH 13/22] Adding copyright headers --- Bukkit/Loader/pom.xml | 16 ++++++++ .../bukkit/loader/BukkitLoaderPlugin.java | 16 ++++++++ Bukkit/Plugin/pom.xml | 16 ++++++++ .../antivpn/bukkit/BukkitCommandExecutor.java | 16 ++++++++ .../antivpn/bukkit/BukkitListener.java | 16 ++++++++ .../brighten/antivpn/bukkit/BukkitPlayer.java | 16 ++++++++ .../antivpn/bukkit/BukkitPlayerExecutor.java | 16 ++++++++ .../brighten/antivpn/bukkit/BukkitPlugin.java | 16 ++++++++ .../antivpn/bukkit/PlayerCommandRunner.java | 16 ++++++++ .../antivpn/bukkit/command/BukkitCommand.java | 16 ++++++++ Bukkit/pom.xml | 16 ++++++++ Bungee/BungeeLoader/pom.xml | 16 ++++++++ .../antivpn/bungee/BungeeLoaderPlugin.java | 16 ++++++++ Bungee/BungeePlugin/pom.xml | 16 ++++++++ .../antivpn/bungee/BungeeListener.java | 16 ++++++++ .../brighten/antivpn/bungee/BungeePlayer.java | 16 ++++++++ .../antivpn/bungee/BungeePlayerExecutor.java | 16 ++++++++ .../brighten/antivpn/bungee/BungeePlugin.java | 16 ++++++++ .../antivpn/bungee/command/BungeeCommand.java | 16 ++++++++ .../bungee/command/BungeeCommandExecutor.java | 16 ++++++++ Bungee/pom.xml | 16 ++++++++ Common/Source/pom.xml | 16 ++++++++ .../java/dev/brighten/antivpn/AntiVPN.java | 16 ++++++++ .../dev/brighten/antivpn/api/CheckResult.java | 16 ++++++++ .../brighten/antivpn/api/OfflinePlayer.java | 16 ++++++++ .../brighten/antivpn/api/PlayerExecutor.java | 16 ++++++++ .../dev/brighten/antivpn/api/ResultType.java | 16 ++++++++ .../dev/brighten/antivpn/api/VPNExecutor.java | 16 ++++++++ .../dev/brighten/antivpn/command/Command.java | 16 ++++++++ .../antivpn/command/CommandExecutor.java | 16 ++++++++ .../antivpn/command/impl/AlertsCommand.java | 16 ++++++++ .../command/impl/AllowlistCommand.java | 16 ++++++++ .../antivpn/command/impl/AntiVPNCommand.java | 16 ++++++++ .../antivpn/command/impl/LookupCommand.java | 16 ++++++++ .../antivpn/command/impl/PlanCommand.java | 16 ++++++++ .../antivpn/command/impl/ReloadCommand.java | 16 ++++++++ .../antivpn/database/VPNDatabase.java | 16 ++++++++ .../antivpn/database/mongo/MongoVPN.java | 16 ++++++++ .../antivpn/database/sql/MySqlVPN.java | 16 ++++++++ .../sql/utils/ExecutableStatement.java | 16 ++++++++ .../antivpn/database/sql/utils/MySQL.java | 16 ++++++++ .../sql/utils/NonClosableConnection.java | 29 +++++--------- .../antivpn/database/sql/utils/Query.java | 16 ++++++++ .../database/sql/utils/ResultSetIterator.java | 16 ++++++++ .../antivpn/depends/LibraryLoader.java | 29 +++++--------- .../antivpn/depends/MavenLibraries.java | 29 +++++--------- .../antivpn/depends/MavenLibrary.java | 29 +++++--------- .../brighten/antivpn/depends/Relocate.java | 16 ++++++++ .../brighten/antivpn/depends/Repository.java | 29 +++++--------- .../antivpn/depends/URLClassLoaderAccess.java | 29 +++++--------- .../antivpn/message/MessageHandler.java | 16 ++++++++ .../brighten/antivpn/message/VpnString.java | 16 ++++++++ .../dev/brighten/antivpn/utils/CIDRUtils.java | 37 +++++++---------- .../brighten/antivpn/utils/ConfigDefault.java | 16 ++++++++ .../brighten/antivpn/utils/EvictingMap.java | 16 ++++++++ .../utils/ExtraObjectsMethodsForWeb.java | 18 +++++---- .../dev/brighten/antivpn/utils/MiscUtils.java | 16 ++++++++ .../antivpn/utils/NonnullByDefault.java | 29 +++++--------- .../brighten/antivpn/utils/NullnessCasts.java | 18 +++++---- .../brighten/antivpn/utils/Preconditions.java | 16 ++++++++ .../brighten/antivpn/utils/StringUtil.java | 16 ++++++++ .../dev/brighten/antivpn/utils/Supplier.java | 16 ++++++++ .../dev/brighten/antivpn/utils/Suppliers.java | 18 +++++---- .../dev/brighten/antivpn/utils/Tuple.java | 16 ++++++++ .../antivpn/utils/config/Configuration.java | 16 ++++++++ .../utils/config/ConfigurationProvider.java | 16 ++++++++ .../utils/config/YamlConfiguration.java | 16 ++++++++ .../dev/brighten/antivpn/utils/json/CDL.java | 38 +++++++----------- .../brighten/antivpn/utils/json/Cookie.java | 38 +++++++----------- .../antivpn/utils/json/CookieList.java | 38 +++++++----------- .../dev/brighten/antivpn/utils/json/HTTP.java | 38 +++++++----------- .../antivpn/utils/json/HTTPTokener.java | 38 +++++++----------- .../antivpn/utils/json/JSONArray.java | 38 +++++++----------- .../antivpn/utils/json/JSONException.java | 16 ++++++++ .../brighten/antivpn/utils/json/JSONML.java | 38 +++++++----------- .../antivpn/utils/json/JSONObject.java | 38 +++++++----------- .../antivpn/utils/json/JSONString.java | 16 ++++++++ .../antivpn/utils/json/JSONStringer.java | 38 +++++++----------- .../antivpn/utils/json/JSONTokener.java | 40 ++++++++----------- .../antivpn/utils/json/JSONWriter.java | 40 ++++++++----------- .../antivpn/utils/json/JsonReader.java | 16 ++++++++ .../dev/brighten/antivpn/utils/json/XML.java | 38 +++++++----------- .../antivpn/utils/json/XMLTokener.java | 38 +++++++----------- .../brighten/antivpn/web/FunkemunkyAPI.java | 16 ++++++++ .../antivpn/web/objects/QueryResponse.java | 16 ++++++++ .../antivpn/web/objects/VPNResponse.java | 16 ++++++++ Common/loader-utils/pom.xml | 16 ++++++++ .../antivpn/loader/JarInJarClassLoader.java | 29 +++++--------- .../antivpn/loader/LoaderBootstrap.java | 29 +++++--------- .../antivpn/loader/LoadingException.java | 29 +++++--------- Common/pom.xml | 16 ++++++++ Sponge/SpongeLoader/pom.xml | 16 ++++++++ .../antivpn/sponge/SpongeLoaderPlugin.java | 16 ++++++++ Sponge/SpongePlugin/pom.xml | 16 ++++++++ .../antivpn/sponge/SpongeListener.java | 16 ++++++++ .../brighten/antivpn/sponge/SpongePlayer.java | 16 ++++++++ .../antivpn/sponge/SpongePlayerExecutor.java | 16 ++++++++ .../brighten/antivpn/sponge/SpongePlugin.java | 16 ++++++++ .../antivpn/sponge/command/SpongeCommand.java | 16 ++++++++ .../sponge/command/SpongeCommandExecutor.java | 16 ++++++++ .../antivpn/sponge/util/StringUtil.java | 16 ++++++++ Sponge/pom.xml | 16 ++++++++ Universal/pom.xml | 16 ++++++++ Velocity/VelocityLoader/pom.xml | 16 ++++++++ .../velocity/VelocityPluginLoader.java | 16 ++++++++ Velocity/VelocityPlugin/pom.xml | 16 ++++++++ .../antivpn/velocity/VelocityListener.java | 16 ++++++++ .../antivpn/velocity/VelocityPlayer.java | 16 ++++++++ .../velocity/VelocityPlayerExecutor.java | 16 ++++++++ .../antivpn/velocity/VelocityPlugin.java | 16 ++++++++ .../velocity/command/VelocityCommand.java | 16 ++++++++ .../command/VelocityCommandExecutor.java | 16 ++++++++ Velocity/pom.xml | 16 ++++++++ pom.xml | 16 ++++++++ 114 files changed, 1733 insertions(+), 538 deletions(-) diff --git a/Bukkit/Loader/pom.xml b/Bukkit/Loader/pom.xml index b4dff27..621ec61 100644 --- a/Bukkit/Loader/pom.xml +++ b/Bukkit/Loader/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Bukkit/Loader/src/main/java/dev/brighten/antivpn/bukkit/loader/BukkitLoaderPlugin.java b/Bukkit/Loader/src/main/java/dev/brighten/antivpn/bukkit/loader/BukkitLoaderPlugin.java index f8ea3c8..81048eb 100644 --- a/Bukkit/Loader/src/main/java/dev/brighten/antivpn/bukkit/loader/BukkitLoaderPlugin.java +++ b/Bukkit/Loader/src/main/java/dev/brighten/antivpn/bukkit/loader/BukkitLoaderPlugin.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bukkit.loader; import dev.brighten.antivpn.loader.JarInJarClassLoader; diff --git a/Bukkit/Plugin/pom.xml b/Bukkit/Plugin/pom.xml index 0a35b0c..106a8ea 100644 --- a/Bukkit/Plugin/pom.xml +++ b/Bukkit/Plugin/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitCommandExecutor.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitCommandExecutor.java index c8df5ae..a1a8001 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitCommandExecutor.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitCommandExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bukkit; import dev.brighten.antivpn.AntiVPN; diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java index 2489ca6..813cdfb 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bukkit; import dev.brighten.antivpn.AntiVPN; diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlayer.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlayer.java index 5f8e6ac..f45f9e9 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlayer.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlayer.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bukkit; import dev.brighten.antivpn.api.APIPlayer; diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlayerExecutor.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlayerExecutor.java index faa1f19..3a6ee4c 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlayerExecutor.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlayerExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bukkit; import dev.brighten.antivpn.api.APIPlayer; diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java index 540780c..2ca99ae 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bukkit; import dev.brighten.antivpn.AntiVPN; diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/PlayerCommandRunner.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/PlayerCommandRunner.java index 8ac64a7..1b240e7 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/PlayerCommandRunner.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/PlayerCommandRunner.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bukkit; import dev.brighten.antivpn.utils.MiscUtils; diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/command/BukkitCommand.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/command/BukkitCommand.java index 2e3ecd4..132de49 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/command/BukkitCommand.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/command/BukkitCommand.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bukkit.command; import dev.brighten.antivpn.AntiVPN; diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index e44a743..278e3b1 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Bungee/BungeeLoader/pom.xml b/Bungee/BungeeLoader/pom.xml index 0aea182..f708039 100644 --- a/Bungee/BungeeLoader/pom.xml +++ b/Bungee/BungeeLoader/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Bungee/BungeeLoader/src/main/java/dev/brighten/antivpn/bungee/BungeeLoaderPlugin.java b/Bungee/BungeeLoader/src/main/java/dev/brighten/antivpn/bungee/BungeeLoaderPlugin.java index 353be25..16ae758 100644 --- a/Bungee/BungeeLoader/src/main/java/dev/brighten/antivpn/bungee/BungeeLoaderPlugin.java +++ b/Bungee/BungeeLoader/src/main/java/dev/brighten/antivpn/bungee/BungeeLoaderPlugin.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bungee; import dev.brighten.antivpn.loader.JarInJarClassLoader; diff --git a/Bungee/BungeePlugin/pom.xml b/Bungee/BungeePlugin/pom.xml index 1727eb0..81abf03 100644 --- a/Bungee/BungeePlugin/pom.xml +++ b/Bungee/BungeePlugin/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java index 7a11eea..d234c7f 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bungee; import dev.brighten.antivpn.AntiVPN; diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlayer.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlayer.java index 5a6b5e7..072a3cf 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlayer.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlayer.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bungee; import dev.brighten.antivpn.api.APIPlayer; diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlayerExecutor.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlayerExecutor.java index ab77f95..cb01b91 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlayerExecutor.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlayerExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bungee; import dev.brighten.antivpn.api.APIPlayer; diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java index f8361fd..5ef8317 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bungee; import dev.brighten.antivpn.AntiVPN; diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/command/BungeeCommand.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/command/BungeeCommand.java index 4b4fa23..a762966 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/command/BungeeCommand.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/command/BungeeCommand.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bungee.command; import dev.brighten.antivpn.AntiVPN; diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/command/BungeeCommandExecutor.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/command/BungeeCommandExecutor.java index 41b955e..c0d3ebb 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/command/BungeeCommandExecutor.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/command/BungeeCommandExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.bungee.command; import dev.brighten.antivpn.AntiVPN; diff --git a/Bungee/pom.xml b/Bungee/pom.xml index 83aee15..6da004f 100644 --- a/Bungee/pom.xml +++ b/Bungee/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Common/Source/pom.xml b/Common/Source/pom.xml index a829d1e..7962e9e 100644 --- a/Common/Source/pom.xml +++ b/Common/Source/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java index c1f2c16..4daf09e 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn; import dev.brighten.antivpn.api.PlayerExecutor; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/CheckResult.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/CheckResult.java index c331961..abfdc0d 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/CheckResult.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/CheckResult.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.api; import dev.brighten.antivpn.web.objects.VPNResponse; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/OfflinePlayer.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/OfflinePlayer.java index 27ce5f7..cec0072 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/OfflinePlayer.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/OfflinePlayer.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.api; import java.net.InetAddress; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/PlayerExecutor.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/PlayerExecutor.java index 56909dc..e5fba0c 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/PlayerExecutor.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/PlayerExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.api; import java.util.List; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/ResultType.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/ResultType.java index e8dfea4..1f8bec9 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/ResultType.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/ResultType.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.api; import lombok.Getter; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java index 657293a..0525d91 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.api; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/command/Command.java b/Common/Source/src/main/java/dev/brighten/antivpn/command/Command.java index 893248e..43baa55 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/command/Command.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/command/Command.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.command; import java.util.List; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/command/CommandExecutor.java b/Common/Source/src/main/java/dev/brighten/antivpn/command/CommandExecutor.java index c9408ca..d781498 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/command/CommandExecutor.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/command/CommandExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.command; import dev.brighten.antivpn.api.APIPlayer; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AlertsCommand.java b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AlertsCommand.java index 113bea4..445f479 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AlertsCommand.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AlertsCommand.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.command.impl; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java index ce99f79..bd22a1d 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AllowlistCommand.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.command.impl; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AntiVPNCommand.java b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AntiVPNCommand.java index 48c0fda..15f23a0 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AntiVPNCommand.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/AntiVPNCommand.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.command.impl; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/LookupCommand.java b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/LookupCommand.java index 9949d40..4a123e2 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/LookupCommand.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/LookupCommand.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.command.impl; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/PlanCommand.java b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/PlanCommand.java index dc0f065..0151b44 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/PlanCommand.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/PlanCommand.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.command.impl; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/ReloadCommand.java b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/ReloadCommand.java index ebba1b4..5e3b97b 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/ReloadCommand.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/command/impl/ReloadCommand.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.command.impl; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java index 3ad1ee4..8823756 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database; import dev.brighten.antivpn.utils.CIDRUtils; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java index daa23f2..8506192 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database.mongo; import com.github.benmanes.caffeine.cache.Cache; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java index f7aa25e..54ac223 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/MySqlVPN.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database.sql; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java index 00c8df5..f69de4b 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database.sql.utils; import dev.brighten.antivpn.utils.MiscUtils; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java index f1e366a..e2aef2e 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database.sql.utils; import com.mysql.cj.jdbc.Driver; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/NonClosableConnection.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/NonClosableConnection.java index 38668af..724d5c2 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/NonClosableConnection.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/NonClosableConnection.java @@ -1,26 +1,17 @@ /* - * This file is part of LuckPerms, licensed under the MIT License. + * Copyright 2026 Dawson Hessler * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.database.sql.utils; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java index 7806524..8c790e7 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/Query.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database.sql.utils; import lombok.Getter; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java index 4e2f911..fa16de4 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ResultSetIterator.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.database.sql.utils; import java.sql.ResultSet; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java b/Common/Source/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java index 8f16b26..913aada 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java @@ -1,26 +1,17 @@ /* - * This file is part of helper, licensed under the MIT License. + * Copyright 2026 Dawson Hessler * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.depends; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/depends/MavenLibraries.java b/Common/Source/src/main/java/dev/brighten/antivpn/depends/MavenLibraries.java index 189f737..4f11cef 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/depends/MavenLibraries.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/depends/MavenLibraries.java @@ -1,26 +1,17 @@ /* - * This file is part of helper, licensed under the MIT License. + * Copyright 2026 Dawson Hessler * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.depends; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/depends/MavenLibrary.java b/Common/Source/src/main/java/dev/brighten/antivpn/depends/MavenLibrary.java index eed8117..f2caf49 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/depends/MavenLibrary.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/depends/MavenLibrary.java @@ -1,26 +1,17 @@ /* - * This file is part of helper, licensed under the MIT License. + * Copyright 2026 Dawson Hessler * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.depends; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/depends/Relocate.java b/Common/Source/src/main/java/dev/brighten/antivpn/depends/Relocate.java index 32b8af5..2d4d910 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/depends/Relocate.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/depends/Relocate.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.depends; import java.lang.annotation.Documented; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/depends/Repository.java b/Common/Source/src/main/java/dev/brighten/antivpn/depends/Repository.java index 4381225..716c291 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/depends/Repository.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/depends/Repository.java @@ -1,26 +1,17 @@ /* - * This file is part of helper, licensed under the MIT License. + * Copyright 2026 Dawson Hessler * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.depends; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/depends/URLClassLoaderAccess.java b/Common/Source/src/main/java/dev/brighten/antivpn/depends/URLClassLoaderAccess.java index a0159f0..1146da8 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/depends/URLClassLoaderAccess.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/depends/URLClassLoaderAccess.java @@ -1,26 +1,17 @@ /* - * This file is part of helper, licensed under the MIT License. + * Copyright 2026 Dawson Hessler * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.depends; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/message/MessageHandler.java b/Common/Source/src/main/java/dev/brighten/antivpn/message/MessageHandler.java index 7649a36..be1f4e3 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/message/MessageHandler.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/message/MessageHandler.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.message; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/message/VpnString.java b/Common/Source/src/main/java/dev/brighten/antivpn/message/VpnString.java index fa6e118..8ea7865 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/message/VpnString.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/message/VpnString.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.message; import dev.brighten.antivpn.api.APIPlayer; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java index 4742431..94cb251 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/CIDRUtils.java @@ -1,27 +1,18 @@ /* -* The MIT License -* -* Copyright (c) 2013 Edin Dazdarevic (edin.dazdarevic@gmail.com) - -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: - -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. - -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -* -* */ + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package dev.brighten.antivpn.utils; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/ConfigDefault.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/ConfigDefault.java index 9a2ec06..5fe30e7 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/ConfigDefault.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/ConfigDefault.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/EvictingMap.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/EvictingMap.java index 02b8a8c..46bacc6 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/EvictingMap.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/EvictingMap.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils; import lombok.Getter; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/ExtraObjectsMethodsForWeb.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/ExtraObjectsMethodsForWeb.java index 484f35e..2e50bae 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/ExtraObjectsMethodsForWeb.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/ExtraObjectsMethodsForWeb.java @@ -1,15 +1,17 @@ /* - * Copyright (C) 2016 The Guava Authors + * Copyright 2026 Dawson Hessler * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.utils; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java index 77cde0b..c737bb3 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/NonnullByDefault.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/NonnullByDefault.java index 48a1f73..33d759f 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/NonnullByDefault.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/NonnullByDefault.java @@ -1,26 +1,17 @@ /* - * This file is part of helper, licensed under the MIT License. + * Copyright 2026 Dawson Hessler * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.utils; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/NullnessCasts.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/NullnessCasts.java index 24d68c9..59710b6 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/NullnessCasts.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/NullnessCasts.java @@ -1,15 +1,17 @@ /* - * Copyright (C) 2021 The Guava Authors + * Copyright 2026 Dawson Hessler * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.utils; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/Preconditions.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/Preconditions.java index 7d24918..ba96d8b 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/Preconditions.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/Preconditions.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java index 0af6cf4..8b3e0b9 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils; import dev.brighten.antivpn.AntiVPN; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/Supplier.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/Supplier.java index c1f7365..159386e 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/Supplier.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/Supplier.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/Suppliers.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/Suppliers.java index d380307..13fef69 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/Suppliers.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/Suppliers.java @@ -1,15 +1,17 @@ /* - * Copyright (C) 2007 The Guava Authors + * Copyright 2026 Dawson Hessler * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.utils; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/Tuple.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/Tuple.java index 0e54854..1e650c6 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/Tuple.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/Tuple.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils; public record Tuple(F first, S second) { diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/Configuration.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/Configuration.java index a84a372..8bfd3a7 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/Configuration.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/Configuration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils.config; import java.util.*; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/ConfigurationProvider.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/ConfigurationProvider.java index 47f8a48..0e12ccd 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/ConfigurationProvider.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/ConfigurationProvider.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils.config; import java.io.*; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/YamlConfiguration.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/YamlConfiguration.java index 8dcf5c9..13a88fa 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/YamlConfiguration.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/config/YamlConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils.config; import lombok.AccessLevel; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/CDL.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/CDL.java index 6af74b3..13da975 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/CDL.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/CDL.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2002 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; /** * This provides static methods to convert comma delimited text into a diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/Cookie.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/Cookie.java index 6a6f892..8525a26 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/Cookie.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/Cookie.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2002 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; /** * Convert a web browser cookie specification to a JSONObject and back. diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/CookieList.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/CookieList.java index ba7ef02..9a2ba97 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/CookieList.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/CookieList.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2002 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; import java.util.Iterator; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/HTTP.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/HTTP.java index ac2ef25..12f596d 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/HTTP.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/HTTP.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2002 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; import java.util.Iterator; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/HTTPTokener.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/HTTPTokener.java index 7304422..d318384 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/HTTPTokener.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/HTTPTokener.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2002 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; /** * The HTTPTokener extends the JSONTokener to provide additional methods diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONArray.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONArray.java index 3f65d9b..8ab4bfc 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONArray.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONArray.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2002 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; import java.io.IOException; import java.io.Writer; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONException.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONException.java index 36fcfaa..599e3b2 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONException.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONException.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils.json; /** diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONML.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONML.java index 3001fc3..f31c6f7 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONML.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONML.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2008 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; import java.util.Iterator; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONObject.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONObject.java index e66aaea..3d487d4 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONObject.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONObject.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2002 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; import java.io.IOException; import java.io.Writer; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONString.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONString.java index 55d1c30..37c656e 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONString.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONString.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils.json; /** diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONStringer.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONStringer.java index 6287010..052c6e0 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONStringer.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONStringer.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2006 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; import java.io.StringWriter; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONTokener.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONTokener.java index a02da99..e0235b7 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONTokener.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONTokener.java @@ -1,31 +1,23 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils.json; import java.io.*; -/* -Copyright (c) 2002 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - /** * A JSONTokener takes a source string and extracts characters and tokens from * it. It is used by the JSONObject and JSONArray constructors to parse diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONWriter.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONWriter.java index aa1ec08..e57b81f 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONWriter.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JSONWriter.java @@ -1,32 +1,24 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils.json; import java.io.IOException; import java.io.Writer; -/* -Copyright (c) 2006 JSON.org - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - /** * JSONWriter provides a quick and convenient way of producing JSON text. * The texts produced strictly conform to JSON syntax rules. No whitespace is diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JsonReader.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JsonReader.java index dfcec2c..25d667c 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JsonReader.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/JsonReader.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.utils.json; import java.io.*; import java.net.URL; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/XML.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/XML.java index 782a908..96852ad 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/XML.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/XML.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2002 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; import java.util.Iterator; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/XMLTokener.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/XMLTokener.java index 9c155fa..f67c5e5 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/XMLTokener.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/json/XMLTokener.java @@ -1,28 +1,20 @@ -package dev.brighten.antivpn.utils.json; - /* -Copyright (c) 2002 JSON.org + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -The Software shall be used for Good, not Evil. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ +package dev.brighten.antivpn.utils.json; /** * The XMLTokener extends the JSONTokener to provide additional methods diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/web/FunkemunkyAPI.java b/Common/Source/src/main/java/dev/brighten/antivpn/web/FunkemunkyAPI.java index 7710325..38a5933 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/web/FunkemunkyAPI.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/web/FunkemunkyAPI.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.web; import dev.brighten.antivpn.utils.json.JSONException; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/web/objects/QueryResponse.java b/Common/Source/src/main/java/dev/brighten/antivpn/web/objects/QueryResponse.java index 3dc96bb..a44e186 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/web/objects/QueryResponse.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/web/objects/QueryResponse.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.web.objects; import dev.brighten.antivpn.utils.json.JSONException; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/web/objects/VPNResponse.java b/Common/Source/src/main/java/dev/brighten/antivpn/web/objects/VPNResponse.java index 645200e..13674e7 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/web/objects/VPNResponse.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/web/objects/VPNResponse.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.web.objects; import dev.brighten.antivpn.utils.json.JSONException; diff --git a/Common/loader-utils/pom.xml b/Common/loader-utils/pom.xml index 9763696..2a6d1a7 100644 --- a/Common/loader-utils/pom.xml +++ b/Common/loader-utils/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/JarInJarClassLoader.java b/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/JarInJarClassLoader.java index 4d8a4c3..3d1ccb4 100644 --- a/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/JarInJarClassLoader.java +++ b/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/JarInJarClassLoader.java @@ -1,26 +1,17 @@ /* - * This file is part of LuckPerms, licensed under the MIT License. + * Copyright 2026 Dawson Hessler * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.loader; diff --git a/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/LoaderBootstrap.java b/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/LoaderBootstrap.java index 38cbb29..38e669c 100644 --- a/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/LoaderBootstrap.java +++ b/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/LoaderBootstrap.java @@ -1,26 +1,17 @@ /* - * This file is part of LuckPerms, licensed under the MIT License. + * Copyright 2026 Dawson Hessler * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.loader; diff --git a/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/LoadingException.java b/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/LoadingException.java index 191ae03..85f69ac 100644 --- a/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/LoadingException.java +++ b/Common/loader-utils/src/main/java/dev/brighten/antivpn/loader/LoadingException.java @@ -1,26 +1,17 @@ /* - * This file is part of LuckPerms, licensed under the MIT License. + * Copyright 2026 Dawson Hessler * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * http://www.apache.org/licenses/LICENSE-2.0 * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package dev.brighten.antivpn.loader; diff --git a/Common/pom.xml b/Common/pom.xml index dff27de..05a1d9f 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Sponge/SpongeLoader/pom.xml b/Sponge/SpongeLoader/pom.xml index ba2f189..762575f 100644 --- a/Sponge/SpongeLoader/pom.xml +++ b/Sponge/SpongeLoader/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Sponge/SpongeLoader/src/main/java/dev/brighten/antivpn/sponge/SpongeLoaderPlugin.java b/Sponge/SpongeLoader/src/main/java/dev/brighten/antivpn/sponge/SpongeLoaderPlugin.java index d77a1eb..00ec663 100644 --- a/Sponge/SpongeLoader/src/main/java/dev/brighten/antivpn/sponge/SpongeLoaderPlugin.java +++ b/Sponge/SpongeLoader/src/main/java/dev/brighten/antivpn/sponge/SpongeLoaderPlugin.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.sponge; import com.google.inject.Inject; diff --git a/Sponge/SpongePlugin/pom.xml b/Sponge/SpongePlugin/pom.xml index d27ce7c..d19f754 100644 --- a/Sponge/SpongePlugin/pom.xml +++ b/Sponge/SpongePlugin/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java index c26fab1..99275d7 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.sponge; import dev.brighten.antivpn.AntiVPN; diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java index 2052eea..595bc4d 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlayer.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.sponge; import dev.brighten.antivpn.api.APIPlayer; diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java index 3904633..6ac58f1 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlayerExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.sponge; import com.github.benmanes.caffeine.cache.Cache; diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java index 2e2f9bb..812c498 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongePlugin.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.sponge; import dev.brighten.antivpn.AntiVPN; diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommand.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommand.java index 06ea090..281e318 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommand.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommand.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.sponge.command; import dev.brighten.antivpn.AntiVPN; diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommandExecutor.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommandExecutor.java index de96dd5..8ccaccb 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommandExecutor.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/command/SpongeCommandExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.sponge.command; import dev.brighten.antivpn.AntiVPN; diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/util/StringUtil.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/util/StringUtil.java index 22d1a5a..bd533c6 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/util/StringUtil.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/util/StringUtil.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.sponge.util; public class StringUtil { diff --git a/Sponge/pom.xml b/Sponge/pom.xml index e3a38e5..4e6ed3d 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Universal/pom.xml b/Universal/pom.xml index 44ff3b2..c243aad 100644 --- a/Universal/pom.xml +++ b/Universal/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Velocity/VelocityLoader/pom.xml b/Velocity/VelocityLoader/pom.xml index 1a52d54..8083e35 100644 --- a/Velocity/VelocityLoader/pom.xml +++ b/Velocity/VelocityLoader/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Velocity/VelocityLoader/src/main/java/dev/brighten/antivpn/velocity/VelocityPluginLoader.java b/Velocity/VelocityLoader/src/main/java/dev/brighten/antivpn/velocity/VelocityPluginLoader.java index 9c7add0..9bf68ba 100644 --- a/Velocity/VelocityLoader/src/main/java/dev/brighten/antivpn/velocity/VelocityPluginLoader.java +++ b/Velocity/VelocityLoader/src/main/java/dev/brighten/antivpn/velocity/VelocityPluginLoader.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.velocity; import com.google.inject.Inject; diff --git a/Velocity/VelocityPlugin/pom.xml b/Velocity/VelocityPlugin/pom.xml index d475480..5b97faf 100644 --- a/Velocity/VelocityPlugin/pom.xml +++ b/Velocity/VelocityPlugin/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java index 3825b47..601423d 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.velocity; import com.velocitypowered.api.event.ResultedEvent; diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayer.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayer.java index b247714..03a127e 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayer.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayer.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.velocity; import com.velocitypowered.api.proxy.Player; diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayerExecutor.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayerExecutor.java index 6c589ee..f137ba6 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayerExecutor.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayerExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.velocity; import com.velocitypowered.api.proxy.Player; diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java index 29d3dc4..93f5f29 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.velocity; import com.velocitypowered.api.proxy.ProxyServer; diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommand.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommand.java index dc49c65..b372f0b 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommand.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommand.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.velocity.command; import com.velocitypowered.api.command.CommandSource; diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommandExecutor.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommandExecutor.java index b581543..1a08dbf 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommandExecutor.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/command/VelocityCommandExecutor.java @@ -1,3 +1,19 @@ +/* + * Copyright 2026 Dawson Hessler + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package dev.brighten.antivpn.velocity.command; import com.velocitypowered.api.command.CommandSource; diff --git a/Velocity/pom.xml b/Velocity/pom.xml index a88309c..3633749 100644 --- a/Velocity/pom.xml +++ b/Velocity/pom.xml @@ -1,4 +1,20 @@ + + diff --git a/pom.xml b/pom.xml index f895638..f597903 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,20 @@ + + From 8a4b86c9ef42a77cc623aa77bc335b3ef172437d Mon Sep 17 00:00:00 2001 From: Dawson Date: Wed, 14 Jan 2026 09:42:20 -0500 Subject: [PATCH 14/22] Allowlist functionality is now working, corrected sql errors --- Bukkit/Loader/pom.xml | 4 +- Bukkit/Plugin/pom.xml | 6 +- Bukkit/pom.xml | 2 +- Bungee/BungeeLoader/pom.xml | 4 +- Bungee/BungeePlugin/pom.xml | 6 +- Bungee/pom.xml | 2 +- Common/Source/pom.xml | 2 +- .../dev/brighten/antivpn/api/VPNExecutor.java | 2 +- .../antivpn/database/local/H2VPN.java | 125 ++++++++++-------- .../antivpn/database/local/version/First.java | 54 +++++--- .../database/local/version/Second.java | 89 ++++++++----- .../antivpn/database/mongo/MongoVPN.java | 2 +- .../sql/utils/ExecutableStatement.java | 30 ++--- .../database/sql/version/MySQLFirst.java | 14 +- Common/loader-utils/pom.xml | 2 +- Common/pom.xml | 2 +- Sponge/SpongeLoader/pom.xml | 4 +- Sponge/SpongePlugin/pom.xml | 6 +- Sponge/pom.xml | 2 +- Universal/pom.xml | 2 +- Velocity/VelocityLoader/pom.xml | 6 +- Velocity/VelocityPlugin/pom.xml | 6 +- Velocity/pom.xml | 2 +- pom.xml | 2 +- 24 files changed, 214 insertions(+), 162 deletions(-) diff --git a/Bukkit/Loader/pom.xml b/Bukkit/Loader/pom.xml index 621ec61..c697135 100644 --- a/Bukkit/Loader/pom.xml +++ b/Bukkit/Loader/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn Bukkit - 1.9.4 + 1.10.0 dev.brighten.antivpn.bukkit Loader @@ -99,7 +99,7 @@ dev.brighten.antivpn loader-utils - 1.9.4 + 1.10.0 compile diff --git a/Bukkit/Plugin/pom.xml b/Bukkit/Plugin/pom.xml index 106a8ea..182d091 100644 --- a/Bukkit/Plugin/pom.xml +++ b/Bukkit/Plugin/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn Bukkit - 1.9.4 + 1.10.0 Plugin @@ -98,7 +98,7 @@ dev.brighten.antivpn Source - 1.9.4 + 1.10.0 provided @@ -110,7 +110,7 @@ dev.brighten.antivpn loader-utils - 1.9.4 + 1.10.0 provided diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 278e3b1..2cb1c28 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -21,7 +21,7 @@ AntiVPN dev.brighten.antivpn - 1.9.4 + 1.10.0 pom diff --git a/Bungee/BungeeLoader/pom.xml b/Bungee/BungeeLoader/pom.xml index f708039..9d19d14 100644 --- a/Bungee/BungeeLoader/pom.xml +++ b/Bungee/BungeeLoader/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn Bungee - 1.9.4 + 1.10.0 ../pom.xml @@ -95,7 +95,7 @@ dev.brighten.antivpn loader-utils - 1.9.4 + 1.10.0 compile diff --git a/Bungee/BungeePlugin/pom.xml b/Bungee/BungeePlugin/pom.xml index 81abf03..e6f1a46 100644 --- a/Bungee/BungeePlugin/pom.xml +++ b/Bungee/BungeePlugin/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn Bungee - 1.9.4 + 1.10.0 ../pom.xml @@ -85,7 +85,7 @@ dev.brighten.antivpn Source - 1.9.4 + 1.10.0 provided @@ -104,7 +104,7 @@ dev.brighten.antivpn loader-utils - 1.9.4 + 1.10.0 provided diff --git a/Bungee/pom.xml b/Bungee/pom.xml index 6da004f..bcc273a 100644 --- a/Bungee/pom.xml +++ b/Bungee/pom.xml @@ -21,7 +21,7 @@ AntiVPN dev.brighten.antivpn - 1.9.4 + 1.10.0 pom 4.0.0 diff --git a/Common/Source/pom.xml b/Common/Source/pom.xml index 7962e9e..6384f17 100644 --- a/Common/Source/pom.xml +++ b/Common/Source/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn Common - 1.9.4 + 1.10.0 Source diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java index 0525d91..4749be3 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -133,7 +133,7 @@ public abstract class VPNExecutor { return AntiVPN.getInstance().getDatabase().isWhitelisted(ip); } try { - return whitelistedIps.contains(new CIDRUtils(ip + "/32")); + return whitelistedIps.contains(new CIDRUtils(ip)); } catch (UnknownHostException e) { throw new RuntimeException(e); } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java index 990cc49..100a378 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java @@ -20,6 +20,7 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.database.VPNDatabase; +import dev.brighten.antivpn.database.sql.utils.ExecutableStatement; import dev.brighten.antivpn.database.sql.utils.MySQL; import dev.brighten.antivpn.database.sql.utils.Query; import dev.brighten.antivpn.database.version.Version; @@ -67,20 +68,23 @@ public class H2VPN implements VPNDatabase { return Optional.empty(); VPNResponse response = cachedResponses.get(ip, ip2 -> { - try(ResultSet rs = Query.prepare("select * from `responses` where `ip` = ? limit 1").append(ip). - executeQuery()) { - if (rs != null && rs.next()) { - return new VPNResponse(rs.getString("asn"), rs.getString("ip"), - rs.getString("countryName"), rs.getString("countryCode"), - rs.getString("city"), rs.getString("timeZone"), - rs.getString("method"), rs.getString("isp"), "N/A", - rs.getBoolean("proxy"), rs.getBoolean("cached"), true, - rs.getDouble("latitude"), rs.getDouble("longitude"), - rs.getTimestamp("inserted").getTime(), -1); + try(ExecutableStatement statement = Query.prepare("select * from `responses` where `ip` = ? limit 1").append(ip)) { + try(ResultSet rs = statement.executeQuery()) { + if (rs != null && rs.next()) { + return new VPNResponse(rs.getString("asn"), rs.getString("ip"), + rs.getString("countryName"), rs.getString("countryCode"), + rs.getString("city"), rs.getString("timeZone"), + rs.getString("method"), rs.getString("isp"), "N/A", + rs.getBoolean("proxy"), rs.getBoolean("cached"), true, + rs.getDouble("latitude"), rs.getDouble("longitude"), + rs.getTimestamp("inserted").getTime(), -1); + } } } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("There was a problem getting a response for " + ip, e); + } catch (Exception e) { + throw new RuntimeException(e); } return null; }); @@ -105,14 +109,14 @@ public class H2VPN implements VPNDatabase { if(AntiVPN.getInstance().getVpnConfig().cachedResults()) { cachedResponses.put(toCache.getIp(), toCache); - try { - Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`," - + "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)") - .append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName()) - .append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone()) - .append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy()) - .append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis())) - .append(toCache.getLatitude()).append(toCache.getLongitude()).execute(); + try(var statement = Query.prepare("insert into `responses` (`ip`,`asn`,`countryName`,`countryCode`,`city`,`timeZone`," + + "`method`,`isp`,`proxy`,`cached`,`inserted`,`latitude`,`longitude`) values (?,?,?,?,?,?,?,?,?,?,?,?,?)") + .append(toCache.getIp()).append(toCache.getAsn()).append(toCache.getCountryName()) + .append(toCache.getCountryCode()).append(toCache.getCity()).append(toCache.getTimeZone()) + .append(toCache.getMethod()).append(toCache.getIsp()).append(toCache.isProxy()) + .append(toCache.isCached()).append(new Timestamp(System.currentTimeMillis())) + .append(toCache.getLatitude()).append(toCache.getLongitude())) { + statement.execute(); } catch(SQLException e) { AntiVPN.getInstance().getExecutor().logException("Could not cache response for IP: " + toCache.getIp(), e); } @@ -124,8 +128,8 @@ public class H2VPN implements VPNDatabase { if(!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - try { - Query.prepare("delete from `responses` where `ip` = ?").append(ip).execute(); + try(var statement = Query.prepare("delete from `responses` where `ip` = ?").append(ip)) { + statement.execute(); } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("Could not delete response from IP: " + ip, e); } @@ -135,9 +139,11 @@ public class H2VPN implements VPNDatabase { public boolean isWhitelisted(UUID uuid) { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return false; - try(ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1") - .append(uuid.toString()).executeQuery()) { - return set != null && set.next() && set.getString("uuid") != null; + try(var statement = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1") + .append(uuid.toString())) { + try(var set = statement.executeQuery()) { + return set != null && set.next() && set.getString("uuid") != null; + } } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("Could not check whitelist for uuid '" + uuid + "' due to SQL error.", e); return false; @@ -147,7 +153,7 @@ public class H2VPN implements VPNDatabase { @SneakyThrows @Override public boolean isWhitelisted(String ip) { - return isWhitelisted(new CIDRUtils(ip + "/32")); + return isWhitelisted(new CIDRUtils(ip)); } @Override @@ -158,10 +164,12 @@ public class H2VPN implements VPNDatabase { BigInteger start = cidr.getStartIpInt(); BigInteger end = cidr.getEndIpInt(); - try(var result = Query.prepare("SELECT * FROM `whitelisted-ranges` WHERE ip_start <= ? AND ip_end >= ?") - .append(start).append(end).executeQuery()) { + try(var statement = Query.prepare("SELECT * FROM `whitelisted-ranges` WHERE ip_start <= ? AND ip_end >= ?") + .append(start).append(end)) { - return result.next(); + try(var result = statement.executeQuery()) { + return result.next(); + } } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("Could not check whitelist for cidr '" + cidr + "' due to SQL error.", e); } @@ -173,8 +181,8 @@ public class H2VPN implements VPNDatabase { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - try { - Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString()).execute(); + try(var statement = Query.prepare("insert into `whitelisted` (`uuid`) values (?)").append(uuid.toString())) { + statement.execute(); AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid); } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("Could not add uuid '" + uuid + "' to whitelist due to SQL error.", e); @@ -185,8 +193,8 @@ public class H2VPN implements VPNDatabase { public void removeWhitelist(UUID uuid) { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - try { - Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString()).execute(); + try(var statement = Query.prepare("delete from `whitelisted` where `uuid` = ?").append(uuid.toString())) { + statement.execute(); AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid); } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("Could not remove uuid '" + uuid + "' from whitelist due to SQL error.", e); @@ -198,9 +206,9 @@ public class H2VPN implements VPNDatabase { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - try { - Query.prepare("insert into `whitelisted-ranges` (`cidr_string`, `ip_start`, `ip_end`) values (?, ?, ?)") - .append(cidr.toString()).append(cidr.getStartIpInt()).append(cidr.getEndIpInt()).execute(); + try(var statement = Query.prepare("insert into `whitelisted-ranges` (`cidr_string`, `ip_start`, `ip_end`) values (?, ?, ?)") + .append(cidr.toString()).append(cidr.getStartIpInt()).append(cidr.getEndIpInt())) { + statement.execute(); } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("Could not add cidr '" + cidr + "' to whitelist due to SQL error.", e); @@ -212,8 +220,8 @@ public class H2VPN implements VPNDatabase { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return; - try { - Query.prepare("delete from `whitelisted-ranges` where `cidr_string` = ?").append(cidr.toString()).execute(); + try(var statement = Query.prepare("delete from `whitelisted-ranges` where `cidr_string` = ?").append(cidr.toString())) { + statement.execute(); } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("Could not remove cidr '" + cidr + "' from whitelist due to SQL error.", e); @@ -227,9 +235,8 @@ public class H2VPN implements VPNDatabase { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return uuids; - try { - if(!MySQL.isClosed()) Query.prepare("select uuid from `whitelisted`") - .execute(set -> uuids.add(UUID.fromString(set.getString("uuid")))); + try(var statement = Query.prepare("select uuid from `whitelisted`")) { + statement.execute(set -> uuids.add(UUID.fromString(set.getString("uuid")))); } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("Could not get all whitelisted players due to SQL error.", e); } @@ -243,13 +250,14 @@ public class H2VPN implements VPNDatabase { if (!AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled() || MySQL.isClosed()) return ips; - try { - if(!MySQL.isClosed()) Query.prepare("select `cidr_string`, `ip_start`, `ip_end` from `whitelisted-ranges`") - .execute(set -> { + try(var statement = Query.prepare("select `cidr_string`, `ip_start`, `ip_end` from `whitelisted-ranges`")) { + statement.execute(set -> { try { ips.add(new CIDRUtils(set.getString("cidr_string"))); } catch (UnknownHostException e) { - AntiVPN.getInstance().getExecutor().logException("Could not format ip " + set.getString("cidr_string") + " into a CIDR!", e); + AntiVPN.getInstance().getExecutor() + .logException("Could not format ip " + + set.getString("cidr_string") + " into a CIDR!", e); } }); } catch (SQLException e) { @@ -262,12 +270,13 @@ public class H2VPN implements VPNDatabase { @Override public void alertsState(UUID uuid, Consumer result) { if(MySQL.isClosed()) return; - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> { - try(ResultSet set = Query.prepare("select * from `alerts` where `uuid` = ? limit 1") - .append(uuid.toString()).executeQuery()) { - result.accept(set != null && set.next() && set.getString("uuid") != null); + try(var statement = Query.prepare("select * from `alerts` where `uuid` = ? limit 1") + .append(uuid.toString())) { + try(var set = statement.executeQuery()) { + result.accept(set != null && set.next() && set.getString("uuid") != null); + } } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("There was a problem getting alerts state for " + uuid, e); result.accept(false); @@ -283,22 +292,22 @@ public class H2VPN implements VPNDatabase { //We want to make sure there isn't already a uuid inserted to prevent double insertions alertsState(uuid, alreadyEnabled -> { //No need to make another thread execute, already async if(!alreadyEnabled) { - try { - Query.prepare("insert into `alerts` (`uuid`) values (?)").append(uuid.toString()) - .execute(); + try(var statement = Query.prepare("insert into `alerts` (`uuid`) values (?)") + .append(uuid.toString())) { + statement.execute(); } catch (SQLException e) { - AntiVPN.getInstance().getExecutor().logException("There was a problem updating alerts state for " + uuid, e); + AntiVPN.getInstance().getExecutor() + .logException("There was a problem updating alerts state for " + uuid, e); } } //No need to insert again of already enabled }); //Removing any uuid from the alerts table will disable alerts globally. } else { - try { - Query.prepare("delete from `alerts` where `uuid` = ?") - .append(uuid.toString()) - .execute(); + try(var statement = Query.prepare("delete from `alerts` where `uuid` = ?").append(uuid.toString())) { + statement.execute(); } catch (SQLException e) { - AntiVPN.getInstance().getExecutor().logException("There was a problem updating alerts state for " + uuid, e); + AntiVPN.getInstance().getExecutor().logException("There was a problem updating alerts state for " + + uuid, e); } } } @@ -307,8 +316,8 @@ public class H2VPN implements VPNDatabase { public void clearResponses() { if(MySQL.isClosed()) return; - try { - Query.prepare("delete from `responses`").execute(); + try(var statement = Query.prepare("delete from `responses`")) { + statement.execute(); } catch (SQLException e) { AntiVPN.getInstance().getExecutor().logException("There was a problem clearing responses.", e); } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java index 3b88541..4724ca2 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/First.java @@ -19,41 +19,56 @@ package dev.brighten.antivpn.database.local.version; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.database.DatabaseException; import dev.brighten.antivpn.database.VPNDatabase; -import dev.brighten.antivpn.database.local.H2VPN; +import dev.brighten.antivpn.database.sql.utils.ExecutableStatement; import dev.brighten.antivpn.database.sql.utils.Query; import dev.brighten.antivpn.database.version.Version; +import dev.brighten.antivpn.utils.MiscUtils; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; public class First implements Version { + + private final List toClose = new ArrayList<>(); @Override public void update(VPNDatabase database) throws DatabaseException { - if(database instanceof H2VPN h2VPN) { - h2VPN.backupDatabase(); - } try { - Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)").execute(); - Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)").execute(); - Query.prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12)," + closeOnEnd(Query.prepare("create table if not exists `whitelisted` (`uuid` varchar(36) not null)")) + .execute(); + closeOnEnd(Query.prepare("create table if not exists `whitelisted-ips` (`ip` varchar(45) not null)")) + .execute(); + closeOnEnd(Query + .prepare("create table if not exists `responses` (`ip` varchar(45) not null, `asn` varchar(12)," + "`countryName` text, `countryCode` varchar(10), `city` text, `timeZone` varchar(64), " + "`method` varchar(32), `isp` text, `proxy` boolean, `cached` boolean, `inserted` timestamp," - + "`latitude` double, `longitude` double)").execute(); - Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)").execute(); - Query.prepare("create table if not exists `database_version` (`version` int)").execute(); - Query.prepare("insert into `database_version` (`version`) values (?)").append(versionNumber()).execute(); + + "`latitude` double, `longitude` double)")).execute(); + closeOnEnd(Query.prepare("create table if not exists `alerts` (`uuid` varchar(36) not null)")) + .execute(); + closeOnEnd(Query.prepare("create table if not exists `database_version` (`version` int)")).execute(); + closeOnEnd(Query.prepare("insert into `database_version` (`version`) values (?)") + .append(versionNumber())).execute(); AntiVPN.getInstance().getExecutor().log("Creating indexes..."); - Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)").execute(); - Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)").execute(); - Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)").execute(); - Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)").execute(); - Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute(); + closeOnEnd(Query.prepare("create index if not exists `uuid_1` on `whitelisted` (`uuid`)")).execute(); + closeOnEnd(Query.prepare("create index if not exists `ip_1` on `responses` (`ip`)")).execute(); + closeOnEnd(Query.prepare("create index if not exists `proxy_1` on `responses` (`proxy`)")).execute(); + closeOnEnd(Query.prepare("create index if not exists `inserted_1` on `responses` (`inserted`)")).execute(); + closeOnEnd(Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)")).execute(); } catch (SQLException e) { throw new DatabaseException("Failed to update database", e); + } finally { + MiscUtils.close(toClose.toArray(AutoCloseable[]::new)); + toClose.clear(); } } + private ExecutableStatement closeOnEnd(ExecutableStatement statement) { + toClose.add(statement); + return statement; + } + @Override public int versionNumber() { return 0; @@ -61,10 +76,13 @@ public class First implements Version { @Override public boolean needsUpdate(VPNDatabase database) { - try(ResultSet set = Query.prepare("select * from `database_version` where version = 0").executeQuery()) { - return set.getFetchSize() == 0; + try(var statement = Query.prepare("select * from `database_version` where version = 0")) { + try(ResultSet set = statement.executeQuery()) { + return set.getFetchSize() == 0; + } } catch (SQLException e) { return true; } + } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java index 2e2ddc4..cf151e8 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/version/Second.java @@ -20,17 +20,20 @@ import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.database.DatabaseException; import dev.brighten.antivpn.database.VPNDatabase; import dev.brighten.antivpn.database.local.H2VPN; +import dev.brighten.antivpn.database.sql.utils.ExecutableStatement; import dev.brighten.antivpn.database.sql.utils.Query; import dev.brighten.antivpn.database.version.Version; import dev.brighten.antivpn.utils.CIDRUtils; +import dev.brighten.antivpn.utils.MiscUtils; import java.net.UnknownHostException; -import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class Second implements Version { + private final List toClose = new ArrayList<>(); + @Override public void update(VPNDatabase database) throws DatabaseException { if(database instanceof H2VPN h2VPN) { @@ -38,22 +41,24 @@ public class Second implements Version { } List whitelistedIps = new ArrayList<>(); - try (var set = Query.prepare("SELECT * FROM `whitelisted-ips`").executeQuery()) { - while (set.next()) { - whitelistedIps.add(set.getString("ip")); + try (var statement = Query.prepare("SELECT * FROM `whitelisted-ips`")) { + try(var set = statement.executeQuery()) { + while (set.next()) { + whitelistedIps.add(set.getString("ip")); + } } } catch (SQLException e) { throw new DatabaseException("Could not get whitelisted ips from database!", e); } try { - Query.prepare("CREATE TABLE IF NOT EXISTS `whitelisted-ranges` " + - "(id INT AUTO_INCREMENT PRIMARY KEY, " + - "cidr_string VARCHAR(45), " + - "ip_start BIGINT NOT NULL, " + - "ip_end BIGINT NOT NULL") + closeOnEnd(Query.prepare("CREATE TABLE IF NOT EXISTS `whitelisted-ranges` " + + "(id INT AUTO_INCREMENT PRIMARY KEY, " + + "cidr_string VARCHAR(45), " + + "ip_start BIGINT NOT NULL, " + + "ip_end BIGINT NOT NULL)")) .execute(); - Query.prepare("CREATE INDEX idx_ip_range ON `whitelisted-ranges` (ip_start, ip_end)").execute(); + closeOnEnd(Query.prepare("CREATE INDEX idx_ip_range ON `whitelisted-ranges` (ip_start, ip_end)")).execute(); var cidrs = whitelistedIps.stream().map(ip -> { try { @@ -79,9 +84,9 @@ public class Second implements Version { } } - Query.prepare("DROP INDEX ip_1 on `whitelisted-ips`").execute(); - Query.prepare("DROP TABLE `whitelisted-ips`").execute(); - Query.prepare("INSERT INTO `database_version` (`version`) VALUES (?)").append(versionNumber()).execute(); + closeOnEnd(Query.prepare("DROP INDEX ip_1 on `whitelisted-ips`")).execute(); + closeOnEnd(Query.prepare("DROP TABLE `whitelisted-ips`")).execute(); + closeOnEnd(Query.prepare("INSERT INTO `database_version` (`version`) VALUES (?)").append(versionNumber())).execute(); } catch (Throwable e) { AntiVPN.getInstance().getExecutor().log("Failed to update database to version 1: " + e.getMessage()); try { @@ -90,29 +95,51 @@ public class Second implements Version { throw new DatabaseException("Failed to rollback database!", e); } throw new DatabaseException("Failed to update to version one, rolling back database!", e); + } finally { + MiscUtils.close(toClose.toArray(AutoCloseable[]::new)); + toClose.clear(); } } + private ExecutableStatement closeOnEnd(ExecutableStatement statement) { + toClose.add(statement); + return statement; + } + private void rollback(List ipAddresses) throws SQLException { AntiVPN.getInstance().getExecutor().log("Rolling back to version 0..."); - Query.prepare("DROP INDEX idx_ip_range ON `whitelisted-ranges`").execute(); - Query.prepare("DROP TABLE `whitelisted-ranges`").execute(); - Query.prepare("DELETE FROM `database_version` WHERE version = ?").append(versionNumber()).execute(); - - Query.prepare("CREATE TABLE IF NOT EXISTS `whitelisted-ips` (`ip` VARCHAR(45) NOT NULL)") - .execute(); - Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)").execute(); - - Query.prepare("DELETE FROM `whitelisted-ips`").execute(); - - var statement = Query.prepare("INSERT INTO `whitelisted-ips` (`ip`) VALUES (?)"); - for (String ip : ipAddresses) { - statement.append(ip); - statement.addBatch(); + try(var statement = Query.prepare("DROP INDEX idx_ip_range ON `whitelisted-ranges`")) { + statement.execute(); + } + try(var statement = Query.prepare("DROP TABLE `whitelisted-ranges`")) { + statement.execute(); } - statement.executeBatch(); + try(var statement = Query.prepare("DELETE FROM `database_version` WHERE version = ?").append(versionNumber())) { + statement.execute(); + } + + try(var statement = Query.prepare("CREATE TABLE IF NOT EXISTS `whitelisted-ips` (`ip` VARCHAR(45) NOT NULL)")) { + statement.execute(); + } + + try(var statement = Query.prepare("create index if not exists `ip_1` on `whitelisted-ips` (`ip`)")) { + statement.execute(); + } + + try(var statement = Query.prepare("DELETE FROM `whitelisted-ips`")) { + statement.execute(); + } + + try(var statement = Query.prepare("INSERT INTO `whitelisted-ips` (`ip`) VALUES (?)")) { + for (String ip : ipAddresses) { + statement.append(ip); + statement.addBatch(); + } + + statement.executeBatch(); + } } @Override @@ -122,8 +149,10 @@ public class Second implements Version { @Override public boolean needsUpdate(VPNDatabase database) { - try (ResultSet set = Query.prepare("select * from `database_version` where version = 1").executeQuery()) { - return set.getFetchSize() == 0; + try (var statement = Query.prepare("select * from `database_version` where version = 1")) { + try(var set = statement.executeQuery()) { + return set.getFetchSize() == 0; + } } catch (SQLException e) { return true; } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java index 8506192..625c3aa 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java @@ -146,7 +146,7 @@ public class MongoVPN implements VPNDatabase { @Override public boolean isWhitelisted(String ip) { try { - return isWhitelisted(new CIDRUtils(ip + "/32")); + return isWhitelisted(new CIDRUtils(ip)); } catch (UnknownHostException e) { AntiVPN.getInstance().getExecutor().log("Failed to check whitelist for IP: " + ip, e); return false; diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java index f69de4b..5b0a7e6 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/utils/ExecutableStatement.java @@ -16,13 +16,14 @@ package dev.brighten.antivpn.database.sql.utils; -import dev.brighten.antivpn.utils.MiscUtils; +import lombok.Getter; import lombok.SneakyThrows; import java.sql.*; import java.util.UUID; -public class ExecutableStatement { +public class ExecutableStatement implements AutoCloseable { + @Getter private final PreparedStatement statement; private int pos = 1; @@ -31,35 +32,21 @@ public class ExecutableStatement { } public int execute() throws SQLException { - try { - return statement.executeUpdate(); - } finally { - MiscUtils.close(statement); - } + return statement.executeUpdate(); } public void execute(ResultSetIterator iterator) throws SQLException { try(var rs = statement.executeQuery()) { while (rs.next()) iterator.next(rs); - } finally { - MiscUtils.close(statement); } } public int[] executeBatch() throws SQLException { - try { - return statement.executeBatch(); - } finally { - MiscUtils.close(statement); - } + return statement.executeBatch(); } public ResultSet executeQuery() throws SQLException { - try { - return statement.executeQuery(); - } finally { - MiscUtils.close(statement); - } + return statement.executeQuery(); } @SneakyThrows @@ -152,4 +139,9 @@ public class ExecutableStatement { statement.addBatch(); return this; } + + @Override + public void close() throws SQLException { + statement.close(); + } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/version/MySQLFirst.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/version/MySQLFirst.java index 0a5a3c8..9f40d48 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/version/MySQLFirst.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/sql/version/MySQLFirst.java @@ -28,15 +28,19 @@ public class MySQLFirst extends First { @Override public void update(VPNDatabase database) throws DatabaseException { - try { - Query.prepare("select `DATA_TYPE` from INFORMATION_SCHEMA.COLUMNS " + - "WHERE table_name = 'responses' AND COLUMN_NAME = 'isp';").execute(set -> { + try(var statement = Query.prepare("select `DATA_TYPE` from INFORMATION_SCHEMA.COLUMNS " + + "WHERE table_name = 'responses' AND COLUMN_NAME = 'isp';")) { + statement.execute(set -> { if(set.getObject("DATA_TYPE").toString().contains("varchar")) { AntiVPN.getInstance().getExecutor().log("Using old database format for storing responses! " + "Dropping table and creating a new one..."); - if(Query.prepare("drop table `responses`").execute() > 0) { - AntiVPN.getInstance().getExecutor().log("Successfully dropped table!"); + try(var state = Query.prepare("drop table `responses`")) { + if(state.execute() > 0) { + AntiVPN.getInstance().getExecutor().log("Successfully dropped table!"); + } } + + } }); } catch (SQLException e) { diff --git a/Common/loader-utils/pom.xml b/Common/loader-utils/pom.xml index 2a6d1a7..2a97bec 100644 --- a/Common/loader-utils/pom.xml +++ b/Common/loader-utils/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn Common - 1.9.4 + 1.10.0 loader-utils diff --git a/Common/pom.xml b/Common/pom.xml index 05a1d9f..e2c9efc 100644 --- a/Common/pom.xml +++ b/Common/pom.xml @@ -21,7 +21,7 @@ AntiVPN dev.brighten.antivpn - 1.9.4 + 1.10.0 pom diff --git a/Sponge/SpongeLoader/pom.xml b/Sponge/SpongeLoader/pom.xml index 762575f..c4c6604 100644 --- a/Sponge/SpongeLoader/pom.xml +++ b/Sponge/SpongeLoader/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn Sponge - 1.9.4 + 1.10.0 ../pom.xml @@ -104,7 +104,7 @@ dev.brighten.antivpn loader-utils - 1.9.4 + 1.10.0 compile diff --git a/Sponge/SpongePlugin/pom.xml b/Sponge/SpongePlugin/pom.xml index d19f754..21fecf6 100644 --- a/Sponge/SpongePlugin/pom.xml +++ b/Sponge/SpongePlugin/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn Sponge - 1.9.4 + 1.10.0 ../pom.xml @@ -49,13 +49,13 @@ dev.brighten.antivpn loader-utils - 1.9.4 + 1.10.0 provided dev.brighten.antivpn Source - 1.9.4 + 1.10.0 provided diff --git a/Sponge/pom.xml b/Sponge/pom.xml index 4e6ed3d..2b0d1f2 100644 --- a/Sponge/pom.xml +++ b/Sponge/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn AntiVPN - 1.9.4 + 1.10.0 pom diff --git a/Universal/pom.xml b/Universal/pom.xml index c243aad..e092308 100644 --- a/Universal/pom.xml +++ b/Universal/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn AntiVPN - 1.9.4 + 1.10.0 Universal diff --git a/Velocity/VelocityLoader/pom.xml b/Velocity/VelocityLoader/pom.xml index 8083e35..1d9598b 100644 --- a/Velocity/VelocityLoader/pom.xml +++ b/Velocity/VelocityLoader/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn Velocity - 1.9.4 + 1.10.0 ../pom.xml @@ -57,13 +57,13 @@ dev.brighten.antivpn loader-utils - 1.9.4 + 1.10.0 compile dev.brighten.antivpn VelocityPlugin - 1.9.4 + 1.10.0 provided diff --git a/Velocity/VelocityPlugin/pom.xml b/Velocity/VelocityPlugin/pom.xml index 5b97faf..45317d0 100644 --- a/Velocity/VelocityPlugin/pom.xml +++ b/Velocity/VelocityPlugin/pom.xml @@ -22,7 +22,7 @@ dev.brighten.antivpn AntiVPN - 1.9.4 + 1.10.0 ../../pom.xml @@ -51,7 +51,7 @@ dev.brighten.antivpn Source - 1.9.4 + 1.10.0 provided @@ -63,7 +63,7 @@ dev.brighten.antivpn loader-utils - 1.9.4 + 1.10.0 provided diff --git a/Velocity/pom.xml b/Velocity/pom.xml index 3633749..d126240 100644 --- a/Velocity/pom.xml +++ b/Velocity/pom.xml @@ -21,7 +21,7 @@ AntiVPN dev.brighten.antivpn - 1.9.4 + 1.10.0 pom 4.0.0 diff --git a/pom.xml b/pom.xml index f597903..8916900 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ dev.brighten.antivpn AntiVPN pom - 1.9.4 + 1.10.0 Common From 7ffba3899236031af9e44367262bbc56a63a8f5b Mon Sep 17 00:00:00 2001 From: Dawson Date: Tue, 20 Jan 2026 09:44:30 -0500 Subject: [PATCH 15/22] Improved performance of kicking players, will not allow players to remain on if API tells us we should block them. --- .../antivpn/bukkit/BukkitListener.java | 94 +++++------- .../antivpn/bungee/BungeeListener.java | 47 ++---- .../dev/brighten/antivpn/api/APIPlayer.java | 48 ++++-- .../dev/brighten/antivpn/api/CheckResult.java | 2 +- .../dev/brighten/antivpn/api/ResultType.java | 1 + .../dev/brighten/antivpn/api/VPNExecutor.java | 38 ++--- .../antivpn/sponge/SpongeListener.java | 59 ++++---- .../antivpn/velocity/VelocityListener.java | 142 +++--------------- .../antivpn/velocity/VelocityPlayer.java | 2 + 9 files changed, 153 insertions(+), 280 deletions(-) diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java index 813cdfb..fe16eea 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java @@ -18,12 +18,9 @@ package dev.brighten.antivpn.bukkit; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.api.APIPlayer; -import dev.brighten.antivpn.api.CheckResult; import dev.brighten.antivpn.api.OfflinePlayer; import dev.brighten.antivpn.api.VPNExecutor; -import dev.brighten.antivpn.message.VpnString; 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.event.EventHandler; @@ -36,7 +33,6 @@ import org.bukkit.event.player.PlayerQuitEvent; import java.util.logging.Level; -@SuppressWarnings("unchecked") public class BukkitListener extends VPNExecutor implements Listener { @Override @@ -81,66 +77,50 @@ public class BukkitListener extends VPNExecutor implements Listener { event.getAddress() )); - CheckResult instantResult = player.checkPlayer(result -> { + 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().isKickPlayers()) { - 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('&', - StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(), - player, - instantResult.response() - ))); - case DENIED_PROXY -> { - if(AntiVPN.getInstance().getVpnConfig().isAlertToSTaff()) { - AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() - .filter(APIPlayer::isAlertsEnabled) - .forEach(pl -> - pl.sendMessage(StringUtil.varReplace( - ChatColor.translateAlternateColorCodes( - '&', - AntiVPN.getInstance().getVpnConfig().getAlertMsg()), - player, - instantResult.response()))); - } - event.setKickMessage(StringUtil.translateAlternateColorCodes('&', - StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().getKickMessage(), - player, - instantResult.response() - ))); + if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { + return; } - } + + AntiVPN.getInstance().getExecutor().log(Level.INFO, "%s was kicked from pre-login cache with IP %s", event.getPlayer().getName(), result.response().getIp()); + + event.setResult(PlayerLoginEvent.Result.KICK_BANNED); + switch (result.resultType()) { + case DENIED_COUNTRY -> event.setKickMessage(StringUtil.translateAlternateColorCodes('&', + StringUtil.varReplace( + AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(), + player, + result.response() + ))); + case DENIED_PROXY -> { + if(AntiVPN.getInstance().getVpnConfig().isAlertToSTaff()) { + AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() + .filter(APIPlayer::isAlertsEnabled) + .forEach(pl -> + pl.sendMessage(StringUtil.varReplace( + ChatColor.translateAlternateColorCodes( + '&', + AntiVPN.getInstance().getVpnConfig().getAlertMsg()), + player, + result.response()))); + } + event.setKickMessage(StringUtil.translateAlternateColorCodes('&', + StringUtil.varReplace( + AntiVPN.getInstance().getVpnConfig().getKickMessage(), + player, + result.response() + ))); + } + } + }); } - @EventHandler(priority = EventPriority.MONITOR) + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onJoin(final PlayerJoinEvent event) { AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId()) - .ifPresent(player -> AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> - AntiVPN.getInstance().getDatabase().alertsState(player.getUuid(), state -> { - if(state) { - player.setAlertsEnabled(true); - player.sendMessage(AntiVPN.getInstance().getMessageHandler() - .getString("command-alerts-toggled") - .getFormattedMessage(new VpnString.Var<>("state", true))); - } - }))); + .ifPresent(APIPlayer::checkAlertsState); } @EventHandler diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java index d234c7f..407337d 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -19,10 +19,7 @@ package dev.brighten.antivpn.bungee; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.api.*; 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.LoginEvent; import net.md_5.bungee.api.event.PlayerDisconnectEvent; import net.md_5.bungee.api.event.PreLoginEvent; import net.md_5.bungee.api.plugin.Listener; @@ -89,43 +86,19 @@ public class BungeeListener extends VPNExecutor implements Listener { ((InetSocketAddress) event.getConnection().getSocketAddress()).getAddress()); }); - CheckResult instantResult = player.checkPlayer(result -> { + player.checkPlayer(result -> { if (!result.resultType().isShouldBlock()) return; - AntiVPN.getInstance().getExecutor().getToKick() - .add(new Tuple<>(result, player.getUuid())); + event.setCancelled(true); }); + } - if (!instantResult.resultType().isShouldBlock()) { - return; - } + @EventHandler(priority = EventPriority.HIGH) + public void onJoin(LoginEvent event) { + if(event.isCancelled()) return; - AntiVPN.getInstance().getExecutor().getToKick() - .add(new Tuple<>(instantResult, player.getUuid())); - - if (!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { - 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().getKickMessage(), - player, - instantResult.response())))); - case DENIED_COUNTRY -> event.setReason(TextComponent.fromLegacy(ChatColor - .translateAlternateColorCodes('&', - StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(), - player, - instantResult.response())))); - } + // Handling player alerts on join + AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getConnection().getUniqueId()) + .ifPresent(APIPlayer::checkAlertsState); } @EventHandler diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java index 3f4a35a..0bf5200 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/APIPlayer.java @@ -19,6 +19,7 @@ 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 dev.brighten.antivpn.message.VpnString; import lombok.Getter; import lombok.Setter; @@ -55,24 +56,46 @@ public abstract class APIPlayer { public void updateAlertsState() { //Updating into database so its synced across servers and saved on logout. - AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> AntiVPN.getInstance().getDatabase().updateAlertsState(uuid, alertsEnabled)); + AntiVPN.getInstance().getDatabase().updateAlertsState(uuid, alertsEnabled); + + sendMessage(AntiVPN.getInstance().getMessageHandler() + .getString("command-alerts-toggled") + .getFormattedMessage(new VpnString.Var<>("state", alertsEnabled))); } - public CheckResult checkPlayer(Consumer onKick) { + public void checkAlertsState() { + AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> + AntiVPN.getInstance().getDatabase().alertsState(uuid, state -> { + if(state) { + alertsEnabled = true; + updateAlertsState(); + } + }) + ); + } + + public void checkPlayer(Consumer onResult) { 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() + "/32") || AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream() - .anyMatch(name::startsWith)) return new CheckResult(null, ResultType.WHITELISTED); + .anyMatch(name::startsWith)) { + onResult.accept(new CheckResult(null, ResultType.WHITELISTED, false)); + return; + } CheckResult cachedResult = checkResultCache.getIfPresent(ip.getHostAddress()); if(cachedResult != null) { if(cachedResult.response().getIp().equals(ip.getHostAddress())) { AntiVPN.getInstance().getExecutor().log(Level.FINE, "Cached result for " + ip.getHostAddress() + " is " + cachedResult.resultType()); - return cachedResult; + if(cachedResult.resultType().isShouldBlock()) { + AntiVPN.getInstance().getExecutor().handleKickingOfPlayer(cachedResult, this); + } + onResult.accept(cachedResult); + return; } } @@ -82,6 +105,8 @@ public abstract class APIPlayer { AntiVPN.getInstance().getExecutor().log(Level.WARNING, "The API query was not a success! " + "You may need to upgrade your license on " + "https://funkemunky.cc/shop"); + onResult.accept(new CheckResult(null, ResultType.API_FAILURE, false)); + return; } // If the countryList() size is zero, no need to check. // Running country check first @@ -99,19 +124,22 @@ public abstract class APIPlayer { .contains(result.getCountryCode()) != AntiVPN.getInstance().getVpnConfig().getWhitelistCountries()) { //Using our built in kicking system if no commands are configured - checkResult = new CheckResult(result, ResultType.DENIED_COUNTRY); + checkResult = new CheckResult(result, ResultType.DENIED_COUNTRY, false); } else if (result.isProxy()) { - checkResult = new CheckResult(result, ResultType.DENIED_PROXY); + checkResult = new CheckResult(result, ResultType.DENIED_PROXY, false); } else { - checkResult = new CheckResult(result, ResultType.ALLOWED); + checkResult = new CheckResult(result, ResultType.ALLOWED, false); } AntiVPN.getInstance().getExecutor().log(Level.FINE, "Result for " + ip.getHostAddress() + " is " + checkResult.resultType()); - checkResultCache.put(ip.getHostAddress(), checkResult); - onKick.accept(checkResult); + checkResultCache.put(ip.getHostAddress(), new CheckResult(checkResult.response(), checkResult.resultType(), true)); + if(checkResult.resultType().isShouldBlock()) { + AntiVPN.getInstance().getExecutor().handleKickingOfPlayer(checkResult, this); + } + onResult.accept(checkResult); AntiVPN.getInstance().checked++; }); - return new CheckResult(null, ResultType.UNKNOWN); + onResult.accept(new CheckResult(null, ResultType.UNKNOWN, false)); } } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/CheckResult.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/CheckResult.java index abfdc0d..d10c57b 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/CheckResult.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/CheckResult.java @@ -18,5 +18,5 @@ package dev.brighten.antivpn.api; import dev.brighten.antivpn.web.objects.VPNResponse; -public record CheckResult(VPNResponse response, ResultType resultType) { +public record CheckResult(VPNResponse response, ResultType resultType, boolean isFromCache) { } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/ResultType.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/ResultType.java index 1f8bec9..3047385 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/ResultType.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/ResultType.java @@ -23,6 +23,7 @@ public enum ResultType { WHITELISTED(false), DENIED_COUNTRY(true), DENIED_PROXY(true), + API_FAILURE(false), UNKNOWN(false); @Getter diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java index 4749be3..623ca0d 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -28,23 +28,18 @@ import lombok.Getter; import java.io.IOException; import java.net.UnknownHostException; 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.concurrent.*; import java.util.logging.Level; +@Getter public abstract class VPNExecutor { - @Getter private final ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2); - - @Getter private final Set whitelisted = Collections.synchronizedSet(new HashSet<>()); - @Getter private final Set whitelistedIps = Collections.synchronizedSet(new HashSet<>()); + private final Queue> toKick = new LinkedBlockingQueue<>(); + private final Queue playersToRecheck = new LinkedBlockingQueue<>(); + private ScheduledFuture kickTask = null; - @Getter - private final List> toKick = Collections.synchronizedList(new LinkedList<>()); public abstract void registerListeners(); @@ -61,15 +56,13 @@ public abstract class VPNExecutor { } public void startKickChecks() { - threadExecutor.scheduleAtFixedRate(() -> { + kickTask = threadExecutor.scheduleAtFixedRate(() -> { synchronized (toKick) { if(toKick.isEmpty()) return; - Iterator> i = toKick.iterator(); - - while(i.hasNext()) { - var toCheck = i.next(); + Tuple toCheck; + while((toCheck = toKick.poll()) != null) { Optional player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(toCheck.second()); if(player.isEmpty()) { @@ -77,14 +70,18 @@ public abstract class VPNExecutor { } handleKickingOfPlayer(toCheck.first(), player.get()); - - i.remove(); } } }, 8, 2, TimeUnit.SECONDS); } public void handleKickingOfPlayer(CheckResult result, APIPlayer player) { + + //Ensuring kick task is always running + if(kickTask == null || kickTask.isDone() || kickTask.isCancelled()) { + startKickChecks(); + } + if (AntiVPN.getInstance().getVpnConfig().isAlertToSTaff()) AntiVPN.getInstance().getPlayerExecutor() .getOnlinePlayers() .stream() @@ -101,10 +98,10 @@ public abstract class VPNExecutor { case DENIED_COUNTRY -> player.kickPlayer(StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() .getCountryVanillaKickReason(), player, result.response())); } + } else { + if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) return; } - if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) return; - switch (result.resultType()) { case DENIED_PROXY -> { for (String command : AntiVPN.getInstance().getVpnConfig().commands()) { @@ -119,6 +116,9 @@ public abstract class VPNExecutor { } } } + + //Ensuring players are actually kicked as they are supposed to be. + toKick.add(new Tuple<>(result, player.getUuid())); } public boolean isWhitelisted(UUID uuid) { diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java index 99275d7..991e0ba 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java @@ -19,7 +19,6 @@ 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; @@ -42,44 +41,38 @@ public class SpongeListener extends VPNExecutor { 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())); + player.get().checkPlayer(result -> { + if(!result.resultType().isShouldBlock()) return; + + if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { + return; } - }); - if(!instantResult.resultType().isShouldBlock()) { - return; - } - - AntiVPN.getInstance().getExecutor().getToKick().add(new Tuple<>(instantResult, player.get().getUuid())); - - if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { - 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 -> { - 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() - .getKickMessage() - .replace("%player%", player.get().getName()) - .replace("%country%", instantResult.response().getCountryName()) - .replace("%code%", instantResult.response().getCountryCode())))); + if(result.isFromCache()) { + AntiVPN.getInstance().getExecutor().log(Level.INFO, "%s was kicked from cache with IP %s", player.get().getName(), result.response().getIp()); } - case DENIED_COUNTRY -> + + event.setCancelled(true); + switch (result.resultType()) { + case DENIED_PROXY -> { + AntiVPN.getInstance().getExecutor().log(Level.INFO, player.get().getName() + + " joined on a VPN/Proxy (" + result.response().getMethod() + ")"); event.setMessage(Component.text(StringUtil .translateColorCodes('&', AntiVPN.getInstance().getVpnConfig() - .getCountryVanillaKickReason() + .getKickMessage() .replace("%player%", player.get().getName()) - .replace("%country%", instantResult.response().getCountryName()) - .replace("%code%", instantResult.response().getCountryCode())))); - } + .replace("%country%", result.response().getCountryName()) + .replace("%code%", result.response().getCountryCode())))); + } + case DENIED_COUNTRY -> + event.setMessage(Component.text(StringUtil + .translateColorCodes('&', AntiVPN.getInstance().getVpnConfig() + .getCountryVanillaKickReason() + .replace("%player%", player.get().getName()) + .replace("%country%", result.response().getCountryName()) + .replace("%code%", result.response().getCountryCode())))); + } + }); } @Listener diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java index 601423d..e797796 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -21,14 +21,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.utils.StringUtil; -import dev.brighten.antivpn.web.objects.VPNResponse; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import java.util.concurrent.TimeUnit; import java.util.logging.Level; public class VelocityListener extends VPNExecutor { @@ -52,135 +49,34 @@ public class VelocityListener extends VPNExecutor { event.getPlayer().getRemoteAddress().getAddress() )); - CheckResult instantResult = player.checkPlayer(result -> { + 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() + switch (result.resultType()) { + case DENIED_COUNTRY -> event.setResult(ResultedEvent.ComponentResult.denied( + LegacyComponentSerializer.builder() + .character('&') + .build().deserialize(AntiVPN.getInstance().getVpnConfig() + .getCountryVanillaKickReason() + .replace("%player%", event.getPlayer().getUsername()) + .replace("%country%", result.response().getCountryName()) + .replace("%code%", result.response().getCountryCode())))); + case DENIED_PROXY -> { + VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername() + + " joined on a VPN/Proxy (" + result.response().getMethod() + ")"); + event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder() .character('&') .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .getCountryVanillaKickReason() + .getKickMessage() .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() - .getKickMessage() - .replace("%player%", event.getPlayer().getUsername()) - .replace("%country%", instantResult.response().getCountryName()) - .replace("%code%", instantResult.response().getCountryCode())))); + .replace("%country%", result.response().getCountryName()) + .replace("%code%", result.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().isAlertToSTaff()) - AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() - .filter(APIPlayer::isAlertsEnabled) - .forEach(pl -> - pl.sendMessage(dev.brighten.antivpn.AntiVPN.getInstance().getVpnConfig() - .getAlertMsg() - .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().isKickPlayers()) { - switch (checkResult.resultType()) { - case DENIED_PROXY -> VelocityPlugin.INSTANCE.getServer().getScheduler() - .buildTask(VelocityPlugin.INSTANCE.getPluginInstance(), () -> - event.getPlayer().disconnect(LegacyComponentSerializer.builder() - .character('&') - .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .getKickMessage() - .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.getPluginInstance(), () -> - event.getPlayer().disconnect(LegacyComponentSerializer.builder() - .character('&') - .build().deserialize(AntiVPN.getInstance().getVpnConfig() - .getCountryVanillaKickReason() - .replace("%player%", event.getPlayer().getUsername()) - .replace("%country%", result.getCountryName()) - .replace("%code%", result.getCountryCode())))) - .delay(1, TimeUnit.SECONDS).schedule(); - } - } - - if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) 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); - } - } - } - - } - @Override public void log(Level level, String log, Object... objects) { VelocityPlugin.INSTANCE.getLogger().log(level, String.format(log, objects)); diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayer.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayer.java index 03a127e..eb613e4 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayer.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlayer.java @@ -44,4 +44,6 @@ public class VelocityPlayer extends APIPlayer { public boolean hasPermission(String permission) { return player.hasPermission(permission); } + + } From e09217877cac787931dc41dc9097bc3d85601f75 Mon Sep 17 00:00:00 2001 From: Dawson Date: Tue, 27 Jan 2026 10:25:03 -0500 Subject: [PATCH 16/22] Update platform listeners to ensure consistent kick functionality --- .../antivpn/bukkit/BukkitListener.java | 37 ++++++------------- .../antivpn/bungee/BungeeListener.java | 14 +++++++ .../brighten/antivpn/utils/StringUtil.java | 4 +- .../antivpn/sponge/SpongeListener.java | 32 ++++------------ .../antivpn/velocity/VelocityListener.java | 4 ++ 5 files changed, 39 insertions(+), 52 deletions(-) diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java index fe16eea..d124b1c 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java @@ -84,36 +84,21 @@ 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(), result.response().getIp()); - event.setResult(PlayerLoginEvent.Result.KICK_BANNED); - switch (result.resultType()) { - case DENIED_COUNTRY -> event.setKickMessage(StringUtil.translateAlternateColorCodes('&', + event.setKickMessage(switch (result.resultType()) { + case DENIED_COUNTRY -> StringUtil.varReplace( + AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(), + player, + result.response() + ); + case DENIED_PROXY -> StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(), + AntiVPN.getInstance().getVpnConfig().getKickMessage(), player, result.response() - ))); - case DENIED_PROXY -> { - if(AntiVPN.getInstance().getVpnConfig().isAlertToSTaff()) { - AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream() - .filter(APIPlayer::isAlertsEnabled) - .forEach(pl -> - pl.sendMessage(StringUtil.varReplace( - ChatColor.translateAlternateColorCodes( - '&', - AntiVPN.getInstance().getVpnConfig().getAlertMsg()), - player, - result.response()))); - } - event.setKickMessage(StringUtil.translateAlternateColorCodes('&', - StringUtil.varReplace( - AntiVPN.getInstance().getVpnConfig().getKickMessage(), - player, - result.response() - ))); - } - } + ); + default -> "You were kicked by KauriVPN for an unknown reason!"; + }); }); } diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java index 407337d..601f2ba 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -19,6 +19,8 @@ package dev.brighten.antivpn.bungee; import dev.brighten.antivpn.AntiVPN; import dev.brighten.antivpn.api.*; import dev.brighten.antivpn.utils.MiscUtils; +import dev.brighten.antivpn.utils.StringUtil; +import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.event.LoginEvent; import net.md_5.bungee.api.event.PlayerDisconnectEvent; import net.md_5.bungee.api.event.PreLoginEvent; @@ -88,7 +90,19 @@ public class BungeeListener extends VPNExecutor implements Listener { player.checkPlayer(result -> { if (!result.resultType().isShouldBlock()) return; + + if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { + return; + } + event.setCancelled(true); + event.setReason(TextComponent.fromLegacy(StringUtil.varReplace(switch (result.resultType()) { + case DENIED_PROXY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() + .getKickMessage(), player, result.response()); + case DENIED_COUNTRY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() + .getCountryVanillaKickReason(), player, result.response()); + default -> "You were kicked by KauriVPN for an unknown reason!"; + }, player, result.response()))); }); } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java index 8b3e0b9..32d4532 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java @@ -54,10 +54,10 @@ public class StringUtil { } public static String varReplace(String input, APIPlayer player, VPNResponse result) { - return input.replace("%player%", player.getName()) + return translateAlternateColorCodes('&', input.replace("%player%", player.getName()) .replace("%reason%", result.getMethod()) .replace("%country%", result.getCountryName()) - .replace("%city%", result.getCity()); + .replace("%city%", result.getCity())); } public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) { diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java index 991e0ba..1346e6d 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java @@ -18,7 +18,7 @@ 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.StringUtil; import net.kyori.adventure.text.Component; import org.spongepowered.api.Sponge; import org.spongepowered.api.command.exception.CommandException; @@ -48,30 +48,14 @@ public class SpongeListener extends VPNExecutor { return; } - if(result.isFromCache()) { - AntiVPN.getInstance().getExecutor().log(Level.INFO, "%s was kicked from cache with IP %s", player.get().getName(), result.response().getIp()); - } - event.setCancelled(true); - switch (result.resultType()) { - case DENIED_PROXY -> { - AntiVPN.getInstance().getExecutor().log(Level.INFO, player.get().getName() - + " joined on a VPN/Proxy (" + result.response().getMethod() + ")"); - event.setMessage(Component.text(StringUtil - .translateColorCodes('&', AntiVPN.getInstance().getVpnConfig() - .getKickMessage() - .replace("%player%", player.get().getName()) - .replace("%country%", result.response().getCountryName()) - .replace("%code%", result.response().getCountryCode())))); - } - case DENIED_COUNTRY -> - event.setMessage(Component.text(StringUtil - .translateColorCodes('&', AntiVPN.getInstance().getVpnConfig() - .getCountryVanillaKickReason() - .replace("%player%", player.get().getName()) - .replace("%country%", result.response().getCountryName()) - .replace("%code%", result.response().getCountryCode())))); - } + event.setMessage(Component.text(switch (result.resultType()) { + case DENIED_PROXY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() + .getKickMessage(), player.get(), result.response()); + case DENIED_COUNTRY -> StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig() + .getCountryVanillaKickReason(), player.get(), result.response()); + default -> "You were kicked by KauriVPN for an unknown reason!"; + })); }); } diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java index e797796..66e0c50 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityListener.java @@ -52,6 +52,10 @@ public class VelocityListener extends VPNExecutor { player.checkPlayer(result -> { if(!result.resultType().isShouldBlock()) return; + if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) { + return; + } + switch (result.resultType()) { case DENIED_COUNTRY -> event.setResult(ResultedEvent.ComponentResult.denied( LegacyComponentSerializer.builder() From dddd860c15e0454363defd1a40cc5af6e29fc332 Mon Sep 17 00:00:00 2001 From: Dawson Date: Tue, 27 Jan 2026 10:25:21 -0500 Subject: [PATCH 17/22] Delay command execution to prevent messaging errors --- .../dev/brighten/antivpn/api/VPNExecutor.java | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java index 623ca0d..dfaf6c8 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -102,19 +102,26 @@ public abstract class VPNExecutor { if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) 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()))); + Runnable runCommands = () -> { + switch (result.resultType()) { + case DENIED_PROXY -> { + for (String command : AntiVPN.getInstance().getVpnConfig().commands()) { + runCommand(StringUtil.varReplace(command, player, result.response())); + } + } + case DENIED_COUNTRY -> { + for (String command : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) { + runCommand(StringUtil.varReplace(command, player, result.response())); + } } } + }; + + // Fixes the commands running too fast and causing messaging errors by any downstream plugins like LiteBans + var scheduleResult = threadExecutor.schedule(runCommands, 1, TimeUnit.SECONDS); + + if(scheduleResult.isCancelled()) { + runCommands.run(); } //Ensuring players are actually kicked as they are supposed to be. From 50c357f5082847346239fa8bb34a2d0363b13077 Mon Sep 17 00:00:00 2001 From: Dawson Date: Tue, 27 Jan 2026 10:25:36 -0500 Subject: [PATCH 18/22] Standarized isWhitelisted to make sure it only accepts cidr strings --- .../java/dev/brighten/antivpn/api/VPNExecutor.java | 6 +++--- .../dev/brighten/antivpn/database/VPNDatabase.java | 2 +- .../dev/brighten/antivpn/database/local/H2VPN.java | 4 ++-- .../dev/brighten/antivpn/database/mongo/MongoVPN.java | 11 ++++++----- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java index dfaf6c8..6a9f870 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/api/VPNExecutor.java @@ -135,12 +135,12 @@ public abstract class VPNExecutor { return whitelisted.contains(uuid); } - public boolean isWhitelisted(String ip) { + public boolean isWhitelisted(String cidr) { if(AntiVPN.getInstance().getVpnConfig().isDatabaseEnabled()) { - return AntiVPN.getInstance().getDatabase().isWhitelisted(ip); + return AntiVPN.getInstance().getDatabase().isWhitelisted(cidr); } try { - return whitelistedIps.contains(new CIDRUtils(ip)); + return whitelistedIps.contains(new CIDRUtils(cidr)); } catch (UnknownHostException e) { throw new RuntimeException(e); } diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java index 8823756..02b958e 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/VPNDatabase.java @@ -33,7 +33,7 @@ public interface VPNDatabase { boolean isWhitelisted(UUID uuid); - boolean isWhitelisted(String ip); + boolean isWhitelisted(String cidr); boolean isWhitelisted(CIDRUtils cidr); diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java index 100a378..b0a1971 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/local/H2VPN.java @@ -152,8 +152,8 @@ public class H2VPN implements VPNDatabase { @SneakyThrows @Override - public boolean isWhitelisted(String ip) { - return isWhitelisted(new CIDRUtils(ip)); + public boolean isWhitelisted(String cidr) { + return isWhitelisted(new CIDRUtils(cidr)); } @Override diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java index 625c3aa..cd8fe24 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/database/mongo/MongoVPN.java @@ -144,11 +144,11 @@ public class MongoVPN implements VPNDatabase { } @Override - public boolean isWhitelisted(String ip) { + public boolean isWhitelisted(String cidr) { try { - return isWhitelisted(new CIDRUtils(ip)); + return isWhitelisted(new CIDRUtils(cidr)); } catch (UnknownHostException e) { - AntiVPN.getInstance().getExecutor().log("Failed to check whitelist for IP: " + ip, e); + AntiVPN.getInstance().getExecutor().log("Failed to check whitelist for IP: " + cidr, e); return false; } } @@ -157,7 +157,7 @@ public class MongoVPN implements VPNDatabase { public boolean isWhitelisted(CIDRUtils cidr) { var start = new Decimal128(new BigDecimal(cidr.getStartIpInt())); var end = new Decimal128(new BigDecimal(cidr.getEndIpInt())); - return settingsDocument.find(Filters.and(Filters.eq("setting", "whitelisted"), + return settingsDocument.find(Filters.and(Filters.eq("setting", "whitelist"), Filters.lte("ip_start", start), Filters.gte("ip_end", end))).first() != null; } @@ -193,7 +193,8 @@ public class MongoVPN implements VPNDatabase { settingsDocument.deleteMany(Filters .and( Filters.eq("setting", "whitelist"), - Filters.eq("cidr_string", cidr.toString()))); + Filters.eq("ip_start", new Decimal128(new BigDecimal(cidr.getStartIpInt()))), + Filters.eq("ip_end", new Decimal128(new BigDecimal(cidr.getEndIpInt()))))); } @Override From 17cbed8bda809b5a7e776658f974712044c92374 Mon Sep 17 00:00:00 2001 From: Dawson Date: Tue, 27 Jan 2026 10:25:47 -0500 Subject: [PATCH 19/22] Standarized logging calls across platforms --- .../main/java/dev/brighten/antivpn/bungee/BungeeListener.java | 2 +- .../main/java/dev/brighten/antivpn/sponge/SpongeListener.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java index 601f2ba..b09cab2 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeeListener.java @@ -50,7 +50,7 @@ public class BungeeListener extends VPNExecutor implements Listener { @Override public void log(String log, Object... objects) { - log(Level.INFO, String.format(log, objects)); + log(Level.INFO, log, objects); } @Override diff --git a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java index 1346e6d..6c38d97 100644 --- a/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java +++ b/Sponge/SpongePlugin/src/main/java/dev/brighten/antivpn/sponge/SpongeListener.java @@ -83,7 +83,7 @@ public class SpongeListener extends VPNExecutor { @Override public void log(String log, Object... objects) { - log(Level.INFO, String.format(log, objects)); + log(Level.INFO, log, objects); } @Override From e044d27e27b016b3765017fab55c12145eba16f1 Mon Sep 17 00:00:00 2001 From: Dawson Date: Tue, 27 Jan 2026 10:26:07 -0500 Subject: [PATCH 20/22] Removed redundant "Disabling AntiVPN..." log message on Velocity --- .../main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java index 93f5f29..a93f180 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java @@ -104,7 +104,6 @@ public class VelocityPlugin implements LoaderBootstrap { @Override public void onDisable() { - logger.info("Disabling AntiVPN..."); AntiVPN.getInstance().getExecutor().log("Disabling AntiVPN..."); if (AntiVPN.getInstance().getDatabase() != null) { From 5792b81cb10d89ce0cceb581180e8ebe6fe5dd02 Mon Sep 17 00:00:00 2001 From: Dawson Date: Tue, 27 Jan 2026 10:27:56 -0500 Subject: [PATCH 21/22] Correcting logic bug with getDatabaseType function, removing unnecessary function in StringUtil --- .../brighten/antivpn/bukkit/BukkitPlugin.java | 6 ++--- .../brighten/antivpn/bungee/BungeePlugin.java | 7 +++--- .../java/dev/brighten/antivpn/AntiVPN.java | 2 +- .../brighten/antivpn/utils/StringUtil.java | 25 ------------------- .../antivpn/velocity/VelocityPlugin.java | 9 +++---- 5 files changed, 11 insertions(+), 38 deletions(-) diff --git a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java index 2ca99ae..1cab6a2 100644 --- a/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java +++ b/Bukkit/Plugin/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java @@ -149,10 +149,10 @@ public class BukkitPlugin implements LoaderBootstrap { private String getDatabaseType() { VPNDatabase database = AntiVPN.getInstance().getDatabase(); - if(database instanceof H2VPN) { - return "H2"; - } else if(database instanceof MySqlVPN) { + if(database instanceof MySqlVPN) { return "MySQL"; + } else if(database instanceof H2VPN) { + return "H2"; } else if(database instanceof MongoVPN) { return "MongoDB"; } else { diff --git a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java index 5ef8317..15bb2ac 100644 --- a/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java +++ b/Bungee/BungeePlugin/src/main/java/dev/brighten/antivpn/bungee/BungeePlugin.java @@ -85,11 +85,10 @@ public class BungeePlugin implements LoaderBootstrap { private String getDatabaseType() { VPNDatabase database = AntiVPN.getInstance().getDatabase(); - - if(database instanceof H2VPN) { - return "H2"; - } else if(database instanceof MySqlVPN) { + if(database instanceof MySqlVPN) { return "MySQL"; + } else if(database instanceof H2VPN) { + return "H2"; } else if(database instanceof MongoVPN) { return "MongoDB"; } else { diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java index 4daf09e..944b2f6 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/AntiVPN.java @@ -125,7 +125,7 @@ public class AntiVPN { break; } case "mysql": - case "sql":{ + case "sql": { AntiVPN.getInstance().getExecutor().log("Using databaseType MySQL..."); INSTANCE.database = new MySqlVPN(); INSTANCE.database.init(); diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java index 32d4532..2fe79fe 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/StringUtil.java @@ -16,12 +16,6 @@ package dev.brighten.antivpn.utils; -import dev.brighten.antivpn.AntiVPN; - -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - import dev.brighten.antivpn.api.APIPlayer; import dev.brighten.antivpn.web.objects.VPNResponse; @@ -34,25 +28,6 @@ public class StringUtil { return "&m-----------------------------------------------------"; } - public static String getHash(String input) { - try { - MessageDigest digest = MessageDigest.getInstance("SHA1"); - byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8)); - StringBuilder hexString = new StringBuilder(2 * hash.length); - for (byte b : hash) { - String hex = Integer.toHexString(0xff & b); - if (hex.length() == 1) { - hexString.append('0'); - } - hexString.append(hex); - } - return hexString.toString(); - } catch (NoSuchAlgorithmException e) { - AntiVPN.getInstance().getExecutor().logException(e); - } - return null; - } - public static String varReplace(String input, APIPlayer player, VPNResponse result) { return translateAlternateColorCodes('&', input.replace("%player%", player.getName()) .replace("%reason%", result.getMethod()) diff --git a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java index a93f180..10760a1 100644 --- a/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java +++ b/Velocity/VelocityPlugin/src/main/java/dev/brighten/antivpn/velocity/VelocityPlugin.java @@ -61,12 +61,11 @@ public class VelocityPlugin implements LoaderBootstrap { private String getDatabaseType() { VPNDatabase database = AntiVPN.getInstance().getDatabase(); - - if(database instanceof H2VPN) { - return "H2"; - } else if(database instanceof MySqlVPN) { + if(database instanceof MySqlVPN) { return "MySQL"; - } else if(database instanceof MongoVPN) { + } else if(database instanceof H2VPN) { + return "H2"; + } else if(database instanceof MongoVPN) { return "MongoDB"; } else { return "No-Database"; From de6dc8aa7bec70d489b932670a4db4d8f54cbcba Mon Sep 17 00:00:00 2001 From: Dawson Date: Fri, 20 Feb 2026 08:57:54 -0500 Subject: [PATCH 22/22] Adding mojang API backup --- .../dev/brighten/antivpn/utils/MiscUtils.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Common/Source/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java b/Common/Source/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java index c737bb3..28d0735 100644 --- a/Common/Source/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java +++ b/Common/Source/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java @@ -72,18 +72,6 @@ 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 @@ -93,12 +81,26 @@ public class MiscUtils { return UUID.fromString(object.getString("uuid")); } } catch (IOException | JSONException e) { - AntiVPN.getInstance().getExecutor().logException("Error while looking up UUID for " + playername, e); + AntiVPN.getInstance().getExecutor().logException("Error while looking up UUID for " + playername + "! Falling back to Mojang API", e); + return lookupMojangUuid(playername); } return null; } + private static UUID lookupMojangUuid(String playerName) { + try { + JSONObject object = JsonReader.readJsonFromUrl("https://api.mojang.com/users/profiles/minecraft/" + playerName); + + if(object.has("id")) { + return UUID.fromString(object.getString("id")); + } + } catch (IOException | JSONException e) { + AntiVPN.getInstance().getExecutor().logException("Error while looking up UUID for " + playerName + " from Mojang!:", e); + } + + return null; + } public static boolean isIpv4(String ip) { return ipv4.matcher(ip).matches();