mirror of
https://github.com/funkemunky/AntiVPN.git
synced 2026-06-09 21:27:40 +00:00
Merge branch 'refs/heads/master' into 57-feature-allow-subnets-to-be-whitelisted
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
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;
|
||||
import org.spongepowered.api.event.Listener;
|
||||
import org.spongepowered.api.event.Order;
|
||||
import org.spongepowered.api.event.network.ServerSideConnectionEvent;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class SpongeListener extends VPNExecutor {
|
||||
|
||||
@Listener(order = Order.EARLY)
|
||||
public void onJoin(ServerSideConnectionEvent.Login event) {
|
||||
AtomicReference<APIPlayer> player = new AtomicReference<>(AntiVPN.getInstance().getPlayerExecutor()
|
||||
.getPlayer(event.profile().uuid())
|
||||
.orElse(new OfflinePlayer(
|
||||
event.profile().uuid(),
|
||||
event.profile().name().orElse("Unknown"),
|
||||
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()));
|
||||
}
|
||||
});
|
||||
|
||||
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()))));
|
||||
}
|
||||
case DENIED_COUNTRY ->
|
||||
event.setMessage(Component.text(StringUtil
|
||||
.translateColorCodes('&', AntiVPN.getInstance().getVpnConfig()
|
||||
.getCountryVanillaKickReason()
|
||||
.replace("%player%", player.get().getName())
|
||||
.replace("%country%", instantResult.response().getCountryName())
|
||||
.replace("%code%", instantResult.response().getCountryCode()))));
|
||||
}
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onPlayerDisconnect(ServerSideConnectionEvent.Disconnect event) {
|
||||
event.profile().ifPresent(profile ->
|
||||
AntiVPN.getInstance().getPlayerExecutor().unloadPlayer(profile.uuid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerListeners() {
|
||||
Sponge.eventManager().registerListeners(SpongePlugin.getInstance().getContainer(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(Level level, String log, Object... objects) {
|
||||
if (level.equals(Level.SEVERE)) {
|
||||
SpongePlugin.getInstance().getLogger().error(String.format(log, objects));
|
||||
} else if (level.equals(Level.WARNING)) {
|
||||
SpongePlugin.getInstance().getLogger().warn(String.format(log, objects));
|
||||
} else {
|
||||
SpongePlugin.getInstance().getLogger().info(String.format(log, objects));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String log, Object... objects) {
|
||||
log(Level.INFO, String.format(log, objects));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logException(String message, Throwable ex) {
|
||||
SpongePlugin.getInstance().getLogger().error(message, ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runCommand(String command) {
|
||||
try {
|
||||
Sponge.server().commandManager().process(Sponge.systemSubject(), command);
|
||||
} catch (CommandException e) {
|
||||
logException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disablePlugin() {
|
||||
AntiVPN.getInstance().getExecutor().log(Level.INFO, "Disabling listeners for plugin...");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.brighten.antivpn.sponge;
|
||||
|
||||
import dev.brighten.antivpn.api.APIPlayer;
|
||||
import dev.brighten.antivpn.sponge.util.StringUtil;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
|
||||
public class SpongePlayer extends APIPlayer {
|
||||
|
||||
private final ServerPlayer player;
|
||||
|
||||
public SpongePlayer(ServerPlayer player) {
|
||||
super(player.uniqueId(), player.name(), player.connection().address().getAddress());
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
player.sendMessage(Component.text(StringUtil.translateColorCodes('&', message)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kickPlayer(String reason) {
|
||||
player.kick(Component.text(StringUtil.translateColorCodes('&', reason)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
return player.hasPermission(permission);
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package dev.brighten.antivpn.sponge;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import dev.brighten.antivpn.api.APIPlayer;
|
||||
import dev.brighten.antivpn.api.PlayerExecutor;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SpongePlayerExecutor implements PlayerExecutor {
|
||||
|
||||
private final Cache<UUID, SpongePlayer> playerCache = Caffeine.newBuilder().maximumSize(10000)
|
||||
.expireAfterAccess(30, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public Optional<APIPlayer> getPlayer(String name) {
|
||||
Optional<ServerPlayer> serverPlayer = Sponge.server().player(name);
|
||||
|
||||
return serverPlayer.map(SpongePlayer::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<APIPlayer> getPlayer(UUID uuid) {
|
||||
SpongePlayer cachedPlayer = playerCache.getIfPresent(uuid);
|
||||
|
||||
if(cachedPlayer != null) {
|
||||
return Optional.of(cachedPlayer);
|
||||
}
|
||||
|
||||
Optional<ServerPlayer> serverPlayer = Sponge.server().player(uuid);
|
||||
|
||||
Optional<APIPlayer> player = serverPlayer.map(SpongePlayer::new);
|
||||
|
||||
player.ifPresent(value -> playerCache.put(uuid, (SpongePlayer) value));
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unloadPlayer(UUID uuid) {
|
||||
playerCache.invalidate(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<APIPlayer> getOnlinePlayers() {
|
||||
if(!Sponge.game().isServerAvailable()) return Collections.emptyList();
|
||||
return Sponge.server().onlinePlayers()
|
||||
.stream()
|
||||
.map(pl -> {
|
||||
SpongePlayer cachedPlayer = playerCache.getIfPresent(pl.uniqueId());
|
||||
|
||||
if(cachedPlayer != null) {
|
||||
return cachedPlayer;
|
||||
}
|
||||
|
||||
SpongePlayer player = new SpongePlayer(pl);
|
||||
playerCache.put(pl.uniqueId(), player);
|
||||
|
||||
return (APIPlayer) player;
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package dev.brighten.antivpn.sponge;
|
||||
|
||||
import dev.brighten.antivpn.AntiVPN;
|
||||
import dev.brighten.antivpn.loader.LoaderBootstrap;
|
||||
import dev.brighten.antivpn.sponge.command.SpongeCommand;
|
||||
import lombok.Getter;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.command.Command;
|
||||
import org.spongepowered.api.event.Listener;
|
||||
import org.spongepowered.api.event.lifecycle.*;
|
||||
import org.spongepowered.plugin.PluginContainer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
public class SpongePlugin implements LoaderBootstrap {
|
||||
|
||||
//Plugin init
|
||||
@Getter
|
||||
private static SpongePlugin instance;
|
||||
|
||||
private Logger logger;
|
||||
private PluginContainer container;
|
||||
private final Map<Class<?>, Object> objects;
|
||||
private File dataFolder;
|
||||
|
||||
|
||||
public SpongePlugin(Map<Class<?>, Object> objects) {
|
||||
this.objects = objects;
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onRegisterRawCommands(final RegisterCommandEvent<Command.Raw> event){
|
||||
AntiVPN.getInstance().getExecutor().log("Registering commands...");
|
||||
for (dev.brighten.antivpn.command.Command command : AntiVPN.getInstance().getCommands()) {
|
||||
AntiVPN.getInstance().getExecutor().log("Registering command %s...", command.name());
|
||||
event.register(this.container, new SpongeCommand(command), command.name(), command.aliases());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad(File dataFolder) {
|
||||
this.dataFolder = dataFolder;
|
||||
container = (PluginContainer) objects.get(PluginContainer.class);
|
||||
logger = (Logger) objects.get(Logger.class);
|
||||
Sponge.eventManager().registerListeners(this.container, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
|
||||
SpongeListener spongeListener = new SpongeListener();
|
||||
|
||||
AntiVPN.start(spongeListener, new SpongePlayerExecutor(), dataFolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
AntiVPN.getInstance().getExecutor().disablePlugin();
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
package dev.brighten.antivpn.sponge.command;
|
||||
|
||||
import dev.brighten.antivpn.AntiVPN;
|
||||
import dev.brighten.antivpn.command.Command;
|
||||
import dev.brighten.antivpn.command.CommandExecutor;
|
||||
import dev.brighten.antivpn.utils.StringUtil;
|
||||
import lombok.val;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.spongepowered.api.command.CommandCause;
|
||||
import org.spongepowered.api.command.CommandCompletion;
|
||||
import org.spongepowered.api.command.CommandResult;
|
||||
import org.spongepowered.api.command.parameter.ArgumentReader;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class SpongeCommand implements org.spongepowered.api.command.Command.Raw {
|
||||
|
||||
private final Command command;
|
||||
|
||||
public SpongeCommand(Command command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandResult process(CommandCause sender, ArgumentReader.Mutable arguments) {
|
||||
|
||||
String[] args = arguments.input().split(" ");
|
||||
|
||||
CommandExecutor commandExecutor = new SpongeCommandExecutor(sender);
|
||||
|
||||
val children = command.children();
|
||||
|
||||
if(children.length > 0 && args.length > 0) {
|
||||
for (Command child : children) {
|
||||
if(child.name().equalsIgnoreCase(args[0]) || Arrays.stream(child.aliases())
|
||||
.anyMatch(alias -> alias.equalsIgnoreCase(args[0]))) {
|
||||
if(!sender.hasPermission("antivpn.command.*")
|
||||
&& !sender.hasPermission(child.permission())) {
|
||||
return CommandResult.error(Component.text(StringUtil.translateAlternateColorCodes('&',
|
||||
AntiVPN.getInstance().getMessageHandler().getString("no-permission").getMessage())));
|
||||
}
|
||||
|
||||
commandExecutor.sendMessage(StringUtil
|
||||
.translateAlternateColorCodes('&',
|
||||
child.execute(commandExecutor, IntStream
|
||||
.range(0, args.length - 1)
|
||||
.mapToObj(i -> args[i + 1]).toArray(String[]::new))));
|
||||
return CommandResult.success();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
commandExecutor.sendMessage(StringUtil
|
||||
.translateAlternateColorCodes('&',
|
||||
command.execute(new SpongeCommandExecutor(sender), args)));
|
||||
|
||||
command.execute(new SpongeCommandExecutor(sender), args);
|
||||
return CommandResult.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommandCompletion> complete(CommandCause sender, ArgumentReader.Mutable arguments) {
|
||||
val children = command.children();
|
||||
String[] args = arguments.input().split(" ");
|
||||
if(children.length > 0 && args.length > 0) {
|
||||
for (Command child : children) {
|
||||
if(child.name().equalsIgnoreCase(args[0]) || Arrays.stream(child.aliases())
|
||||
.anyMatch(alias2 -> alias2.equalsIgnoreCase(args[0]))) {
|
||||
return child.tabComplete(new SpongeCommandExecutor(sender), "alias", IntStream
|
||||
.range(0, args.length - 1)
|
||||
.mapToObj(i -> args[i + 1]).toArray(String[]::new))
|
||||
.stream()
|
||||
.map(CommandCompletion::of)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
}
|
||||
return command.tabComplete(new SpongeCommandExecutor(sender), "alias", args)
|
||||
.stream()
|
||||
.map(CommandCompletion::of)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExecute(CommandCause cause) {
|
||||
return cause.hasPermission(command.permission());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Component> shortDescription(CommandCause cause) {
|
||||
return command.description() != null ? Optional.of(Component.text(command.description())) : Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Component> extendedDescription(CommandCause cause) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Component> help(@NonNull CommandCause cause) {
|
||||
return Optional.of(Component.text(StringUtil.translateAlternateColorCodes('&',
|
||||
command.execute(new SpongeCommandExecutor(cause), new String[0]))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component usage(CommandCause cause) {
|
||||
return command.usage() != null ? Component.text(command.usage()) : Component.empty();
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package dev.brighten.antivpn.sponge.command;
|
||||
|
||||
import dev.brighten.antivpn.AntiVPN;
|
||||
import dev.brighten.antivpn.api.APIPlayer;
|
||||
import dev.brighten.antivpn.command.CommandExecutor;
|
||||
import dev.brighten.antivpn.sponge.util.StringUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.spongepowered.api.command.CommandCause;
|
||||
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class SpongeCommandExecutor implements CommandExecutor {
|
||||
|
||||
private final CommandCause cause;
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message, Object... objects) {
|
||||
cause.sendMessage(Component.text(StringUtil.translateColorCodes('&',
|
||||
String.format(message, objects))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
return cause.hasPermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<APIPlayer> getPlayer() {
|
||||
if(cause.subject() instanceof ServerPlayer serverPlayer) {
|
||||
return AntiVPN.getInstance().getPlayerExecutor().getPlayer(serverPlayer.uniqueId());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayer() {
|
||||
return cause.subject() instanceof ServerPlayer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.brighten.antivpn.sponge.util;
|
||||
|
||||
public class StringUtil {
|
||||
|
||||
public static String translateColorCodes(char altColorChar, String textToTranslate) {
|
||||
char[] b = textToTranslate.toCharArray();
|
||||
|
||||
for(int i = 0; i < b.length - 1; ++i) {
|
||||
if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i + 1]) > -1) {
|
||||
b[i] = 167;
|
||||
b[i + 1] = Character.toLowerCase(b[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
return new String(b);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user