Refactor, code cleanup, sponge impl.

BungeeCord still has problems, bad API, not my fault technically. still need to fix though
This commit is contained in:
2025-05-27 13:13:53 -04:00
parent de31d837b9
commit 3f6bb4a0e6
19 changed files with 739 additions and 446 deletions
@@ -1,33 +1,27 @@
package dev.brighten.antivpn.bukkit;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
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.web.objects.VPNResponse;
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.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
@SuppressWarnings("unchecked")
public class BukkitListener extends VPNExecutor implements Listener {
private final Cache<UUID, VPNResponse> responseCache = Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.maximumSize(2000)
.build();
@Override
public void registerListeners() {
@@ -50,6 +44,12 @@ public class BukkitListener extends VPNExecutor implements Listener {
Bukkit.getLogger().log(Level.SEVERE, message, ex);
}
@Override
public void runCommand(String command) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(),
ChatColor.translateAlternateColorCodes('&', command));
}
@Override
public void disablePlugin() {
HandlerList.unregisterAll(this);
@@ -57,6 +57,61 @@ public class BukkitListener extends VPNExecutor implements Listener {
}
@EventHandler(priority = EventPriority.HIGH)
public void onLogin(final PlayerLoginEvent event) {
APIPlayer player = AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId())
.orElse(new OfflinePlayer(
event.getPlayer().getUniqueId(),
event.getPlayer().getName(),
event.getRealAddress()
));
CheckResult instantResult = 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().kickPlayersOnDetect()) {
return;
}
event.setResult(PlayerLoginEvent.Result.KICK_BANNED);
switch (instantResult.resultType()) {
case DENIED_COUNTRY -> event.setKickMessage(StringUtil.translateAlternateColorCodes('&',
StringUtil.varReplace(
AntiVPN.getInstance().getVpnConfig().countryVanillaKickReason(),
player,
instantResult.response()
)));
case DENIED_PROXY -> {
if(AntiVPN.getInstance().getVpnConfig().alertToStaff()) {
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
.filter(APIPlayer::isAlertsEnabled)
.forEach(pl ->
pl.sendMessage(StringUtil.varReplace(
ChatColor.translateAlternateColorCodes(
'&',
AntiVPN.getInstance().getVpnConfig().alertMessage()),
player,
instantResult.response())));
}
event.setKickMessage(StringUtil.translateAlternateColorCodes('&',
StringUtil.varReplace(
AntiVPN.getInstance().getVpnConfig().getKickString(),
player,
instantResult.response()
)));
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onJoin(final PlayerJoinEvent event) {
AntiVPN.getInstance().getPlayerExecutor().getPlayer(event.getPlayer().getUniqueId())
.ifPresent(player -> AntiVPN.getInstance().getDatabase().alertsState(player.getUuid(), enabled -> {
@@ -67,142 +122,6 @@ public class BukkitListener extends VPNExecutor implements Listener {
.getFormattedMessage(new VpnString.Var<>("state", true)));
}
}));
String address;
if(event.getPlayer().getAddress() != null) {
address = event.getPlayer().getAddress().getAddress().getHostAddress();
} else {
log(Level.WARNING, "Player %s address is null! This is a bug and should be reported!", event.getPlayer().getName());
return;
}
if(event.getPlayer().hasPermission("antivpn.bypass") //Has bypass permission
|| AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId()) //Is exempt
//Or has a name that starts with a certain prefix. This is for Bedrock exempting.
|| AntiVPN.getInstance().getExecutor().isWhitelisted(address)
|| 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());
if (cached != null && cached.isProxy()) {
proxyKick(event.getPlayer(), cached);
return;
}
}
final Player player = event.getPlayer();
checkIp(address).thenAccept(result -> {
if(result.isSuccess()) {
//We need to run on main thread or kicking and running commands will cause errors
//If the player is whitelisted, we don't want to kick them
if(AntiVPN.getInstance().getExecutor().isWhitelisted(event.getPlayer().getUniqueId())) {
log("UUID is whitelisted: %s", event.getPlayer().getUniqueId().toString());
return;
}
//If the IP is whitelisted, we don't want to kick them
if (AntiVPN.getInstance().getExecutor().isWhitelisted(address)) {
log("IP is whitelisted: %s",
address);
return;
}
// If the countryList() size is zero, no need to check.
// Running country check first
if(!AntiVPN.getInstance().getVpnConfig().countryList().isEmpty()
// This bit of code will decide whether to kick the player
// If contains the code, and set to whitelist, it will not kick as they are equal
// and vise versa. However, if the contains does not match the state, it will kick.
&& AntiVPN.getInstance().getVpnConfig().countryList()
.contains(result.getCountryCode())
!= AntiVPN.getInstance().getVpnConfig().whitelistCountries()) {
countryKick(player, result);
} else if(result.isProxy()) {
proxyKick(player, result);
}
} else {
log(Level.WARNING,
"The API query was not a success! " +
"You may need to upgrade your license on https://funkemunky.cc/shop");
}
AntiVPN.getInstance().checked++;
});
}
private void countryKick(Player player, VPNResponse result) {
final String kickReason = AntiVPN.getInstance().getVpnConfig()
.countryVanillaKickReason();
//Using our built-in kicking system if no commands are configured
if(AntiVPN.getInstance().getVpnConfig().countryKickCommands().isEmpty()) {
// Kicking our player
new BukkitRunnable() {
public void run() {
player.kickPlayer(ChatColor
.translateAlternateColorCodes('&',
kickReason
.replace("%player%", player.getName())
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode())));
}
}.runTask(BukkitPlugin.pluginInstance);
} else {
final String playerName = player.getName();
BukkitPlugin.pluginInstance.getPlayerCommandRunner()
.addAction(player.getUniqueId(), () -> {
for (String cmd : AntiVPN.getInstance().getVpnConfig().countryKickCommands()) {
final String formattedCommand = ChatColor.translateAlternateColorCodes('&',
cmd.replace("%player%", playerName)
.replace("%country%", result.getCountryName())
.replace("%code%", result.getCountryCode()));
// Runs our command from console
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), formattedCommand);
}
});
}
}
private void proxyKick(Player player, VPNResponse result) {
log(Level.INFO, player.getName()
+ " joined on a VPN/Proxy (" + result.getMethod() + ")");
//Ensuring the user wishes to alert to staff
if(AntiVPN.getInstance().getVpnConfig().alertToStaff())
AntiVPN.getInstance().getPlayerExecutor().getOnlinePlayers().stream()
.filter(APIPlayer::isAlertsEnabled)
.forEach(pl -> pl.sendMessage(AntiVPN.getInstance().getVpnConfig().alertMessage()
.replace("%player%", player.getName())
.replace("%reason%", result.getMethod())
.replace("%country%", result.getCountryName())
.replace("%city%", result.getCity())));
if(AntiVPN.getInstance().getVpnConfig().kickPlayersOnDetect()) {
new BukkitRunnable() {
public void run() {
player.kickPlayer(org.bukkit.ChatColor.translateAlternateColorCodes('&',
AntiVPN.getInstance().getVpnConfig().getKickString()));
}
}.runTask(BukkitPlugin.pluginInstance);
} else {
//In case the user wants to run their own commands instead of using the built-in kicking
if(AntiVPN.getInstance().getVpnConfig().runCommands()) {
String playerName = player.getName();
BukkitPlugin.pluginInstance.getPlayerCommandRunner()
.addAction(player.getUniqueId(), () -> {
for (String command : AntiVPN.getInstance().getVpnConfig().commands()) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(),
ChatColor.translateAlternateColorCodes('&',
command.replace("%player%",
playerName)));
}
});
}
AntiVPN.getInstance().detections++;
}
}
@EventHandler