mirror of
https://github.com/funkemunky/AntiVPN.git
synced 2026-05-31 09:31:54 +00:00
Start of versioning database functions and handling errors
This commit is contained in:
@@ -173,6 +173,12 @@
|
||||
<version>3.12.14</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>26.0.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -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<Command> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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 <a href="https://funkemunky.cc/shop">...</a> 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<String> 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<String> 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<String> 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<String> 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<String> 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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<UUID> whitelisted = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
@Getter
|
||||
private final Set<String> 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())));
|
||||
}
|
||||
|
||||
@@ -41,4 +41,4 @@ public interface VPNDatabase {
|
||||
void init();
|
||||
|
||||
void shutdown();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<H2VPN> {
|
||||
|
||||
List<H2Version> versions = new ArrayList<>();
|
||||
|
||||
static void registerVersions() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.brighten.antivpn.database.version;
|
||||
|
||||
public interface Version<DB> {
|
||||
void update(DB database) throws Exception;
|
||||
int versionNumber();
|
||||
boolean needsUpdate(DB database);
|
||||
}
|
||||
@@ -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<Byte> newArr = new ArrayList<Byte>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user