mirror of
https://github.com/funkemunky/AntiVPN.git
synced 2026-06-18 17:40:39 +00:00
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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user