Improved performance of kicking players, will not allow players to remain on if API tells us we should block them.

This commit is contained in:
2026-01-20 09:44:30 -05:00
parent 8a4b86c9ef
commit 7ffba38992
9 changed files with 153 additions and 280 deletions
@@ -18,12 +18,9 @@ package dev.brighten.antivpn.bukkit;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.APIPlayer;
import dev.brighten.antivpn.api.CheckResult;
import dev.brighten.antivpn.api.OfflinePlayer;
import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.message.VpnString;
import dev.brighten.antivpn.utils.StringUtil;
import dev.brighten.antivpn.utils.Tuple;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
@@ -36,7 +33,6 @@ import org.bukkit.event.player.PlayerQuitEvent;
import java.util.logging.Level;
@SuppressWarnings("unchecked")
public class BukkitListener extends VPNExecutor implements Listener {
@Override
@@ -81,66 +77,50 @@ public class BukkitListener extends VPNExecutor implements Listener {
event.getAddress()
));
CheckResult instantResult = player.checkPlayer(result -> {
player.checkPlayer(result -> {
if(!result.resultType().isShouldBlock()) return;
AntiVPN.getInstance().getExecutor().log(Level.INFO, "Adding %s to kick", event.getPlayer().getName());
AntiVPN.getInstance().getExecutor().getToKick().add(new Tuple<>(result, event.getPlayer().getUniqueId()));
});
if(!instantResult.resultType().isShouldBlock()) return;
AntiVPN.getInstance().getExecutor().getToKick()
.add(new Tuple<>(instantResult, event.getPlayer().getUniqueId()));
if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) {
return;
}
AntiVPN.getInstance().getExecutor().log(Level.INFO, "%s was kicked from pre-login cache with IP %s", event.getPlayer().getName(), instantResult.response().getIp());
event.setResult(PlayerLoginEvent.Result.KICK_BANNED);
switch (instantResult.resultType()) {
case DENIED_COUNTRY -> event.setKickMessage(StringUtil.translateAlternateColorCodes('&',
StringUtil.varReplace(
AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(),
player,
instantResult.response()
)));
case DENIED_PROXY -> {
if(AntiVPN.getInstance().getVpnConfig().isAlertToSTaff()) {
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
.filter(APIPlayer::isAlertsEnabled)
.forEach(pl ->
pl.sendMessage(StringUtil.varReplace(
ChatColor.translateAlternateColorCodes(
'&',
AntiVPN.getInstance().getVpnConfig().getAlertMsg()),
player,
instantResult.response())));
}
event.setKickMessage(StringUtil.translateAlternateColorCodes('&',
StringUtil.varReplace(
AntiVPN.getInstance().getVpnConfig().getKickMessage(),
player,
instantResult.response()
)));
if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) {
return;
}
}
AntiVPN.getInstance().getExecutor().log(Level.INFO, "%s was kicked from pre-login cache with IP %s", event.getPlayer().getName(), result.response().getIp());
event.setResult(PlayerLoginEvent.Result.KICK_BANNED);
switch (result.resultType()) {
case DENIED_COUNTRY -> event.setKickMessage(StringUtil.translateAlternateColorCodes('&',
StringUtil.varReplace(
AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(),
player,
result.response()
)));
case DENIED_PROXY -> {
if(AntiVPN.getInstance().getVpnConfig().isAlertToSTaff()) {
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
.filter(APIPlayer::isAlertsEnabled)
.forEach(pl ->
pl.sendMessage(StringUtil.varReplace(
ChatColor.translateAlternateColorCodes(
'&',
AntiVPN.getInstance().getVpnConfig().getAlertMsg()),
player,
result.response())));
}
event.setKickMessage(StringUtil.translateAlternateColorCodes('&',
StringUtil.varReplace(
AntiVPN.getInstance().getVpnConfig().getKickMessage(),
player,
result.response()
)));
}
}
});
}
@EventHandler(priority = EventPriority.MONITOR)
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onJoin(final PlayerJoinEvent event) {
AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId())
.ifPresent(player -> AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() ->
AntiVPN.getInstance().getDatabase().alertsState(player.getUuid(), state -> {
if(state) {
player.setAlertsEnabled(true);
player.sendMessage(AntiVPN.getInstance().getMessageHandler()
.getString("command-alerts-toggled")
.getFormattedMessage(new VpnString.Var<>("state", true)));
}
})));
.ifPresent(APIPlayer::checkAlertsState);
}
@EventHandler
@@ -19,10 +19,7 @@ package dev.brighten.antivpn.bungee;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.*;
import dev.brighten.antivpn.utils.MiscUtils;
import dev.brighten.antivpn.utils.StringUtil;
import dev.brighten.antivpn.utils.Tuple;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.event.LoginEvent;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
import net.md_5.bungee.api.event.PreLoginEvent;
import net.md_5.bungee.api.plugin.Listener;
@@ -89,43 +86,19 @@ public class BungeeListener extends VPNExecutor implements Listener {
((InetSocketAddress) event.getConnection().getSocketAddress()).getAddress());
});
CheckResult instantResult = player.checkPlayer(result -> {
player.checkPlayer(result -> {
if (!result.resultType().isShouldBlock()) return;
AntiVPN.getInstance().getExecutor().getToKick()
.add(new Tuple<>(result, player.getUuid()));
event.setCancelled(true);
});
}
if (!instantResult.resultType().isShouldBlock()) {
return;
}
@EventHandler(priority = EventPriority.HIGH)
public void onJoin(LoginEvent event) {
if(event.isCancelled()) return;
AntiVPN.getInstance().getExecutor().getToKick()
.add(new Tuple<>(instantResult, player.getUuid()));
if (!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) {
return;
}
event.setCancelled(true);
AntiVPN.getInstance().getExecutor().log(Level.INFO,
"%s was kicked from pre-login proxy cache.",
event.getConnection().getName());
switch (instantResult.resultType()) {
case DENIED_PROXY -> event.setReason(TextComponent.fromLegacy(ChatColor
.translateAlternateColorCodes('&',
StringUtil.varReplace(
AntiVPN.getInstance().getVpnConfig().getKickMessage(),
player,
instantResult.response()))));
case DENIED_COUNTRY -> event.setReason(TextComponent.fromLegacy(ChatColor
.translateAlternateColorCodes('&',
StringUtil.varReplace(
AntiVPN.getInstance().getVpnConfig().getCountryVanillaKickReason(),
player,
instantResult.response()))));
}
// Handling player alerts on join
AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getConnection().getUniqueId())
.ifPresent(APIPlayer::checkAlertsState);
}
@EventHandler
@@ -19,6 +19,7 @@ package dev.brighten.antivpn.api;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.message.VpnString;
import lombok.Getter;
import lombok.Setter;
@@ -55,24 +56,46 @@ public abstract class APIPlayer {
public void updateAlertsState() {
//Updating into database so its synced across servers and saved on logout.
AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() -> AntiVPN.getInstance().getDatabase().updateAlertsState(uuid, alertsEnabled));
AntiVPN.getInstance().getDatabase().updateAlertsState(uuid, alertsEnabled);
sendMessage(AntiVPN.getInstance().getMessageHandler()
.getString("command-alerts-toggled")
.getFormattedMessage(new VpnString.Var<>("state", alertsEnabled)));
}
public CheckResult checkPlayer(Consumer<CheckResult> onKick) {
public void checkAlertsState() {
AntiVPN.getInstance().getExecutor().getThreadExecutor().execute(() ->
AntiVPN.getInstance().getDatabase().alertsState(uuid, state -> {
if(state) {
alertsEnabled = true;
updateAlertsState();
}
})
);
}
public void checkPlayer(Consumer<CheckResult> onResult) {
if (hasPermission("antivpn.bypass") //Has bypass permission
//Is exempt
|| (uuid != null && AntiVPN.getInstance().getExecutor().isWhitelisted(uuid))
//Or has a name that starts with a certain prefix. This is for Bedrock exempting.
|| AntiVPN.getInstance().getExecutor().isWhitelisted(ip.getHostAddress() + "/32")
|| AntiVPN.getInstance().getVpnConfig().getPrefixWhitelists().stream()
.anyMatch(name::startsWith)) return new CheckResult(null, ResultType.WHITELISTED);
.anyMatch(name::startsWith)) {
onResult.accept(new CheckResult(null, ResultType.WHITELISTED, false));
return;
}
CheckResult cachedResult = checkResultCache.getIfPresent(ip.getHostAddress());
if(cachedResult != null) {
if(cachedResult.response().getIp().equals(ip.getHostAddress())) {
AntiVPN.getInstance().getExecutor().log(Level.FINE, "Cached result for " + ip.getHostAddress() + " is " + cachedResult.resultType());
return cachedResult;
if(cachedResult.resultType().isShouldBlock()) {
AntiVPN.getInstance().getExecutor().handleKickingOfPlayer(cachedResult, this);
}
onResult.accept(cachedResult);
return;
}
}
@@ -82,6 +105,8 @@ public abstract class APIPlayer {
AntiVPN.getInstance().getExecutor().log(Level.WARNING, "The API query was not a success! " +
"You may need to upgrade your license on " +
"https://funkemunky.cc/shop");
onResult.accept(new CheckResult(null, ResultType.API_FAILURE, false));
return;
}
// If the countryList() size is zero, no need to check.
// Running country check first
@@ -99,19 +124,22 @@ public abstract class APIPlayer {
.contains(result.getCountryCode())
!= AntiVPN.getInstance().getVpnConfig().getWhitelistCountries()) {
//Using our built in kicking system if no commands are configured
checkResult = new CheckResult(result, ResultType.DENIED_COUNTRY);
checkResult = new CheckResult(result, ResultType.DENIED_COUNTRY, false);
} else if (result.isProxy()) {
checkResult = new CheckResult(result, ResultType.DENIED_PROXY);
checkResult = new CheckResult(result, ResultType.DENIED_PROXY, false);
} else {
checkResult = new CheckResult(result, ResultType.ALLOWED);
checkResult = new CheckResult(result, ResultType.ALLOWED, false);
}
AntiVPN.getInstance().getExecutor().log(Level.FINE, "Result for " + ip.getHostAddress() + " is " + checkResult.resultType());
checkResultCache.put(ip.getHostAddress(), checkResult);
onKick.accept(checkResult);
checkResultCache.put(ip.getHostAddress(), new CheckResult(checkResult.response(), checkResult.resultType(), true));
if(checkResult.resultType().isShouldBlock()) {
AntiVPN.getInstance().getExecutor().handleKickingOfPlayer(checkResult, this);
}
onResult.accept(checkResult);
AntiVPN.getInstance().checked++;
});
return new CheckResult(null, ResultType.UNKNOWN);
onResult.accept(new CheckResult(null, ResultType.UNKNOWN, false));
}
}
@@ -18,5 +18,5 @@ package dev.brighten.antivpn.api;
import dev.brighten.antivpn.web.objects.VPNResponse;
public record CheckResult(VPNResponse response, ResultType resultType) {
public record CheckResult(VPNResponse response, ResultType resultType, boolean isFromCache) {
}
@@ -23,6 +23,7 @@ public enum ResultType {
WHITELISTED(false),
DENIED_COUNTRY(true),
DENIED_PROXY(true),
API_FAILURE(false),
UNKNOWN(false);
@Getter
@@ -28,23 +28,18 @@ import lombok.Getter;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.*;
import java.util.logging.Level;
@Getter
public abstract class VPNExecutor {
@Getter
private final ScheduledExecutorService threadExecutor = Executors.newScheduledThreadPool(2);
@Getter
private final Set<UUID> whitelisted = Collections.synchronizedSet(new HashSet<>());
@Getter
private final Set<CIDRUtils> whitelistedIps = Collections.synchronizedSet(new HashSet<>());
private final Queue<Tuple<CheckResult, UUID>> toKick = new LinkedBlockingQueue<>();
private final Queue<APIPlayer> playersToRecheck = new LinkedBlockingQueue<>();
private ScheduledFuture<?> kickTask = null;
@Getter
private final List<Tuple<CheckResult, UUID>> toKick = Collections.synchronizedList(new LinkedList<>());
public abstract void registerListeners();
@@ -61,15 +56,13 @@ public abstract class VPNExecutor {
}
public void startKickChecks() {
threadExecutor.scheduleAtFixedRate(() -> {
kickTask = threadExecutor.scheduleAtFixedRate(() -> {
synchronized (toKick) {
if(toKick.isEmpty()) return;
Iterator<Tuple<CheckResult, UUID>> i = toKick.iterator();
while(i.hasNext()) {
var toCheck = i.next();
Tuple<CheckResult, UUID> toCheck;
while((toCheck = toKick.poll()) != null) {
Optional<APIPlayer> player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(toCheck.second());
if(player.isEmpty()) {
@@ -77,14 +70,18 @@ public abstract class VPNExecutor {
}
handleKickingOfPlayer(toCheck.first(), player.get());
i.remove();
}
}
}, 8, 2, TimeUnit.SECONDS);
}
public void handleKickingOfPlayer(CheckResult result, APIPlayer player) {
//Ensuring kick task is always running
if(kickTask == null || kickTask.isDone() || kickTask.isCancelled()) {
startKickChecks();
}
if (AntiVPN.getInstance().getVpnConfig().isAlertToSTaff()) AntiVPN.getInstance().getPlayerExecutor()
.getOnlinePlayers()
.stream()
@@ -101,10 +98,10 @@ public abstract class VPNExecutor {
case DENIED_COUNTRY -> player.kickPlayer(StringUtil.varReplace(AntiVPN.getInstance().getVpnConfig()
.getCountryVanillaKickReason(), player, result.response()));
}
} else {
if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) return;
}
if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) return;
switch (result.resultType()) {
case DENIED_PROXY -> {
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
@@ -119,6 +116,9 @@ public abstract class VPNExecutor {
}
}
}
//Ensuring players are actually kicked as they are supposed to be.
toKick.add(new Tuple<>(result, player.getUuid()));
}
public boolean isWhitelisted(UUID uuid) {
@@ -19,7 +19,6 @@ package dev.brighten.antivpn.sponge;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.*;
import dev.brighten.antivpn.sponge.util.StringUtil;
import dev.brighten.antivpn.utils.Tuple;
import net.kyori.adventure.text.Component;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.exception.CommandException;
@@ -42,44 +41,38 @@ public class SpongeListener extends VPNExecutor {
event.connection().address().getAddress()
)));
CheckResult instantResult = player.get().checkPlayer(result -> {
if(result.resultType().isShouldBlock()) {
AntiVPN.getInstance().getExecutor().getToKick().add(new Tuple<>(result, player.get().getUuid()));
player.get().checkPlayer(result -> {
if(!result.resultType().isShouldBlock()) return;
if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) {
return;
}
});
if(!instantResult.resultType().isShouldBlock()) {
return;
}
AntiVPN.getInstance().getExecutor().getToKick().add(new Tuple<>(instantResult, player.get().getUuid()));
if(!AntiVPN.getInstance().getVpnConfig().isKickPlayers()) {
return;
}
AntiVPN.getInstance().getExecutor().log(Level.INFO, "%s was kicked from cache with IP %s", player.get().getName(), instantResult.response().getIp());
event.setCancelled(true);
switch (instantResult.resultType()) {
case DENIED_PROXY -> {
AntiVPN.getInstance().getExecutor().log(Level.INFO, player.get().getName()
+ " joined on a VPN/Proxy (" + instantResult.response().getMethod() + ")");
event.setMessage(Component.text(StringUtil
.translateColorCodes('&', AntiVPN.getInstance().getVpnConfig()
.getKickMessage()
.replace("%player%", player.get().getName())
.replace("%country%", instantResult.response().getCountryName())
.replace("%code%", instantResult.response().getCountryCode()))));
if(result.isFromCache()) {
AntiVPN.getInstance().getExecutor().log(Level.INFO, "%s was kicked from cache with IP %s", player.get().getName(), result.response().getIp());
}
case DENIED_COUNTRY ->
event.setCancelled(true);
switch (result.resultType()) {
case DENIED_PROXY -> {
AntiVPN.getInstance().getExecutor().log(Level.INFO, player.get().getName()
+ " joined on a VPN/Proxy (" + result.response().getMethod() + ")");
event.setMessage(Component.text(StringUtil
.translateColorCodes('&', AntiVPN.getInstance().getVpnConfig()
.getCountryVanillaKickReason()
.getKickMessage()
.replace("%player%", player.get().getName())
.replace("%country%", instantResult.response().getCountryName())
.replace("%code%", instantResult.response().getCountryCode()))));
}
.replace("%country%", result.response().getCountryName())
.replace("%code%", result.response().getCountryCode()))));
}
case DENIED_COUNTRY ->
event.setMessage(Component.text(StringUtil
.translateColorCodes('&', AntiVPN.getInstance().getVpnConfig()
.getCountryVanillaKickReason()
.replace("%player%", player.get().getName())
.replace("%country%", result.response().getCountryName())
.replace("%code%", result.response().getCountryCode()))));
}
});
}
@Listener
@@ -21,14 +21,11 @@ import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.connection.LoginEvent;
import dev.brighten.antivpn.AntiVPN;
import dev.brighten.antivpn.api.APIPlayer;
import dev.brighten.antivpn.api.CheckResult;
import dev.brighten.antivpn.api.OfflinePlayer;
import dev.brighten.antivpn.api.VPNExecutor;
import dev.brighten.antivpn.utils.StringUtil;
import dev.brighten.antivpn.web.objects.VPNResponse;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
public class VelocityListener extends VPNExecutor {
@@ -52,135 +49,34 @@ public class VelocityListener extends VPNExecutor {
event.getPlayer().getRemoteAddress().getAddress()
));
CheckResult instantResult = player.checkPlayer(result -> {
player.checkPlayer(result -> {
if(!result.resultType().isShouldBlock()) return;
handleDeniedTasks(event, result);
});
if(!instantResult.resultType().isShouldBlock()) return;
switch (instantResult.resultType()) {
case DENIED_COUNTRY -> event.setResult(ResultedEvent.ComponentResult.denied(
LegacyComponentSerializer.builder()
switch (result.resultType()) {
case DENIED_COUNTRY -> event.setResult(ResultedEvent.ComponentResult.denied(
LegacyComponentSerializer.builder()
.character('&')
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
.getCountryVanillaKickReason()
.replace("%player%", event.getPlayer().getUsername())
.replace("%country%", result.response().getCountryName())
.replace("%code%", result.response().getCountryCode()))));
case DENIED_PROXY -> {
VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername()
+ " joined on a VPN/Proxy (" + result.response().getMethod() + ")");
event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder()
.character('&')
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
.getCountryVanillaKickReason()
.getKickMessage()
.replace("%player%", event.getPlayer().getUsername())
.replace("%country%", instantResult.response().getCountryName())
.replace("%code%", instantResult.response().getCountryCode()))));
case DENIED_PROXY -> {
VelocityPlugin.INSTANCE.getLogger().info(event.getPlayer().getUsername()
+ " joined on a VPN/Proxy (" + instantResult.response().getMethod() + ")");
event.setResult(ResultedEvent.ComponentResult.denied(LegacyComponentSerializer.builder()
.character('&')
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
.getKickMessage()
.replace("%player%", event.getPlayer().getUsername())
.replace("%country%", instantResult.response().getCountryName())
.replace("%code%", instantResult.response().getCountryCode()))));
.replace("%country%", result.response().getCountryName())
.replace("%code%", result.response().getCountryCode()))));
}
}
}
handleDeniedTasks(event, instantResult, true);
});
});
}
private void handleDeniedTasks(LoginEvent event, CheckResult result) {
handleDeniedTasks(event, result, false);
}
private void handleDeniedTasks(LoginEvent event, CheckResult checkResult, boolean deniedOnLogin) {
VPNResponse result = checkResult.response();
//Ensuring the user wishes to alert to staff
if (AntiVPN.getInstance().getVpnConfig().isAlertToSTaff())
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
.filter(APIPlayer::isAlertsEnabled)
.forEach(pl ->
pl.sendMessage(dev.brighten.antivpn.AntiVPN.getInstance().getVpnConfig()
.getAlertMsg()
.replace("%player%",
event.getPlayer().getUsername())
.replace("%reason%",
result.getMethod())
.replace("%country%",
result.getCountryName())
.replace("%city%",
result.getCity())));
if(deniedOnLogin) return;
//In case the user wants to run their own commands instead of using the
// built in kicking
if(AntiVPN.getInstance().getVpnConfig().isKickPlayers()) {
switch (checkResult.resultType()) {
case DENIED_PROXY -> VelocityPlugin.INSTANCE.getServer().getScheduler()
.buildTask(VelocityPlugin.INSTANCE.getPluginInstance(), () ->
event.getPlayer().disconnect(LegacyComponentSerializer.builder()
.character('&')
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
.getKickMessage()
.replace("%player%", event.getPlayer().getUsername())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()))))
.delay(1, TimeUnit.SECONDS).schedule();
case DENIED_COUNTRY -> VelocityPlugin.INSTANCE.getServer().getScheduler()
.buildTask(VelocityPlugin.INSTANCE.getPluginInstance(), () ->
event.getPlayer().disconnect(LegacyComponentSerializer.builder()
.character('&')
.build().deserialize(AntiVPN.getInstance().getVpnConfig()
.getCountryVanillaKickReason()
.replace("%player%", event.getPlayer().getUsername())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()))))
.delay(1, TimeUnit.SECONDS).schedule();
}
}
if(!AntiVPN.getInstance().getVpnConfig().isCommandsEnabled()) return;
switch (checkResult.resultType()) {
case DENIED_PROXY -> {
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
VelocityPlugin.INSTANCE.getServer().getCommandManager()
.executeAsync(VelocityPlugin.INSTANCE.getServer()
.getConsoleCommandSource(),
StringUtil.translateAlternateColorCodes('&',
StringUtil.varReplace(
command,
AntiVPN.getInstance().getPlayerExecutor()
.getPlayer(event.getPlayer().getUniqueId())
.orElse(new OfflinePlayer(
event.getPlayer().getUniqueId(),
event.getPlayer().getUsername(),
event.getPlayer().getRemoteAddress().getAddress())
),
result)));
}
}
case DENIED_COUNTRY -> {
for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
final String formattedCommand = StringUtil
.translateAlternateColorCodes('&',
StringUtil.varReplace(
cmd,
AntiVPN.getInstance().getPlayerExecutor()
.getPlayer(event.getPlayer().getUniqueId())
.orElse(new OfflinePlayer(
event.getPlayer().getUniqueId(),
event.getPlayer().getUsername(),
event.getPlayer().getRemoteAddress().getAddress())
),
result));
// Running the command from console
runCommand(formattedCommand);
}
}
}
}
@Override
public void log(Level level, String log, Object... objects) {
VelocityPlugin.INSTANCE.getLogger().log(level, String.format(log, objects));
@@ -44,4 +44,6 @@ public class VelocityPlayer extends APIPlayer {
public boolean hasPermission(String permission) {
return player.hasPermission(permission);
}
}