From e74a959d7481a4514cd91389949c68a382997706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Pani=C4=87?= Date: Sun, 7 Apr 2019 19:55:48 +0200 Subject: Created basic ban functionality (IP bans not yet supported) --- .../com/redstoner/bungeeBans/BanJoinListener.java | 57 ++++++++++++ .../java/com/redstoner/bungeeBans/BanManager.java | 66 +++++++++++++ src/main/java/com/redstoner/bungeeBans/Main.java | 91 ++++++++++++++++++ src/main/java/com/redstoner/bungeeBans/Util.java | 23 +++++ .../redstoner/bungeeBans/commands/BanCommand.java | 102 +++++++++++++++++++++ .../bungeeBans/commands/GetBanCommand.java | 66 +++++++++++++ .../bungeeBans/commands/UnbanCommand.java | 80 ++++++++++++++++ .../java/com/redstoner/bungeeBans/json/Ban.java | 49 ++++++++++ .../java/com/redstoner/bungeeBans/json/IPBan.java | 25 +++++ .../com/redstoner/bungeeBans/json/PlayerBan.java | 35 +++++++ src/main/resources/plugin.yml | 4 + 11 files changed, 598 insertions(+) create mode 100644 src/main/java/com/redstoner/bungeeBans/BanJoinListener.java create mode 100644 src/main/java/com/redstoner/bungeeBans/BanManager.java create mode 100644 src/main/java/com/redstoner/bungeeBans/Main.java create mode 100644 src/main/java/com/redstoner/bungeeBans/Util.java create mode 100644 src/main/java/com/redstoner/bungeeBans/commands/BanCommand.java create mode 100644 src/main/java/com/redstoner/bungeeBans/commands/GetBanCommand.java create mode 100644 src/main/java/com/redstoner/bungeeBans/commands/UnbanCommand.java create mode 100644 src/main/java/com/redstoner/bungeeBans/json/Ban.java create mode 100644 src/main/java/com/redstoner/bungeeBans/json/IPBan.java create mode 100644 src/main/java/com/redstoner/bungeeBans/json/PlayerBan.java create mode 100644 src/main/resources/plugin.yml diff --git a/src/main/java/com/redstoner/bungeeBans/BanJoinListener.java b/src/main/java/com/redstoner/bungeeBans/BanJoinListener.java new file mode 100644 index 0000000..c868c4b --- /dev/null +++ b/src/main/java/com/redstoner/bungeeBans/BanJoinListener.java @@ -0,0 +1,57 @@ +package com.redstoner.bungeeBans; + +import com.mojang.api.profiles.Profile; +import com.redstoner.bungeeBans.json.Ban; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.connection.PendingConnection; +import net.md_5.bungee.api.event.PreLoginEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; +import net.md_5.bungee.event.EventPriority; + +public class BanJoinListener implements Listener { + private BanManager bm; + + BanJoinListener(BanManager bm) { + this.bm = bm; + } + + @EventHandler (priority = EventPriority.HIGHEST) + public void onJoin(PreLoginEvent event) { + event.setCancelled(true); + + PendingConnection conn = event.getConnection(); + String name = conn.getName(); + + Profile[] profiles = Util.findProfilesByNames(name); + + if (profiles.length != 1) { + event.setCancelReason( + new ComponentBuilder(ChatColor.RED + "Server error occured while joining: ") + .append(ChatColor.AQUA + "The mojang API does not know your UUID!") + .create() + ); + + return; + } + + T ban = bm.getBan(Util.dashUUID(profiles[0].getId())); + + if (ban != null) { + event.setCancelReason( + new ComponentBuilder(ChatColor.RED + "You were banned by ") + .append(ChatColor.AQUA + ban.getSource()) + .append(ChatColor.RED + " for ") + .append(ChatColor.AQUA + ban.getReason()) + .append(ChatColor.RED + " on ") + .append(ChatColor.AQUA + ban.getCreated()) + .append(ChatColor.RED + " until ") + .append(ChatColor.AQUA + ban.getExpires()) + .create() + ); + } else { + event.setCancelled(false); + } + } +} diff --git a/src/main/java/com/redstoner/bungeeBans/BanManager.java b/src/main/java/com/redstoner/bungeeBans/BanManager.java new file mode 100644 index 0000000..3c152f3 --- /dev/null +++ b/src/main/java/com/redstoner/bungeeBans/BanManager.java @@ -0,0 +1,66 @@ +package com.redstoner.bungeeBans; + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.redstoner.bungeeBans.json.Ban; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class BanManager { + private Gson gson = new Gson(); + private File file; + + private Class type; + + private List bans = new ArrayList<>(); + + BanManager(File file, Class type) { + this.file = file; + this.type = type; + } + + public void loadBans() throws JsonSyntaxException, IOException { + String json = new String(Files.readAllBytes(file.toPath())); + + try { + @SuppressWarnings ("unchecked") + T[] bans = gson.fromJson(json, (Class) java.lang.reflect.Array.newInstance(type, 0).getClass()); + if (bans != null) this.bans.addAll(Arrays.asList(bans)); + } catch (ClassCastException e) { + //IGNORE + e.printStackTrace(); + } + } + + public void saveBans() throws IOException { + String json = gson.toJson(bans); + + FileOutputStream outputStream = new FileOutputStream(file); + outputStream.write(json.getBytes()); + outputStream.close(); + } + + public void addBan(T ban) { + this.bans.add(ban); + } + + public void removeBan(T ban) { + this.bans.remove(ban); + } + + public T getBan(String identifier) { + for (T ban : bans) { + if (ban.getIdentifier().equals(identifier)) { + return ban; + } + } + + return null; + } +} diff --git a/src/main/java/com/redstoner/bungeeBans/Main.java b/src/main/java/com/redstoner/bungeeBans/Main.java new file mode 100644 index 0000000..3b847e4 --- /dev/null +++ b/src/main/java/com/redstoner/bungeeBans/Main.java @@ -0,0 +1,91 @@ +package com.redstoner.bungeeBans; + +import com.redstoner.bungeeBans.commands.BanCommand; +import com.redstoner.bungeeBans.commands.GetBanCommand; +import com.redstoner.bungeeBans.commands.UnbanCommand; +import com.redstoner.bungeeBans.json.PlayerBan; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.api.plugin.PluginManager; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +public class Main extends Plugin { + private File bansFile = new File("banned-players.json"); + + private BanManager playerBanManager = new BanManager<>(bansFile, PlayerBan.class); + + private boolean shouldSave = true; + + @Override + public void onEnable() { + try { + getLogger().info("Loading bans..."); + + playerBanManager.loadBans(); + + getLogger().info("Loaded bans!"); + } catch (FileNotFoundException e) { + getLogger().warning("Bans file does not exist! Creating!"); + + try { + if (bansFile.createNewFile()) { + getLogger().info("File created! Retrying load..."); + onEnable(); + return; + } else { + getLogger().severe("File could not be created! Disabling!"); + } + } catch (IOException e2) { + getLogger().severe("File could not be created! Disabling!"); + getLogger().severe(e2.getMessage()); + e2.printStackTrace(); + } + + disable(); + return; + } catch (Exception e) { + getLogger().severe("Failed to load bans: " + e.getMessage()); + e.printStackTrace(); + + disable(); + return; + } + + PluginManager pm = getProxy().getPluginManager(); + + pm.registerCommand(this, new BanCommand(playerBanManager, this)); + pm.registerCommand(this, new UnbanCommand(playerBanManager)); + pm.registerCommand(this, new GetBanCommand(playerBanManager)); + + pm.registerListener(this, new BanJoinListener<>(playerBanManager)); + } + + @Override + public void onDisable() { + if (shouldSave) { + try { + playerBanManager.saveBans(); + getLogger().info("Saved bans to file!"); + } catch (IOException e) { + getLogger().severe("Failed to save bans: " + e.getMessage()); + e.printStackTrace(); + } + } + } + + private void disable() { + getLogger().severe("Disabling plugin!"); + + shouldSave = false; + this.onDisable(); + + PluginManager pm = getProxy().getPluginManager(); + + pm.unregisterListeners(this); + pm.unregisterCommands(this); + } + + +} diff --git a/src/main/java/com/redstoner/bungeeBans/Util.java b/src/main/java/com/redstoner/bungeeBans/Util.java new file mode 100644 index 0000000..c633801 --- /dev/null +++ b/src/main/java/com/redstoner/bungeeBans/Util.java @@ -0,0 +1,23 @@ +package com.redstoner.bungeeBans; + +import com.mojang.api.profiles.HttpProfileRepository; +import com.mojang.api.profiles.Profile; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +public class Util { + private static final HttpProfileRepository profileRepo = new HttpProfileRepository("minecraft"); + + public static String dashUUID(String uuid) { + return uuid.replaceFirst("([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+)", "$1-$2-$3-$4-$5"); + } + + public static String getNow() { + return ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss Z")); + } + + public static Profile[] findProfilesByNames(String... names) { + return profileRepo.findProfilesByNames(names); + } +} diff --git a/src/main/java/com/redstoner/bungeeBans/commands/BanCommand.java b/src/main/java/com/redstoner/bungeeBans/commands/BanCommand.java new file mode 100644 index 0000000..ec9e980 --- /dev/null +++ b/src/main/java/com/redstoner/bungeeBans/commands/BanCommand.java @@ -0,0 +1,102 @@ +package com.redstoner.bungeeBans.commands; + +import com.mojang.api.profiles.Profile; +import com.redstoner.bungeeBans.BanManager; +import com.redstoner.bungeeBans.Main; +import com.redstoner.bungeeBans.Util; +import com.redstoner.bungeeBans.json.PlayerBan; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.io.IOException; +import java.util.Arrays; + +public class BanCommand extends Command { + private BanManager bm; + private Main plugin; + + public BanCommand(BanManager bm, Main plugin) { + super("ban", "bungeeBans.ban"); + + this.bm = bm; + this.plugin = plugin; + } + + @Override + public void execute(CommandSender sender, String[] args) { + String reason = "Banned by an operator."; + + switch (args.length) { + case 0: + sender.sendMessage( + new ComponentBuilder("Usage: ") + .append(ChatColor.AQUA + "/ban ") + .append(ChatColor.GOLD + " ") + .append(ChatColor.YELLOW + "[reason]") + .create() + ); + case 1: + break; + default: + reason = String.join(" ", Arrays.copyOfRange(args, 1, args.length)); + break; + } + + Profile[] profiles = Util.findProfilesByNames(args[0]); + + if (profiles.length != 1) { + sender.sendMessage(new TextComponent(ChatColor.RED + "Invalid name!")); + return; + } + + String uuid = Util.dashUUID(profiles[0].getId()); + String name = profiles[0].getName(); + String expires = "forever"; //TODO: expiry option + + if (bm.getBan(uuid) != null) { + sender.sendMessage(new TextComponent(ChatColor.RED + "That player is already banned!")); + return; + } + + PlayerBan ban = new PlayerBan(uuid, name, Util.getNow(), sender.getName(), expires, reason); + bm.addBan(ban); + + try { + bm.saveBans(); + sender.sendMessage(new TextComponent(ChatColor.GREEN + "Saved bans to file!")); + } catch (IOException e) { + sender.sendMessage(new TextComponent(ChatColor.RED + "Failed to save bans to file!")); + e.printStackTrace(); + + bm.removeBan(ban); + return; + } + + ProxiedPlayer proxiedPlayer = plugin.getProxy().getPlayer(name); + + if (proxiedPlayer != null) { + proxiedPlayer.disconnect( + new ComponentBuilder(ChatColor.RED + "You were banned by ") + .append(ChatColor.AQUA + sender.getName()) + .append(ChatColor.RED + " for ") + .append(ChatColor.YELLOW + reason) + .create() + ); + } + + + sender.sendMessage( + new ComponentBuilder(ChatColor.GREEN + "Banned player ") + .append(ChatColor.AQUA + name) + .append(ChatColor.GREEN + " with uuid ") + .append(ChatColor.AQUA + uuid) + .append(ChatColor.GREEN + " and reason ") + .append(ChatColor.AQUA + reason) + .create() + ); + } +} diff --git a/src/main/java/com/redstoner/bungeeBans/commands/GetBanCommand.java b/src/main/java/com/redstoner/bungeeBans/commands/GetBanCommand.java new file mode 100644 index 0000000..5ff213a --- /dev/null +++ b/src/main/java/com/redstoner/bungeeBans/commands/GetBanCommand.java @@ -0,0 +1,66 @@ +package com.redstoner.bungeeBans.commands; + +import com.mojang.api.profiles.Profile; +import com.redstoner.bungeeBans.BanManager; +import com.redstoner.bungeeBans.Util; +import com.redstoner.bungeeBans.json.PlayerBan; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.plugin.Command; + +public class GetBanCommand extends Command { + private BanManager bm; + + public GetBanCommand(BanManager bm) { + super("getban", "bungeebans.getban"); + + this.bm = bm; + } + + @Override + public void execute(CommandSender sender, String[] args) { + if (args.length != 1) { + sender.sendMessage( + new ComponentBuilder(ChatColor.RED + "Invalid command! ") + .append("Usage: ") + .append(ChatColor.AQUA + "/getban ") + .append(ChatColor.GOLD + " ") + .create() + ); + + return; + } + + Profile[] profiles = Util.findProfilesByNames(args[0]); + + if (profiles.length != 1) { + sender.sendMessage(new TextComponent(ChatColor.RED + "Invalid name!")); + return; + } + + String uuid = Util.dashUUID(profiles[0].getId()); + String name = profiles[0].getName(); + + PlayerBan ban = bm.getBan(uuid); + + if (ban == null) { + sender.sendMessage(new TextComponent(ChatColor.RED + "That player is not banned!")); + return; + } + + sender.sendMessage( + new ComponentBuilder(ChatColor.GREEN + "Player ") + .append(ChatColor.AQUA + name) + .append(ChatColor.GREEN + " with uuid ") + .append(ChatColor.AQUA + uuid) + .append(ChatColor.GREEN + " is banned for ") + .append(ChatColor.AQUA + ban.getReason()) + .append(ChatColor.GREEN + " until ") + .append(ChatColor.AQUA + ban.getExpires()) + .create() + ); + + } +} diff --git a/src/main/java/com/redstoner/bungeeBans/commands/UnbanCommand.java b/src/main/java/com/redstoner/bungeeBans/commands/UnbanCommand.java new file mode 100644 index 0000000..a495dbb --- /dev/null +++ b/src/main/java/com/redstoner/bungeeBans/commands/UnbanCommand.java @@ -0,0 +1,80 @@ +package com.redstoner.bungeeBans.commands; + +import com.mojang.api.profiles.HttpProfileRepository; +import com.mojang.api.profiles.Profile; +import com.redstoner.bungeeBans.BanManager; +import com.redstoner.bungeeBans.Util; +import com.redstoner.bungeeBans.json.PlayerBan; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.plugin.Command; + +import java.io.IOException; + +public class UnbanCommand extends Command { + HttpProfileRepository profileRepo = new HttpProfileRepository("minecraft"); + + private BanManager bm; + + public UnbanCommand(BanManager bm) { + super("unban", "bungeebans.unban", "pardon"); + + this.bm = bm; + } + + @Override + public void execute(CommandSender sender, String[] args) { + if (args.length != 1) { + sender.sendMessage( + new ComponentBuilder(ChatColor.RED + "Invalid command! ") + .append("Usage: ") + .append(ChatColor.AQUA + "/unban ") + .append(ChatColor.GOLD + " ") + .create() + ); + + return; + } + + Profile[] profiles = profileRepo.findProfilesByNames(args[0]); + + if (profiles.length != 1) { + sender.sendMessage(new TextComponent(ChatColor.RED + "Invalid name!")); + return; + } + + String uuid = Util.dashUUID(profiles[0].getId()); + String name = profiles[0].getName(); + + PlayerBan ban = bm.getBan(uuid); + + if (ban == null) { + sender.sendMessage(new TextComponent(ChatColor.RED + "That player is not banned!")); + return; + } + + bm.removeBan(ban); + + try { + bm.saveBans(); + sender.sendMessage(new TextComponent(ChatColor.GREEN + "Saved bans to file!")); + } catch (IOException e) { + sender.sendMessage(new TextComponent(ChatColor.RED + "Failed to save bans to file!")); + e.printStackTrace(); + + bm.addBan(ban); + return; + } + + sender.sendMessage( + new ComponentBuilder(ChatColor.GREEN + "Unbanned player ") + .append(ChatColor.AQUA + name) + .append(ChatColor.GREEN + " with uuid ") + .append(ChatColor.AQUA + uuid) + .create() + ); + + } +} diff --git a/src/main/java/com/redstoner/bungeeBans/json/Ban.java b/src/main/java/com/redstoner/bungeeBans/json/Ban.java new file mode 100644 index 0000000..d5434d5 --- /dev/null +++ b/src/main/java/com/redstoner/bungeeBans/json/Ban.java @@ -0,0 +1,49 @@ +package com.redstoner.bungeeBans.json; + +public abstract class Ban { + private String created; + private String source; + private String expires; + private String reason; + + protected Ban(String created, String source, String expires, String reason) { + this.created = created; + this.source = source; + this.expires = expires; + this.reason = reason; + } + + public abstract String getIdentifier(); + + public String getCreated() { + return created; + } + + public void setCreated(String created) { + this.created = created; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getExpires() { + return expires; + } + + public void setExpires(String expires) { + this.expires = expires; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } +} diff --git a/src/main/java/com/redstoner/bungeeBans/json/IPBan.java b/src/main/java/com/redstoner/bungeeBans/json/IPBan.java new file mode 100644 index 0000000..99fb2e0 --- /dev/null +++ b/src/main/java/com/redstoner/bungeeBans/json/IPBan.java @@ -0,0 +1,25 @@ +package com.redstoner.bungeeBans.json; + +public class IPBan extends Ban { + private String ip; + + + public IPBan(String ip, String created, String source, String expires, String reason) { + super(created, source, expires, reason); + + this.ip = ip; + } + + @Override + public String getIdentifier() { + return ip; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } +} diff --git a/src/main/java/com/redstoner/bungeeBans/json/PlayerBan.java b/src/main/java/com/redstoner/bungeeBans/json/PlayerBan.java new file mode 100644 index 0000000..5375493 --- /dev/null +++ b/src/main/java/com/redstoner/bungeeBans/json/PlayerBan.java @@ -0,0 +1,35 @@ +package com.redstoner.bungeeBans.json; + +public class PlayerBan extends Ban { + private String uuid; + private String name; + + + public PlayerBan(String uuid, String name, String created, String source, String expires, String reason) { + super(created, source, expires, reason); + + this.uuid = uuid; + this.name = name; + } + + @Override + public String getIdentifier() { + return uuid; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..0667329 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,4 @@ +name: BungeeBans +main: com.redstoner.bungeeBans.Main +version: 1.0 +author: psrcek \ No newline at end of file -- cgit v1.2.3