Skip to content

Commit

Permalink
Feat/antivpn (#80)
Browse files Browse the repository at this point in the history
* refactor: move packages for better structure

* feat: check if player's address is a proxy on join via proxycheck.io

* feat: address whitelist interfaces

* chore: provide tests for proxies and cache

* fix: code smells

* fix: interrupt when catching exception

* feat: api url for proxycheck is configurable

* use VARBINARY for address

---------

Co-authored-by: Netherwhal <netherwhal@simplyvanilla.net>
  • Loading branch information
rexlManu and Netherwhal authored Jan 27, 2024
1 parent 1c5356b commit 009531d
Show file tree
Hide file tree
Showing 52 changed files with 1,150 additions and 257 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
}

group 'net.simplyvanilla'
version '0.7.0'
version '0.8.0'

java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
Expand Down
38 changes: 27 additions & 11 deletions src/main/java/net/simplyvanilla/simplyrank/SimplyRankPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,27 @@
import com.google.gson.GsonBuilder;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.simplyvanilla.simplyrank.addresswhitelist.AddressWhitelistService;
import net.simplyvanilla.simplyrank.command.SimplyRankCommandExecutor;
import net.simplyvanilla.simplyrank.data.GroupPermissionService;
import net.simplyvanilla.simplyrank.data.PermissionApplyService;
import net.simplyvanilla.simplyrank.data.PlayerDataService;
import net.simplyvanilla.simplyrank.data.PlayerPermissionService;
import net.simplyvanilla.simplyrank.data.database.group.GroupData;
import net.simplyvanilla.simplyrank.data.database.sql.MySqlClient;
import net.simplyvanilla.simplyrank.data.database.sql.MySqlRepository;
import net.simplyvanilla.simplyrank.exception.DatabaseConnectionFailException;
import net.simplyvanilla.simplyrank.command.address.AddressWhitelistCommand;
import net.simplyvanilla.simplyrank.database.exception.DatabaseConnectionFailException;
import net.simplyvanilla.simplyrank.database.group.GroupData;
import net.simplyvanilla.simplyrank.database.sql.MySqlClient;
import net.simplyvanilla.simplyrank.database.sql.MySqlRepository;
import net.simplyvanilla.simplyrank.gson.TextColorGsonDeserializer;
import net.simplyvanilla.simplyrank.listener.PlayerLoginEventListener;
import net.simplyvanilla.simplyrank.listener.PlayerQuitEventListener;
import net.simplyvanilla.simplyrank.permission.GroupPermissionService;
import net.simplyvanilla.simplyrank.permission.PermissionApplyService;
import net.simplyvanilla.simplyrank.permission.PlayerDataService;
import net.simplyvanilla.simplyrank.permission.PlayerPermissionService;
import net.simplyvanilla.simplyrank.placeholder.MiniPlaceholderRegister;
import net.simplyvanilla.simplyrank.placeholder.ScoreboardTeamsPlaceholderExtension;
import net.simplyvanilla.simplyrank.placeholder.SimplyRankPlaceholderExpansion;
import net.simplyvanilla.simplyrank.proxy.ProxyService;
import net.simplyvanilla.simplyrank.proxy.ProxyTtlCleanupTask;
import net.simplyvanilla.simplyrank.proxy.provider.ProxyCheckProvider;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
Expand All @@ -30,18 +36,21 @@
import java.nio.file.Files;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

public class SimplyRankPlugin extends JavaPlugin {

private static SimplyRankPlugin instance;
private PlayerDataService playerDataService;

private MySqlClient mySqlClient = null;


@Override
public void onEnable() {
MySqlRepository mySqlRepository = null;
ProxyService proxyService;
MySqlRepository mySqlRepository;
FileConfiguration config;
instance = this;

Expand Down Expand Up @@ -82,7 +91,9 @@ public void onEnable() {
}

this.playerDataService =
new PlayerDataService(this, mySqlRepository, mySqlRepository);
new PlayerDataService(mySqlRepository, mySqlRepository);
proxyService = new ProxyService(mySqlRepository, new ProxyCheckProvider(this.getConfig().getString("proxycheck-api-url", "https://proxycheck.io/v2/%s&vpn=1")));
Bukkit.getAsyncScheduler().runAtFixedRate(this, new ProxyTtlCleanupTask(proxyService, this.getConfig().getInt("proxycache-ttl", 720)), 1, 10, TimeUnit.SECONDS);

if (!this.playerDataService.groupExists("default")) {
GroupData defaultData = new GroupData(NamedTextColor.GRAY, "Member ");
Expand Down Expand Up @@ -118,15 +129,20 @@ public void onEnable() {
});
}

AddressWhitelistService addressWhitelistService = new AddressWhitelistService(mySqlRepository);

this.getServer()
.getPluginManager()
.registerEvents(new PlayerQuitEventListener(playerPermissionService), this);
this.getServer()
.getPluginManager()
.registerEvents(new PlayerLoginEventListener(this, permissionApplyService), this);
.registerEvents(new PlayerLoginEventListener(this, permissionApplyService, proxyService, addressWhitelistService), this);

this.getCommand("simplyrank")
.setExecutor(new SimplyRankCommandExecutor(this.playerDataService, permissionApplyService));

this.getCommand("vpn-whitelist")
.setExecutor(new AddressWhitelistCommand(addressWhitelistService));
} catch (IOException e) {
this.getLogger().severe("Could not load perms.yml");
e.printStackTrace();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net.simplyvanilla.simplyrank.addresswhitelist;

import net.simplyvanilla.simplyrank.database.addresswhitelist.AddressWhitelist;
import net.simplyvanilla.simplyrank.database.addresswhitelist.AddressWhitelistRepository;
import org.bukkit.entity.Player;

import java.time.LocalDateTime;
import java.util.UUID;

public class AddressWhitelistService {
private final AddressWhitelistRepository repository;

public AddressWhitelistService(AddressWhitelistRepository repository) {
this.repository = repository;
}

public void addAddress(String address, UUID invokerId) {
this.repository.save(new AddressWhitelist(address, invokerId, LocalDateTime.now()));
}

public void removeAddress(String address) {
this.repository.deleteByAddress(address);
}

public boolean isWhitelisted(Player player) {
String address = player.getAddress().getAddress().getHostAddress();
return this.repository.existsByAddress(address);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package net.simplyvanilla.simplyrank.command;

import net.simplyvanilla.simplyrank.data.PlayerDataService;
import net.simplyvanilla.simplyrank.data.PermissionApplyService;
import net.simplyvanilla.simplyrank.permission.PlayerDataService;
import net.simplyvanilla.simplyrank.permission.PermissionApplyService;

public abstract class AbstractCommand implements SubCommand {
protected final CommandErrorMessages errorMessages;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package net.simplyvanilla.simplyrank.command;

import net.simplyvanilla.simplyrank.command.impl.*;
import net.simplyvanilla.simplyrank.data.PlayerDataService;
import net.simplyvanilla.simplyrank.data.PermissionApplyService;
import net.simplyvanilla.simplyrank.permission.PlayerDataService;
import net.simplyvanilla.simplyrank.permission.PermissionApplyService;
import org.bukkit.command.*;
import org.jetbrains.annotations.NotNull;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package net.simplyvanilla.simplyrank.command;

import net.simplyvanilla.simplyrank.data.PermissionApplyService;
import net.simplyvanilla.simplyrank.data.PlayerDataService;
import net.simplyvanilla.simplyrank.data.database.player.PlayerData;
import net.simplyvanilla.simplyrank.permission.PermissionApplyService;
import net.simplyvanilla.simplyrank.permission.PlayerDataService;
import net.simplyvanilla.simplyrank.database.player.PlayerData;
import net.simplyvanilla.simplyrank.utils.PlayerUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package net.simplyvanilla.simplyrank.command.address;

import net.simplyvanilla.simplyrank.addresswhitelist.AddressWhitelistService;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

import java.util.UUID;

import static net.kyori.adventure.text.Component.text;

public class AddressWhitelistCommand implements CommandExecutor {
private static final UUID CONSOLE_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000");
private final AddressWhitelistService service;

public AddressWhitelistCommand(AddressWhitelistService service) {
this.service = service;
}

@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
UUID senderId = sender instanceof Player player ? player.getUniqueId() : CONSOLE_UUID;

if (args.length != 2) {
this.printHelp(sender);
} else if ("add".equals(args[0])) {
this.handleAddCommand(sender, args[1], senderId);
} else if ("remove".equals(args[0])) {
this.handleRemoveCommand(sender, args[1]);
} else {
this.printHelp(sender);
}
return true;
}

private void printHelp(CommandSender sender) {
sender.sendMessage(text("Usage: /vpn-whitelist <add|remove> <address>"));
}

private boolean validateAddress(String address) {
// check if address is valid ipv4 or ipv6 address
if (address.contains(":")) {
// ipv6
return address.matches("^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");
} else {
// ipv4
return address.matches("^(?:\\d{1,3}\\.){3}\\d{1,3}$");
}
}

private void handleRemoveCommand(CommandSender sender, String address) {
this.service.removeAddress(address);
sender.sendMessage(text("Removed address " + address));
}

private void handleAddCommand(CommandSender sender, String address, UUID invokerId) {
if (!this.validateAddress(address)) {
sender.sendMessage(text("Invalid address " + address));
return;
}
this.service.addAddress(address, invokerId);
sender.sendMessage(text("Added address " + address));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import net.simplyvanilla.simplyrank.command.AbstractCommand;
import net.simplyvanilla.simplyrank.command.CommandContext;
import net.simplyvanilla.simplyrank.command.CommandErrorMessages;
import net.simplyvanilla.simplyrank.data.PlayerDataService;
import net.simplyvanilla.simplyrank.data.PermissionApplyService;
import net.simplyvanilla.simplyrank.permission.PlayerDataService;
import net.simplyvanilla.simplyrank.permission.PermissionApplyService;

import static net.kyori.adventure.text.Component.text;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import net.simplyvanilla.simplyrank.command.AbstractCommand;
import net.simplyvanilla.simplyrank.command.CommandContext;
import net.simplyvanilla.simplyrank.command.CommandErrorMessages;
import net.simplyvanilla.simplyrank.data.PermissionApplyService;
import net.simplyvanilla.simplyrank.data.PlayerDataService;
import net.simplyvanilla.simplyrank.data.database.group.GroupData;
import net.simplyvanilla.simplyrank.permission.PermissionApplyService;
import net.simplyvanilla.simplyrank.permission.PlayerDataService;
import net.simplyvanilla.simplyrank.database.group.GroupData;

import java.util.Arrays;
import java.util.Locale;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import net.simplyvanilla.simplyrank.command.AbstractCommand;
import net.simplyvanilla.simplyrank.command.CommandContext;
import net.simplyvanilla.simplyrank.command.CommandErrorMessages;
import net.simplyvanilla.simplyrank.data.PermissionApplyService;
import net.simplyvanilla.simplyrank.data.PlayerDataService;
import net.simplyvanilla.simplyrank.data.database.player.PlayerData;
import net.simplyvanilla.simplyrank.permission.PermissionApplyService;
import net.simplyvanilla.simplyrank.permission.PlayerDataService;
import net.simplyvanilla.simplyrank.database.player.PlayerData;
import net.simplyvanilla.simplyrank.utils.PlayerUtils;

import java.util.UUID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import net.simplyvanilla.simplyrank.command.AbstractCommand;
import net.simplyvanilla.simplyrank.command.CommandContext;
import net.simplyvanilla.simplyrank.command.CommandErrorMessages;
import net.simplyvanilla.simplyrank.data.PermissionApplyService;
import net.simplyvanilla.simplyrank.data.PlayerDataService;
import net.simplyvanilla.simplyrank.permission.PermissionApplyService;
import net.simplyvanilla.simplyrank.permission.PlayerDataService;
import net.simplyvanilla.simplyrank.utils.PlayerUtils;
import org.bukkit.Bukkit;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import net.simplyvanilla.simplyrank.command.AbstractCommand;
import net.simplyvanilla.simplyrank.command.CommandContext;
import net.simplyvanilla.simplyrank.command.CommandErrorMessages;
import net.simplyvanilla.simplyrank.data.PlayerDataService;
import net.simplyvanilla.simplyrank.data.PermissionApplyService;
import net.simplyvanilla.simplyrank.permission.PlayerDataService;
import net.simplyvanilla.simplyrank.permission.PermissionApplyService;

import static net.kyori.adventure.text.Component.text;

Expand Down
Loading

0 comments on commit 009531d

Please sign in to comment.