diff --git a/src/main/java/fr/communaywen/core/AywenCraftPlugin.java b/src/main/java/fr/communaywen/core/AywenCraftPlugin.java index 2908fbf7..88847c8a 100644 --- a/src/main/java/fr/communaywen/core/AywenCraftPlugin.java +++ b/src/main/java/fr/communaywen/core/AywenCraftPlugin.java @@ -16,6 +16,7 @@ import fr.communaywen.core.commands.explosion.ExplodeRandomCommand; import fr.communaywen.core.commands.explosion.FBoomCommand; import fr.communaywen.core.commands.fun.*; +import fr.communaywen.core.commands.staff.ReportCommands; import fr.communaywen.core.commands.utils.*; import fr.communaywen.core.commands.teleport.RTPCommand; import fr.communaywen.core.commands.teleport.SpawnCommand; @@ -193,7 +194,8 @@ public void onEnable() { new AdminShopCommand(), new PayCommands(), new FallBloodCommand(), - new DiscordCommand(this) + new DiscordCommand(this), + new ReportCommands() ); /* -------- */ diff --git a/src/main/java/fr/communaywen/core/Managers.java b/src/main/java/fr/communaywen/core/Managers.java index f4ea9ba7..e3592d2a 100644 --- a/src/main/java/fr/communaywen/core/Managers.java +++ b/src/main/java/fr/communaywen/core/Managers.java @@ -9,6 +9,7 @@ import fr.communaywen.core.levels.LevelsDataManager; import fr.communaywen.core.levels.LevelsManager; import fr.communaywen.core.scoreboard.ScoreboardManager; +import fr.communaywen.core.staff.report.ReportManager; import fr.communaywen.core.teams.Team; import fr.communaywen.core.teams.TeamManager; import fr.communaywen.core.utils.ConfigUtils; @@ -38,6 +39,7 @@ public class Managers { private FallingBlocksExplosionManager fbeManager; private LevelsManager levelsManager; private TransactionsManager transactionsManager; + private ReportManager reportManager; private FileConfiguration bookConfig; private FileConfiguration wikiConfig; @@ -89,15 +91,19 @@ public void init(AywenCraftPlugin plugin) { fbeManager = new FallingBlocksExplosionManager(); levelsManager = new LevelsManager(); transactionsManager = new TransactionsManager(); + reportManager = new ReportManager(); + reportManager.loadReports(); LevelsDataManager.setLevelsFile(levelsConfig, new File(plugin.getDataFolder(), "levels.yml")); LevelsDataManager.setLevelsFile(levelsConfig, new File(plugin.getDataFolder(), "levels.yml")); } public void cleanup() { + reportManager.saveReports(); databaseManager.close(); quizManager.close(); corpseManager.removeAll(); teamManager.getTeamCache().saveAllTeamsToDatabase(); + } } diff --git a/src/main/java/fr/communaywen/core/commands/staff/ReportCommands.java b/src/main/java/fr/communaywen/core/commands/staff/ReportCommands.java new file mode 100644 index 00000000..1f7c5370 --- /dev/null +++ b/src/main/java/fr/communaywen/core/commands/staff/ReportCommands.java @@ -0,0 +1,136 @@ +package fr.communaywen.core.commands.staff; + +import fr.communaywen.core.AywenCraftPlugin; +import fr.communaywen.core.staff.report.ReportManager; +import fr.communaywen.core.credit.Credit; +import fr.communaywen.core.credit.Feature; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import revxrsal.commands.annotation.*; +import revxrsal.commands.bukkit.annotation.CommandPermission; +import org.bukkit.ChatColor; +import java.sql.Timestamp; + + +@Feature("Report") +@Credit("rafael_trx") +@Command("report") +public class ReportCommands { + @DefaultFor("~") + @Description("Signale un joueur pour un motif spécifique") + @CommandPermission("ayw.command.report") + + public boolean report(CommandSender sender, @Named("Joueur") OfflinePlayer target, @Named("Motif") String reason) { + ReportManager reportManager = AywenCraftPlugin.getInstance().getManagers().getReportManager(); + + if (sender instanceof Player) { + Player player = (Player) sender; + String senderName = sender.getName(); + String reportedPlayer = target.getName(); + Timestamp currentTimestamp = new Timestamp(System.currentTimeMillis()); + + if (reportedPlayer.equals(senderName)) { + player.sendMessage("Vous ne pouvez pas vous signaler vous-même"); + return false; + } + if(reportManager.checkReportability(target)) { + if (reportManager.addReport(player, target, reason, currentTimestamp)) { + player.sendMessage("Vous avez signalé " + ChatColor.GREEN + reportedPlayer + ChatColor.WHITE + " pour : " + reason); + return true; + } + } + else{ + player.sendMessage("Votre dernier signalement de " + ChatColor.GREEN + reportedPlayer + ChatColor.WHITE + " est trop récent"); + } + } + else { + return false; + } + return false; + } + + @Subcommand("history") + @Description("Permet de voir son historique de signalement") + @CommandPermission("ayw.command.report") + + public boolean history(CommandSender sender) { + ReportManager reportManager = AywenCraftPlugin.getInstance().getManagers().getReportManager(); + + if (sender instanceof Player) { + Player player = (Player) sender; + + reportManager.seeHistory(player); + return true; + + } + else { + return false; + } + } + + + @Subcommand("see") + @Description("Consulte les signalements d'un joueur") + @CommandPermission("ayw.mods.report") + + public boolean see(CommandSender sender, @Named("Joueur") OfflinePlayer target) { + ReportManager reportManager = AywenCraftPlugin.getInstance().getManagers().getReportManager(); + if (sender instanceof Player) { + Player player = (Player) sender; + + reportManager.seeReports(player, target); + + return true; + } + else { + return false; + } + } + + + @Subcommand("toplist") + @Description("Affiche les 5 joueurs les plus signalés") + @CommandPermission("ayw.mods.report") + + public boolean toplist(CommandSender sender) { + ReportManager reportManager = AywenCraftPlugin.getInstance().getManagers().getReportManager(); + if (sender instanceof Player) { + Player player = (Player) sender; + + reportManager.topReports(player); + return true; + } + return false; + + } + + @Subcommand("clear") + @Description("Consulte les signalements d'un joueur") + @CommandPermission("ayw.mods.report") + + public boolean clear(CommandSender sender, @Named("Joueur") Player target) { + ReportManager reportManager = AywenCraftPlugin.getInstance().getManagers().getReportManager(); + if (sender instanceof Player) { + Player player = (Player) sender; + if(reportManager.clearReports(target)){ + player.sendMessage("Les signalements de " + player.getName() + " ont été supprimés"); + return true; + } + else { + return false; + } + + + } + else { + return false; + } + } + + + + +} + + diff --git a/src/main/java/fr/communaywen/core/staff/report/ReportCache.java b/src/main/java/fr/communaywen/core/staff/report/ReportCache.java new file mode 100644 index 00000000..c00d7fb3 --- /dev/null +++ b/src/main/java/fr/communaywen/core/staff/report/ReportCache.java @@ -0,0 +1,4 @@ +package fr.communaywen.core.staff.report; + +public class ReportCache { +} diff --git a/src/main/java/fr/communaywen/core/staff/report/ReportManager.java b/src/main/java/fr/communaywen/core/staff/report/ReportManager.java new file mode 100644 index 00000000..36595175 --- /dev/null +++ b/src/main/java/fr/communaywen/core/staff/report/ReportManager.java @@ -0,0 +1,179 @@ +package fr.communaywen.core.staff.report; + +import fr.communaywen.core.utils.database.DatabaseConnector; +import fr.communaywen.core.credit.Credit; +import fr.communaywen.core.credit.Feature; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.ChatColor; + +import java.sql.*; +import java.util.*; +import java.time.Instant; +import java.time.temporal.ChronoUnit; + +@Feature("Report") +@Credit("rafael_trx") + +public class ReportManager extends DatabaseConnector { + + private final Map> reportCache = new HashMap<>(); + + public class Report { + private final UUID sender; + private final UUID reported; + private final String reason; + private final Timestamp timestamp; + + public Report(UUID sender, UUID reported, String reason, Timestamp timestamp) { + this.sender = sender; + this.reported = reported; + this.reason = reason; + this.timestamp = timestamp; + } + + // Getters + public UUID getSender() { return sender; } + public UUID getReported() { return reported; } + public String getReason() { return reason; } + public Timestamp getTimestamp() { return timestamp; } + } + + public void loadReports() { + try { + PreparedStatement statement = connection.prepareStatement("SELECT * FROM reports"); + ResultSet rs = statement.executeQuery(); + while (rs.next()) { + UUID sender = UUID.fromString(rs.getString("sender")); + UUID reported = UUID.fromString(rs.getString("reported")); + String reason = rs.getString("reason"); + Timestamp timestamp = rs.getTimestamp("timestamp"); + + Report report = new Report(sender, reported, reason, timestamp); + reportCache.computeIfAbsent(reported, k -> new ArrayList<>()).add(report); + } + } catch (SQLException ignored) {} + } + + public void saveReports() { + try { + connection.setAutoCommit(false); + PreparedStatement deleteStatement = connection.prepareStatement("DELETE FROM reports"); + deleteStatement.executeUpdate(); + + PreparedStatement insertStatement = connection.prepareStatement("INSERT INTO reports (sender, reported, reason, timestamp) VALUES (?, ?, ?, ?)"); + for (List reports : reportCache.values()) { + for (Report report : reports) { + insertStatement.setString(1, report.getSender().toString()); + insertStatement.setString(2, report.getReported().toString()); + insertStatement.setString(3, report.getReason()); + insertStatement.setTimestamp(4, report.getTimestamp()); + insertStatement.addBatch(); + } + } + insertStatement.executeBatch(); + connection.commit(); + connection.setAutoCommit(true); + } catch (SQLException ignored) {} + } + + public boolean addReport(Player player, OfflinePlayer target, String reason, Timestamp timestamp) { + UUID senderUUID = player.getUniqueId(); + UUID targetUUID = target.getUniqueId(); + Report report = new Report(senderUUID, targetUUID, reason, timestamp); + + reportCache.computeIfAbsent(targetUUID, k -> new ArrayList<>()).add(report); + return true; + } + + public void seeHistory(Player player) { + UUID playerUUID = player.getUniqueId(); + List reports = reportCache.getOrDefault(playerUUID, new ArrayList<>()); + + if (reports.isEmpty()) { + player.sendMessage(" \nVous n'avez effectué aucun signalement"); + return; + } + + StringBuilder historyMessage = new StringBuilder("\nVos signalements : \n \n"); + for (Report report : reports) { + OfflinePlayer reportedPlayer = Bukkit.getOfflinePlayer(report.getReported()); + String reportedName = reportedPlayer.getName(); + + historyMessage.append("Vous avez signalé ").append(ChatColor.GREEN).append(reportedName).append(ChatColor.WHITE).append("\n") + .append("Motif : ").append(report.getReason()).append("\n") + .append("Date : ").append(report.getTimestamp()).append("\n") + .append("--------\n"); + } + player.sendMessage(historyMessage.toString()); + } + + public void seeReports(Player player, OfflinePlayer target) { + UUID targetUUID = target.getUniqueId(); + List reports = reportCache.getOrDefault(targetUUID, new ArrayList<>()); + + if (reports.isEmpty()) { + player.sendMessage(" \nAucun signalement pour " + ChatColor.GREEN + target.getName() + ChatColor.WHITE + " !"); + return; + } + + StringBuilder reportMessage = new StringBuilder("\nSignalements de " + ChatColor.GREEN + target.getName() + ChatColor.WHITE + " : \n \n"); + for (Report report : reports) { + OfflinePlayer senderPlayer = Bukkit.getOfflinePlayer(report.getSender()); + String senderName = senderPlayer.getName(); + + reportMessage.append("Signalé par : ").append(senderName).append("\n") + .append("Motif : ").append(report.getReason()).append("\n") + .append("Date : ").append(report.getTimestamp()).append("\n") + .append("--------\n"); + } + player.sendMessage(reportMessage.toString()); + } + + public void topReports(Player player) { + Map reportCount = new HashMap<>(); + for (List reports : reportCache.values()) { + for (Report report : reports) { + reportCount.put(report.getReported(), reportCount.getOrDefault(report.getReported(), 0) + 1); + } + } + + List> topReports = new ArrayList<>(reportCount.entrySet()); + topReports.sort((e1, e2) -> e2.getValue() - e1.getValue()); + + if (topReports.isEmpty()) { + player.sendMessage(" \nAucun joueur n'a de signalement ! "); + return; + } + + StringBuilder topReportMessage = new StringBuilder("\nTop des signalements : \n \n"); + for (int i = 0; i < Math.min(5, topReports.size()); i++) { + Map.Entry entry = topReports.get(i); + OfflinePlayer reportedPlayer = Bukkit.getOfflinePlayer(entry.getKey()); + String reportedName = reportedPlayer.getName(); + + topReportMessage.append("- ").append(ChatColor.GREEN).append(reportedName).append(ChatColor.WHITE).append(" - ") + .append(entry.getValue()).append(" signalement(s)\n"); + } + player.sendMessage(topReportMessage.toString()); + player.sendMessage("\n -------- \n"); + } + + public boolean clearReports(Player target) { + UUID targetUUID = target.getUniqueId(); + if (reportCache.containsKey(targetUUID)) { + reportCache.remove(targetUUID); + return true; + } + return false; + } + + public boolean checkReportability(OfflinePlayer target) { + UUID targetUUID = target.getUniqueId(); + List reports = reportCache.getOrDefault(targetUUID, new ArrayList<>()); + + Timestamp last24Hours = Timestamp.from(Instant.now().minus(24, ChronoUnit.HOURS)); + return reports.stream().noneMatch(report -> report.getTimestamp().after(last24Hours)); + } +} diff --git a/src/main/java/fr/communaywen/core/utils/database/DatabaseManager.java b/src/main/java/fr/communaywen/core/utils/database/DatabaseManager.java index 1467f10d..bf66a2d9 100644 --- a/src/main/java/fr/communaywen/core/utils/database/DatabaseManager.java +++ b/src/main/java/fr/communaywen/core/utils/database/DatabaseManager.java @@ -51,6 +51,10 @@ public void init() throws SQLException { this.getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS teams (teamName VARCHAR(16) NOT NULL PRIMARY KEY, owner VARCHAR(36) NOT NULL, balance BIGINT UNSIGNED, inventory LONGBLOB)").executeUpdate(); this.getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS transactions (recipient VARCHAR(36), sender VARCHAR(36), amount DOUBLE, reason VARCHAR(255), date TIMESTAMP DEFAULT CURRENT_TIMESTAMP)").executeUpdate(); + //Système de signalements + + this.getConnection().prepareStatement("CREATE TABLE `reports` (`sender` text NOT NULL,`reported` text NOT NULL,`reason` text NOT NULL,`timestamp` timestamp NOT NULL)"); + // Système de claims this.getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS claim (" + " claimID varchar(36) NOT NULL PRIMARY KEY," + @@ -68,7 +72,7 @@ public void init() throws SQLException { " balance double NOT NULL" + ")").executeUpdate(); - System.out.println("Les tables ont été créer si besoin"); + System.out.println("Les tables ont été créées si besoin"); } public void close() { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 06ea84b4..71c7bef0 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -54,4 +54,6 @@ permissions: default: true ayw.command.bandage: description: 'Donne un bandage' + ayw.command.report: + description: 'Permet de signaler un joueur'