mirror of
https://github.com/funkemunky/AntiVPN.git
synced 2026-05-31 17:31:55 +00:00
Compare commits
11 Commits
1.9.3
...
v1.9.4-DEV
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a0419cbac | |||
| 24257e4f42 | |||
| 2b7f043eb9 | |||
| 2dbe465b9e | |||
| ac628811cc | |||
| 3aae8d8f49 | |||
| f0c37c6ff0 | |||
| 311f1e198b | |||
| 9cbeed1df3 | |||
| 6453898ca4 | |||
| 6243727ebf |
+7
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>AntiVPN</artifactId>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<version>1.9.3</version>
|
||||
<version>1.9.4-DEV</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -65,6 +65,12 @@
|
||||
<version>${version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.41.2.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<artifactId>Bukkit</artifactId>
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>AntiVPN</artifactId>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<version>1.9.3</version>
|
||||
<version>1.9.4-DEV</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<dependency>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<artifactId>Common</artifactId>
|
||||
<version>1.9.3</version>
|
||||
<version>1.9.4-DEV</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -11,14 +11,13 @@ import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
@@ -37,7 +36,7 @@ public class BukkitListener extends VPNExecutor implements Listener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
public void onShutdown() {
|
||||
|
||||
}
|
||||
|
||||
@@ -56,7 +55,13 @@ public class BukkitListener extends VPNExecutor implements Listener {
|
||||
Bukkit.getLogger().log(Level.SEVERE, message, ex);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@Override
|
||||
public void disablePlugin() {
|
||||
HandlerList.unregisterAll(this);
|
||||
BukkitPlugin.pluginInstance.getServer().getPluginManager().disablePlugin(BukkitPlugin.pluginInstance);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onJoin(final PlayerJoinEvent event) {
|
||||
AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId())
|
||||
.ifPresent(player -> AntiVPN.getInstance().getDatabase().alertsState(player.getUuid(), enabled -> {
|
||||
@@ -67,15 +72,20 @@ public class BukkitListener extends VPNExecutor implements Listener {
|
||||
.getFormattedMessage(new VpnString.Var<>("state", true)));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onListener(final PlayerLoginEvent event) {
|
||||
//If they're exempt, don't check.
|
||||
String address;
|
||||
|
||||
if(event.getPlayer().getAddress() != null) {
|
||||
address = event.getPlayer().getAddress().getAddress().getHostAddress();
|
||||
} else {
|
||||
log(Level.WARNING, "Player %s address is null! This is a bug and should be reported!", event.getPlayer().getName());
|
||||
return;
|
||||
}
|
||||
|
||||
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.getAddress().getHostAddress())
|
||||
|| AntiVPN.getInstance().getExecutor().isWhitelisted(address)
|
||||
|| AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream()
|
||||
.anyMatch(prefix -> event.getPlayer().getName().startsWith(prefix))) return;
|
||||
|
||||
@@ -83,147 +93,124 @@ public class BukkitListener extends VPNExecutor implements Listener {
|
||||
VPNResponse cached = responseCache.getIfPresent(event.getPlayer().getUniqueId());
|
||||
|
||||
if (cached != null && cached.isProxy()) {
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_BANNED);
|
||||
event.setKickMessage(org.bukkit.ChatColor.translateAlternateColorCodes('&',
|
||||
AntiVPN.getInstance().getVpnConfig().getKickString()));
|
||||
proxyKick(event.getPlayer(), cached);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
checkIp(event.getAddress().getHostAddress(),
|
||||
checkIp(address,
|
||||
AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> {
|
||||
if(result.isSuccess()) {
|
||||
//We need to run on main thread or kicking and running commands will cause errors
|
||||
//If the player is whitelisted, we don't want to kick them
|
||||
if(AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())) {
|
||||
log("UUID is whitelisted: %s",
|
||||
event.getPlayer().getUniqueId().toString());
|
||||
log("UUID is whitelisted: %s", event.getPlayer().getUniqueId().toString());
|
||||
return;
|
||||
}
|
||||
|
||||
//If the IP is whitelisted, we don't want to kick them
|
||||
InetSocketAddress address = event.getPlayer().getAddress();
|
||||
if (address != null){
|
||||
InetAddress address1 = address.getAddress();
|
||||
if (address1 != null && AntiVPN.getInstance().getExecutor()
|
||||
.isWhitelisted(address1.getHostAddress())) {
|
||||
log("IP is whitelisted: %s",
|
||||
address1.getHostAddress());
|
||||
return;
|
||||
}
|
||||
if (AntiVPN.getInstance().getExecutor().isWhitelisted(address)) {
|
||||
log("IP is whitelisted: %s",
|
||||
address);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the countryList() size is zero, no need to check.
|
||||
// Running country check first
|
||||
if(!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty()
|
||||
// This bit of code will decide whether or not to kick the player
|
||||
// If it contains the code and it is set to whitelist, it will not kick as they are equal
|
||||
// This bit of code will decide whether to kick the player
|
||||
// If contains the code, and set to whitelist, it will not kick as they are equal
|
||||
// and vise versa. However, if the contains does not match the state, it will kick.
|
||||
&& AntiVPN.getInstance().getVpnConfig().countryList()
|
||||
.contains(result.getCountryCode())
|
||||
!= AntiVPN.getInstance().getVpnConfig().whitelistCountries()) {
|
||||
final String kickReason = AntiVPN.getInstance().getVpnConfig()
|
||||
.countryVanillaKickReason();
|
||||
|
||||
// Start "online" fix
|
||||
// In case the response was so fast from API the player wouldn't be "online".
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_BANNED);
|
||||
event.setKickMessage(ChatColor
|
||||
.translateAlternateColorCodes('&',
|
||||
kickReason
|
||||
.replace("%player%", event.getPlayer().getName())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode())));
|
||||
// End "online" fix
|
||||
|
||||
//Using our built in kicking system if no commands are configured
|
||||
if(AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) {
|
||||
// Kicking our player
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
event.getPlayer().kickPlayer(ChatColor
|
||||
.translateAlternateColorCodes('&',
|
||||
kickReason
|
||||
.replace("%player%", event.getPlayer().getName())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode())));
|
||||
}
|
||||
}.runTask(BukkitPlugin.pluginInstance);
|
||||
} else {
|
||||
final String playerName = event.getPlayer().getName();
|
||||
|
||||
BukkitPlugin.pluginInstance.getPlayerCommandRunner()
|
||||
.addAction(event.getPlayer().getUniqueId(), () -> {
|
||||
for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
|
||||
final String formattedCommand = ChatColor.translateAlternateColorCodes('&',
|
||||
cmd.replace("%player%", playerName)
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()));
|
||||
|
||||
// Runs our command from console
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), formattedCommand);
|
||||
}
|
||||
});
|
||||
}
|
||||
countryKick(player, result);
|
||||
} else if(result.isProxy()) {
|
||||
|
||||
// Start "online" fix
|
||||
// In case the response was so fast from API the player wouldn't be "online".
|
||||
event.setResult(PlayerLoginEvent.Result.KICK_BANNED);
|
||||
event.setKickMessage(ChatColor
|
||||
.translateAlternateColorCodes('&',
|
||||
AntiVPN.getInstance().getVpnConfig().getKickString()
|
||||
.replace("%player%", event.getPlayer().getName())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode())));
|
||||
// End "online" fix
|
||||
|
||||
if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) {
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
player.kickPlayer(org.bukkit.ChatColor.translateAlternateColorCodes('&',
|
||||
AntiVPN.getInstance().getVpnConfig().getKickString()));
|
||||
}
|
||||
}.runTask(BukkitPlugin.pluginInstance);
|
||||
}
|
||||
log(Level.INFO, event.getPlayer().getName()
|
||||
+ " joined on a VPN/Proxy (" + result.getMethod() + ")");
|
||||
|
||||
//Ensuring the user wishes to alert to staff
|
||||
if(AntiVPN.getInstance().getVpnConfig().alertToStaff())
|
||||
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
|
||||
.filter(APIPlayer::isAlertsEnabled)
|
||||
.forEach(pl -> pl.sendMessage(AntiVPN.getInstance().getVpnConfig().alertMessage()
|
||||
.replace("%player%", event.getPlayer().getName())
|
||||
.replace("%reason%", result.getMethod())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%city%", result.getCity())));
|
||||
|
||||
//In case the user wants to run their own commands instead of using the built in kicking
|
||||
if(AntiVPN.getInstance().getVpnConfig().runCommands()) {
|
||||
String playerName = event.getPlayer().getName();
|
||||
BukkitPlugin.pluginInstance.getPlayerCommandRunner()
|
||||
.addAction(event.getPlayer().getUniqueId(), () -> {
|
||||
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(),
|
||||
ChatColor.translateAlternateColorCodes('&',
|
||||
command.replace("%player%",
|
||||
playerName)));
|
||||
}
|
||||
});
|
||||
}
|
||||
AntiVPN.getInstance().detections++;
|
||||
proxyKick(player, result);
|
||||
}
|
||||
} else {
|
||||
log(Level.WARNING,
|
||||
"The API query was not a success! " +
|
||||
"You may need to upgrade your license on https://funkemunky.cc/shop");
|
||||
"The API query was not a success! " +
|
||||
"You may need to upgrade your license on https://funkemunky.cc/shop");
|
||||
}
|
||||
AntiVPN.getInstance().checked++;
|
||||
});
|
||||
}
|
||||
|
||||
private void countryKick(Player player, VPNResponse result) {
|
||||
final String kickReason = AntiVPN.getInstance().getVpnConfig()
|
||||
.countryVanillaKickReason();
|
||||
//Using our built-in kicking system if no commands are configured
|
||||
if(AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) {
|
||||
// Kicking our player
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
player.kickPlayer(ChatColor
|
||||
.translateAlternateColorCodes('&',
|
||||
kickReason
|
||||
.replace("%player%", player.getName())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode())));
|
||||
}
|
||||
}.runTask(BukkitPlugin.pluginInstance);
|
||||
} else {
|
||||
final String playerName = player.getName();
|
||||
|
||||
BukkitPlugin.pluginInstance.getPlayerCommandRunner()
|
||||
.addAction(player.getUniqueId(), () -> {
|
||||
for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
|
||||
final String formattedCommand = ChatColor.translateAlternateColorCodes('&',
|
||||
cmd.replace("%player%", playerName)
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()));
|
||||
|
||||
// Runs our command from console
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), formattedCommand);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void proxyKick(Player player, VPNResponse result) {
|
||||
log(Level.INFO, player.getName()
|
||||
+ " joined on a VPN/Proxy (" + result.getMethod() + ")");
|
||||
|
||||
//Ensuring the user wishes to alert to staff
|
||||
if(AntiVPN.getInstance().getVpnConfig().alertToStaff())
|
||||
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
|
||||
.filter(APIPlayer::isAlertsEnabled)
|
||||
.forEach(pl -> pl.sendMessage(AntiVPN.getInstance().getVpnConfig().alertMessage()
|
||||
.replace("%player%", player.getName())
|
||||
.replace("%reason%", result.getMethod())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%city%", result.getCity())));
|
||||
|
||||
if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) {
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
player.kickPlayer(org.bukkit.ChatColor.translateAlternateColorCodes('&',
|
||||
AntiVPN.getInstance().getVpnConfig().getKickString()));
|
||||
}
|
||||
}.runTask(BukkitPlugin.pluginInstance);
|
||||
} else {
|
||||
//In case the user wants to run their own commands instead of using the built-in kicking
|
||||
if(AntiVPN.getInstance().getVpnConfig().runCommands()) {
|
||||
String playerName = player.getName();
|
||||
BukkitPlugin.pluginInstance.getPlayerCommandRunner()
|
||||
.addAction(player.getUniqueId(), () -> {
|
||||
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(),
|
||||
ChatColor.translateAlternateColorCodes('&',
|
||||
command.replace("%player%",
|
||||
playerName)));
|
||||
}
|
||||
});
|
||||
}
|
||||
AntiVPN.getInstance().detections++;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
AntiVPN.getInstance().getPlayerExecutor().unloadPlayer(event.getPlayer().getUniqueId());
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>AntiVPN</artifactId>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<version>1.9.3</version>
|
||||
<version>1.9.4-DEV</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
<dependency>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<artifactId>Common</artifactId>
|
||||
<version>1.9.3</version>
|
||||
<version>1.9.4-DEV</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -37,12 +37,11 @@ public class BungeeListener extends VPNExecutor implements Listener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
public void onShutdown() {
|
||||
if(cacheResetTask != null) {
|
||||
cacheResetTask.cancel();
|
||||
cacheResetTask = null;
|
||||
}
|
||||
threadExecutor.shutdown();
|
||||
BungeePlugin.pluginInstance.getProxy().getPluginManager().unregisterListener(this);
|
||||
}
|
||||
|
||||
@@ -61,6 +60,17 @@ public class BungeeListener extends VPNExecutor implements Listener {
|
||||
BungeeCord.getInstance().getLogger().log(Level.SEVERE, message, ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disablePlugin() {
|
||||
BungeeCord.getInstance().getPluginManager().unregisterListeners(BungeePlugin.pluginInstance);
|
||||
if(cacheResetTask != null) {
|
||||
cacheResetTask.cancel();
|
||||
cacheResetTask = null;
|
||||
}
|
||||
BungeeCord.getInstance().getPluginManager().unregisterCommands(BungeePlugin.pluginInstance);
|
||||
BungeePlugin.pluginInstance.onDisable();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onListener(final PreLoginEvent event) {
|
||||
if(!responseCache.asMap().containsKey(event.getConnection().getUniqueId())) return;
|
||||
|
||||
+3
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>AntiVPN</artifactId>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<version>1.9.3</version>
|
||||
<version>1.9.4-DEV</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -86,6 +86,8 @@
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>9.1.0</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
|
||||
@@ -54,13 +54,17 @@ public class AntiVPN {
|
||||
try {
|
||||
File configFile = new File(pluginFolder, "config.yml");
|
||||
if(!configFile.exists()){
|
||||
configFile.getParentFile().mkdirs();
|
||||
if(configFile.getParentFile().mkdirs()) {
|
||||
AntiVPN.getInstance().getExecutor().log("Created plugin folder!");
|
||||
}
|
||||
MiscUtils.copy(INSTANCE.getResource( "config.yml"), configFile);
|
||||
}
|
||||
INSTANCE.config = ConfigurationProvider.getProvider(YamlConfiguration.class)
|
||||
.load(configFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
AntiVPN.getInstance().getExecutor().logException("Could not load config.yml, plugin disabling...", e);
|
||||
executor.disablePlugin();
|
||||
return;
|
||||
}
|
||||
|
||||
INSTANCE.vpnConfig = new VPNConfig();
|
||||
@@ -139,7 +143,8 @@ public class AntiVPN {
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
executor.shutdown();
|
||||
executor.onShutdown();
|
||||
VPNExecutor.threadExecutor.shutdown();
|
||||
if(database != null) database.shutdown();
|
||||
}
|
||||
|
||||
@@ -188,7 +193,7 @@ public class AntiVPN {
|
||||
ConfigurationProvider.getProvider(YamlConfiguration.class)
|
||||
.save(getConfig(), new File(pluginFolder.getPath() + File.separator + "config.yml"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
AntiVPN.getInstance().getExecutor().logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public abstract class VPNExecutor {
|
||||
|
||||
public abstract void registerListeners();
|
||||
|
||||
public abstract void shutdown();
|
||||
public abstract void onShutdown();
|
||||
|
||||
public abstract void log(Level level, String log, Object... objects);
|
||||
|
||||
@@ -97,4 +97,6 @@ public abstract class VPNExecutor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void disablePlugin();
|
||||
}
|
||||
|
||||
@@ -2,13 +2,17 @@ package dev.brighten.antivpn.database.sql.utils;
|
||||
|
||||
import com.mysql.cj.jdbc.Driver;
|
||||
import dev.brighten.antivpn.AntiVPN;
|
||||
import org.h2.jdbc.JdbcConnection;
|
||||
import org.h2.jdbc.JdbcSQLFeatureNotSupportedException;
|
||||
import org.h2.jdbc.JdbcSQLNonTransientConnectionException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class MySQL {
|
||||
private static Connection conn;
|
||||
@@ -34,11 +38,24 @@ public class MySQL {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean didRetry = false;
|
||||
|
||||
public static void initH2() {
|
||||
if(didRetry) {
|
||||
AntiVPN.getInstance().getExecutor().log(Level.WARNING,
|
||||
"Already attempted to retry H2 connection, skipping.");
|
||||
return;
|
||||
}
|
||||
File dataFolder = new File(AntiVPN.getInstance().getPluginFolder(), "databases");
|
||||
if (!dataFolder.exists() && dataFolder.mkdirs()) {
|
||||
AntiVPN.getInstance().getExecutor().log("Created database directory");
|
||||
}
|
||||
|
||||
File dbFile = new File(dataFolder, "database.mv.db");
|
||||
|
||||
File databaseFile = new File(dataFolder, "database");
|
||||
try {
|
||||
conn = new NonClosableConnection(new JdbcConnection("jdbc:h2:file:" +
|
||||
conn = new NonClosableConnection(new org.h2.jdbc.JdbcConnection("jdbc:h2:file:" +
|
||||
databaseFile.getAbsolutePath(),
|
||||
new Properties(), AntiVPN.getInstance().getVpnConfig().getUsername(),
|
||||
AntiVPN.getInstance().getVpnConfig().getPassword(), false));
|
||||
@@ -46,7 +63,45 @@ public class MySQL {
|
||||
Query.use(conn);
|
||||
AntiVPN.getInstance().getExecutor().log("Connection to H2 has been established.");
|
||||
} catch (SQLException ex) {
|
||||
AntiVPN.getInstance().getExecutor().logException("H2 exception on initialize: " + ex.getMessage(), ex);
|
||||
AntiVPN.getInstance().getExecutor().logException("H2 exception on initialize", ex);
|
||||
if(ex instanceof JdbcSQLFeatureNotSupportedException
|
||||
|| ex instanceof JdbcSQLNonTransientConnectionException) {
|
||||
AntiVPN.getInstance().getExecutor()
|
||||
.log("H2 database file is incompatible with this version of AntiVPN. " +
|
||||
"Backing up old database file...");
|
||||
backupOldDB(dbFile, dataFolder);
|
||||
initH2();
|
||||
didRetry = true;
|
||||
} else {
|
||||
AntiVPN.getInstance().getExecutor().logException("Failed to load H2 database: " + ex.getCause().toString(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void backupOldDB(File dbFile, File dataFolder) {
|
||||
if (dbFile.exists()) {
|
||||
try {
|
||||
// Optional: Make backup first
|
||||
File backupDir = new File(dataFolder, "backups");
|
||||
if(backupDir.mkdirs()) {
|
||||
AntiVPN.getInstance().getExecutor().log("Created backup directory");
|
||||
} else {
|
||||
AntiVPN.getInstance().getExecutor().log("Backup directory already exists");
|
||||
}
|
||||
File backupFile = new File(backupDir, "database.mv.db.backup_" + System.currentTimeMillis());
|
||||
Files.copy(dbFile.toPath(), backupFile.toPath());
|
||||
|
||||
// Actually delete the file
|
||||
if (!dbFile.delete()) {
|
||||
// If normal delete fails, try force delete on JVM exit
|
||||
dbFile.deleteOnExit();
|
||||
AntiVPN.getInstance().getExecutor().log("Could not delete database file - will try again on shutdown");
|
||||
} else {
|
||||
AntiVPN.getInstance().getExecutor().log("Successfully deleted incompatible database file");
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
AntiVPN.getInstance().getExecutor().logException("Failed to handle database file", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ cachedResults: true
|
||||
# All players with any of the following characters in the beginning of their name will be whitelisted
|
||||
# This is a useful feature for servers that allow players through Geyser and their IPs are not forwarded, causing
|
||||
# players to be removed falsely for use of proxy.
|
||||
prefixWhitelists: []
|
||||
prefixWhitelists:
|
||||
- "*"
|
||||
# Configure your database here.
|
||||
database:
|
||||
# Enable to cache queries and save alerts state beyond restarts
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>AntiVPN</artifactId>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<version>1.9.3</version>
|
||||
<version>1.9.4-DEV</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<dependency>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<artifactId>Common</artifactId>
|
||||
<version>1.9.3</version>
|
||||
<version>1.9.4-DEV</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>AntiVPN</artifactId>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<version>1.9.3</version>
|
||||
<version>1.9.4-DEV</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<dependency>
|
||||
<groupId>dev.brighten.antivpn</groupId>
|
||||
<artifactId>Common</artifactId>
|
||||
<version>1.9.3</version>
|
||||
<version>1.9.4-DEV</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.brighten.antivpn.velocity;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.velocitypowered.api.event.EventHandler;
|
||||
import com.velocitypowered.api.event.ResultedEvent;
|
||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||
import com.velocitypowered.api.event.connection.LoginEvent;
|
||||
@@ -26,6 +27,145 @@ public class VelocityListener extends VPNExecutor {
|
||||
.maximumSize(2000)
|
||||
.build();
|
||||
|
||||
private final EventHandler<LoginEvent> loginEvent = event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
if (event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission
|
||||
//Is exempt
|
||||
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())
|
||||
//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().getVpnConfig().getPrefixWhitelists().stream()
|
||||
.anyMatch(prefix -> event.getPlayer().getUsername().startsWith(prefix))) return;
|
||||
|
||||
if(responseCache.asMap().containsKey(event.getPlayer().getUniqueId())) {
|
||||
VPNResponse cached = responseCache.getIfPresent(event.getPlayer().getUniqueId());
|
||||
|
||||
if (cached != null && cached.isProxy()) {
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(Component.text("No")));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
checkIp(event.getPlayer().getRemoteAddress().getAddress().getHostAddress(),
|
||||
AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> {
|
||||
if (result.isSuccess()) {
|
||||
// If the countryList() size is zero, no need to check.
|
||||
// Running country check first
|
||||
if (!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty()
|
||||
&& !(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()))
|
||||
// This bit of code will decide whether or not to kick the player
|
||||
// If it contains the code and it is set to whitelist, it will not kick
|
||||
// as they are equal and vise versa. However, if the contains does not match
|
||||
// the state, it will kick.
|
||||
&& AntiVPN.getInstance().getVpnConfig().countryList()
|
||||
.contains(result.getCountryCode())
|
||||
!= AntiVPN.getInstance().getVpnConfig().whitelistCountries()) {
|
||||
//Using our built in kicking system if no commands are configured
|
||||
if (AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) {
|
||||
final String kickReason = AntiVPN.getInstance().getVpnConfig()
|
||||
.countryVanillaKickReason();
|
||||
// Kicking our player
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder()
|
||||
.character('&')
|
||||
.build().deserialize(kickReason
|
||||
.replace("%player%", event.getPlayer().getUsername())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()))));
|
||||
VelocityPlugin.INSTANCE.getServer().getScheduler()
|
||||
.buildTask(VelocityPlugin.INSTANCE, () ->
|
||||
event.getPlayer().disconnect(LegacyComponentSerializer.builder()
|
||||
.character('&')
|
||||
.build().deserialize(kickReason
|
||||
.replace("%player%", event.getPlayer().getUsername())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()))));
|
||||
} else {
|
||||
for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
|
||||
final String formattedCommand = StringUtils
|
||||
.translateAlternateColorCodes('&',
|
||||
cmd.replace("%player%",
|
||||
event.getPlayer().getUsername())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()));
|
||||
// Running the command from console
|
||||
VelocityPlugin.INSTANCE.getServer().getCommandManager()
|
||||
.executeAsync(VelocityPlugin.INSTANCE.getServer()
|
||||
.getConsoleCommandSource(),
|
||||
StringUtils.translateAlternateColorCodes('&',
|
||||
formattedCommand));
|
||||
}
|
||||
}
|
||||
} else if (result.isProxy()) {
|
||||
if (AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) {
|
||||
// Delay code execution
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder()
|
||||
.character('&')
|
||||
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
|
||||
.getKickString()
|
||||
.replace("%player%", event.getPlayer().getUsername())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()))));
|
||||
|
||||
VelocityPlugin.INSTANCE.getServer().getScheduler()
|
||||
.buildTask(VelocityPlugin.INSTANCE, () ->
|
||||
event.getPlayer().disconnect(LegacyComponentSerializer.builder()
|
||||
.character('&')
|
||||
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
|
||||
.getKickString()
|
||||
.replace("%player%", event.getPlayer().getUsername())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()))))
|
||||
.delay(1, TimeUnit.SECONDS).schedule();
|
||||
}
|
||||
VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername()
|
||||
+ " joined on a VPN/Proxy (" + result.getMethod() + ")");
|
||||
//Ensuring the user wishes to alert to staff
|
||||
if (AntiVPN.getInstance().getVpnConfig().alertToStaff())
|
||||
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
|
||||
.filter(APIPlayer::isAlertsEnabled)
|
||||
.forEach(pl ->
|
||||
pl.sendMessage(AntiVPN.getInstance().getVpnConfig()
|
||||
.alertMessage()
|
||||
.replace("%player%",
|
||||
event.getPlayer().getUsername())
|
||||
.replace("%reason%",
|
||||
result.getMethod())
|
||||
.replace("%country%",
|
||||
result.getCountryName())
|
||||
.replace("%city%",
|
||||
result.getCity())));
|
||||
|
||||
//In case the user wants to run their own commands instead of using the
|
||||
// built in kicking
|
||||
if (AntiVPN.getInstance().getVpnConfig().runCommands()) {
|
||||
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
|
||||
VelocityPlugin.INSTANCE.getServer().getCommandManager()
|
||||
.executeAsync(VelocityPlugin.INSTANCE.getServer()
|
||||
.getConsoleCommandSource(),
|
||||
StringUtils.translateAlternateColorCodes('&',
|
||||
command.replace("%player%",
|
||||
event.getPlayer().getUsername())));
|
||||
}
|
||||
}
|
||||
AntiVPN.getInstance().detections++;
|
||||
}
|
||||
} else {
|
||||
VelocityPlugin.INSTANCE.getLogger()
|
||||
.log(Level.WARNING,
|
||||
"The API query was not a success! " +
|
||||
"You may need to upgrade your license on " +
|
||||
"https://funkemunky.cc/shop");
|
||||
}
|
||||
AntiVPN.getInstance().checked++;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
public void registerListeners() {
|
||||
@@ -33,156 +173,19 @@ public class VelocityListener extends VPNExecutor {
|
||||
.register(VelocityPlugin.INSTANCE, this);
|
||||
|
||||
VelocityPlugin.INSTANCE.getServer().getEventManager().register(VelocityPlugin.INSTANCE, DisconnectEvent.class,
|
||||
event -> AntiVPN.getInstance().getPlayerExecutor().unloadPlayer(event.getPlayer().getUniqueId()));
|
||||
event -> AntiVPN.getInstance().getPlayerExecutor()
|
||||
.unloadPlayer(event.getPlayer().getUniqueId()));
|
||||
|
||||
VelocityPlugin.INSTANCE.getServer().getEventManager().register(VelocityPlugin.INSTANCE, LoginEvent.class,
|
||||
event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
if (event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission
|
||||
//Is exempt
|
||||
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())
|
||||
//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().getVpnConfig().getPrefixWhitelists().stream()
|
||||
.anyMatch(prefix -> event.getPlayer().getUsername().startsWith(prefix))) return;
|
||||
|
||||
if(responseCache.asMap().containsKey(event.getPlayer().getUniqueId())) {
|
||||
VPNResponse cached = responseCache.getIfPresent(event.getPlayer().getUniqueId());
|
||||
|
||||
if (cached != null && cached.isProxy()) {
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(Component.text("No")));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
checkIp(event.getPlayer().getRemoteAddress().getAddress().getHostAddress(),
|
||||
AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> {
|
||||
if (result.isSuccess()) {
|
||||
// If the countryList() size is zero, no need to check.
|
||||
// Running country check first
|
||||
if (!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty()
|
||||
&& !(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()))
|
||||
// This bit of code will decide whether or not to kick the player
|
||||
// If it contains the code and it is set to whitelist, it will not kick
|
||||
// as they are equal and vise versa. However, if the contains does not match
|
||||
// the state, it will kick.
|
||||
&& AntiVPN.getInstance().getVpnConfig().countryList()
|
||||
.contains(result.getCountryCode())
|
||||
!= AntiVPN.getInstance().getVpnConfig().whitelistCountries()) {
|
||||
//Using our built in kicking system if no commands are configured
|
||||
if (AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) {
|
||||
final String kickReason = AntiVPN.getInstance().getVpnConfig()
|
||||
.countryVanillaKickReason();
|
||||
// Kicking our player
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder()
|
||||
.character('&')
|
||||
.build().deserialize(kickReason
|
||||
.replace("%player%", event.getPlayer().getUsername())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()))));
|
||||
VelocityPlugin.INSTANCE.getServer().getScheduler()
|
||||
.buildTask(VelocityPlugin.INSTANCE, () ->
|
||||
event.getPlayer().disconnect(LegacyComponentSerializer.builder()
|
||||
.character('&')
|
||||
.build().deserialize(kickReason
|
||||
.replace("%player%", event.getPlayer().getUsername())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()))));
|
||||
} else {
|
||||
for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
|
||||
final String formattedCommand = StringUtils
|
||||
.translateAlternateColorCodes('&',
|
||||
cmd.replace("%player%",
|
||||
event.getPlayer().getUsername())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()));
|
||||
// Running the command from console
|
||||
VelocityPlugin.INSTANCE.getServer().getCommandManager()
|
||||
.executeAsync(VelocityPlugin.INSTANCE.getServer()
|
||||
.getConsoleCommandSource(),
|
||||
StringUtils.translateAlternateColorCodes('&',
|
||||
formattedCommand));
|
||||
}
|
||||
}
|
||||
} else if (result.isProxy()) {
|
||||
if (AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) {
|
||||
// Delay code execution
|
||||
event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder()
|
||||
.character('&')
|
||||
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
|
||||
.getKickString()
|
||||
.replace("%player%", event.getPlayer().getUsername())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()))));
|
||||
|
||||
VelocityPlugin.INSTANCE.getServer().getScheduler()
|
||||
.buildTask(VelocityPlugin.INSTANCE, () ->
|
||||
event.getPlayer().disconnect(LegacyComponentSerializer.builder()
|
||||
.character('&')
|
||||
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
|
||||
.getKickString()
|
||||
.replace("%player%", event.getPlayer().getUsername())
|
||||
.replace("%country%", result.getCountryName())
|
||||
.replace("%code%", result.getCountryCode()))))
|
||||
.delay(1, TimeUnit.SECONDS).schedule();
|
||||
}
|
||||
VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername()
|
||||
+ " joined on a VPN/Proxy (" + result.getMethod() + ")");
|
||||
//Ensuring the user wishes to alert to staff
|
||||
if (AntiVPN.getInstance().getVpnConfig().alertToStaff())
|
||||
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
|
||||
.filter(APIPlayer::isAlertsEnabled)
|
||||
.forEach(pl ->
|
||||
pl.sendMessage(AntiVPN.getInstance().getVpnConfig()
|
||||
.alertMessage()
|
||||
.replace("%player%",
|
||||
event.getPlayer().getUsername())
|
||||
.replace("%reason%",
|
||||
result.getMethod())
|
||||
.replace("%country%",
|
||||
result.getCountryName())
|
||||
.replace("%city%",
|
||||
result.getCity())));
|
||||
|
||||
//In case the user wants to run their own commands instead of using the
|
||||
// built in kicking
|
||||
if (AntiVPN.getInstance().getVpnConfig().runCommands()) {
|
||||
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
|
||||
VelocityPlugin.INSTANCE.getServer().getCommandManager()
|
||||
.executeAsync(VelocityPlugin.INSTANCE.getServer()
|
||||
.getConsoleCommandSource(),
|
||||
StringUtils.translateAlternateColorCodes('&',
|
||||
command.replace("%player%",
|
||||
event.getPlayer().getUsername())));
|
||||
}
|
||||
}
|
||||
AntiVPN.getInstance().detections++;
|
||||
}
|
||||
} else {
|
||||
VelocityPlugin.INSTANCE.getLogger()
|
||||
.log(Level.WARNING,
|
||||
"The API query was not a success! " +
|
||||
"You may need to upgrade your license on " +
|
||||
"https://funkemunky.cc/shop");
|
||||
}
|
||||
AntiVPN.getInstance().checked++;
|
||||
});
|
||||
}
|
||||
});
|
||||
loginEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
public void onShutdown() {
|
||||
if (cacheResetTask != null) {
|
||||
cacheResetTask.cancel();
|
||||
cacheResetTask = null;
|
||||
}
|
||||
threadExecutor.shutdown();
|
||||
VelocityPlugin.INSTANCE.getServer().getEventManager().unregisterListener(VelocityPlugin.INSTANCE, this);
|
||||
}
|
||||
|
||||
@@ -200,4 +203,10 @@ public class VelocityListener extends VPNExecutor {
|
||||
public void logException(String message, Exception ex) {
|
||||
VelocityPlugin.INSTANCE.getLogger().log(Level.SEVERE, message, ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disablePlugin() {
|
||||
VelocityPlugin.INSTANCE.getServer().getEventManager().unregisterListener(VelocityPlugin.INSTANCE, this);
|
||||
VelocityPlugin.INSTANCE.getServer().getCommandManager().unregister("antivpn");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.brighten.antivpn.velocity;
|
||||
import com.google.inject.Inject;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
||||
import com.velocitypowered.api.plugin.Plugin;
|
||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
@@ -12,6 +13,7 @@ import dev.brighten.antivpn.velocity.command.VelocityCommand;
|
||||
import lombok.Getter;
|
||||
import org.bstats.velocity.Metrics;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.nio.file.Path;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -24,6 +26,9 @@ public class VelocityPlugin {
|
||||
private final Metrics.Factory metricsFactory;
|
||||
private final Path configDir;
|
||||
|
||||
@Nullable
|
||||
private Metrics metrics;
|
||||
|
||||
public static VelocityPlugin INSTANCE;
|
||||
|
||||
@Inject
|
||||
@@ -45,7 +50,7 @@ public class VelocityPlugin {
|
||||
|
||||
if(AntiVPN.getInstance().getVpnConfig().metrics()) {
|
||||
logger.info("Starting metrics...");
|
||||
Metrics metrics = metricsFactory.make(this, 12791);
|
||||
metrics = metricsFactory.make(this, 12791);
|
||||
}
|
||||
|
||||
logger.info("Registering commands...");
|
||||
@@ -54,4 +59,10 @@ public class VelocityPlugin {
|
||||
.aliases(command.aliases()).build(), new VelocityCommand(command));
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onShutdown(ProxyShutdownEvent event) {
|
||||
AntiVPN.getInstance().stop();
|
||||
INSTANCE = null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user