diff --git a/Assembly/pom.xml b/Assembly/pom.xml
index 12a478a..9e3fa66 100644
--- a/Assembly/pom.xml
+++ b/Assembly/pom.xml
@@ -5,7 +5,7 @@
AntiVPNdev.brighten.antivpn
- 1.9.3-DEV
+ 1.9.34.0.0
diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml
index 2eb649b..15cd426 100644
--- a/Bukkit/pom.xml
+++ b/Bukkit/pom.xml
@@ -5,7 +5,7 @@
AntiVPNdev.brighten.antivpn
- 1.9.3-DEV
+ 1.9.34.0.0
@@ -78,7 +78,7 @@
dev.brighten.antivpnCommon
- 1.9.3-DEV
+ 1.9.3provided
diff --git a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java
index 3d5a25a..46c0016 100644
--- a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java
+++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitListener.java
@@ -15,7 +15,6 @@ 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;
@@ -56,12 +55,11 @@ public class BukkitListener extends VPNExecutor implements Listener {
.ifPresent(player -> {
AntiVPN.getInstance().getDatabase().alertsState(player.getUuid(), enabled -> {
if(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 AntiVPN.getInstance().getExecutor().log("Not enabled");
+ }
});
});
}
@@ -76,7 +74,6 @@ public class BukkitListener extends VPNExecutor implements Listener {
|| AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream()
.anyMatch(prefix -> event.getPlayer().getName().startsWith(prefix))) return;
-
if(responseCache.asMap().containsKey(event.getPlayer().getUniqueId())) {
VPNResponse cached = responseCache.getIfPresent(event.getPlayer().getUniqueId());
@@ -93,113 +90,117 @@ public class BukkitListener extends VPNExecutor implements Listener {
AntiVPN.getInstance().getVpnConfig().cachedResults(), result -> {
if(result.isSuccess()) {
//We need to run on main thread or kicking and running commands will cause errors
- new BukkitRunnable() {
- public void run() {
- //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());
- 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 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());
+ 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
- // 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
- event.getPlayer().kickPlayer(ChatColor
- .translateAlternateColorCodes('&',
- kickReason
- .replace("%player%", event.getPlayer().getName())
- .replace("%country%", result.getCountryName())
- .replace("%code%", result.getCountryCode())));
- } else {
- for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
- final String formattedCommand = ChatColor.translateAlternateColorCodes('&',
- cmd.replace("%player%", event.getPlayer().getName())
- .replace("%country%", result.getCountryName())
- .replace("%code%", result.getCountryCode()));
-
- // Runs our command from console
- Bukkit.dispatchCommand(Bukkit.getConsoleSender(), formattedCommand);
- }
- }
- } 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())
- player.kickPlayer(org.bukkit.ChatColor.translateAlternateColorCodes('&',
- AntiVPN.getInstance().getVpnConfig().getKickString()));
- 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()) {
- for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
- Bukkit.dispatchCommand(Bukkit.getConsoleSender(),
- ChatColor.translateAlternateColorCodes('&',
- command.replace("%player%",
- event.getPlayer().getName())));
- }
- }
- AntiVPN.getInstance().detections++;
- }
+ //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;
}
- }.runTask(BukkitPlugin.pluginInstance);
+ }
+
+ // 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
+ // 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
+ event.getPlayer().kickPlayer(ChatColor
+ .translateAlternateColorCodes('&',
+ kickReason
+ .replace("%player%", event.getPlayer().getName())
+ .replace("%country%", result.getCountryName())
+ .replace("%code%", result.getCountryCode())));
+ } 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);
+ }
+ });
+ }
+ } 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())
+ player.kickPlayer(org.bukkit.ChatColor.translateAlternateColorCodes('&',
+ AntiVPN.getInstance().getVpnConfig().getKickString()));
+ 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++;
+ }
} else {
log(Level.WARNING,
"The API query was not a success! " +
diff --git a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java
index 9af38c2..2b67350 100644
--- a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java
+++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/BukkitPlugin.java
@@ -3,6 +3,7 @@ package dev.brighten.antivpn.bukkit;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.bukkit.command.BukkitCommand;
import dev.brighten.antivpn.command.Command;
+import lombok.Getter;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SingleLineChart;
import org.bukkit.Bukkit;
@@ -21,8 +22,12 @@ public class BukkitPlugin extends JavaPlugin {
public static BukkitPlugin pluginInstance;
private SimpleCommandMap commandMap;
- private List registeredCommands = new ArrayList<>();
+ private final List registeredCommands = new ArrayList<>();
+
+ @Getter
private SingleLineChart vpnDetections, ipsChecked;
+ @Getter
+ private PlayerCommandRunner playerCommandRunner;
public void onEnable() {
pluginInstance = this;
@@ -30,6 +35,9 @@ public class BukkitPlugin extends JavaPlugin {
Bukkit.getLogger().info("Starting AntiVPN services...");
AntiVPN.start(new BukkitListener(), new BukkitPlayerExecutor(), getDataFolder());
+ playerCommandRunner = new PlayerCommandRunner();
+ playerCommandRunner.start();
+
// Loading our bStats metrics to be pushed to https://bstats.org
if(AntiVPN.getInstance().getVpnConfig().metrics()) {
Bukkit.getLogger().info("Starting bStats metrics...");
@@ -84,6 +92,7 @@ public class BukkitPlugin extends JavaPlugin {
public void onDisable() {
Bukkit.getLogger().info("Stopping plugin services...");
AntiVPN.getInstance().stop();
+ playerCommandRunner.stop();
Bukkit.getLogger().info("Unregistering commands...");
try {
diff --git a/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/PlayerCommandRunner.java b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/PlayerCommandRunner.java
new file mode 100644
index 0000000..3a285a8
--- /dev/null
+++ b/Bukkit/src/main/java/dev/brighten/antivpn/bukkit/PlayerCommandRunner.java
@@ -0,0 +1,61 @@
+package dev.brighten.antivpn.bukkit;
+
+import dev.brighten.antivpn.utils.MiscUtils;
+import lombok.Data;
+import org.bukkit.Bukkit;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import java.util.Queue;
+import java.util.UUID;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class PlayerCommandRunner {
+ private final ScheduledExecutorService executorService;
+ private final Queue playerActions = new ArrayBlockingQueue<>(10000);
+
+ public PlayerCommandRunner() {
+ executorService = Executors.newSingleThreadScheduledExecutor(
+ MiscUtils.createThreadFactory("AntiVPN:PlayerCommandRunner")
+ );
+ }
+
+ void start() {
+ executorService.scheduleAtFixedRate(() -> {
+ long currentTime = System.currentTimeMillis();
+ while(!playerActions.isEmpty()) {
+ PlayerAction action = playerActions.peek();
+
+ if(action == null) continue;
+
+ if(currentTime - action.start > 2000L || Bukkit.getPlayer(action.getUuid()) != null) {
+ new BukkitRunnable() {
+ public void run() {
+ action.getAction().run();
+ }
+ }.runTask(BukkitPlugin.pluginInstance);
+
+ playerActions.poll();
+ }
+ }
+ }, 1000, 100, TimeUnit.MILLISECONDS);
+ }
+
+ void stop() {
+ executorService.shutdown();
+ playerActions.clear();
+ }
+
+ void addAction(UUID uuid, Runnable action) {
+ playerActions.add(new PlayerAction(uuid, System.currentTimeMillis(), action));
+ }
+
+ @Data
+ static class PlayerAction {
+ private final UUID uuid;
+ private final long start;
+ private final Runnable action;
+ }
+}
diff --git a/Bungee/pom.xml b/Bungee/pom.xml
index 93d0fea..74b9836 100644
--- a/Bungee/pom.xml
+++ b/Bungee/pom.xml
@@ -5,7 +5,7 @@
AntiVPNdev.brighten.antivpn
- 1.9.3-DEV
+ 1.9.34.0.0
@@ -71,7 +71,7 @@
dev.brighten.antivpnCommon
- 1.9.3-DEV
+ 1.9.3provided
diff --git a/Common/pom.xml b/Common/pom.xml
index ed83b14..3db22b1 100644
--- a/Common/pom.xml
+++ b/Common/pom.xml
@@ -5,7 +5,7 @@
AntiVPNdev.brighten.antivpn
- 1.9.3-DEV
+ 1.9.34.0.0
@@ -21,17 +21,24 @@
org.apache.maven.pluginsmaven-compiler-plugin
- 3.8.1
+ 3.10.188-XDignore.symbol.file
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+
+ org.apache.maven.pluginsmaven-shade-plugin
- 3.2.4
+ 3.4.1package
@@ -49,6 +56,10 @@
com.google.commondev.brighten.antivpn.shaded.com.google.common
+
+ org.h2
+ dev.brighten.antivpn.shaded.org.h2
+
@@ -76,13 +87,13 @@
mysql-connector-j8.2.0jar
- provided
+ compilecom.h2databaseh2
- 2.2.224
- provided
+ 2.1.210
+ compileorg.yaml
@@ -99,7 +110,7 @@
org.mongodbmongo-java-driver3.12.14
- provided
+ compile
diff --git a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java
index 16dd2a5..2bc20f4 100644
--- a/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java
+++ b/Common/src/main/java/dev/brighten/antivpn/AntiVPN.java
@@ -9,8 +9,6 @@ import dev.brighten.antivpn.database.VPNDatabase;
import dev.brighten.antivpn.database.local.H2VPN;
import dev.brighten.antivpn.database.mongo.MongoVPN;
import dev.brighten.antivpn.database.sql.MySqlVPN;
-import dev.brighten.antivpn.depends.LibraryLoader;
-import dev.brighten.antivpn.depends.MavenLibrary;
import dev.brighten.antivpn.message.MessageHandler;
import dev.brighten.antivpn.utils.ConfigDefault;
import dev.brighten.antivpn.utils.MiscUtils;
@@ -31,9 +29,6 @@ import java.util.List;
@Getter
@Setter(AccessLevel.PRIVATE)
-@MavenLibrary(groupId = "com.h2database", artifactId ="h2", version = "2.2.224")
-@MavenLibrary(groupId = "org.mongodb", artifactId = "mongo-java-driver", version = "3.12.14")
-@MavenLibrary(groupId = "com.mysql", artifactId = "mysql-connector-j", version = "8.2.0")
public class AntiVPN {
private static AntiVPN INSTANCE;
@@ -56,8 +51,6 @@ public class AntiVPN {
INSTANCE.executor = executor;
INSTANCE.playerExecutor = playerExecutor;
- LibraryLoader.loadAll(INSTANCE);
-
try {
File configFile = new File(pluginFolder, "config.yml");
if(!configFile.exists()){
diff --git a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java b/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java
index 0b99084..c643a20 100644
--- a/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java
+++ b/Common/src/main/java/dev/brighten/antivpn/database/sql/utils/MySQL.java
@@ -1,13 +1,9 @@
package dev.brighten.antivpn.database.sql.utils;
import dev.brighten.antivpn.AntiVPN;
-import org.h2.jdbc.JdbcSQLNonTransientConnectionException;
+import org.h2.jdbc.JdbcConnection;
import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.nio.file.Files;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
@@ -47,10 +43,8 @@ public class MySQL {
File dataFolder = new File(AntiVPN.getInstance().getPluginFolder(), "databases");
File databaseFile = new File(dataFolder, "database");
try {
- Constructor jdbcConnection = Class.forName("org.h2.jdbc.JdbcConnection")
- .getConstructor(String.class, Properties.class, String.class, Object.class, boolean.class);
- conn = new NonClosableConnection((Connection)jdbcConnection.newInstance("jdbc:h2:file:" +
- databaseFile.getAbsolutePath(),
+ conn = new NonClosableConnection(new JdbcConnection("jdbc:h2:file:" +
+ databaseFile.getAbsolutePath(),
new Properties(), AntiVPN.getInstance().getVpnConfig().getUsername(),
AntiVPN.getInstance().getVpnConfig().getPassword(), false));
conn.setAutoCommit(true);
@@ -59,47 +53,6 @@ public class MySQL {
} catch (SQLException ex) {
AntiVPN.getInstance().getExecutor().log("H2 exception on initialize");
ex.printStackTrace();
- } catch (ClassNotFoundException ex) {
- AntiVPN.getInstance().getExecutor().log("No H2 library found!");
- } catch (NoSuchMethodException | InstantiationException | IllegalAccessException e) {
- AntiVPN.getInstance().getExecutor().log("Java exception on initialize");
- e.printStackTrace();
- } catch(InvocationTargetException e) {
- if(attemptedTwice) return;
- if(e.getCause() instanceof JdbcSQLNonTransientConnectionException) {
- File[] files = dataFolder.listFiles();
-
- if(files == null) {
- e.printStackTrace();
- return;
- }
-
- File oldDbs = new File(dataFolder, "old");
-
- boolean made = false;
- if(!oldDbs.isDirectory()) {
- made = oldDbs.mkdir();
- } else made = true;
-
- if(!made) {
- throw new RuntimeException(String.format("Unable to upgrade H2 files since this application " +
- "was unable to create a new directory %s (insufficient permissions?)!", oldDbs.getPath()));
- }
- AntiVPN.getInstance().getExecutor().log("Upgrading h2 files...");
- for (File file : files) {
- if(file.getName().endsWith(".db")) {
- try {
- Files.copy(file.toPath(), new File(oldDbs, file.getName()).toPath());
- } catch (IOException ex) {
- throw new RuntimeException(ex);
- }
- if(file.delete()) {
- AntiVPN.getInstance().getExecutor().log("Successfully deleted old " + file.getName());
- } else throw new RuntimeException("Unable to delete old database file " + file.getName());
- }
- }
- initH2();
- } else e.printStackTrace();
}
attemptedTwice = true;
}
diff --git a/Common/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java b/Common/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java
deleted file mode 100644
index 5ee3961..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/depends/LibraryLoader.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * This file is part of helper, licensed under the MIT License.
- *
- * Copyright (c) lucko (Luck)
- * Copyright (c) contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package dev.brighten.antivpn.depends;
-
-import dev.brighten.antivpn.AntiVPN;
-import dev.brighten.antivpn.utils.NonnullByDefault;
-import dev.brighten.antivpn.utils.Supplier;
-import dev.brighten.antivpn.utils.Suppliers;
-
-import java.io.File;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.file.Files;
-import java.util.Objects;
-
-/**
- * Resolves {@link MavenLibrary} annotations for a class, and loads the dependency
- * into the classloader.
- */
-@NonnullByDefault
-public final class LibraryLoader {
-
- private static final Supplier URL_INJECTOR = Suppliers.memoize(() -> URLClassLoaderAccess.create((URLClassLoader) AntiVPN.getInstance().getClass().getClassLoader()));
-
- /**
- * Resolves all {@link MavenLibrary} annotations on the given object.
- *
- * @param object the object to load libraries for.
- */
- public static void loadAll(Object object) {
- loadAll(object.getClass());
- }
-
- /**
- * Resolves all {@link MavenLibrary} annotations on the given class.
- *
- * @param clazz the class to load libraries for.
- */
- public static void loadAll(Class> clazz) {
- MavenLibrary[] libs = clazz.getDeclaredAnnotationsByType(MavenLibrary.class);
- if (libs == null) {
- return;
- }
-
- for (MavenLibrary lib : libs) {
- load(lib.groupId(), lib.artifactId(), lib.version(), lib.repo().url());
- }
- }
-
- public static void load(String groupId, String artifactId, String version) {
- load(groupId, artifactId, version, "https://repo1.maven.org/maven2");
- }
-
- public static void load(String groupId, String artifactId, String version, String repoUrl) {
- load(new Dependency(groupId, artifactId, version, repoUrl));
- }
-
- public static void load(Dependency d) {
- AntiVPN.getInstance().getExecutor().log(String.format("Loading dependency %s:%s:%s from %s", d.getGroupId(), d.getArtifactId(), d.getVersion(), d.getRepoUrl()));
- String name = d.getArtifactId() + "-" + d.getVersion();
-
- File saveLocation = new File(getLibFolder(), name + ".jar");
- if (!saveLocation.exists()) {
-
- try {
- AntiVPN.getInstance().getExecutor().log("Dependency '" + name + "' is not already in the libraries folder. Attempting to download...");
- URL url = d.getUrl();
-
- try (InputStream is = url.openStream()) {
- Files.copy(is, saveLocation.toPath());
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- AntiVPN.getInstance().getExecutor().log("Dependency '" + name + "' successfully downloaded.");
- }
-
- if (!saveLocation.exists()) {
- throw new RuntimeException("Unable to download dependency: " + d.toString());
- }
-
- try {
- URL_INJECTOR.get().addURL(saveLocation.toURI().toURL());
- } catch (Exception e) {
- throw new RuntimeException("Unable to load dependency: " + saveLocation.toString(), e);
- }
-
- AntiVPN.getInstance().getExecutor().log("Loaded dependency '" + name + "' successfully.");
- }
-
- private static File getLibFolder() {
- File pluginDataFolder = AntiVPN.getInstance().getPluginFolder();
- File libs = new File(pluginDataFolder, "libraries");
- libs.mkdirs();
- return libs;
- }
-
- @NonnullByDefault
- public static final class Dependency {
- private final String groupId;
- private final String artifactId;
- private final String version;
- private final String repoUrl;
-
- public Dependency(String groupId, String artifactId, String version, String repoUrl) {
- this.groupId = Objects.requireNonNull(groupId, "groupId");
- this.artifactId = Objects.requireNonNull(artifactId, "artifactId");
- this.version = Objects.requireNonNull(version, "version");
- this.repoUrl = Objects.requireNonNull(repoUrl, "repoUrl");
- }
-
- public String getGroupId() {
- return this.groupId;
- }
-
- public String getArtifactId() {
- return this.artifactId;
- }
-
- public String getVersion() {
- return this.version;
- }
-
- public String getRepoUrl() {
- return this.repoUrl;
- }
-
- public URL getUrl() throws MalformedURLException {
- String repo = this.repoUrl;
- if (!repo.endsWith("/")) {
- repo += "/";
- }
- repo += "%s/%s/%s/%s-%s.jar";
-
- String url = String.format(repo, this.groupId.replace(".", "/"), this.artifactId, this.version, this.artifactId, this.version);
- return new URL(url);
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) return true;
- if (!(o instanceof Dependency)) return false;
- final Dependency other = (Dependency) o;
- return this.getGroupId().equals(other.getGroupId()) &&
- this.getArtifactId().equals(other.getArtifactId()) &&
- this.getVersion().equals(other.getVersion()) &&
- this.getRepoUrl().equals(other.getRepoUrl());
- }
-
- @Override
- public int hashCode() {
- final int PRIME = 59;
- int result = 1;
- result = result * PRIME + this.getGroupId().hashCode();
- result = result * PRIME + this.getArtifactId().hashCode();
- result = result * PRIME + this.getVersion().hashCode();
- result = result * PRIME + this.getRepoUrl().hashCode();
- return result;
- }
-
- @Override
- public String toString() {
- return "LibraryLoader.Dependency(" +
- "groupId=" + this.getGroupId() + ", " +
- "artifactId=" + this.getArtifactId() + ", " +
- "version=" + this.getVersion() + ", " +
- "repoUrl=" + this.getRepoUrl() + ")";
- }
- }
-
-
-}
diff --git a/Common/src/main/java/dev/brighten/antivpn/depends/MavenLibraries.java b/Common/src/main/java/dev/brighten/antivpn/depends/MavenLibraries.java
deleted file mode 100644
index 189f737..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/depends/MavenLibraries.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This file is part of helper, licensed under the MIT License.
- *
- * Copyright (c) lucko (Luck)
- * Copyright (c) contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package dev.brighten.antivpn.depends;
-
-import java.lang.annotation.*;
-
-/**
- * Annotation to indicate the required libraries for a class.
- */
-@Documented
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface MavenLibraries {
-
- MavenLibrary[] value() default {};
-
-}
diff --git a/Common/src/main/java/dev/brighten/antivpn/depends/MavenLibrary.java b/Common/src/main/java/dev/brighten/antivpn/depends/MavenLibrary.java
deleted file mode 100644
index 4dad047..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/depends/MavenLibrary.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * This file is part of helper, licensed under the MIT License.
- *
- * Copyright (c) lucko (Luck)
- * Copyright (c) contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package dev.brighten.antivpn.depends;
-
-import java.lang.annotation.*;
-
-/**
- * Annotation to indicate a required library for a class.
- */
-@Documented
-@Repeatable(MavenLibraries.class)
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface MavenLibrary {
-
- /**
- * The group id of the library
- *
- * @return the group id of the library
- */
- String groupId();
-
- /**
- * The artifact id of the library
- *
- * @return the artifact id of the library
- */
- String artifactId();
-
- /**
- * The version of the library
- *
- * @return the version of the library
- */
- String version();
-
- /**
- * The repo where the library can be obtained from
- *
- * @return the repo where the library can be obtained from
- */
- Repository repo() default @Repository(url = "https://repo1.maven.org/maven2");
-
-}
diff --git a/Common/src/main/java/dev/brighten/antivpn/depends/Repository.java b/Common/src/main/java/dev/brighten/antivpn/depends/Repository.java
deleted file mode 100644
index 4381225..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/depends/Repository.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is part of helper, licensed under the MIT License.
- *
- * Copyright (c) lucko (Luck)
- * Copyright (c) contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package dev.brighten.antivpn.depends;
-
-import java.lang.annotation.*;
-
-/**
- * Represents a maven repository.
- */
-@Documented
-@Target(ElementType.LOCAL_VARIABLE)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Repository {
-
- /**
- * Gets the base url of the repository.
- *
- * @return the base url of the repository
- */
- String url();
-
-}
diff --git a/Common/src/main/java/dev/brighten/antivpn/depends/URLClassLoaderAccess.java b/Common/src/main/java/dev/brighten/antivpn/depends/URLClassLoaderAccess.java
deleted file mode 100644
index a0159f0..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/depends/URLClassLoaderAccess.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * This file is part of helper, licensed under the MIT License.
- *
- * Copyright (c) lucko (Luck)
- * Copyright (c) contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package dev.brighten.antivpn.depends;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Collection;
-
-/**
- * Provides access to {@link URLClassLoader}#addURL.
- */
-public abstract class URLClassLoaderAccess {
-
- /**
- * Creates a {@link URLClassLoaderAccess} for the given class loader.
- *
- * @param classLoader the class loader
- * @return the access object
- */
- static URLClassLoaderAccess create(URLClassLoader classLoader) {
- if (Reflection.isSupported()) {
- return new Reflection(classLoader);
- } else if (Unsafe.isSupported()) {
- return new Unsafe(classLoader);
- } else {
- return Noop.INSTANCE;
- }
- }
-
- private final URLClassLoader classLoader;
-
- protected URLClassLoaderAccess(URLClassLoader classLoader) {
- this.classLoader = classLoader;
- }
-
-
- /**
- * Adds the given URL to the class loader.
- *
- * @param url the URL to add
- */
- public abstract void addURL(URL url);
-
- /**
- * Accesses using reflection, not supported on Java 9+.
- */
- private static class Reflection extends URLClassLoaderAccess {
- private static final Method ADD_URL_METHOD;
-
- static {
- Method addUrlMethod;
- try {
- addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
- addUrlMethod.setAccessible(true);
- } catch (Exception e) {
- addUrlMethod = null;
- }
- ADD_URL_METHOD = addUrlMethod;
- }
-
- private static boolean isSupported() {
- return ADD_URL_METHOD != null;
- }
-
- Reflection(URLClassLoader classLoader) {
- super(classLoader);
- }
-
- @Override
- public void addURL(URL url) {
- try {
- ADD_URL_METHOD.invoke(super.classLoader, url);
- } catch (ReflectiveOperationException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- /**
- * Accesses using sun.misc.Unsafe, supported on Java 9+.
- *
- * @author Vaishnav Anil (...)
- */
- private static class Unsafe extends URLClassLoaderAccess {
- private static final sun.misc.Unsafe UNSAFE;
-
- static {
- sun.misc.Unsafe unsafe;
- try {
- Field unsafeField = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
- unsafeField.setAccessible(true);
- unsafe = (sun.misc.Unsafe) unsafeField.get(null);
- } catch (Throwable t) {
- unsafe = null;
- }
- UNSAFE = unsafe;
- }
-
- private static boolean isSupported() {
- return UNSAFE != null;
- }
-
- private final Collection unopenedURLs;
- private final Collection pathURLs;
-
- @SuppressWarnings("unchecked")
- Unsafe(URLClassLoader classLoader) {
- super(classLoader);
-
- Collection unopenedURLs;
- Collection pathURLs;
- try {
- Object ucp = fetchField(URLClassLoader.class, classLoader, "ucp");
- unopenedURLs = (Collection) fetchField(ucp.getClass(), ucp, "unopenedUrls");
- pathURLs = (Collection) fetchField(ucp.getClass(), ucp, "path");
- } catch (Throwable e) {
- unopenedURLs = null;
- pathURLs = null;
- }
- this.unopenedURLs = unopenedURLs;
- this.pathURLs = pathURLs;
- }
-
- private static Object fetchField(final Class> clazz, final Object object, final String name) throws NoSuchFieldException {
- Field field = clazz.getDeclaredField(name);
- long offset = UNSAFE.objectFieldOffset(field);
- return UNSAFE.getObject(object, offset);
- }
-
- @Override
- public void addURL(URL url) {
- this.unopenedURLs.add(url);
- this.pathURLs.add(url);
- }
- }
-
- private static class Noop extends URLClassLoaderAccess {
- private static final Noop INSTANCE = new Noop();
-
- private Noop() {
- super(null);
- }
-
- @Override
- public void addURL(URL url) {
- throw new UnsupportedOperationException();
- }
- }
-
-}
diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/ExtraObjectsMethodsForWeb.java b/Common/src/main/java/dev/brighten/antivpn/utils/ExtraObjectsMethodsForWeb.java
deleted file mode 100644
index 484f35e..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/utils/ExtraObjectsMethodsForWeb.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2016 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package dev.brighten.antivpn.utils;
-
-/**
- * Holder for extra methods of {@code Objects} only in web. Intended to be empty for regular
- * version.
- */
-abstract class ExtraObjectsMethodsForWeb {}
diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java b/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java
index 5e03229..41c1856 100644
--- a/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java
+++ b/Common/src/main/java/dev/brighten/antivpn/utils/MiscUtils.java
@@ -1,6 +1,7 @@
package dev.brighten.antivpn.utils;
import java.io.*;
+import java.util.concurrent.ThreadFactory;
import java.util.regex.Pattern;
public class MiscUtils {
@@ -41,6 +42,14 @@ public class MiscUtils {
}
}
+ public static ThreadFactory createThreadFactory(String threadName) {
+ return r -> {
+ Thread thread = new Thread(r);
+ thread.setName(threadName);
+ return thread;
+ };
+ }
+
public static boolean isIpv4(String ip)
{
return ipv4.matcher(ip).matches();
diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/NonnullByDefault.java b/Common/src/main/java/dev/brighten/antivpn/utils/NonnullByDefault.java
deleted file mode 100644
index 48a1f73..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/utils/NonnullByDefault.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * This file is part of helper, licensed under the MIT License.
- *
- * Copyright (c) lucko (Luck)
- * Copyright (c) contributors
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-package dev.brighten.antivpn.utils;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-public @interface NonnullByDefault {
-
-}
diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/NullnessCasts.java b/Common/src/main/java/dev/brighten/antivpn/utils/NullnessCasts.java
deleted file mode 100644
index e9a33c8..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/utils/NullnessCasts.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2021 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package dev.brighten.antivpn.utils;
-
-/** A utility method to perform unchecked casts to suppress errors produced by nullness analyses. */
-final class NullnessCasts {
- /**
- * Accepts a {@code @Nullable T} and returns a plain {@code T}, without performing any check that
- * that conversion is safe.
- *
- *
This method is intended to help with usages of type parameters that have {
- * ParametricNullness parametric nullness}. If a type parameter instead ranges over only non-null
- * types (or if the type is a non-variable type, like {@code String}), then code should almost
- * never use this method, preferring instead to call {@code requireNonNull} so as to benefit from
- * its runtime check.
- *
- *
An example use case for this method is in implementing an {@code Iterator} whose {@code
- * next} field is lazily initialized. The type of that field would be {@code @Nullable T}, and the
- * code would be responsible for populating a "real" {@code T} (which might still be the value
- * {@code null}!) before returning it to callers. Depending on how the code is structured, a
- * nullness analysis might not understand that the field has been populated. To avoid that problem
- * without having to add {@code @SuppressWarnings}, the code can call this method.
- *
- *
Why not just add {@code SuppressWarnings}? The problem is that this method is
- * typically useful for {@code return} statements. That leaves the code with two options: Either
- * add the suppression to the whole method (which turns off checking for a large section of code),
- * or extract a variable, and put the suppression on that. However, a local variable typically
- * doesn't work: Because nullness analyses typically infer the nullness of local variables,
- * there's no way to assign a {@code @Nullable T} to a field {@code T foo;} and instruct the
- * analysis that that means "plain {@code T}" rather than the inferred type {@code @Nullable T}.
- * (Even if supported added {@code @NonNull}, that would not help, since the problem case
- * addressed by this method is the case in which {@code T} has parametric nullness -- and thus its
- * value may be legitimately {@code null}.)
- */
- @SuppressWarnings("nullness")
- static T uncheckedCastNullableTToT(T t) {
- return t;
- }
-
- private NullnessCasts() {}
-}
diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/Objects.java b/Common/src/main/java/dev/brighten/antivpn/utils/Objects.java
deleted file mode 100644
index 3246091..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/utils/Objects.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package dev.brighten.antivpn.utils;
-
-import com.mongodb.lang.Nullable;
-
-import java.util.Arrays;
-
-/**
- * Helper functions that can operate on any {@code Object}.
- *
- *
See the Guava User Guide on writing {@code Object}
- * methods with {@code Objects}.
- *
- * @author Laurence Gonsalves
- * @since 2.0
- */
-public final class Objects extends ExtraObjectsMethodsForWeb {
- private Objects() {}
-
- /**
- * Determines whether two possibly-null objects are equal. Returns:
- *
- *
- *
{@code true} if {@code a} and {@code b} are both null.
- *
{@code true} if {@code a} and {@code b} are both non-null and they are equal according to
- * {@link Object#equals(Object)}.
- *
{@code false} in all other situations.
- *
- *
- *
This assumes that any non-null objects passed to this function conform to the {@code
- * equals()} contract.
- *
- *
Note for Java 7 and later: This method should be treated as deprecated; use {@link
- * java.util.Objects#equals} instead.
- */
- public static boolean equal(Object a, Object b) {
- return a == b || (a != null && a.equals(b));
- }
-
- /**
- * Generates a hash code for multiple values. The hash code is generated by calling {@link
- * Arrays#hashCode(Object[])}. Note that array arguments to this method, with the exception of a
- * single Object array, do not get any special handling; their hash codes are based on identity
- * and not contents.
- *
- *
This is useful for implementing {@link Object#hashCode()}. For example, in an object that
- * has three properties, {@code x}, {@code y}, and {@code z}, one could write:
- *
- *
{@code
- * public int hashCode() {
- * return Objects.hashCode(getX(), getY(), getZ());
- * }
- * }
- *
- *
Warning: When a single object is supplied, the returned hash code does not equal the
- * hash code of that object.
- *
- *
Note for Java 7 and later: This method should be treated as deprecated; use {@link
- * java.util.Objects#hash} instead.
- */
- public static int hashCode(@Nullable Object... objects) {
- return Arrays.hashCode(objects);
- }
-}
diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/Preconditions.java b/Common/src/main/java/dev/brighten/antivpn/utils/Preconditions.java
deleted file mode 100644
index 175cab0..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/utils/Preconditions.java
+++ /dev/null
@@ -1,602 +0,0 @@
-//
-// Source code recreated from a .class file by IntelliJ IDEA
-// (powered by FernFlower decompiler)
-//
-
-package dev.brighten.antivpn.utils;
-
-public final class Preconditions {
- private Preconditions() {
- }
-
- public static void checkArgument(boolean expression) {
- if (!expression) {
- throw new IllegalArgumentException();
- }
- }
-
- public static void checkArgument(boolean expression, Object errorMessage) {
- if (!expression) {
- throw new IllegalArgumentException(String.valueOf(errorMessage));
- }
- }
-
- public static void checkArgument(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
- if (!expression) {
- throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, char p1) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, int p1) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, long p1) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, Object p1) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, char p1, char p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, char p1, int p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, char p1, long p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, char p1, Object p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, int p1, char p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, int p1, int p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, int p1, long p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, int p1, Object p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, long p1, char p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, long p1, int p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, long p1, long p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, long p1, Object p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, char p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, int p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, long p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, Object p2) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, Object p2, Object p3) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2, p3));
- }
- }
-
- public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, Object p2, Object p3, Object p4) {
- if (!b) {
- throw new IllegalArgumentException(format(errorMessageTemplate, p1, p2, p3, p4));
- }
- }
-
- public static void checkState(boolean expression) {
- if (!expression) {
- throw new IllegalStateException();
- }
- }
-
- public static void checkState(boolean expression, Object errorMessage) {
- if (!expression) {
- throw new IllegalStateException(String.valueOf(errorMessage));
- }
- }
-
- public static void checkState(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
- if (!expression) {
- throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, char p1) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, int p1) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, long p1) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, Object p1) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, char p1, char p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, char p1, int p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, char p1, long p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, char p1, Object p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, int p1, char p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, int p1, int p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, int p1, long p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, int p1, Object p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, long p1, char p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, long p1, int p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, long p1, long p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, long p1, Object p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, Object p1, char p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, Object p1, int p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, Object p1, long p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, Object p1, Object p2) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, Object p1, Object p2, Object p3) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2, p3));
- }
- }
-
- public static void checkState(boolean b, String errorMessageTemplate, Object p1, Object p2, Object p3, Object p4) {
- if (!b) {
- throw new IllegalStateException(format(errorMessageTemplate, p1, p2, p3, p4));
- }
- }
-
- public static T checkNotNull(T reference) {
- if (reference == null) {
- throw new NullPointerException();
- } else {
- return reference;
- }
- }
-
- public static T checkNotNull(T reference, Object errorMessage) {
- if (reference == null) {
- throw new NullPointerException(String.valueOf(errorMessage));
- } else {
- return reference;
- }
- }
-
- public static T checkNotNull(T reference, String errorMessageTemplate, Object... errorMessageArgs) {
- if (reference == null) {
- throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs));
- } else {
- return reference;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, char p1) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, int p1) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, long p1) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, Object p1) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, char p1, char p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, char p1, int p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, char p1, long p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, char p1, Object p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, int p1, char p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, int p1, int p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, int p1, long p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, int p1, Object p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, long p1, char p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, long p1, int p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, long p1, long p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, long p1, Object p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, Object p1, char p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, Object p1, int p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, Object p1, long p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, Object p1, Object p2) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, Object p1, Object p2, Object p3) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2, p3));
- } else {
- return obj;
- }
- }
-
- public static T checkNotNull(T obj, String errorMessageTemplate, Object p1, Object p2, Object p3, Object p4) {
- if (obj == null) {
- throw new NullPointerException(format(errorMessageTemplate, p1, p2, p3, p4));
- } else {
- return obj;
- }
- }
-
- public static int checkElementIndex(int index, int size) {
- return checkElementIndex(index, size, "index");
- }
-
- public static int checkElementIndex(int index, int size, String desc) {
- if (index >= 0 && index < size) {
- return index;
- } else {
- throw new IndexOutOfBoundsException(badElementIndex(index, size, desc));
- }
- }
-
- private static String badElementIndex(int index, int size, String desc) {
- if (index < 0) {
- return format("%s (%s) must not be negative", desc, index);
- } else if (size < 0) {
- throw new IllegalArgumentException("negative size: " + size);
- } else {
- return format("%s (%s) must be less than size (%s)", desc, index, size);
- }
- }
-
- public static int checkPositionIndex(int index, int size) {
- return checkPositionIndex(index, size, "index");
- }
-
- public static int checkPositionIndex(int index, int size, String desc) {
- if (index >= 0 && index <= size) {
- return index;
- } else {
- throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc));
- }
- }
-
- private static String badPositionIndex(int index, int size, String desc) {
- if (index < 0) {
- return format("%s (%s) must not be negative", desc, index);
- } else if (size < 0) {
- throw new IllegalArgumentException("negative size: " + size);
- } else {
- return format("%s (%s) must not be greater than size (%s)", desc, index, size);
- }
- }
-
- public static void checkPositionIndexes(int start, int end, int size) {
- if (start < 0 || end < start || end > size) {
- throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size));
- }
- }
-
- private static String badPositionIndexes(int start, int end, int size) {
- if (start >= 0 && start <= size) {
- return end >= 0 && end <= size ? format("end index (%s) must not be less than start index (%s)", end, start) : badPositionIndex(end, size, "end index");
- } else {
- return badPositionIndex(start, size, "start index");
- }
- }
-
- static String format(String template, Object... args) {
- template = String.valueOf(template);
- StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
- int templateStart = 0;
-
- int i;
- int placeholderStart;
- for(i = 0; i < args.length; templateStart = placeholderStart + 2) {
- placeholderStart = template.indexOf("%s", templateStart);
- if (placeholderStart == -1) {
- break;
- }
-
- builder.append(template, templateStart, placeholderStart);
- builder.append(args[i++]);
- }
-
- builder.append(template, templateStart, template.length());
- if (i < args.length) {
- builder.append(" [");
- builder.append(args[i++]);
-
- while(i < args.length) {
- builder.append(", ");
- builder.append(args[i++]);
- }
-
- builder.append(']');
- }
-
- return builder.toString();
- }
-}
diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/Supplier.java b/Common/src/main/java/dev/brighten/antivpn/utils/Supplier.java
deleted file mode 100644
index c1f7365..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/utils/Supplier.java
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Source code recreated from a .class file by IntelliJ IDEA
-// (powered by FernFlower decompiler)
-//
-
-package dev.brighten.antivpn.utils;
-
-@FunctionalInterface
-public interface Supplier extends java.util.function.Supplier {
- T get();
-}
diff --git a/Common/src/main/java/dev/brighten/antivpn/utils/Suppliers.java b/Common/src/main/java/dev/brighten/antivpn/utils/Suppliers.java
deleted file mode 100644
index a06d62e..0000000
--- a/Common/src/main/java/dev/brighten/antivpn/utils/Suppliers.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package dev.brighten.antivpn.utils;
-
-import java.io.Serializable;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-
-import static dev.brighten.antivpn.utils.NullnessCasts.uncheckedCastNullableTToT;
-import static dev.brighten.antivpn.utils.Preconditions.checkArgument;
-import static dev.brighten.antivpn.utils.Preconditions.checkNotNull;
-import static java.util.Objects.requireNonNull;
-
-/**
- * Useful suppliers.
- *
- *
All methods return serializable suppliers as long as they're given serializable parameters.
- *
- * @author Laurence Gonsalves
- * @author Harry Heymann
- * @since 2.0
- */
-public final class Suppliers {
- private Suppliers() {}
-
- /**
- * Returns a new supplier which is the composition of the provided function and supplier. In other
- * words, the new supplier's value will be computed by retrieving the value from {@code supplier},
- * and then applying {@code function} to that value. Note that the resulting supplier will not
- * call {@code supplier} or invoke {@code function} until it is called.
- */
- public static Supplier compose(
- Function super F, T> function, Supplier supplier) {
- return new SupplierComposition<>(function, supplier);
- }
-
- private static class SupplierComposition
- implements Supplier, Serializable {
- final Function super F, T> function;
- final Supplier supplier;
-
- SupplierComposition(Function super F, T> function, Supplier supplier) {
- this.function = checkNotNull(function);
- this.supplier = checkNotNull(supplier);
- }
-
- @Override
- public T get() {
- return function.apply(supplier.get());
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof SupplierComposition) {
- SupplierComposition, ?> that = (SupplierComposition, ?>) obj;
- return function.equals(that.function) && supplier.equals(that.supplier);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(function, supplier);
- }
-
- @Override
- public String toString() {
- return "Suppliers.compose(" + function + ", " + supplier + ")";
- }
-
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns a supplier which caches the instance retrieved during the first call to {@code get()}
- * and returns that value on subsequent calls to {@code get()}. See: memoization
- *
- *
The returned supplier is thread-safe. The delegate's {@code get()} method will be invoked at
- * most once unless the underlying {@code get()} throws an exception. The supplier's serialized
- * form does not contain the cached value, which will be recalculated when {@code get()} is called
- * on the reserialized instance.
- *
- *
When the underlying delegate throws an exception then this memoizing supplier will keep
- * delegating calls until it returns valid data.
- *
- *
If {@code delegate} is an instance created by an earlier call to {@code memoize}, it is
- * returned directly.
- */
- public static Supplier memoize(Supplier delegate) {
- if (delegate instanceof NonSerializableMemoizingSupplier
- || delegate instanceof MemoizingSupplier) {
- return delegate;
- }
- return delegate instanceof Serializable
- ? new MemoizingSupplier(delegate)
- : new NonSerializableMemoizingSupplier(delegate);
- }
-
- static class MemoizingSupplier implements Supplier, Serializable {
- final Supplier delegate;
- transient volatile boolean initialized;
- // "value" does not need to be volatile; visibility piggy-backs
- // on volatile read of "initialized".
- transient T value;
-
- MemoizingSupplier(Supplier delegate) {
- this.delegate = checkNotNull(delegate);
- }
-
- @Override
- public T get() {
- // A 2-field variant of Double Checked Locking.
- if (!initialized) {
- synchronized (this) {
- if (!initialized) {
- T t = delegate.get();
- value = t;
- initialized = true;
- return t;
- }
- }
- }
- // This is safe because we checked `initialized.`
- return uncheckedCastNullableTToT(value);
- }
-
- @Override
- public String toString() {
- return "Suppliers.memoize("
- + (initialized ? "" : delegate)
- + ")";
- }
-
- private static final long serialVersionUID = 0;
- }
-
- static class NonSerializableMemoizingSupplier implements Supplier {
- volatile Supplier delegate;
- volatile boolean initialized;
- // "value" does not need to be volatile; visibility piggy-backs
- // on volatile read of "initialized".
- T value;
-
- NonSerializableMemoizingSupplier(Supplier delegate) {
- this.delegate = checkNotNull(delegate);
- }
-
- @Override
- public T get() {
- // A 2-field variant of Double Checked Locking.
- if (!initialized) {
- synchronized (this) {
- if (!initialized) {
- /*
- * requireNonNull is safe because we read and write `delegate` under synchronization.
- *
- * TODO(cpovirk): To avoid having to check for null, replace `delegate` with a singleton
- * `Supplier` that always throws an exception.
- */
- T t = requireNonNull(delegate).get();
- value = t;
- initialized = true;
- // Release the delegate to GC.
- delegate = null;
- return t;
- }
- }
- }
- // This is safe because we checked `initialized.`
- return uncheckedCastNullableTToT(value);
- }
-
- @Override
- public String toString() {
- Supplier delegate = this.delegate;
- return "Suppliers.memoize("
- + (delegate == null ? "" : delegate)
- + ")";
- }
- }
-
- /**
- * Returns a supplier that caches the instance supplied by the delegate and removes the cached
- * value after the specified time has passed. Subsequent calls to {@code get()} return the cached
- * value if the expiration time has not passed. After the expiration time, a new value is
- * retrieved, cached, and returned. See: memoization
- *
- *
The returned supplier is thread-safe. The supplier's serialized form does not contain the
- * cached value, which will be recalculated when {@code get()} is called on the reserialized
- * instance. The actual memoization does not happen when the underlying delegate throws an
- * exception.
- *
- *
When the underlying delegate throws an exception then this memoizing supplier will keep
- * delegating calls until it returns valid data.
- *
- * @param duration the length of time after a value is created that it should stop being returned
- * by subsequent {@code get()} calls
- * @param unit the unit that {@code duration} is expressed in
- * @throws IllegalArgumentException if {@code duration} is not positive
- * @since 2.0
- */
- @SuppressWarnings("GoodTime") // should accept a java.time.Duration
- public static Supplier memoizeWithExpiration(
- Supplier delegate, long duration, TimeUnit unit) {
- return new ExpiringMemoizingSupplier<>(delegate, duration, unit);
- }
-
- @SuppressWarnings("GoodTime") // lots of violations
- static class ExpiringMemoizingSupplier
- implements Supplier, Serializable {
- final Supplier delegate;
- final long durationNanos;
- transient volatile T value;
- // The special value 0 means "not yet initialized".
- transient volatile long expirationNanos;
-
- ExpiringMemoizingSupplier(Supplier delegate, long duration, TimeUnit unit) {
- this.delegate = checkNotNull(delegate);
- this.durationNanos = unit.toNanos(duration);
- checkArgument(duration > 0, "duration (%s %s) must be > 0", duration, unit);
- }
-
- @Override
- public T get() {
- // Another variant of Double Checked Locking.
- //
- // We use two volatile reads. We could reduce this to one by
- // putting our fields into a holder class, but (at least on x86)
- // the extra memory consumption and indirection are more
- // expensive than the extra volatile reads.
- long nanos = expirationNanos;
- long now = System.nanoTime();
- if (nanos == 0 || now - nanos >= 0) {
- synchronized (this) {
- if (nanos == expirationNanos) { // recheck for lost race
- T t = delegate.get();
- value = t;
- nanos = now + durationNanos;
- // In the very unlikely event that nanos is 0, set it to 1;
- // no one will notice 1 ns of tardiness.
- expirationNanos = (nanos == 0) ? 1 : nanos;
- return t;
- }
- }
- }
- // This is safe because we checked `expirationNanos.`
- return uncheckedCastNullableTToT(value);
- }
-
- @Override
- public String toString() {
- // This is a little strange if the unit the user provided was not NANOS,
- // but we don't want to store the unit just for toString
- return "Suppliers.memoizeWithExpiration(" + delegate + ", " + durationNanos + ", NANOS)";
- }
-
- private static final long serialVersionUID = 0;
- }
-
- /** Returns a supplier that always supplies {@code instance}. */
- public static Supplier ofInstance(
- T instance) {
- return new SupplierOfInstance<>(instance);
- }
-
- private static class SupplierOfInstance
- implements Supplier, Serializable {
- final T instance;
-
- SupplierOfInstance(T instance) {
- this.instance = instance;
- }
-
- @Override
- public T get() {
- return instance;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof SupplierOfInstance) {
- SupplierOfInstance> that = (SupplierOfInstance>) obj;
- return Objects.equal(instance, that.instance);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(instance);
- }
-
- @Override
- public String toString() {
- return "Suppliers.ofInstance(" + instance + ")";
- }
-
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns a supplier whose {@code get()} method synchronizes on {@code delegate} before calling
- * it, making it thread-safe.
- */
- public static Supplier synchronizedSupplier(
- Supplier delegate) {
- return new ThreadSafeSupplier<>(delegate);
- }
-
- private static class ThreadSafeSupplier
- implements Supplier, Serializable {
- final Supplier delegate;
-
- ThreadSafeSupplier(Supplier delegate) {
- this.delegate = checkNotNull(delegate);
- }
-
- @Override
- public T get() {
- synchronized (delegate) {
- return delegate.get();
- }
- }
-
- @Override
- public String toString() {
- return "Suppliers.synchronizedSupplier(" + delegate + ")";
- }
-
- private static final long serialVersionUID = 0;
- }
-
- /**
- * Returns a function that accepts a supplier and returns the result of invoking {@link
- * Supplier#get} on that supplier.
- *
- *