diff --git a/make_jar.jardesc b/make_jar.jardesc index 91fbdfa..7aff601 100644 --- a/make_jar.jardesc +++ b/make_jar.jardesc @@ -1,6 +1,6 @@ - + diff --git a/resources/config.yml b/resources/config.yml index d97b7ac..888f7bf 100644 --- a/resources/config.yml +++ b/resources/config.yml @@ -68,5 +68,17 @@ networkAPI: - - +modo: + # en seconde + durationLimit: + low: 43200 + normal: 1209600 + jailsPosition: + world: Survival + x: -1046.5 + y: 32 + z: 314.5 + jailWalls: + width: 3 + height: 3 + direction: WEST diff --git a/resources/plugin.yml b/resources/plugin.yml index 75c9559..40ce909 100644 --- a/resources/plugin.yml +++ b/resources/plugin.yml @@ -1,6 +1,6 @@ name: PandacraftUtils main: net.mc_pandacraft.java.plugin.pandacraftutils.PandacraftUtils -version: 3.14 +version: 3.15 @@ -189,6 +189,21 @@ permissions: default: op +#### à ajouter + pandacraft.modo: + description: Utiliser la commande modo + default: op + pandacraft.modo.low: + description: Utiliser un bas niveau de sanction + default: op + pandacraft.modo.normal: + description: Utiliser un niveau moyen de sanction + default: op + pandacraft.modo.high: + description: Utiliser les plus hauts niveau de sanction + default: op + + pandacraft.antispam.exempt: description: Ignoré par le système anti-spam diff --git a/src/net/mc_pandacraft/java/plugin/pandacraftutils/PandacraftUtils.java b/src/net/mc_pandacraft/java/plugin/pandacraftutils/PandacraftUtils.java index 9bbaec3..fe67c2f 100644 --- a/src/net/mc_pandacraft/java/plugin/pandacraftutils/PandacraftUtils.java +++ b/src/net/mc_pandacraft/java/plugin/pandacraftutils/PandacraftUtils.java @@ -7,6 +7,7 @@ import net.mc_pandacraft.java.plugin.pandacraftutils.config.ConfigManager; import net.mc_pandacraft.java.plugin.pandacraftutils.modules.AutoMessagesManager; import net.mc_pandacraft.java.plugin.pandacraftutils.modules.CalculatorManager; import net.mc_pandacraft.java.plugin.pandacraftutils.modules.CommandAliasManager; +import net.mc_pandacraft.java.plugin.pandacraftutils.modules.JailsManager; import net.mc_pandacraft.java.plugin.pandacraftutils.modules.LoginLogoutMessageManager; import net.mc_pandacraft.java.plugin.pandacraftutils.modules.PacketOutServerInfoListener; import net.mc_pandacraft.java.plugin.pandacraftutils.modules.SpawnTimeManager; @@ -78,6 +79,7 @@ public class PandacraftUtils extends JavaPlugin { public TamedEntityProtectManager tamedEntityProtectManager; public WorldBorderManager worldBorderManager; public HeartThrowManager heartThrowManager; + public JailsManager jailsManager; @@ -126,6 +128,7 @@ public class PandacraftUtils extends JavaPlugin { tamedEntityProtectManager = new TamedEntityProtectManager(); worldBorderManager = new WorldBorderManager(); heartThrowManager = new HeartThrowManager(); + jailsManager = new JailsManager(); NetworkAPI.loadNewInstance(); @@ -170,6 +173,7 @@ public class PandacraftUtils extends JavaPlugin { tamedEntityProtectManager = null; worldBorderManager = null; heartThrowManager = null; + jailsManager = null; instance = null; diff --git a/src/net/mc_pandacraft/java/plugin/pandacraftutils/commands/AbstractCommandExecutor.java b/src/net/mc_pandacraft/java/plugin/pandacraftutils/commands/AbstractCommandExecutor.java index 69797ec..4d1d06d 100644 --- a/src/net/mc_pandacraft/java/plugin/pandacraftutils/commands/AbstractCommandExecutor.java +++ b/src/net/mc_pandacraft/java/plugin/pandacraftutils/commands/AbstractCommandExecutor.java @@ -1,5 +1,6 @@ package net.mc_pandacraft.java.plugin.pandacraftutils.commands; +import org.apache.commons.lang.StringUtils; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -40,6 +41,13 @@ import net.mc_pandacraft.java.plugin.pandacraftutils.PandacraftUtils; } + public static String getLastParam(String[] args, int index) { + if (index < 0 || index >= args.length) + return null; + + + return StringUtils.join(args, " ", index, args.length); + } } diff --git a/src/net/mc_pandacraft/java/plugin/pandacraftutils/commands/CommandModo.java b/src/net/mc_pandacraft/java/plugin/pandacraftutils/commands/CommandModo.java index 22044c4..548f5bd 100644 --- a/src/net/mc_pandacraft/java/plugin/pandacraftutils/commands/CommandModo.java +++ b/src/net/mc_pandacraft/java/plugin/pandacraftutils/commands/CommandModo.java @@ -1,7 +1,28 @@ package net.mc_pandacraft.java.plugin.pandacraftutils.commands; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; + +import net.mc_pandacraft.java.plugin.pandacraftutils.config.ConfigManager; +import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.ModoHistoryElement; +import net.mc_pandacraft.java.plugin.pandacraftutils.data_model.ModoHistoryElement.ActionType; +import net.mc_pandacraft.java.plugin.pandacraftutils.players.OnlinePlayer; +import net.mc_pandacraft.java.plugin.pandacraftutils.players.OnlinePlayerManager; +import net.mc_pandacraft.java.plugin.pandacraftutils.plugin_interface.EssentialsInterface; +import net.mc_pandacraft.java.util.TimeUtil; + +import org.bukkit.BanList.Type; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import com.earth2me.essentials.User; +import com.earth2me.essentials.utils.DateUtil; public class CommandModo extends AbstractCommandExecutor { @@ -17,7 +38,824 @@ public class CommandModo extends AbstractCommandExecutor { - return false; + // affichage de l'aide + if (args.length <= 1) { + + int page = 1; + + if (args.length == 1) + try { + page = Integer.parseInt(args[0]); + } catch (NumberFormatException e) { } + + showHelp(sender, page); + + return true; + + } + + + + /* + * report + */ + + if (args.length >= 3 && args[0].equalsIgnoreCase("report")) { + String player = args[1]; + + String message = getLastParam(args, 2); + + onCommandReport(sender, player, message); + + return true; + + } + + /* + * jails + */ + + if (args.length >= 1 && args[0].equalsIgnoreCase("report")) { + + if (!(sender instanceof Player)) + { + sender.sendMessage(ChatColor.RED+"Vous devez être en ligne pour faire cette sous-commande"); + return true; + } + + onCommandJails((Player) sender); + + return true; + } + + /* + * amende + */ + if (args.length >= 4 && args[0].equalsIgnoreCase("amende")) { + + String player = args[1]; + + long somme = 0; + + try { + somme = Long.parseLong(args[2]); + } catch(NumberFormatException e) { + sender.sendMessage(ChatColor.RED+"La somme d'argent à retirer n'est pas valide"); + return true; + } + + String message = getLastParam(args, 3); + + onCommandAmende(sender, player, somme, message); + + return true; + } + + /* + * kick + */ + if (args.length >= 3 && args[0].equalsIgnoreCase("kick")) { + String player = args[1]; + + String message = getLastParam(args, 2); + + onCommandKick(sender, player, message); + + return true; + + } + + /* + * ban + */ + if (args.length >= 4 && args[0].equalsIgnoreCase("ban")) { + + String player = args[1]; + + long duree; + + try { + duree = Math.round((DateUtil.parseDateDiff(args[2], true)-System.currentTimeMillis())/1000D); + } catch(Exception e) { + // l'exception est généré par Essentials, qui rend le message User Friendly + sender.sendMessage(ChatColor.RED+e.getMessage()); + return true; + } + + String message = getLastParam(args, 3); + + onCommandBan(sender, player, duree, message); + + return true; + } + + /* + * unban + */ + if (args.length >= 3 && args[0].equalsIgnoreCase("unban")) { + String player = args[1]; + + String message = getLastParam(args, 2); + + onCommandUnban(sender, player, message); + + return true; + + } + + /* + * mute + */ + if (args.length >= 4 && args[0].equalsIgnoreCase("mute")) { + + String player = args[1]; + + long duree; + + try { + duree = Math.round((DateUtil.parseDateDiff(args[2], true)-System.currentTimeMillis())/1000D); + } catch(Exception e) { + // l'exception est généré par Essentials, qui rend le message User Friendly + sender.sendMessage(ChatColor.RED+e.getMessage()); + return true; + } + + String message = getLastParam(args, 3); + + onCommandMute(sender, player, duree, message); + + return true; + } + + /* + * unmute + */ + if (args.length >= 3 && args[0].equalsIgnoreCase("unmute")) { + String player = args[1]; + + String message = getLastParam(args, 2); + + onCommandUnmute(sender, player, message); + + return true; + + } + + /* + * jail + */ + if (args.length >= 4 && args[0].equalsIgnoreCase("jail")) { + + String player = args[1]; + + long duree; + + try { + duree = Math.round((DateUtil.parseDateDiff(args[2], true)-System.currentTimeMillis())/1000D); + } catch(Exception e) { + // l'exception est généré par Essentials, qui rend le message User Friendly + sender.sendMessage(ChatColor.RED+e.getMessage()); + return true; + } + + String message = getLastParam(args, 3); + + onCommandJail(sender, player, duree, message); + + return true; + } + + /* + * unjail + */ + if (args.length >= 3 && args[0].equalsIgnoreCase("unmute")) { + String player = args[1]; + + String message = getLastParam(args, 2); + + onCommandUnjail(sender, player, message); + + return true; + + } + + + + + + + + return true; } + + + + + + + + + + + + + + + + + + + + + + + + private void onCommandReport(CommandSender sender, String player, String message) { + + player = getRealNameIfWasAlreadyOnline(player); + + if (player == null) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué n'existe pas"); + return; + } + + ModoHistoryElement historyEl = new ModoHistoryElement(sender.getName(), ActionType.REPORT, player, message); + historyEl.save(); + + broadcastModoMessage(sender.getName(), " viens de report ", player, " pour ", message); + } + + + + + private void onCommandJails(Player sender) { + + Vector v = ConfigManager.getInstance().defaultConfig.modo_jailsPosition_coords; + World w = plugin.getServer().getWorld(ConfigManager.getInstance().defaultConfig.modo_jailsPosition_world); + + sender.teleport(new Location(w, v.getX(), v.getY(), v.getZ())); + } + + + + + + private void onCommandAmende(CommandSender sender, String player, long somme, String message) { + + if (!hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.HIGH)) { + sender.sendMessage(ChatColor.RED+"Vous n'avez pas le niveau de permission suffisant pour exécuter cette sous-commande"); + return; + } + + player = getRealNameIfWasAlreadyOnline(player); + + if (player == null) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué n'existe pas"); + return; + } + + + User u = EssentialsInterface.getPlugin().getOfflineUser(player); + + if (u.isAuthorized("pandacraft.modo") && !hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.HIGH)) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué est protégé contre les sanctions"); + return; + } + + if (somme < 0) { + sender.sendMessage(ChatColor.RED+"La somme indiquée doit être positive"); + return; + } + + double actualMoney = u.getMoney().doubleValue(); + long moneyToRemove = somme; + + if (somme > actualMoney) { + moneyToRemove = (long) actualMoney; + double newMoney = actualMoney - moneyToRemove; + u.setMoney(new BigDecimal(newMoney)); + + message = message + " (manque "+(somme - moneyToRemove)+" P à retirer)"; + + ModoHistoryElement historyEl = new ModoHistoryElement(sender.getName(), ActionType.MONEY, player, message); + historyEl.setValue(moneyToRemove); + historyEl.save(); + + } + else { + double newMoney = actualMoney - moneyToRemove; + u.setMoney(new BigDecimal(newMoney)); + + ModoHistoryElement historyEl = new ModoHistoryElement(sender.getName(), ActionType.MONEY, player, message); + historyEl.setValue(somme); + historyEl.save(); + } + + + broadcastModoMessage(sender.getName(), " viens d'appliquer une amende de ", String.valueOf(moneyToRemove), "P à ", player, " pour ", message); + + } + + + + + private void onCommandKick(CommandSender sender, String player, String message) { + + if (!hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.LOW)) { + sender.sendMessage(ChatColor.RED+"Vous n'avez pas le niveau de permission suffisant pour exécuter cette sous-commande"); + return; + } + + + Player p = plugin.getServer().getPlayer(player); + + if (p == null || !p.isOnline() || (sender instanceof Player && !((Player)sender).canSee(p))) { // la dernière condition protège les joueurs vanish + sender.sendMessage(ChatColor.RED+"Le joueur indiqué n'est pas en ligne"); + return; + } + + if (p.hasPermission("pandacraft.modo") && !hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.HIGH)) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué est protégé contre les sanctions"); + return; + } + + + + player = p.getName(); + + + p.kickPlayer(message); + + ModoHistoryElement historyEl = new ModoHistoryElement(sender.getName(), ActionType.KICK, player, message); + historyEl.save(); + + broadcastModoMessage(sender.getName(), " viens d'expulser ", player, " pour ", message); + + + } + + + + + + /** + * @param duration en seconde + */ + private void onCommandBan(CommandSender sender, String player, long duration, String message) { + // vérification des droits d'exécution + if (!hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.LOW)) { + sender.sendMessage(ChatColor.RED+"Vous n'avez pas le niveau de permission suffisant pour exécuter cette sous-commande"); + return; + } + + // vérification du joueur indiqué + player = getRealNameIfWasAlreadyOnline(player); + + if (player == null) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué n'existe pas"); + return; + } + + User u = EssentialsInterface.getPlugin().getOfflineUser(player); + + // on vérifie si le joueur est protégé contre les sanctions + if (u.isAuthorized("pandacraft.modo") && !hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.HIGH)) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué est protégé contre les sanctions"); + return; + } + // on vérifie si le joueur est déjà banni + if (plugin.getServer().getBanList(Type.NAME).isBanned(player)) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué est déjà banni"); + return; + } + + + // vérification des droits sur la durée + duration = correctPermittedDuration(sender, duration); + + Date expire = new Date(System.currentTimeMillis()+(duration*1000)); + + // application de la sanction + plugin.getServer().getBanList(Type.NAME).addBan(player, message, expire, sender.getName()); + + // enregistrement de l'action + ModoHistoryElement historyEl = new ModoHistoryElement(sender.getName(), ActionType.BAN, player, message); + historyEl.setValue(duration); + historyEl.save(); + + // diffusion + broadcastModoMessage(sender.getName(), " viens de bannir ", player, " pendant ", TimeUtil.durationToString(duration*1000), " pour ", message); + + } + + + + + + + private void onCommandUnban(CommandSender sender, String player, String message) { + // vérification des droits d'exécution + if (!hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.LOW)) { + sender.sendMessage(ChatColor.RED+"Vous n'avez pas le niveau de permission suffisant pour exécuter cette sous-commande"); + return; + } + + /* on a pas besoin de vérifier si le joueur a déjà existé, car c'est + * forcément le cas, si le joueur a déjà été banni + */ + + // on vérifie si le joueur est déjà banni + if (!plugin.getServer().getBanList(Type.NAME).isBanned(player)) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué n'est pas banni"); + return; + } + + // application du retrait de sanction + plugin.getServer().getBanList(Type.NAME).pardon(player); + + // enregistrement de l'action + ModoHistoryElement historyEl = new ModoHistoryElement(sender.getName(), ActionType.UNBAN, player, message); + historyEl.save(); + + // diffusion + broadcastModoMessage(sender.getName(), " viens de débannir ", player, " pour ", message); + + } + + + + + + + + + + + /** + * @param duration en seconde + */ + private void onCommandMute(CommandSender sender, String player, long duration, String message) { + // vérification des droits d'exécution + if (!hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.LOW)) { + sender.sendMessage(ChatColor.RED+"Vous n'avez pas le niveau de permission suffisant pour exécuter cette sous-commande"); + return; + } + + // vérification du joueur indiqué + player = getRealNameIfWasAlreadyOnline(player); + + if (player == null) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué n'existe pas"); + return; + } + + User u = EssentialsInterface.getPlugin().getOfflineUser(player); + + // on vérifie si le joueur est protégé contre les sanctions + if (u.isAuthorized("pandacraft.modo") && !hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.HIGH)) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué est protégé contre les sanctions"); + return; + } + // on vérifie si le joueur est déjà mute + if (u.isMuted()) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué est déjà muet"); + return; + } + + + // vérification des droits sur la durée + duration = correctPermittedDuration(sender, duration); + + Date expire = new Date(System.currentTimeMillis()+(duration*1000)); + + // application de la sanction + u.setMuted(true); + u.setMuteTimeout(expire.getTime()); + + // enregistrement de l'action + ModoHistoryElement historyEl = new ModoHistoryElement(sender.getName(), ActionType.MUTE, player, message); + historyEl.setValue(duration); + historyEl.save(); + + // diffusion + broadcastModoMessage(sender.getName(), " viens de rendre muet ", player, " pendant ", TimeUtil.durationToString(duration*1000), " pour ", message); + + } + + + + + + + private void onCommandUnmute(CommandSender sender, String player, String message) { + // vérification des droits d'exécution + if (!hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.LOW)) { + sender.sendMessage(ChatColor.RED+"Vous n'avez pas le niveau de permission suffisant pour exécuter cette sous-commande"); + return; + } + + // vérification du joueur indiqué + player = getRealNameIfWasAlreadyOnline(player); + + if (player == null) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué n'existe pas"); + return; + } + + User u = EssentialsInterface.getPlugin().getOfflineUser(player); + + // on vérifie si le joueur est déjà mute + if (!u.isMuted()) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué n'est pas mute"); + return; + } + + // application du retrait de sanction + u.setMuted(false); + u.setMuteTimeout(0); + + // enregistrement de l'action + ModoHistoryElement historyEl = new ModoHistoryElement(sender.getName(), ActionType.UNMUTE, player, message); + historyEl.save(); + + // diffusion + broadcastModoMessage(sender.getName(), " viens de rendre la parole à ", player, " pour ", message); + + } + + + + + + + + + + + + + + /** + * @param duration en seconde + */ + private void onCommandJail(CommandSender sender, String player, long duration, String message) { + // vérification des droits d'exécution + if (!hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.LOW)) { + sender.sendMessage(ChatColor.RED+"Vous n'avez pas le niveau de permission suffisant pour exécuter cette sous-commande"); + return; + } + + // vérification du joueur indiqué + player = getRealNameIfWasAlreadyOnline(player); + + if (player == null) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué n'existe pas"); + return; + } + + User u = EssentialsInterface.getPlugin().getOfflineUser(player); + + // on vérifie si le joueur est protégé contre les sanctions + if (u.isAuthorized("pandacraft.modo") && !hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.HIGH)) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué est protégé contre les sanctions"); + return; + } + + + // vérification des droits sur la durée + duration = correctPermittedDuration(sender, duration); + + // application de la sanction + boolean ok = plugin.jailsManager.addJailedPlayer(u, message, duration); + + if (!ok) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué ne peut pas être emprisonné"); + return; + } + + // enregistrement de l'action + ModoHistoryElement historyEl = new ModoHistoryElement(sender.getName(), ActionType.JAIL, player, message); + historyEl.setValue(duration); + historyEl.save(); + + // diffusion + broadcastModoMessage(sender.getName(), " viens d'emprisonner ", player, " pendant ", TimeUtil.durationToString(duration*1000), " pour ", message); + + } + + + + + + + private void onCommandUnjail(CommandSender sender, String player, String message) { + // vérification des droits d'exécution + if (!hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.LOW)) { + sender.sendMessage(ChatColor.RED+"Vous n'avez pas le niveau de permission suffisant pour exécuter cette sous-commande"); + return; + } + + // vérification du joueur indiqué + player = getRealNameIfWasAlreadyOnline(player); + + if (player == null) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué n'existe pas"); + return; + } + + User u = EssentialsInterface.getPlugin().getOfflineUser(player); + + // application du retrait de sanction + boolean ok = plugin.jailsManager.removeJailedPlayer(u); + + if (!ok) { + sender.sendMessage(ChatColor.RED+"Le joueur indiqué ne peut pas être libéré (il n'est peut-être pas en prison)"); + return; + } + + // enregistrement de l'action + ModoHistoryElement historyEl = new ModoHistoryElement(sender.getName(), ActionType.UNJAIL, player, message); + historyEl.save(); + + // diffusion + broadcastModoMessage(sender.getName(), " viens de libérer ", player, " pour ", message); + + } + + + + + + + + + + + + + + + + + private void showHelp(CommandSender sender, int page) { + ArrayList s = new ArrayList(); + + s.add(ChatColor.GOLD+"-------- Assistant de modération --------"); + + + + if (page == 1) { + s.add(ChatColor.GOLD+"- Commandes sans sanction :"); + s.add(ChatColor.GRAY+"/modo report "+ChatColor.WHITE+" faire un rapport d'un joueur, sans appliquer de sanction"); + s.add(ChatColor.GRAY+"/modo jails"+ChatColor.WHITE+" aller à la prison"); + s.add(ChatColor.GOLD+"- Aide sur les sanctions :"); + s.add(ChatColor.GRAY+"/modo 2"+ChatColor.WHITE+" application d'une sanction"); + s.add(ChatColor.GRAY+"/modo 3"+ChatColor.WHITE+" retrait d'une sanction"); + s.add(ChatColor.GRAY+"/modo 4"+ChatColor.WHITE+" règles sur les sanctions"); + } + else if (page == 2) { + s.add(ChatColor.GOLD+"- Appliquer une sanction :"); + s.add(ChatColor.GRAY+"/modo jail "+ChatColor.WHITE+" emprisonner un pendant une en précisant la "); + s.add(ChatColor.GRAY+"/modo mute "+ChatColor.WHITE+" rendre muet un pendant une en précisant la "); + s.add(ChatColor.GRAY+"/modo ban "+ChatColor.WHITE+" bannir un pendant une en précisant la "); + s.add(ChatColor.GRAY+"/modo kick "+ChatColor.WHITE+" expulse un en précisant la "); + s.add(ChatColor.GRAY+"/modo amende "+ChatColor.WHITE+" expulse un en précisant la "); + } + else if (page == 3) { + s.add(ChatColor.GOLD+"- Retirer une sanction :"); + s.add(ChatColor.GRAY+"/modo unjail "+ChatColor.WHITE+" sortir de prison un en précisant la "); + s.add(ChatColor.GRAY+"/modo unmute "+ChatColor.WHITE+" rendre la parole à un en précisant la "); + s.add(ChatColor.GRAY+"/modo unban "+ChatColor.WHITE+" retirer le banissement d'un en précisant la "); + } + else if (page == 4) { + s.add(ChatColor.GOLD+"- Règles sur les sanctions :"); + s.add(ChatColor.WHITE+"- Certains membres du staff on plus ou moins de droits concernant les sanctions (durée de jail, ban et mute)"); + s.add(ChatColor.WHITE+"- Toutes les sanctions doivent être justifiées. Vous êtes obligé d'indiquer la raison de la sanction dans les commandes"); + s.add(ChatColor.WHITE+"- Toutes les actions dans la commande "+ChatColor.GRAY+"/modo"+ChatColor.WHITE+" sont enregistrées"); + s.add(ChatColor.WHITE+"- Rendez vous sur MineAdmin pour les autres règles de Modération"); + s.add(ChatColor.WHITE+"- Rendez vous sur le site web de Pandacraft pour le règlement du serveur et les sanctions à appliquer"); + } + else { + s.add(ChatColor.GOLD+"La page "+page+" n'existe pas"); + } + + s.add(ChatColor.GOLD+"------------------------------------------"); + + sender.sendMessage(s.toArray(new String[s.size()])); + } + + + + + + + + + + + + private long correctPermittedDuration(CommandSender sender, long duration) { + + if (!hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.NORMAL) && duration > ConfigManager.getInstance().defaultConfig.modo_durationLimit_low) { + duration = ConfigManager.getInstance().defaultConfig.modo_durationLimit_low; + sender.sendMessage(ChatColor.RED+"Vous n'avez pas le niveau de permission suffisant pour sanctionner sur une durée aussi longue"); + sender.sendMessage(ChatColor.RED+"La durée a été réduite à" + TimeUtil.durationToString(duration*1000)); + } + + else if (!hasCommandSenderPermissionLevel(sender, ModoPermissionLevel.HIGH) && duration > ConfigManager.getInstance().defaultConfig.modo_durationLimit_normal) { + duration = ConfigManager.getInstance().defaultConfig.modo_durationLimit_normal; + sender.sendMessage(ChatColor.RED+"Vous n'avez pas le niveau de permission suffisant pour sanctionner sur une durée aussi longue"); + sender.sendMessage(ChatColor.RED+"La durée a été réduite à" + TimeUtil.durationToString(duration*1000)); + } + + return duration; + } + + + + + + + /** + * Retourne le nom du joueur avec la casse corrigée, ou null si le joueur n'est pas dans les données Essentials + * @param player + * @return le pseudo corrigé ou null + */ + protected String getRealNameIfWasAlreadyOnline(String player) { + + User u = EssentialsInterface.getPlugin().getOfflineUser(player); + + if (u == null) { + return null; + } + + return u.getName(); // correction du nom (majuscule) si Essentials effectue une correction + + } + + + + /** + * Diffuse un message destiné au staff ayant les droits de modération.
+ * Ce message est préfixé de [Modération].
+ * Les 1er, 3ème, 5ème, ... paramètres sont colorés en gris, et 2ème, 4ème, 6ème, ... paramètres + * sont colorés en blanc. Ces paramètres sont ensuite concaténé pour former le message final. + * @param messages + */ + protected void broadcastModoMessage(String ... messages) { + boolean colorToggle = true; + StringBuilder sb = new StringBuilder(); + for (String message : messages) { + sb.append(colorToggle?ChatColor.GRAY:ChatColor.RESET); + + sb.append(message); + + colorToggle = !colorToggle; + } + plugin.broadcast("["+ChatColor.GREEN+"Modération"+ChatColor.RESET+"] "+sb.toString(), false, true, "pandacraft.modo"); + } + + + + + + protected ModoPermissionLevel getPermissionLevel(OnlinePlayer op) { + if (op == null) return null; + + ModoPermissionLevel highestLevel = null; + + for (ModoPermissionLevel level : ModoPermissionLevel.values()) { + if (op.hasPermission("pandacrat.modo."+level.name().toLowerCase())) + if (highestLevel == null || level.level >= highestLevel.level) + highestLevel = level; + } + + return highestLevel; + + + } + + + protected boolean hasCommandSenderPermissionLevel(CommandSender sender, ModoPermissionLevel level) { + if (sender == null || level == null) return false; + if (!(sender instanceof Player)) return true; + OnlinePlayer op = OnlinePlayerManager.get((Player)sender); + ModoPermissionLevel levelPlayer = getPermissionLevel(op); + return (levelPlayer != null && (levelPlayer.level >= level.level)); + } + + + + + public enum ModoPermissionLevel{ + HIGH(2), NORMAL(1), LOW(0); + + private ModoPermissionLevel(int l) { + level = l; + } + + public final int level; + } + } diff --git a/src/net/mc_pandacraft/java/plugin/pandacraftutils/config/DefaultConfig.java b/src/net/mc_pandacraft/java/plugin/pandacraftutils/config/DefaultConfig.java index 236e5cd..2338a8f 100644 --- a/src/net/mc_pandacraft/java/plugin/pandacraftutils/config/DefaultConfig.java +++ b/src/net/mc_pandacraft/java/plugin/pandacraftutils/config/DefaultConfig.java @@ -5,7 +5,9 @@ import java.util.Collections; import java.util.List; import org.bukkit.ChatColor; +import org.bukkit.block.BlockFace; import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.util.Vector; import net.mc_pandacraft.java.plugin.pandacraftutils.PandacraftUtils; @@ -46,11 +48,11 @@ public class DefaultConfig { * Configuration analyse du chat et des messages privés * (antispam, insultes, publicité) */ - /** En milisecondes */ + /** En millisecondes */ public final long chatAnalysis_timeBeforeResendSameMessage; - /** En milisecondes */ + /** En millisecondes */ public final long chatAnalysis_timeBeforeResendSameCommand; - /** En milisecondes */ + /** En millisecondes */ public final long chatAnalysis_timePerCaracterForNewMessage; public final int chatAnalysis_maxViolationLevel; public final int chatAnalysis_nbSecondForOneVLDown; @@ -95,8 +97,19 @@ public class DefaultConfig { */ public final String networkAPI_pass; + /* + * Modération + */ + /** En seconde */ + public final long modo_durationLimit_low; + /** En seconde */ + public final long modo_durationLimit_normal; + public final String modo_jailsPosition_world; + public final Vector modo_jailsPosition_coords; - + public final BlockFace modo_jailWalls_direction; + public final int modo_jailWalls_width; + public final int modo_jailWalls_height; @@ -139,11 +152,11 @@ public class DefaultConfig { autoMessages_defaultInterval = configFile.getInt("autoMessages.defaultInterval"); - serverMessages_defaultColor = getTransletedColorCode("serverMessages.defaultColor"); - serverMessages_prefix = getTransletedColorCode("serverMessages.prefix"); + serverMessages_defaultColor = getTranslatedColorCode("serverMessages.defaultColor"); + serverMessages_prefix = getTranslatedColorCode("serverMessages.prefix"); - pingMOTD = getTransletedColorCode("pingMOTD").replace("\\n", "\n"); + pingMOTD = getTranslatedColorCode("pingMOTD").replace("\\n", "\n"); entitySpam_worlds = getSplittedString("entitySpam.worlds", ";"); @@ -152,6 +165,17 @@ public class DefaultConfig { networkAPI_pass = configFile.getString("networkAPI.pass"); + + modo_durationLimit_low = configFile.getLong("modo.durationLimit.low"); + modo_durationLimit_normal = configFile.getLong("modo.durationLimit.normal"); + modo_jailsPosition_world = configFile.getString("modo.jailsPosition.world"); + modo_jailsPosition_coords = new Vector( + configFile.getDouble("modo.jailsPosition.x"), + configFile.getDouble("modo.jailsPosition.y"), + configFile.getDouble("modo.jailsPosition.z")); + modo_jailWalls_direction = BlockFace.valueOf(configFile.getString("modo.jailWalls.direction")); + modo_jailWalls_width = configFile.getInt("modo.jailWalls.width"); + modo_jailWalls_height = configFile.getInt("modo.jailWalls.height"); } @@ -168,7 +192,7 @@ public class DefaultConfig { return Collections.unmodifiableList(Arrays.asList(value.split(split))); } - private String getTransletedColorCode(String path) { + private String getTranslatedColorCode(String path) { return ChatColor.translateAlternateColorCodes('&', configFile.getString(path, "")); } } diff --git a/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/ModoHistoryElement.java b/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/ModoHistoryElement.java index 303f4cb..8ea8942 100644 --- a/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/ModoHistoryElement.java +++ b/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/ModoHistoryElement.java @@ -6,26 +6,26 @@ public class ModoHistoryElement extends SQLElement { private ActionType actionType; private long time; private String playerName; - private Long duration = null; + private Long value = null; private String message; - public ModoHistoryElement(String modo, ActionType type, long time, String player, String message) { + public ModoHistoryElement(String modo, ActionType type, String player, String message) { super("pandacraft_modo_history"); setModoName(modo); setActionType(type); - setTime(time); setPlayerName(player); setMessage(message); + time = System.currentTimeMillis(); } - ModoHistoryElement(int id, String modo, ActionType type, long time, String player, String message) { + ModoHistoryElement(int id, String modo, ActionType type, String player, String message) { super("pandacraft_modo_history", id); setModoName(modo); setActionType(type); - setTime(time); setPlayerName(player); setMessage(message); + time = System.currentTimeMillis(); } @Override @@ -35,7 +35,7 @@ public class ModoHistoryElement extends SQLElement { actionType.name(), String.valueOf(time), playerName, - (duration == null)?null:duration.toString(), + (value == null)?null:value.toString(), message }; } @@ -75,14 +75,21 @@ public class ModoHistoryElement extends SQLElement { } - - public long getDuration() { - return duration; + /** + * Retourne la durée de la sanction appliquée (en secondes), ou la somme d'argent retirée du compte + * @return + */ + public long getValue() { + return value; } - public void setDuration(Long duration) { - if (duration != null && duration.longValue() < 0) duration = null; - this.duration = duration; + /** + * Value correspond soit à la durée de la sanction appliquée (en secondes), soit à la valeur de l'amende appliquée + * @param value + */ + public void setValue(Long value) { + if (value != null && value.longValue() < 0) value = null; + this.value = value; } @@ -127,7 +134,7 @@ public class ModoHistoryElement extends SQLElement { public enum ActionType{ - TEMPBAN, MUTE, JAIL, REPORT, KICK, MONEY + BAN, UNBAN, MUTE, UNMUTE, JAIL, UNJAIL, REPORT, KICK, MONEY } } diff --git a/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/ModoHistoryTable.java b/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/ModoHistoryTable.java index 36ae286..2aba7ed 100644 --- a/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/ModoHistoryTable.java +++ b/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/ModoHistoryTable.java @@ -17,10 +17,10 @@ public class ModoHistoryTable extends SQLTable { protected String createTableParameters() { return "id INT AUTO_INCREMENT PRIMARY KEY," + "modoName VARCHAR(16) NOT NULL," - + "actionType ENUM('TEMPBAN', 'MUTE', 'JAIL', 'REPORT', 'KICK', 'MONEY') NOT NULL," + + "actionType ENUM('BAN', 'UNBAN', 'MUTE', 'UNMUTE', 'JAIL', 'UNJAIL', 'REPORT', 'KICK', 'MONEY') NOT NULL," + "time BIGINT NOT NULL," + "playerName VARCHAR(16) NOT NULL," - + "duration BIGINT NULL," + + "value BIGINT NULL," + "message VARCHAR(512) NOT NULL"; } @@ -30,10 +30,10 @@ public class ModoHistoryTable extends SQLTable { sqlResult.getInt("id"), sqlResult.getString("modoName"), ActionType.valueOf(sqlResult.getString("actionType")), - sqlResult.getLong("time"), sqlResult.getString("playerName"), sqlResult.getString("message")); - el.setDuration(sqlResult.getLong("duration")); + el.setValue(sqlResult.getLong("value")); + el.setTime(sqlResult.getLong("time")); return el; } diff --git a/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/SQLElement.java b/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/SQLElement.java index f6aaa84..858cc3b 100644 --- a/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/SQLElement.java +++ b/src/net/mc_pandacraft/java/plugin/pandacraftutils/data_model/SQLElement.java @@ -64,6 +64,7 @@ public abstract class SQLElement { } st.executeUpdate(); + st.close(); } else { // ajouter dans la base @@ -84,6 +85,7 @@ public abstract class SQLElement { } id = st.executeUpdate(); + st.close(); saved = true; } } catch (SQLException e) { diff --git a/src/net/mc_pandacraft/java/plugin/pandacraftutils/modules/JailsManager.java b/src/net/mc_pandacraft/java/plugin/pandacraftutils/modules/JailsManager.java new file mode 100644 index 0000000..78c7f83 --- /dev/null +++ b/src/net/mc_pandacraft/java/plugin/pandacraftutils/modules/JailsManager.java @@ -0,0 +1,309 @@ +package net.mc_pandacraft.java.plugin.pandacraftutils.modules; + +import java.sql.Date; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; + +import org.apache.commons.lang.WordUtils; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; + +import com.earth2me.essentials.User; +import com.earth2me.essentials.UserMap; + +import net.mc_pandacraft.java.plugin.pandacraftutils.PandacraftUtils; +import net.mc_pandacraft.java.plugin.pandacraftutils.config.ConfigManager; +import net.mc_pandacraft.java.plugin.pandacraftutils.plugin_interface.EssentialsInterface; + +public class JailsManager { + private PandacraftUtils plugin = PandacraftUtils.getInstance(); + + private List jails; + private Map jailedPlayers; + + + + public JailsManager() { + + // initialisation retardée (besoin des données d'un autre plugin) + plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable() { + @Override + public void run() { + updateDataFromEssentials(); + } + }, 50); + } + + + + + + + + + + /** + * En principe, cette méthone ne doit-être appelée qu'une seule fois, après le chargement + * du plugin Essentials + */ + private void updateDataFromEssentials() { + plugin.getLogger().info("[JailsManager] chargement des données de la prison depuis Essentials"); + try { + jails = new ArrayList(EssentialsInterface.getPlugin().getJails().getList()); + + // retirer les cellules qui n'ont pas la forme "cX" avec X un nombre + jails.removeIf(new Predicate() { + @Override public boolean test(String t) { + return t == null || !t.matches("c[0-9]+"); + } + }); + + // on trie les cellules, pour qu'elle se remplissent toujours dans le même ordre + Collections.sort(jails, new Comparator() { + @Override public int compare(String o1, String o2) { + try { + int i1 = Integer.parseInt(o1.substring(1)); + int i2 = Integer.parseInt(o2.substring(1)); + if (i1 < i2) return -1; + if (i1 > i2) return 1; + return 0; + } catch (NumberFormatException e) { return 0; } + } + }); + + UserMap um = EssentialsInterface.getPlugin().getUserMap(); + + Set users = um.getAllUniqueUsers(); + + jailedPlayers = new HashMap(); + + // on parcours les joueurs et on ajoute ceux qui sont emprisonnés, dans les données + for (String user : users) { + User u = um.getUser(user); + if (u.isJailed() && (u.getJailTimeout() == 0 || u.getJailTimeout() >= System.currentTimeMillis())) { + String jail = u.getJail(); + if (jails.contains(jail)) { + jailedPlayers.put(jail, new JailedPlayer(user, jail, null, u.getJailTimeout())); + + + } + } + } + + updateJailsSign(); + + } catch (Exception e) { + e.printStackTrace(); + } + plugin.getLogger().info("[JailsManager] chargement terminé"); + } + + + + + + + /** + * Emprisonne le joueur passé en paramètre. Les données Essentials sont mise + * à jour à l'appel de cette méthode. + * @param duree en seconde + */ + public boolean addJailedPlayer(User player, String raison, long duree) { + if (player.isJailed() && (player.getJailTimeout() == 0 || player.getJailTimeout() >= System.currentTimeMillis())) + return false; // le joueur est déjà en prison + + String jail = getFirstAvailableJail(); + + if (jail == null) + return false; // aucune cellule de libre + + player.setJailed(true); + player.setJail(jail); + player.setJailTimeout(System.currentTimeMillis()+duree*1000); + + jailedPlayers.put(jail, new JailedPlayer(player.getName(), jail, raison, System.currentTimeMillis()+duree*1000)); + + + updateJailsSign(); + + return true; + + } + + + + public boolean removeJailedPlayer(User player) { + if (!player.isJailed() || player.getJailTimeout() == 0 || player.getJailTimeout() < System.currentTimeMillis()) + return false; // le joueur n'est pas en prison + + String jail = player.getJail(); + + JailedPlayer jp = jailedPlayers.get(jail); + + if (jp == null || !jp.playerName.equalsIgnoreCase(player.getName())) + return false; // incohérence dans les données + + player.setJailed(false); + + jailedPlayers.remove(jail); + + updateJailsSign(); + + return true; + + } + + + + + private String getFirstAvailableJail() { + + // supprime d'abord les joueurs dont leur emprisonnement est expiré + for (String jail : jailedPlayers.keySet().toArray(new String[jailedPlayers.size()])) { + if (jailedPlayers.get(jail).timeout < System.currentTimeMillis()) + jailedPlayers.remove(jail); + } + + + + for (String j : jails) { + if (jailedPlayers.containsKey(j)) + continue; + return j; + } + return null; + } + + + + + + private void updateJailsSign() { + /* + * Disposition des panneaux : + * + * Raison : + * libéré(e) le + * + * + * + * La raison peut prendre plusieurs panneaux + */ + + + try { + + int wallWidth = ConfigManager.getInstance().defaultConfig.modo_jailWalls_width; + int wallHeight = ConfigManager.getInstance().defaultConfig.modo_jailWalls_height; + BlockFace wallDir = ConfigManager.getInstance().defaultConfig.modo_jailWalls_direction; + + + for (String jail : jails) { + + Location jailLoc = EssentialsInterface.getPlugin().getJails().getJail(jail); + + Block topLeftWallBloc = jailLoc.getBlock() + .getRelative(wallDir) + .getRelative(BlockFace.UP, wallHeight-1) + .getRelative(wallDir.getModZ(), 0, -wallDir.getModX()); + + // liste de tout les panneaux de la cellulre + Block[] blocks = new Block[wallWidth*wallHeight]; + int n = 0; + for (int i=0; i 15) ? player.substring(0, 15) : player; + + String raison = jp.reason; + raison = WordUtils.wrap(raison, 15, "\n", true); + + Date d = new Date(jp.timeout); + DateFormat date = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.FRANCE); + DateFormat hour = DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.FRANCE); + + String affDate = date.format(d) + " à " + hour.format(d); + affDate = WordUtils.wrap(affDate, 15, "\n", true); + + // TODO doooooooo + + } + + + + + + } + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + + + + + + + + + + + + + + + + public class JailedPlayer { + public final String playerName; + public final String jail; + /** + * Si cette valeur est nulle, on ne met pas à jour les panneaux + */ + public final String reason; + public final long timeout; + + public JailedPlayer(String n, String j, String r, long t) { + playerName = n; + jail = j; + reason = r; + timeout = t; + } + } + + + + +}