diff --git a/src/main/java/net/kuraczyk/banhammer/BanHammer.java b/src/main/java/net/kuraczyk/banhammer/BanHammer.java index 5675a7c..921ea89 100644 --- a/src/main/java/net/kuraczyk/banhammer/BanHammer.java +++ b/src/main/java/net/kuraczyk/banhammer/BanHammer.java @@ -1,5 +1,6 @@ package net.kuraczyk.banhammer; +import net.kuraczyk.banhammer.workers.BanJobWorker; import org.bukkit.ChatColor; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -57,6 +58,8 @@ public final class BanHammer extends JavaPlugin { new BHConfig(this); getServer().getPluginManager().registerEvents(new PlayerPreLogin(this), this); + + new BanJobWorker(this); } @Override diff --git a/src/main/java/net/kuraczyk/banhammer/cmds/Ban.java b/src/main/java/net/kuraczyk/banhammer/cmds/Ban.java index d8ac176..4bf22dc 100644 --- a/src/main/java/net/kuraczyk/banhammer/cmds/Ban.java +++ b/src/main/java/net/kuraczyk/banhammer/cmds/Ban.java @@ -106,7 +106,7 @@ public class Ban implements CommandExecutor { stmt.setString(2, scope); ResultSet rs = stmt.executeQuery(); if(rs.next()){ - p.sendMessage(TextUtils.colorString(addPrefix(plugin.translations.getString("command.ban.alreadyBannedInScopeError")))); + p.sendMessage(TextUtils.colorString(resolveBanMessagePlaceholders(addPrefix(plugin.translations.getString("command.ban.alreadyBannedInScopeError")), args[0], scope, reason, p.getName()))); return false; } } catch (SQLException e){ @@ -119,9 +119,7 @@ public class Ban implements CommandExecutor { if(b != null) { if(banEndDate == null) { - if(target!=null) - if(target.isOnline()) - if(Objects.equals(plugin.config.getString("serverID"), scope) || Objects.equals(scope, "*")) target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanPerm"), b))); + createPlayerKickJob(b, scope); p.sendMessage(TextUtils.colorString(resolveBanMessagePlaceholders(addPrefix(plugin.translations.getString("command.ban.successfulBanMessagePerm")), args[0], scope, reason, p.getName()))); String bcMess = plugin.translations.getString("command.ban.banPublicAnnouncementPerm"); if(bcMess!=null) Bukkit.broadcast(TextUtils.colorString(resolveBanMessagePlaceholders(bcMess, args[0], scope, reason, p.getName()))); @@ -137,9 +135,7 @@ public class Ban implements CommandExecutor { long timeLeftSeconds = TimeUnit.MILLISECONDS.toSeconds(timeLeft); String parsedBanDuration = TextUtils.parsePolishDate(timeLeftDays, timeLeftHours, timeLeftMinutes, timeLeftSeconds); - if(target!=null) - if(target.isOnline()) - if(Objects.equals(plugin.config.getString("serverID"), scope) || Objects.equals(scope, "*")) target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanTemp"), b))); + createPlayerKickJob(b, scope); p.sendMessage(TextUtils.colorString(resolveBanMessagePlaceholders(addPrefix(plugin.translations.getString("command.ban.successfulBanMessageTemp")), args[0], scope, reason, p.getName(), parsedBanDuration))); String bcMess = plugin.translations.getString("command.ban.banPublicAnnouncementTemp"); if(bcMess!=null) Bukkit.broadcast(TextUtils.colorString(resolveBanMessagePlaceholders(bcMess, args[0], scope, reason, p.getName(), parsedBanDuration))); @@ -220,7 +216,7 @@ public class Ban implements CommandExecutor { stmt.setString(2, scope); ResultSet rs = stmt.executeQuery(); if(rs.next()){ - Bukkit.getConsoleSender().sendMessage(TextUtils.colorString(addPrefix(plugin.translations.getString("command.ban.alreadyBannedInScopeError")))); + Bukkit.getConsoleSender().sendMessage(TextUtils.colorString(resolveBanMessagePlaceholders(addPrefix(plugin.translations.getString("command.ban.alreadyBannedInScopeError")), args[0], scope, reason, "CONSOLE"))); return false; } } catch (SQLException e){ @@ -233,9 +229,7 @@ public class Ban implements CommandExecutor { if(b != null) { if(banEndDate == null) { - if(target!=null) - if(target.isOnline()) - if(Objects.equals(plugin.config.getString("serverID"), scope) || Objects.equals(scope, "*")) target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanPerm"), b))); + createPlayerKickJob(b, scope); Bukkit.getConsoleSender().sendMessage(TextUtils.colorString(resolveBanMessagePlaceholders(addPrefix(plugin.translations.getString("command.ban.successfulBanMessagePerm")), args[0], scope, reason, "CONSOLE"))); String bcMess = plugin.translations.getString("command.ban.banPublicAnnouncementPerm"); if(bcMess!=null) Bukkit.broadcast(TextUtils.colorString(resolveBanMessagePlaceholders(bcMess, args[0], scope, reason, "CONSOLE"))); @@ -251,9 +245,7 @@ public class Ban implements CommandExecutor { long timeLeftSeconds = TimeUnit.MILLISECONDS.toSeconds(timeLeft); String parsedBanDuration = TextUtils.parsePolishDate(timeLeftDays, timeLeftHours, timeLeftMinutes, timeLeftSeconds); - if(target!=null) - if(target.isOnline()) - if(Objects.equals(plugin.config.getString("serverID"), scope) || Objects.equals(scope, "*")) target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanTemp"), b))); + createPlayerKickJob(b, scope); Bukkit.getConsoleSender().sendMessage(TextUtils.colorString(resolveBanMessagePlaceholders(addPrefix(plugin.translations.getString("command.ban.successfulBanMessageTemp")), args[0], scope, reason, "CONSOLE", parsedBanDuration))); String bcMess = plugin.translations.getString("command.ban.banPublicAnnouncementTemp"); if(bcMess!=null) Bukkit.broadcast(TextUtils.colorString(resolveBanMessagePlaceholders(bcMess, args[0], scope, reason, "CONSOLE", parsedBanDuration))); @@ -315,7 +307,7 @@ public class Ban implements CommandExecutor { } } - private void createPlayerKickJob(IPBan b, String scope){ + private void createPlayerKickJob(PlayerBan b, String scope){ final Gson gson = new Gson(); try { Connection conn = plugin.db.getConnection(); @@ -324,7 +316,6 @@ public class Ban implements CommandExecutor { JsonObject wrapper = new JsonObject(); wrapper.addProperty("ban_type", "player"); wrapper.addProperty("ban_scope", scope); - wrapper.add("ban_data", banObject); String json = gson.toJson(wrapper); diff --git a/src/main/java/net/kuraczyk/banhammer/cmds/BanIP.java b/src/main/java/net/kuraczyk/banhammer/cmds/BanIP.java index 169e3b1..3a7c5cd 100644 --- a/src/main/java/net/kuraczyk/banhammer/cmds/BanIP.java +++ b/src/main/java/net/kuraczyk/banhammer/cmds/BanIP.java @@ -123,10 +123,7 @@ public class BanIP implements CommandExecutor { if(b != null) { if(banEndDate == null) { - for(Player target : Bukkit.getOnlinePlayers()) { - if (target.getAddress().getAddress().equals(addr)) - if(Objects.equals(plugin.config.getString("serverID"), scope) || Objects.equals(scope, "*")) target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanPerm"), b))); - } + createIPKickJob(b, scope); p.sendMessage(TextUtils.colorString(resolveIpBanMessagePlaceholders(addPrefix(plugin.translations.getString("command.banip.successfulBanMessagePerm")), args[0], scope, reason, p.getName()))); String bcMess = plugin.translations.getString("command.banip.banPublicAnnouncementPerm"); if(bcMess!=null) Bukkit.broadcast(TextUtils.colorString(resolveIpBanMessagePlaceholders(bcMess, args[0], scope, reason, p.getName()))); @@ -142,11 +139,7 @@ public class BanIP implements CommandExecutor { long timeLeftSeconds = TimeUnit.MILLISECONDS.toSeconds(timeLeft); String parsedBanDuration = TextUtils.parsePolishDate(timeLeftDays, timeLeftHours, timeLeftMinutes, timeLeftSeconds); - for(Player target : Bukkit.getOnlinePlayers()) { - if (target.getAddress().getAddress().equals(addr)) - if (Objects.equals(plugin.config.getString("serverID"), scope) || Objects.equals(scope, "*")) - target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanTemp"), b))); - } + createIPKickJob(b, scope); p.sendMessage(TextUtils.colorString(resolveIpBanMessagePlaceholders(addPrefix(plugin.translations.getString("command.banip.successfulBanMessageTemp")), args[0], scope, reason, p.getName(), parsedBanDuration))); String bcMess = plugin.translations.getString("command.banip.banPublicAnnouncementTemp"); if(bcMess!=null) Bukkit.broadcast(TextUtils.colorString(resolveIpBanMessagePlaceholders(bcMess, args[0], scope, reason, p.getName(), parsedBanDuration))); @@ -245,10 +238,7 @@ public class BanIP implements CommandExecutor { if(b != null) { if(banEndDate == null) { - for(Player target : Bukkit.getOnlinePlayers()) { - if (target.getAddress().getAddress().equals(addr)) - if(Objects.equals(plugin.config.getString("serverID"), scope) || Objects.equals(scope, "*")) target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanPerm"), b))); - } + createIPKickJob(b, scope); Bukkit.getConsoleSender().sendMessage(TextUtils.colorString(resolveIpBanMessagePlaceholders(addPrefix(plugin.translations.getString("command.banip.successfulBanMessagePerm")), args[0], scope, reason, "CONSOLE"))); String bcMess = plugin.translations.getString("command.banip.banPublicAnnouncementPerm"); if(bcMess!=null) Bukkit.broadcast(TextUtils.colorString(resolveIpBanMessagePlaceholders(bcMess, args[0], scope, reason, "CONSOLE"))); @@ -264,11 +254,7 @@ public class BanIP implements CommandExecutor { long timeLeftSeconds = TimeUnit.MILLISECONDS.toSeconds(timeLeft); String parsedBanDuration = TextUtils.parsePolishDate(timeLeftDays, timeLeftHours, timeLeftMinutes, timeLeftSeconds); - for(Player target : Bukkit.getOnlinePlayers()) { - if (target.getAddress().getAddress().equals(addr)) - if (Objects.equals(plugin.config.getString("serverID"), scope) || Objects.equals(scope, "*")) - target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanTemp"), b))); - } + createIPKickJob(b, scope); Bukkit.getConsoleSender().sendMessage(TextUtils.colorString(resolveIpBanMessagePlaceholders(addPrefix(plugin.translations.getString("command.banip.successfulBanMessageTemp")), args[0], scope, reason, "CONSOLE", parsedBanDuration))); String bcMess = plugin.translations.getString("command.banip.banPublicAnnouncementTemp"); if(bcMess!=null) Bukkit.broadcast(TextUtils.colorString(resolveIpBanMessagePlaceholders(bcMess, args[0], scope, reason, "CONSOLE", parsedBanDuration))); diff --git a/src/main/java/net/kuraczyk/banhammer/utils/IPBan.java b/src/main/java/net/kuraczyk/banhammer/utils/IPBan.java index adb6d68..f412d3e 100644 --- a/src/main/java/net/kuraczyk/banhammer/utils/IPBan.java +++ b/src/main/java/net/kuraczyk/banhammer/utils/IPBan.java @@ -17,4 +17,24 @@ public class IPBan { this.operator = operator; this.banId = banId; } + + public InetAddress getIp() { + return ip; + } + + public String getReason() { + return reason; + } + + public String getTimeLeft() { + return timeLeft; + } + + public String getOperator() { + return operator; + } + + public UUID getBanId() { + return banId; + } } diff --git a/src/main/java/net/kuraczyk/banhammer/utils/PlayerBan.java b/src/main/java/net/kuraczyk/banhammer/utils/PlayerBan.java index 7172850..88060b5 100644 --- a/src/main/java/net/kuraczyk/banhammer/utils/PlayerBan.java +++ b/src/main/java/net/kuraczyk/banhammer/utils/PlayerBan.java @@ -2,6 +2,7 @@ package net.kuraczyk.banhammer.utils; import org.bukkit.entity.Player; +import java.net.InetAddress; import java.sql.Timestamp; import java.util.UUID; @@ -22,4 +23,28 @@ public class PlayerBan { this.banId = banId; } + public String getPlayerName() { + return playerName; + } + + public UUID getPlayerUUID() { + return uuid; + } + + public String getReason() { + return reason; + } + + public String getTimeLeft() { + return timeLeft; + } + + public String getOperator() { + return operator; + } + + public UUID getBanId() { + return banId; + } + } \ No newline at end of file diff --git a/src/main/java/net/kuraczyk/banhammer/workers/BanJobWorker.java b/src/main/java/net/kuraczyk/banhammer/workers/BanJobWorker.java index 48566c0..2a68639 100644 --- a/src/main/java/net/kuraczyk/banhammer/workers/BanJobWorker.java +++ b/src/main/java/net/kuraczyk/banhammer/workers/BanJobWorker.java @@ -1,24 +1,126 @@ package net.kuraczyk.banhammer.workers; import net.kuraczyk.banhammer.BanHammer; +import net.kuraczyk.banhammer.utils.IPBan; +import net.kuraczyk.banhammer.utils.PlayerBan; +import net.kuraczyk.banhammer.utils.TextUtils; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.postgresql.PGConnection; +import org.postgresql.PGNotification; + +import javax.swing.plaf.nimbus.State; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Objects; + +import com.google.gson.*; public class BanJobWorker { BanHammer plugin; - public void BanJobWorker(BanHammer p) { + public BanJobWorker(BanHammer p) { plugin=p; banJobListener(); } private void banJobListener() { + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> { + try { + Connection conn = plugin.db.getConnection(); + PGConnection pgConn = conn.unwrap(PGConnection.class); + try (Statement stmt = conn.createStatement()) { + stmt.execute("LISTEN ban_jobs"); + } + + while (!conn.isClosed()){ + try (Statement ping = conn.createStatement()) { + ping.execute("SELECT 1"); + } + + PGNotification[] notifications = pgConn.getNotifications(); + + if(notifications!=null){ + for(PGNotification notif : notifications){ + JsonObject unwrappedJson = JsonParser.parseString(notif.getParameter()).getAsJsonObject(); + String banType = unwrappedJson.get("ban_type").getAsString(); + String banScope = unwrappedJson.get("ban_scope").getAsString(); + JsonElement banData = unwrappedJson.get("ban_data"); + + if(banScope.equals("*") || banScope.equals(plugin.config.getString("serverID"))){ + if(banJobExecutor(banType, banData)) plugin.getLogger().info(String.format("[BanHammer] Job %d has been executed successfully!", notif.getPID())); + else plugin.getLogger().severe("[BanHammer] Error occured while executing ban job!"); + } + + } + } + } + + } catch (SQLException e) { + plugin.getLogger().severe(e.toString()); + } + }); } - private boolean banJobExecutor() { - + private boolean banJobExecutor(String type, JsonElement banData) { + final Gson gson = new Gson(); + switch(type){ + case "player" -> { + PlayerBan ban = gson.fromJson(banData, PlayerBan.class); + handlePlayerBanJob(ban); + } + case "ip" -> { + IPBan ban = gson.fromJson(banData, IPBan.class); + handleIPBanJob(ban); + } + default -> { + plugin.getLogger().severe("[BanHammer] (BanJobExecutorException) Unexpected ban type provided."); + return false; + } + } + return true; } + private boolean handlePlayerBanJob(PlayerBan b) { + Player target = Bukkit.getPlayer(b.getPlayerName()); + if(target!=null) + if(target.isOnline()) { + if(b.getTimeLeft()!=null){ + plugin.getServer().getScheduler().runTask(plugin, () -> { + target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanTemp"), b))); + }); + return true; + } + plugin.getServer().getScheduler().runTask(plugin, () -> { + target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanPerm"), b))); + }); + return true; + } + return false; + } -} + private boolean handleIPBanJob(IPBan b) { + for(Player target : Bukkit.getOnlinePlayers()) { + if (target.getAddress().getAddress().equals(b.getIp())) { + if (b.getTimeLeft() != null) { + plugin.getServer().getScheduler().runTask(plugin, () -> { + target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanTemp"), b))); + }); + return true; + } + plugin.getServer().getScheduler().runTask(plugin, () -> { + target.kick(TextUtils.colorString(TextUtils.resolvePlaceholders(plugin.translations.getString("banKickMessage.playerBanPerm"), b))); + }); + return true; + } + } + + return false; + } + +} \ No newline at end of file