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