Compare commits

...

14 Commits

Author SHA1 Message Date
Dawson Hessler e03deb6ba6 1.6.1 2022-02-08 14:56:06 -05:00
Dawson Hessler 6142ef603d Merge branch 'master' of https://github.com/funkemunky/AntiVPN 2022-02-08 14:55:39 -05:00
Dawson Hessler 2d82e0c433 Fixing potential memory leak 2022-02-08 14:55:37 -05:00
Dawson 3b629f4796 Merge pull request #15 from unbeproducoes/patch-1
Try to use the new MySQL driver first.
2022-02-06 11:29:28 -05:00
Unbê Produções 23481bd786 Check the new driver before the old one 2022-02-05 02:27:02 -03:00
Unbê Produções 46156c4286 update MySQL Driver
=3
2022-02-05 02:19:22 -03:00
Dawson Hessler cd502b6f34 Adding mongo support and /antivpn clearcache command 2022-01-12 15:37:02 -05:00
Dawson Hessler 7ee04b74ea Fixing config 2021-12-22 09:51:26 -05:00
Dawson Hessler 206d375bbd Fixing version and sql on load 2021-12-19 13:48:05 -05:00
Dawson Hessler cba3c2f2d9 Fixing KauriVPN on Velocity 1.5.2.1 2021-12-19 13:45:53 -05:00
Dawson Hessler 5ec4cb98e3 Starting to implement h2, fixing Java 17 bug, v1.5.2 2021-12-14 10:34:23 -05:00
Dawson Hessler e44bd5843d Working on mysql missing libraries 2021-11-06 13:01:56 -04:00
Dawson Hessler a9d356a04a 1.5.1
- Added ip exemptions in addition to the existing player exemptions./
- Fixing System.out usage warnings that some users were experiencing.
- Fixing MySQL drivers not loading on some servers.
- Fixing bug that would make whitelisted players not load for awhile after server starts
2021-11-04 10:36:31 -04:00
Dawson Hessler 5ba19b42f9 1.5.1 KauriVPN plugin.yml rename and System print fix 2021-11-04 08:27:32 -04:00
36 changed files with 870 additions and 137 deletions
+2 -2
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.5.0</version>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Assembly</artifactId>
@@ -35,8 +35,8 @@
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>8</maven.compiler.source>
</properties>
</project>
+3 -3
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.5.0</version>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -46,13 +46,13 @@
</dependency>
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<artifactId>Velocity</artifactId>
<version>${version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Velocity</artifactId>
<artifactId>Common</artifactId>
<version>${version}</version>
<scope>compile</scope>
</dependency>
+21 -3
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.5.0</version>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Bukkit</artifactId>
@@ -56,8 +56,26 @@
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.5.0</version>
<version>1.6.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>toml4j</artifactId>
<groupId>com.moandjiezana.toml</groupId>
</exclusion>
<exclusion>
<artifactId>mysql-connector-java</artifactId>
<groupId>mysql</groupId>
</exclusion>
<exclusion>
<artifactId>h2</artifactId>
<groupId>com.h2database</groupId>
</exclusion>
<exclusion>
<artifactId>mongo-java-driver</artifactId>
<groupId>org.mongodb</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cc.funkemunky.utils</groupId>
@@ -67,8 +85,8 @@
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>8</maven.compiler.source>
</properties>
</project>
+2 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.5.0</version>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -69,7 +69,7 @@
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.5.0</version>
<version>1.6.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -18,18 +18,19 @@ public class BukkitConfig implements VPNConfig {
"database.type", BukkitPlugin.pluginInstance),
defaultDatabaseName = new ConfigDefault<>("kaurivpn",
"database.database", BukkitPlugin.pluginInstance),
defaultMongoURL = new ConfigDefault<>("", "database.mongoURL", BukkitPlugin.pluginInstance),
defaultUsername = new ConfigDefault<>("root",
"database.username", BukkitPlugin.pluginInstance),
defaultPassword = new ConfigDefault<>("password",
"database.password", BukkitPlugin.pluginInstance),
defaultAuthDatabase = new ConfigDefault<>("admin",
"database.auth", BukkitPlugin.pluginInstance),
defaultIp = new ConfigDefault<>("localhost", "database.ip", BukkitPlugin.pluginInstance),
defaultAlertMsg = new ConfigDefault<>("&8[&6KauriVPN&8] &e%player% &7has joined on a VPN/proxy" +
" &8(&f%reason%&8) &7in location &8(&f%city%&7, &f%country%&8)", "alerts.message",
BukkitPlugin.pluginInstance);
private final ConfigDefault<Boolean> cacheResultsDefault = new ConfigDefault<>(true,
"cachedResults", BukkitPlugin.pluginInstance),
defaultUseCredentials = new ConfigDefault<>(true,
"database.useCredentials", BukkitPlugin.pluginInstance),
defaultDatabaseEnabled = new ConfigDefault<>(false, "database.enabled",
BukkitPlugin.pluginInstance), defaultCommandsEnable = new ConfigDefault<>(false,
"commands.enabled", BukkitPlugin.pluginInstance), defaultKickPlayers
@@ -44,10 +45,10 @@ public class BukkitConfig implements VPNConfig {
Collections.singletonList("kick %player% VPNs are not allowed on our server!"), "commands.execute",
BukkitPlugin.pluginInstance);
private String license, kickMessage, databaseType, databaseName, username, password, ip, alertMsg;
private String license, kickMessage, databaseType, databaseName, mongoURL, username, password, ip, alertMsg;
private List<String> prefixWhitelists, commands;
private int port;
private boolean cacheResults, databaseEnabled, commandsEnabled, kickPlayers, alertToStaff, metrics;
private boolean cacheResults, databaseEnabled, useCredentials, commandsEnabled, kickPlayers, alertToStaff, metrics;
@Override
public String getLicense() {
@@ -99,6 +100,16 @@ public class BukkitConfig implements VPNConfig {
return databaseEnabled;
}
@Override
public boolean useDatabaseCreds() {
return useCredentials;
}
@Override
public String mongoDatabaseURL() {
return mongoURL;
}
@Override
public String getDatabaseType() {
return databaseType;
@@ -152,8 +163,10 @@ public class BukkitConfig implements VPNConfig {
cacheResults = cacheResultsDefault.get();
prefixWhitelists = prefixWhitelistsDefault.get();
databaseEnabled = defaultDatabaseEnabled.get();
useCredentials = defaultUseCredentials.get();
databaseType = defaultDatabaseType.get();
databaseName = defaultDatabaseName.get();
mongoURL = defaultMongoURL.get();
username = defaultUsername.get();
password = defaultPassword.get();
ip = defaultIp.get();
@@ -47,18 +47,23 @@ public class BukkitListener extends VPNExecutor implements Listener {
if(cacheResetTask != null && !cacheResetTask.isCancelled()) cacheResetTask.cancel();
}
@Override
public void log(String log, Object... objects) {
Bukkit.getLogger().log(Level.INFO, String.format(log, objects));
}
@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) {
System.out.println("Enabled");
AntiVPN.getInstance().getExecutor().log("Enabled");
player.setAlertsEnabled(true);
player.sendMessage(AntiVPN.getInstance().getMessageHandler()
.getString("command-alerts-toggled")
.getFormattedMessage(new VpnString.Var<>("state", true)));
} else System.out.println("Not enabled");
} else AntiVPN.getInstance().getExecutor().log("Not enabled");
});
});
}
@@ -66,7 +71,8 @@ public class BukkitListener extends VPNExecutor implements Listener {
@EventHandler
public void onListener(final PlayerLoginEvent event) {
//If they're exempt, don't check.
if(AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())) return;
if(AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getAddress().getHostAddress())) return;
checkIp(event.getAddress().getHostAddress(), AntiVPN.getInstance().getConfig().cachedResults(), result -> {
if(result.isSuccess() && result.isProxy()) {
new BukkitRunnable() {
@@ -38,7 +38,7 @@ public class BukkitPlugin extends JavaPlugin {
saveDefaultConfig();
Bukkit.getLogger().info("Starting AntiVPN services...");
AntiVPN.start(new BukkitConfig(), new BukkitListener(), new BukkitPlayerExecutor());
AntiVPN.start(new BukkitConfig(), new BukkitListener(), new BukkitPlayerExecutor(), getDataFolder());
if(AntiVPN.getInstance().getConfig().metrics()) {
Bukkit.getLogger().info("Starting bStats metrics...");
+1 -1
View File
@@ -1,4 +1,4 @@
name: AntiVPN
name: KauriVPN
main: dev.brighten.antivpn.bukkit.BukkitPlugin
version: ${project.version}
author: funkemunky
+21 -3
View File
@@ -3,7 +3,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.5.0</version>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Bungee</artifactId>
@@ -50,8 +50,26 @@
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.5.0</version>
<version>1.6.1</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>toml4j</artifactId>
<groupId>com.moandjiezana.toml</groupId>
</exclusion>
<exclusion>
<artifactId>mysql-connector-java</artifactId>
<groupId>mysql</groupId>
</exclusion>
<exclusion>
<artifactId>h2</artifactId>
<groupId>com.h2database</groupId>
</exclusion>
<exclusion>
<artifactId>mongo-java-driver</artifactId>
<groupId>org.mongodb</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.github.bungee</groupId>
@@ -67,8 +85,8 @@
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>8</maven.compiler.source>
</properties>
</project>
+2 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.5.0</version>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -63,7 +63,7 @@
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.5.0</version>
<version>1.6.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -16,12 +16,11 @@ public class BungeeConfig implements VPNConfig {
"database.type", BungeePlugin.pluginInstance),
defaultDatabaseName = new ConfigDefault<>("kaurivpn",
"database.database", BungeePlugin.pluginInstance),
defaultMongoURL = new ConfigDefault<>("", "database.mongoURL", BungeePlugin.pluginInstance),
defaultUsername = new ConfigDefault<>("root",
"database.username", BungeePlugin.pluginInstance),
defaultPassword = new ConfigDefault<>("password",
"database.password", BungeePlugin.pluginInstance),
defaultAuthDatabase = new ConfigDefault<>("admin",
"database.auth", BungeePlugin.pluginInstance),
defaultIp = new ConfigDefault<>("localhost", "database.ip", BungeePlugin.pluginInstance),
defaultAlertMsg = new ConfigDefault<>("&8[&6KauriVPN&8] &e%player% &7has joined on a VPN/proxy" +
" &8(&f%reason%&8) &7in location &8(&f%city%&7, &f%country%&8)", "alerts.message",
@@ -34,6 +33,8 @@ public class BungeeConfig implements VPNConfig {
= new ConfigDefault<>(true, "kickPlayers", BungeePlugin.pluginInstance),
defaultAlertToStaff = new ConfigDefault<>(true, "alerts.enabled",
BungeePlugin.pluginInstance),
defaultUseCredentials = new ConfigDefault<>(true,
"database.useCredentials", BungeePlugin.pluginInstance),
defaultMetrics = new ConfigDefault<>(true, "bstats", BungeePlugin.pluginInstance);
private final ConfigDefault<Integer>
defaultPort = new ConfigDefault<>(-1, "database.port", BungeePlugin.pluginInstance);
@@ -42,10 +43,10 @@ public class BungeeConfig implements VPNConfig {
Collections.singletonList("kick %player% VPNs are not allowed on our server!"), "commands.execute",
BungeePlugin.pluginInstance);
private String license, kickMessage, databaseType, databaseName, username, password, ip, alertMsg;
private String license, kickMessage, databaseType, databaseName, mongoURL, username, password, ip, alertMsg;
private List<String> prefixWhitelists, commands;
private int port;
private boolean cacheResults, databaseEnabled, commandsEnabled, kickPlayers, alertToStaff, metrics;
private boolean cacheResults, useCredentials, databaseEnabled, commandsEnabled, kickPlayers, alertToStaff, metrics;
@Override
public String getLicense() {
@@ -97,6 +98,16 @@ public class BungeeConfig implements VPNConfig {
return databaseEnabled;
}
@Override
public boolean useDatabaseCreds() {
return useCredentials;
}
@Override
public String mongoDatabaseURL() {
return mongoURL;
}
@Override
public String getDatabaseType() {
return databaseType;
@@ -150,8 +161,10 @@ public class BungeeConfig implements VPNConfig {
cacheResults = cacheResultsDefault.get();
prefixWhitelists = prefixWhitelistsDefault.get();
databaseEnabled = defaultDatabaseEnabled.get();
useCredentials = defaultUseCredentials.get();
databaseType = defaultDatabaseType.get();
databaseName = defaultDatabaseName.get();
mongoURL = defaultMongoURL.get();
username = defaultUsername.get();
password = defaultPassword.get();
ip = defaultIp.get();
@@ -40,11 +40,18 @@ public class BungeeListener extends VPNExecutor implements Listener {
BungeePlugin.pluginInstance.getProxy().getPluginManager().unregisterListener(this);
}
@Override
public void log(String log, Object... objects) {
BungeeCord.getInstance().getLogger().log(Level.INFO, String.format(log, objects));
}
@EventHandler
public void onListener(final PostLoginEvent event) {
if(event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId()) //Is exempt
//Or has a name that starts with a certain prefix. This is for Bedrock exempting.
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getAddress().getAddress()
.getHostAddress())
|| AntiVPN.getInstance().getConfig().getPrefixWhitelists().stream()
.anyMatch(prefix -> event.getPlayer().getName().startsWith(prefix))) return;
@@ -42,7 +42,7 @@ public class BungeePlugin extends Plugin {
//Loading plugin
BungeeCord.getInstance().getLogger().info("Starting AntiVPN services...");
AntiVPN.start(new BungeeConfig(), new BungeeListener(), new BungeePlayerExecutor());
AntiVPN.start(new BungeeConfig(), new BungeeListener(), new BungeePlayerExecutor(), getDataFolder());
if(AntiVPN.getInstance().getConfig().metrics()) {
BungeeCord.getInstance().getLogger().info("Starting bStats metrics...");
+1 -1
View File
@@ -1,4 +1,4 @@
name: AntiVPN
name: KauriVPN
main: dev.brighten.antivpn.bungee.BungeePlugin
description: A simple and fast antivpn plugin.
version: ${project.version}
+37 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.5.0</version>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -21,7 +21,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
@@ -37,4 +37,39 @@
</resources>
</build>
<repositories>
<repository>
<id>funkemunky-releases</id>
<url>https://nexus.funkemunky.cc/content/repositories/releases/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.moandjiezana.toml</groupId>
<artifactId>toml4j</artifactId>
<version>0.7.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.200</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.12.10</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
@@ -6,6 +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.mongo.MongoVPN;
import dev.brighten.antivpn.database.sql.MySqlVPN;
import dev.brighten.antivpn.message.MessageHandler;
import dev.brighten.antivpn.utils.VPNResponse;
@@ -16,6 +17,7 @@ import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -32,12 +34,14 @@ public class AntiVPN {
private MessageHandler messageHandler;
private List<Command> commands = new ArrayList<>();
public int detections, checked;
private File pluginFolder;
public static void start(VPNConfig config, VPNExecutor executor, PlayerExecutor playerExecutor) {
public static void start(VPNConfig config, VPNExecutor executor, PlayerExecutor playerExecutor, File pluginFolder) {
//Initializing
INSTANCE = new AntiVPN();
INSTANCE.pluginFolder = pluginFolder;
INSTANCE.config = config;
INSTANCE.executor = executor;
INSTANCE.playerExecutor = playerExecutor;
@@ -50,7 +54,7 @@ public class AntiVPN {
switch(INSTANCE.config.getDatabaseType().toLowerCase()) {
case "mysql":
case "sql":{
System.out.println("Using databaseType MySQL...");
AntiVPN.getInstance().getExecutor().log("Using databaseType MySQL...");
INSTANCE.database = new MySqlVPN();
INSTANCE.database.init();
break;
@@ -58,11 +62,12 @@ public class AntiVPN {
case "mongo":
case "mongodb":
case "mongod": {
System.out.println("We currently do not support Mongo, but this is coming in future updates.");
INSTANCE.database = new MongoVPN();
INSTANCE.database.init();
break;
}
default: {
System.out.println("Could not find database type \"" + INSTANCE.config.getDatabaseType() + "\". " +
AntiVPN.getInstance().getExecutor().log("Could not find database type \"" + INSTANCE.config.getDatabaseType() + "\". " +
"Options: [MySQL]");
break;
}
@@ -24,6 +24,10 @@ public interface VPNConfig {
boolean isDatabaseEnabled();
boolean useDatabaseCreds();
String mongoDatabaseURL();
String getDatabaseType();
String getDatabaseName();
@@ -1,6 +1,7 @@
package dev.brighten.antivpn.api;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.utils.EvictingMap;
import dev.brighten.antivpn.utils.VPNResponse;
import dev.brighten.antivpn.utils.json.JSONException;
import lombok.Getter;
@@ -15,9 +16,11 @@ import java.util.function.Consumer;
public abstract class VPNExecutor {
public static ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
private static final Map<String, VPNResponse> responseCache = new HashMap<>();
public static final Map<String, VPNResponse> responseCache = new EvictingMap<>(5000);
@Getter
private final Set<UUID> whitelisted = Collections.synchronizedSet(new HashSet<>());
@Getter
private final Set<String> whitelistedIps = Collections.synchronizedSet(new HashSet<>());
public abstract void registerListeners();
@@ -29,10 +32,16 @@ public abstract class VPNExecutor {
public abstract void shutdown();
public abstract void log(String log, Object... objects);
public boolean isWhitelisted(UUID uuid) {
return whitelisted.contains(uuid);
}
public boolean isWhitelisted(String ip) {
return whitelistedIps.contains(ip);
}
public void checkIp(String ip, boolean cachedResults, Consumer<VPNResponse> result) {
threadExecutor.execute(() -> result.accept(responseCache.compute(ip, (key, val) -> {
if(val == null) {
@@ -47,12 +56,12 @@ public abstract class VPNExecutor {
if(response.isSuccess()) {
AntiVPN.getInstance().getDatabase().cacheResponse(response);
} else {
System.out.println("Query to VPN API failed! Reason: " + response.getFailureReason());
log("Query to VPN API failed! Reason: " + response.getFailureReason());
}
return response;
} catch (JSONException | IOException e) {
System.out.println("Query to VPN API failed! Reason: Java Exception");
log("Query to VPN API failed! Reason: Java Exception");
e.printStackTrace();
}
}
@@ -76,12 +85,12 @@ public abstract class VPNExecutor {
if(response.isSuccess()) {
threadExecutor.execute(() -> AntiVPN.getInstance().getDatabase().cacheResponse(response));
} else {
System.out.println("Query to VPN API failed! Reason: " + response.getFailureReason());
log("Query to VPN API failed! Reason: " + response.getFailureReason());
}
return response;
} catch (JSONException | IOException e) {
System.out.println("Query to VPN API failed! Reason: Java Exception");
log("Query to VPN API failed! Reason: Java Exception");
e.printStackTrace();
}
}
@@ -4,6 +4,7 @@ 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.MiscUtils;
import java.util.*;
import java.util.stream.Collectors;
@@ -34,7 +35,7 @@ public class AllowlistCommand extends Command {
@Override
public String usage() {
return "<add/remove> <player/uuid>";
return "<add/remove> <player/uuid/ip>";
}
@Override
@@ -50,7 +51,7 @@ public class AllowlistCommand extends Command {
@Override
public String execute(CommandExecutor executor, String[] args) {
if(args.length == 0 || Arrays.stream(secondArgs).noneMatch(arg -> arg.equalsIgnoreCase(args[0]))) {
return "&cUsage: /antivpn allowlist <add/remove> <player>";
return "&cUsage: /antivpn allowlist " + usage();
}
if(args.length == 1)
@@ -61,34 +62,82 @@ public class AllowlistCommand extends Command {
if(!databaseEnabled) executor.sendMessage("&cThe database is currently not setup, " +
"so any changes here will disappear after a restart.");
UUID uuid = null;
try {
uuid = UUID.fromString(args[1]);
} catch(IllegalArgumentException e) {
Optional<APIPlayer> player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(args[1]);
if(!player.isPresent()) {
return "&cThe player \"" + args[1] + "\" is not online, so please provide a UUID.";
}
uuid = player.get().getUuid();
}
if(!databaseEnabled) {
if(args[0].equalsIgnoreCase("add")) {
AntiVPN.getInstance().getExecutor().getWhitelisted().add(uuid);
return String.format("&aAdded &6%s &auuid to the exemption allowlist.", uuid.toString());
if(MiscUtils.isIpv4(args[1])) {
if(!databaseEnabled) {
switch(args[0].toLowerCase()) {
case "add": {
AntiVPN.getInstance().getExecutor().getWhitelistedIps().add(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]);
return String.format("&cRemoved &6%s &cfrom the exemption allowlist.", args[1]);
}
default: {
return "&c\"" + args[0] + "\" is not a valid argument";
}
}
} else {
AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid);
return String.format("&cRemoved &6%s &cuuid from the exemption allowlist.", uuid.toString());
switch(args[0].toLowerCase()) {
case "add": {
AntiVPN.getInstance().getDatabase().setWhitelisted(args[1], true);
return String.format("&aAdded &6%s &a to the exemption allowlist.", args[1]);
}
case "remove":
case "delete": {
AntiVPN.getInstance().getDatabase().setWhitelisted(args[1], false);
return String.format("&cRemoved &6%s &c from the exemption allowlist.", args[1]);
}
default: {
return "&c\"" + args[0] + "\" is not a valid argument";
}
}
}
} else {
if(args[0].equalsIgnoreCase("add")) {
AntiVPN.getInstance().getDatabase().setWhitelisted(uuid, true);
return String.format("&aAdded &6%s &auuid to the exemption allowlist.", uuid.toString());
UUID uuid = null;
try {
uuid = UUID.fromString(args[1]);
} catch(IllegalArgumentException e) {
Optional<APIPlayer> player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(args[1]);
if(!player.isPresent()) {
return "&cThe player \"" + args[1] + "\" is not online, so please provide a UUID.";
}
uuid = player.get().getUuid();
}
if(!databaseEnabled) {
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());
}
case "remove":
case "delete": {
AntiVPN.getInstance().getExecutor().getWhitelisted().remove(uuid);
return String.format("&cRemoved &6%s &cuuid from the exemption allowlist.", uuid.toString());
}
default: {
return "&c\"" + args[0] + "\" is not a valid argument";
}
}
} else {
AntiVPN.getInstance().getDatabase().setWhitelisted(uuid, false);
return String.format("&cRemoved &6%s &cuuid from the exemption allowlist.", uuid.toString());
switch(args[0].toLowerCase()) {
case "add": {
AntiVPN.getInstance().getDatabase().setWhitelisted(uuid, true);
return String.format("&aAdded &6%s &auuid to the exemption allowlist.", uuid.toString());
}
case "remove":
case "delete": {
AntiVPN.getInstance().getDatabase().setWhitelisted(uuid, false);
return String.format("&cRemoved &6%s &cuuid from the exemption allowlist.", uuid.toString());
}
default: {
return "&c\"" + args[0] + "\" is not a valid argument";
}
}
}
}
}
@@ -41,7 +41,8 @@ public class AntiVPNCommand extends Command {
@Override
public Command[] children() {
return new Command[] {new LookupCommand(), new AllowlistCommand(), new AlertsCommand()};
return new Command[] {new LookupCommand(), new AllowlistCommand(), new AlertsCommand(),
new ClearCacheCommand()};
}
@Override
@@ -0,0 +1,58 @@
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;
import java.util.Collections;
import java.util.List;
public class ClearCacheCommand extends Command {
@Override
public String permission() {
return "antivpn.command.clearcache";
}
@Override
public String name() {
return "clearcache";
}
@Override
public String[] aliases() {
return new String[] {"clear", "cc"};
}
@Override
public String description() {
return "Clear the API response cache if you're having problems.";
}
@Override
public String usage() {
return "";
}
@Override
public String parent() {
return "antivpn";
}
@Override
public Command[] children() {
return new Command[0];
}
@Override
public String execute(CommandExecutor executor, String[] args) {
AntiVPN.getInstance().getDatabase().clearResponses();
VPNExecutor.responseCache.clear();
return "&aCleared all cached API response information!";
}
@Override
public List<String> tabComplete(CommandExecutor executor, String alias, String[] args) {
return Collections.emptyList();
}
}
@@ -14,18 +14,28 @@ public interface VPNDatabase {
boolean isWhitelisted(UUID uuid);
boolean isWhitelisted(String ip);
void setWhitelisted(UUID uuid, boolean whitelisted);
void setWhitelisted(String ip, boolean whitelisted);
List<UUID> getAllWhitelisted();
List<String> getAllWhitelistedIps();
void getStoredResponseAsync(String ip, Consumer<Optional<VPNResponse>> result);
void isWhitelistedAsync(UUID uuid, Consumer<Boolean> result);
void isWhitelistedAsync(String ip, Consumer<Boolean> result);
void alertsState(UUID uuid, Consumer<Boolean> result);
void updateAlertsState(UUID uuid, boolean state);
void clearResponses();
void init();
void shutdown();
@@ -0,0 +1,208 @@
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 dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.database.VPNDatabase;
import dev.brighten.antivpn.utils.VPNResponse;
import org.bson.Document;
import java.util.*;
import java.util.function.Consumer;
public class MongoVPN implements VPNDatabase {
private MongoCollection<Document> settingsDocument, cacheDocument;
private MongoClient client;
private MongoDatabase antivpnDatabase;
@Override
public Optional<VPNResponse> getStoredResponse(String ip) {
Document rdoc = cacheDocument.find(Filters.eq("ip", ip)).first();
if(rdoc != null) {
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"))
.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());
VPNExecutor.threadExecutor.execute(() -> {
cacheDocument.deleteMany(Filters.eq("ip", toCache.getIp()));
cacheDocument.insertOne(rdoc);
});
}
@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());
VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc));
} else {
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");
wdoc.put("ip", ip);
VPNExecutor.threadExecutor.execute(() -> settingsDocument.insertOne(wdoc));
} else {
VPNExecutor.threadExecutor.execute(() -> settingsDocument.deleteMany(Filters
.and(
Filters.eq("setting", "whitelist"),
Filters.eq("ip", ip))));
}
}
@Override
public List<UUID> getAllWhitelisted() {
List<UUID> uuids = new ArrayList<>();
settingsDocument.find(Filters.and(Filters.eq("setting", "whitelist"),
Filters.exists("uuid")))
.forEach((Consumer<? super Document>) doc -> uuids.add(UUID.fromString(doc.getString("uuid"))));
return uuids;
}
@Override
public List<String> getAllWhitelistedIps() {
List<String> ips = new ArrayList<>();
settingsDocument.find(Filters.and(Filters.eq("setting", "whitelist"),
Filters.exists("ip")))
.forEach((Consumer<? super Document>) doc -> ips.add(doc.getString("ip")));
return ips;
}
@Override
public void getStoredResponseAsync(String ip, Consumer<Optional<VPNResponse>> result) {
VPNExecutor.threadExecutor.execute(() -> result.accept(getStoredResponse(ip)));
}
@Override
public void isWhitelistedAsync(UUID uuid, Consumer<Boolean> result) {
VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid)));
}
@Override
public void isWhitelistedAsync(String ip, Consumer<Boolean> result) {
VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip)));
}
@Override
public void alertsState(UUID uuid, Consumer<Boolean> 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().getConfig().mongoDatabaseURL().length() > 0) { //URL
ConnectionString cs = new ConnectionString(AntiVPN.getInstance().getConfig().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().getConfig().getIp(),
AntiVPN.getInstance().getConfig().getPort())));
});
if(AntiVPN.getInstance().getConfig().useDatabaseCreds()) {
settingsBld = settingsBld.credential(MongoCredential
.createCredential(AntiVPN.getInstance().getConfig().getUsername(),
AntiVPN.getInstance().getConfig().getDatabaseName(),
AntiVPN.getInstance().getConfig().getPassword().toCharArray()));
}
client = MongoClients.create(settingsBld.build());
}
antivpnDatabase = client.getDatabase(AntiVPN.getInstance().getConfig().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();
}
}
@@ -20,7 +20,7 @@ public class MySqlVPN implements VPNDatabase {
public MySqlVPN() {
whitelistedThread = new Thread(() -> {
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(8));
Thread.sleep(TimeUnit.SECONDS.toMillis(2));
} catch (InterruptedException e) {
e.printStackTrace();
}
@@ -30,6 +30,9 @@ public class MySqlVPN implements VPNDatabase {
AntiVPN.getInstance().getExecutor().getWhitelisted().clear();
AntiVPN.getInstance().getExecutor().getWhitelisted()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelisted());
AntiVPN.getInstance().getExecutor().getWhitelistedIps().clear();
AntiVPN.getInstance().getExecutor().getWhitelistedIps()
.addAll(AntiVPN.getInstance().getDatabase().getAllWhitelistedIps());
}
try {
Thread.sleep(TimeUnit.SECONDS.toMillis(4));
@@ -95,15 +98,28 @@ public class MySqlVPN implements VPNDatabase {
public boolean isWhitelisted(UUID uuid) {
if (!AntiVPN.getInstance().getConfig().isDatabaseEnabled() || MySQL.isClosed())
return false;
ResultSet set = Query.prepare("select uuid from `whitelisted` where `uuid` = ? limit 1").append(uuid.toString())
.executeQuery();
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().getConfig().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(MySQL.isClosed()) return;
if (!AntiVPN.getInstance().getConfig().isDatabaseEnabled() || MySQL.isClosed())
return;
if (whitelisted) {
if (!isWhitelisted(uuid)) {
@@ -116,24 +132,42 @@ public class MySqlVPN implements VPNDatabase {
}
}
@Override
public void setWhitelisted(String ip, boolean whitelisted) {
if (!AntiVPN.getInstance().getConfig().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<UUID> getAllWhitelisted() {
List<UUID> uuids = new ArrayList<>();
if(MySQL.isClosed()) return uuids;
if(!MySQL.isClosed()) Query.prepare("select uuid from `whitelisted`")
.execute(set -> uuids.add(UUID.fromString(set.getString("uuid"))));
ResultSet set = Query.prepare("select uuid from `whitelisted`").executeQuery();
try {
while (set.next()) {
uuids.add(UUID.fromString(set.getString("uuid")));
}
} catch (SQLException e) {
e.printStackTrace();
}
return uuids;
}
@Override
public List<String> getAllWhitelistedIps() {
List<String> 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<Optional<VPNResponse>> result) {
if(MySQL.isClosed()) return;
@@ -148,6 +182,13 @@ public class MySqlVPN implements VPNDatabase {
VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(uuid)));
}
@Override
public void isWhitelistedAsync(String ip, Consumer<Boolean> result) {
if(MySQL.isClosed()) return;
VPNExecutor.threadExecutor.execute(() -> result.accept(isWhitelisted(ip)));
}
@Override
public void alertsState(UUID uuid, Consumer<Boolean> result) {
if(MySQL.isClosed()) return;
@@ -184,75 +225,104 @@ public class MySqlVPN implements VPNDatabase {
.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().getConfig().isDatabaseEnabled())
return;
System.out.println("Initializing MySQL...");
AntiVPN.getInstance().getExecutor().log("Initializing MySQL...");
MySQL.init();
System.out.println("Creating tables...");
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")) {
System.out.println("Using old database format for storing responses! " +
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) {
System.out.println("Successfully dropped table!");
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();
System.out.println("Creating indexes...");
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';";
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;
while (rs.next()) {
id = rs.getInt("IndexExists");
whitelistedIndex: {
while (rs.next()) {
id = rs.getInt("IndexExists");
}
if (id == 0) {
Query.prepare("create index `uuid_1` on `whitelisted` (`uuid`)").execute();
}
id = 0;
}
if (id == 0) {
Query.prepare("create index `uuid_1` on `whitelisted` (`uuid`)").execute();
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;
}
id = 0;
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();
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());
@@ -12,6 +12,11 @@ public class MySQL {
public static void init() {
try {
if (conn == null || conn.isClosed()) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
Class.forName("com.mysql.jdbc.Driver");
}
conn = DriverManager.getConnection("jdbc:mysql://" + AntiVPN.getInstance().getConfig().getIp()
+ ":" + AntiVPN.getInstance().getConfig().getPort()
+ "/?useSSL=true&autoReconnect=true",
@@ -22,14 +27,31 @@ public class MySQL {
Query.prepare("CREATE DATABASE IF NOT EXISTS `"
+ AntiVPN.getInstance().getConfig().getDatabaseName() + "`").execute();
Query.prepare("USE `" + AntiVPN.getInstance().getConfig().getDatabaseName() + "`").execute();
System.out.println("Connection to MySQL has been established.");
AntiVPN.getInstance().getExecutor().log("Connection to MySQL has been established.");
}
} catch (Exception e) {
System.out.println("Failed to load mysql: " + e.getMessage());
AntiVPN.getInstance().getExecutor().log("Failed to load mysql: " + e.getMessage());
e.printStackTrace();
}
}
/*public static void initH2() {
File dataFolder = new File(AntiVPN.getInstance().getPluginFolder(), "databases" + File.separator + "database");
try {
Class.forName("org.h2.Driver");
conn = new NonClosableConnection(new JdbcConnection("jdbc:h2:file:" +
dataFolder.getAbsolutePath(), new Properties()));
conn.setAutoCommit(true);
Query.use(conn);
AntiVPN.getInstance().getExecutor().log("Connection to SQlLite has been established.");
} catch (SQLException ex) {
AntiVPN.getInstance().getExecutor().log("SQLite exception on initialize");
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
AntiVPN.getInstance().getExecutor().log("No H2 library found!");
}
}*/
public static void use() {
try {
init();
@@ -41,7 +63,9 @@ public class MySQL {
public static void shutdown() {
try {
if(conn != null && !conn.isClosed()) {
conn.close();
if(conn instanceof NonClosableConnection) {
((NonClosableConnection)conn).shutdown();
} else conn.close();
conn = null;
}
} catch (Exception e) {
@@ -0,0 +1,122 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* 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> T unwrap(Class<T> 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<String, Class<?>> getTypeMap() throws SQLException { return this.delegate.getTypeMap(); }
@Override public void setTypeMap(Map<String, Class<?>> 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(); }
}
@@ -0,0 +1,19 @@
package dev.brighten.antivpn.utils;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.LinkedHashMap;
import java.util.Map;
@RequiredArgsConstructor
public class EvictingMap<K, V> extends LinkedHashMap<K, V> {
@Getter
private final int size;
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() >= size;
}
}
@@ -1,6 +1,16 @@
package dev.brighten.antivpn.utils;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
public class MiscUtils {
@@ -20,4 +30,15 @@ public class MiscUtils {
}
}
public static boolean isIpv4(String ip)
{
try {
InetAddress address = InetAddress.getByName(ip);
return address instanceof Inet4Address;
} catch(Exception e) {
return false;
}
}
}
@@ -2,15 +2,13 @@ package dev.brighten.antivpn.utils;
import dev.brighten.antivpn.utils.json.JSONException;
import dev.brighten.antivpn.utils.json.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.*;
@Getter
@Setter
@AllArgsConstructor
@RequiredArgsConstructor
@Builder
public class VPNResponse {
private String asn, ip, countryName, countryCode, city, timeZone, method, isp, failureReason = "N/A";
private boolean proxy, cached;
+2 -2
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>AntiVPN</artifactId>
<groupId>dev.brighten.antivpn</groupId>
<version>1.5.0</version>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -33,7 +33,7 @@
<dependency>
<groupId>dev.brighten.antivpn</groupId>
<artifactId>Common</artifactId>
<version>1.5.0</version>
<version>1.6.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -16,12 +16,11 @@ public class VelocityConfig implements VPNConfig {
"database.type", VelocityPlugin.INSTANCE),
defaultDatabaseName = new ConfigDefault<>("kaurivpn",
"database.database", VelocityPlugin.INSTANCE),
defaultMongoURL = new ConfigDefault<>("", "database.mongoURL", VelocityPlugin.INSTANCE),
defaultUsername = new ConfigDefault<>("root",
"database.username", VelocityPlugin.INSTANCE),
defaultPassword = new ConfigDefault<>("password",
"database.password", VelocityPlugin.INSTANCE),
defaultAuthDatabase = new ConfigDefault<>("admin",
"database.auth", VelocityPlugin.INSTANCE),
defaultIp = new ConfigDefault<>("localhost", "database.ip", VelocityPlugin.INSTANCE),
defaultAlertMsg = new ConfigDefault<>("&8[&6KauriVPN&8] &e%player% &7has joined on a VPN/proxy" +
" &8(&f%reason%&8) &7in location &8(&f%city%&7, &f%country%&8)", "alerts.message",
@@ -32,6 +31,8 @@ public class VelocityConfig implements VPNConfig {
VelocityPlugin.INSTANCE), defaultCommandsEnable = new ConfigDefault<>(false,
"commands.enabled", VelocityPlugin.INSTANCE), defaultKickPlayers
= new ConfigDefault<>(true, "kickPlayers", VelocityPlugin.INSTANCE),
defaultUseCredentials = new ConfigDefault<>(true,
"database.useCredentials", VelocityPlugin.INSTANCE),
defaultAlertToStaff = new ConfigDefault<>(true, "alerts.enabled",
VelocityPlugin.INSTANCE),
defaultMetrics = new ConfigDefault<>(true, "bstats", VelocityPlugin.INSTANCE);
@@ -42,10 +43,10 @@ public class VelocityConfig implements VPNConfig {
Collections.singletonList("kick %player% VPNs are not allowed on our server!"), "commands.execute",
VelocityPlugin.INSTANCE);
private String license, kickMessage, databaseType, databaseName, username, password, ip, alertMsg;
private String license, kickMessage, databaseType, databaseName, mongoURL, username, password, ip, alertMsg;
private List<String> prefixWhitelists, commands;
private int port;
private boolean cacheResults, databaseEnabled, commandsEnabled, kickPlayers, alertToStaff, metrics;
private boolean cacheResults, useCredentials, databaseEnabled, commandsEnabled, kickPlayers, alertToStaff, metrics;
@Override
public String getLicense() {
@@ -97,6 +98,16 @@ public class VelocityConfig implements VPNConfig {
return databaseEnabled;
}
@Override
public boolean useDatabaseCreds() {
return useCredentials;
}
@Override
public String mongoDatabaseURL() {
return mongoURL;
}
@Override
public String getDatabaseType() {
return databaseType;
@@ -150,8 +161,10 @@ public class VelocityConfig implements VPNConfig {
cacheResults = cacheResultsDefault.get();
prefixWhitelists = prefixWhitelistsDefault.get();
databaseEnabled = defaultDatabaseEnabled.get();
useCredentials = defaultUseCredentials.get();
databaseType = defaultDatabaseType.get();
databaseName = defaultDatabaseName.get();
mongoURL = defaultMongoURL.get();
username = defaultUsername.get();
password = defaultPassword.get();
ip = defaultIp.get();
@@ -26,6 +26,8 @@ public class VelocityListener extends VPNExecutor {
if(event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId()) //Is exempt
//Or has a name that starts with a certain prefix. This is for Bedrock exempting.
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getRemoteAddress()
.getAddress().getHostAddress())
|| AntiVPN.getInstance().getConfig().getPrefixWhitelists().stream()
.anyMatch(prefix -> event.getPlayer().getUsername().startsWith(prefix))) return;
@@ -88,4 +90,9 @@ public class VelocityListener extends VPNExecutor {
threadExecutor.shutdown();
VelocityPlugin.INSTANCE.getServer().getEventManager().unregisterListener(VelocityPlugin.INSTANCE, this);
}
@Override
public void log(String log, Object... objects) {
VelocityPlugin.INSTANCE.getLogger().log(Level.INFO, String.format(log, objects));
}
}
@@ -54,7 +54,7 @@ public class VelocityPlugin {
//Loading plugin
logger.info("Starting AntiVPN services...");
AntiVPN.start(new VelocityConfig(), new VelocityListener(), new VelocityPlayerExecutor());
AntiVPN.start(new VelocityConfig(), new VelocityListener(), new VelocityPlayerExecutor(), configDir.toFile());
if(AntiVPN.getInstance().getConfig().metrics()) {
logger.info("Starting metrics...");
@@ -29,10 +29,6 @@ public class Config {
dataFolder.mkdir();
}
this.file.createNewFile();
try (final InputStream is =VelocityPlugin.INSTANCE.getClass().getResourceAsStream("config.yml");
final OutputStream os = new FileOutputStream(this.file)) {
ByteStreams.copy(is, os);
}
}
this.configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(this.file);
}
@@ -0,0 +1 @@
{"id":"kaurivpn","name":"KauriVPN","version":"${project.version}","authors":["funkemunky"],"dependencies":[],"main":"dev.brighten.antivpn.velocity.VelocityPlugin"}
+9 -1
View File
@@ -7,7 +7,7 @@
<groupId>dev.brighten.antivpn</groupId>
<artifactId>AntiVPN</artifactId>
<packaging>pom</packaging>
<version>1.5.0</version>
<version>1.6.1</version>
<modules>
<module>Common</module>
@@ -32,6 +32,14 @@
<source>8</source>
<target>8</target>
<compilerArgument>-XDignore.symbol.file</compilerArgument>
<useIncrementalCompilation>false</useIncrementalCompilation>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>