Refactoring des classes de gestion de spam car elle vont servir pour le système de censure

This commit is contained in:
2014-11-24 19:21:06 +01:00
parent b2e47d1e2e
commit 22916afa05
4 changed files with 17 additions and 17 deletions

View File

@@ -0,0 +1,90 @@
package net.mc_pandacraft.java.plugin.pandacraftutils.chat_analyzer;
import net.mc_pandacraft.java.plugin.pandacraftutils.PandacraftUtils;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
public class ChatAnalysisManager implements Listener {
private ChatAnalysisPlayer[] aPlayers;
private PandacraftUtils plugin;
public ChatAnalysisManager(PandacraftUtils pl)
{
plugin = pl;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
aPlayers = new ChatAnalysisPlayer[plugin.getServer().getMaxPlayers()];
// analyse des joueurs déjà en ligne (/reload)
for (Player p : plugin.getServer().getOnlinePlayers())
onPlayerJoin(new PlayerJoinEvent(p, "")); // simule l'évènement d'arrivé d'un joueur, pour le rajouter
}
@EventHandler(priority=EventPriority.HIGHEST)
public void onAsyncPlayerChat(AsyncPlayerChatEvent event)
{
try {
getAPlayer(event.getPlayer()).onAsyncPlayerChat(event);
} catch (NullPointerException e) { }
}
@EventHandler(priority=EventPriority.HIGH)
public void onPlayerCommandPreprocess (PlayerCommandPreprocessEvent event)
{
try {
getAPlayer(event.getPlayer()).onPlayerCommandPreprocess(event);
} catch (NullPointerException e) { }
}
public ChatAnalysisPlayer getAPlayer(Player p)
{
if (p == null || !p.isOnline())
return null;
for (ChatAnalysisPlayer ap : aPlayers)
{
if (ap != null && ap.getPlayer() == p)
return ap;
}
return null;
}
@EventHandler
public void onPlayerJoin (PlayerJoinEvent event)
{
int i=0;
while (i<aPlayers.length && aPlayers[i] != null) i++;
if (aPlayers[i] == null) aPlayers[i] = new ChatAnalysisPlayer(plugin, event.getPlayer());
}
@EventHandler
public void onPlayerQuit (PlayerQuitEvent event)
{
for (int i=0; i<aPlayers.length; i++)
{
if (aPlayers[i] == null)
continue;
if (aPlayers[i].getPlayer() == event.getPlayer())
aPlayers[i] = null;
}
}
}

View File

@@ -0,0 +1,248 @@
package net.mc_pandacraft.java.plugin.pandacraftutils.chat_analyzer;
import net.mc_pandacraft.java.plugin.pandacraftutils.ConfigManager;
import net.mc_pandacraft.java.plugin.pandacraftutils.PandacraftUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.util.NumberConversions;
public class ChatAnalysisPlayer {
private long time_before_resend_same_message = ConfigManager.getInstance().AntiSpam_timeBeforeResendSameMessage;// 30 sec
private long time_before_resend_same_command = ConfigManager.getInstance().AntiSpam_timeBeforeResendSameCommand;// 30 sec
// définit si un message a été tapé super vite ou non
/* pour un message reçu, on prends la durée depuis le message précédent,
* et on le compare au produit de cette variable par le nombre de caractère du nouveau message
* */
private long time_per_caracter_for_new_message = ConfigManager.getInstance().AntiSpam_timePerCaracterForNewMessage;// 0.1 sec
private int max_violation_level = ConfigManager.getInstance().AntiSpam_maxViolationLevel;
private int nb_second_for_1_vl_down = ConfigManager.getInstance().AntiSpam_nbSecondForOneVLDown;
private Player player;
private PandacraftUtils plugin;
private String last_message = null;
private long last_message_time = 0;
private String last_command = null;
private long last_command_time = 0;
private int violation_level = 0;
public ChatAnalysisPlayer(PandacraftUtils pl, Player p)
{
player = p;
plugin = pl;
}
private void addVL(int nb)
{
violation_level += nb;
if (violation_level >= max_violation_level)
Bukkit.getScheduler().runTaskLater(plugin, new Runnable() {
@Override
public void run() {
player.kickPlayer("Ralentissez la cadance, les spams sont interdits !");
}
}, 1L);
}
private void removeVL(int nb)
{
violation_level -= nb;
if (violation_level < 0) violation_level = 0;
}
public int getVL() { return violation_level; }
public int getMaxVL() { return max_violation_level; }
public Player getPlayer() { return player; }
public void onAsyncPlayerChat(AsyncPlayerChatEvent event)
{
if (event.getPlayer() != player)
return;
if (event.getPlayer().hasPermission("pandacraft.antispam.exempt"))
return;
String message = event.getMessage();
long time = System.currentTimeMillis();
if (last_message != null)
{
if (last_message.equals(message) && time - last_message_time < time_before_resend_same_message)
{
event.getPlayer().sendMessage(ChatColor.RED+"Evitez de renvoyer le même message !");
if (violation_level >= max_violation_level/2)
event.setCancelled(true);
addVL(5);
return;
}
else
{
long time_since_last_message = time - last_message_time;
long timeout_needed = message.length() * time_per_caracter_for_new_message;
if (time_since_last_message < timeout_needed)
{
event.getPlayer().sendMessage(ChatColor.RED+"Vous parlez un peu trop vite, ralentissez x)");
addVL(4);
return;
}
}
}
message = analyseString(message);
event.setMessage(message);
removeVL(NumberConversions.floor(((time - last_message_time)/1000)/nb_second_for_1_vl_down));
last_message = message;
last_message_time = time;
}
public void onPlayerCommandPreprocess (PlayerCommandPreprocessEvent event)
{
if (event.getPlayer() != player)
return;
if (event.getPlayer().hasPermission("pandacraft.antispam.exempt"))
return;
String[] command_line = event.getMessage().split(" ");
long time = System.currentTimeMillis();
String commande = command_line[0].substring(1);
if (commande.equalsIgnoreCase("afk")
|| commande.equalsIgnoreCase("away")
|| commande.equalsIgnoreCase("time")
|| commande.equalsIgnoreCase("day")
|| commande.equalsIgnoreCase("night")
|| commande.equalsIgnoreCase("me")
|| commande.equalsIgnoreCase("action")
|| commande.equalsIgnoreCase("describe")
|| commande.equalsIgnoreCase("tpa")
|| commande.equalsIgnoreCase("call")
|| commande.equalsIgnoreCase("tpask")
|| commande.equalsIgnoreCase("r")
|| commande.equalsIgnoreCase("reply")
|| commande.equalsIgnoreCase("msg")
|| commande.equalsIgnoreCase("m")
|| commande.equalsIgnoreCase("tell")
|| commande.equalsIgnoreCase("t")
|| commande.equalsIgnoreCase("whisper")
|| commande.equalsIgnoreCase("w")
|| commande.equalsIgnoreCase("mail")
|| commande.equalsIgnoreCase("email"))
{
if (last_command != null)
{
if (last_command.equals(event.getMessage()) && time - last_command_time < time_before_resend_same_command)
{
event.getPlayer().sendMessage(ChatColor.RED+"Patientez avant de renvoyer cette commande !");
if (violation_level >= max_violation_level/2)
event.setCancelled(true);
addVL(5);
return;
}
}
removeVL(NumberConversions.floor(((time - last_command_time)/1000)/nb_second_for_1_vl_down));
last_command = event.getMessage();
last_command_time = time;
}
}
private String analyseString(String s)
{
// évite les suites d'au moins 4 caractàres à la suite
char[] cs = s.toCharArray();
String ret = s.substring(0, (s.length()>=3)?3:s.length());
int nb_duplicated_char = 0;
for (int i=3; i<cs.length; i++)
{
if (cs[i] == cs[i-1] && cs[i-1] == cs[i-2] && cs[i-2] == cs[i-3])
{
nb_duplicated_char++;
continue;
}
ret = ret.concat(String.valueOf(cs[i]));
}
if (nb_duplicated_char > 0)
{
addVL(nb_duplicated_char/4+1);
player.sendMessage(ChatColor.RED+"Evitez les répétitions de caractères !");
}
s = ret;
char[] sChar = s.toCharArray();
char[] minChar = s.toLowerCase().toCharArray();
// vérification des majuscules
if (sChar.length > 10)
{
int nb_caps = 0;
for (int i=0; i<sChar.length; i++)
if (sChar[i] != minChar[i])
nb_caps++;
if (nb_caps * 100 / sChar.length > 70 || nb_caps > 20)
{
// si plus de 70% des caractères sont majuscules
// ou plus de 20 majuscules
addVL(4);
ret = s.toLowerCase();
player.sendMessage(ChatColor.RED+"Il y a trop de majuscules dans votre message, faites attention avant d'envoyer votre message ;)");
}
}
return ret;
}
}