add kick counter list to chatcleaner to kickban disturbing players after multiple kicks for chat offence
This commit is contained in:
@@ -43,7 +43,7 @@ using namespace std;
|
|||||||
CleanerConfig::CleanerConfig()
|
CleanerConfig::CleanerConfig()
|
||||||
{
|
{
|
||||||
// !!!! Revisionsnummer der Configdefaults !!!!!
|
// !!!! Revisionsnummer der Configdefaults !!!!!
|
||||||
configRev = 7;
|
configRev = 8;
|
||||||
|
|
||||||
// Pfad und Dateinamen setzen
|
// Pfad und Dateinamen setzen
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -121,6 +121,9 @@ CleanerConfig::CleanerConfig()
|
|||||||
configList.push_back(ConfigInfo("TextFloodLevelToTrigger", CONFIG_TYPE_INT, "3"));
|
configList.push_back(ConfigInfo("TextFloodLevelToTrigger", CONFIG_TYPE_INT, "3"));
|
||||||
configList.push_back(ConfigInfo("CapsFloodCapsNumberToTrigger", CONFIG_TYPE_INT, "10"));
|
configList.push_back(ConfigInfo("CapsFloodCapsNumberToTrigger", CONFIG_TYPE_INT, "10"));
|
||||||
configList.push_back(ConfigInfo("LetterRepeatingNumberToTrigger", CONFIG_TYPE_INT, "10"));
|
configList.push_back(ConfigInfo("LetterRepeatingNumberToTrigger", CONFIG_TYPE_INT, "10"));
|
||||||
|
|
||||||
|
configList.push_back(ConfigInfo("KickNumberToBan", CONFIG_TYPE_INT, "2"));
|
||||||
|
configList.push_back(ConfigInfo("SecondsToForgetAboutKick", CONFIG_TYPE_INT, "1800"));
|
||||||
|
|
||||||
list<string> badWordsList;
|
list<string> badWordsList;
|
||||||
badWordsList.push_back("arsch");
|
badWordsList.push_back("arsch");
|
||||||
|
|||||||
+177
-132
@@ -10,156 +10,201 @@
|
|||||||
#include "urlcheck.h"
|
#include "urlcheck.h"
|
||||||
|
|
||||||
enum ActionType {
|
enum ActionType {
|
||||||
NOTHING,
|
NOTHING,
|
||||||
WARN,
|
WARN,
|
||||||
KICK };
|
KICK,
|
||||||
|
KICKBAN
|
||||||
|
};
|
||||||
|
|
||||||
enum OffenceType {
|
enum OffenceType {
|
||||||
NONE,
|
NONE,
|
||||||
BAD_WORD,
|
BAD_WORD,
|
||||||
TEXT_FLOOD_LINES,
|
TEXT_FLOOD_LINES,
|
||||||
CAPS_FLOOD,
|
CAPS_FLOOD,
|
||||||
LETTER_REPEATING,
|
LETTER_REPEATING,
|
||||||
URL
|
URL
|
||||||
};
|
};
|
||||||
|
|
||||||
MessageFilter::MessageFilter(CleanerConfig *c): config(c)
|
MessageFilter::MessageFilter(CleanerConfig *c): config(c)
|
||||||
{
|
{
|
||||||
myBadWordCheck = new BadWordCheck;
|
myBadWordCheck = new BadWordCheck;
|
||||||
myTextFloodCheck = new TextFloodCheck;
|
myTextFloodCheck = new TextFloodCheck;
|
||||||
myCapsFloodCheck = new CapsFloodCheck;
|
myCapsFloodCheck = new CapsFloodCheck;
|
||||||
myLetterRepeatingCheck = new LetterRepeatingCheck;
|
myLetterRepeatingCheck = new LetterRepeatingCheck;
|
||||||
myUrlCheck = new UrlCheck;
|
myUrlCheck = new UrlCheck;
|
||||||
|
|
||||||
|
cleanTimer = new QTimer();
|
||||||
|
connect(cleanTimer, SIGNAL(timeout()), this, SLOT(cleanKickCounterList()));
|
||||||
|
cleanTimer->start(30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageFilter::~MessageFilter() {
|
MessageFilter::~MessageFilter() {
|
||||||
|
|
||||||
delete myBadWordCheck;
|
delete myBadWordCheck;
|
||||||
delete myTextFloodCheck;
|
delete myTextFloodCheck;
|
||||||
delete myCapsFloodCheck;
|
delete myCapsFloodCheck;
|
||||||
delete myLetterRepeatingCheck;
|
delete myLetterRepeatingCheck;
|
||||||
delete myUrlCheck;
|
delete myUrlCheck;
|
||||||
|
delete cleanTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList MessageFilter::check(unsigned playerId, QString nick, QString msg)
|
QStringList MessageFilter::check(unsigned playerId, QString nick, QString msg)
|
||||||
{
|
{
|
||||||
QStringList returnList;
|
QStringList returnList;
|
||||||
QString returnMessage;
|
QString returnMessage;
|
||||||
QString returnAction;
|
QString returnAction;
|
||||||
|
|
||||||
OffenceType offence = NONE;
|
|
||||||
ActionType action = NOTHING;
|
|
||||||
|
|
||||||
if(myBadWordCheck->run(msg)) offence = BAD_WORD;
|
|
||||||
if(myCapsFloodCheck->run(msg)) offence = CAPS_FLOOD;
|
|
||||||
if(myLetterRepeatingCheck->run(msg)) offence = LETTER_REPEATING;
|
|
||||||
if(myUrlCheck->run(msg)) offence = URL;
|
|
||||||
if(myTextFloodCheck->run(playerId)) offence = TEXT_FLOOD_LINES;
|
|
||||||
|
|
||||||
if(offence){
|
|
||||||
|
|
||||||
QMap<unsigned, ClientWarnInfos>::const_iterator i = myClientWarnLevelList.find(playerId);
|
|
||||||
|
|
||||||
if(i == myClientWarnLevelList.end()) {
|
|
||||||
ClientWarnInfos tmpInfos;
|
|
||||||
tmpInfos.warnLevel = 1;
|
|
||||||
tmpInfos.lastWarnType = offence;
|
|
||||||
tmpInfos.nick = nick;
|
|
||||||
myClientWarnLevelList.insert(playerId, tmpInfos);
|
|
||||||
action = WARN;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(i.value().warnLevel == warnLevelToKick || i.value().lastWarnType == offence) {
|
|
||||||
// Kick Command
|
|
||||||
action = KICK;
|
|
||||||
//remove playerId from all lists and as LAST from myClientWarnLevelList
|
|
||||||
myTextFloodCheck->removeNickFromList(i.key());
|
|
||||||
myClientWarnLevelList.remove(i.key());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ClientWarnInfos tmpInfos;
|
|
||||||
tmpInfos.warnLevel = i.value().warnLevel+1;
|
|
||||||
tmpInfos.lastWarnType = offence;
|
|
||||||
tmpInfos.nick = nick;
|
|
||||||
myClientWarnLevelList.insert(playerId, tmpInfos);
|
|
||||||
action = WARN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(action == KICK) {
|
|
||||||
returnMessage = QString("Kick: %1\n").arg(nick);
|
|
||||||
returnAction = QString("kick");
|
|
||||||
}
|
|
||||||
if(action == WARN) {
|
|
||||||
|
|
||||||
switch(offence) {
|
|
||||||
case BAD_WORD: {
|
|
||||||
returnMessage = QString ("%1: Warning! No racial, religious, or sexually inflammatory language!\n").arg(nick);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TEXT_FLOOD_LINES: {
|
|
||||||
returnMessage = QString ("%1: Warning! You've triggered text flood (lines) protection, slow down your typing!\n").arg(nick);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CAPS_FLOOD: {
|
|
||||||
returnMessage = QString ("%1: Warning: You've triggered caps flood protection, release your caps!\n").arg(nick);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LETTER_REPEATING: {
|
|
||||||
returnMessage = QString ("%1: Warning: You've triggered letter repeating protection, stop repeating!\n").arg(nick);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case URL: {
|
|
||||||
returnMessage = QString ("%1: Warning: You've triggered url spam protection, stop posting urls!\n").arg(nick);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:;
|
|
||||||
}
|
|
||||||
returnAction = QString("warn");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
returnAction = QString("");
|
|
||||||
returnMessage = QString("");
|
|
||||||
}
|
|
||||||
|
|
||||||
returnList << returnAction << returnMessage;
|
OffenceType offence = NONE;
|
||||||
return returnList;
|
ActionType action = NOTHING;
|
||||||
|
|
||||||
|
if(myBadWordCheck->run(msg)) offence = BAD_WORD;
|
||||||
|
if(myCapsFloodCheck->run(msg)) offence = CAPS_FLOOD;
|
||||||
|
if(myLetterRepeatingCheck->run(msg)) offence = LETTER_REPEATING;
|
||||||
|
if(myUrlCheck->run(msg)) offence = URL;
|
||||||
|
if(myTextFloodCheck->run(playerId)) offence = TEXT_FLOOD_LINES;
|
||||||
|
|
||||||
|
if(offence){
|
||||||
|
|
||||||
|
QMap<unsigned, ClientWarnInfos>::const_iterator i = myClientWarnLevelList.find(playerId);
|
||||||
|
|
||||||
|
if(i == myClientWarnLevelList.end()) {
|
||||||
|
ClientWarnInfos tmpInfos;
|
||||||
|
tmpInfos.warnLevel = 1;
|
||||||
|
tmpInfos.lastWarnType = offence;
|
||||||
|
tmpInfos.nick = nick;
|
||||||
|
myClientWarnLevelList.insert(playerId, tmpInfos);
|
||||||
|
action = WARN;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(i.value().warnLevel == warnLevelToKick || i.value().lastWarnType == offence) {
|
||||||
|
// Kick Command
|
||||||
|
action = KICK;
|
||||||
|
//remove playerId from all lists and as LAST from myClientWarnLevelList
|
||||||
|
myTextFloodCheck->removeNickFromList(i.key());
|
||||||
|
myClientWarnLevelList.remove(i.key());
|
||||||
|
//check if player is already on kickCounterList
|
||||||
|
QMap<QString, ClientKickInfos>::const_iterator j = myClientKickCounterList.find(nick);
|
||||||
|
if(j == myClientKickCounterList.end()) {
|
||||||
|
//if player is NOT on this list put the playerId on it to ban after multiple offence
|
||||||
|
ClientKickInfos tmpInfos;
|
||||||
|
tmpInfos.kickNumber = 1;
|
||||||
|
tmpInfos.lastKickTimestamp = timer.elapsed().total_seconds();
|
||||||
|
myClientKickCounterList.insert(nick, tmpInfos);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//please is already on the list: either raise kickNumber or kickban when kickNumerToBan is reached
|
||||||
|
if(j.value().kickNumber == kickNumberToBan) {
|
||||||
|
action = KICKBAN;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ClientKickInfos tmpInfos;
|
||||||
|
tmpInfos.kickNumber = j.value().kickNumber+1;
|
||||||
|
tmpInfos.lastKickTimestamp = timer.elapsed().total_seconds();
|
||||||
|
myClientKickCounterList.insert(nick, tmpInfos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ClientWarnInfos tmpInfos;
|
||||||
|
tmpInfos.warnLevel = i.value().warnLevel+1;
|
||||||
|
tmpInfos.lastWarnType = offence;
|
||||||
|
tmpInfos.nick = nick;
|
||||||
|
myClientWarnLevelList.insert(playerId, tmpInfos);
|
||||||
|
action = WARN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(action == WARN) {
|
||||||
|
|
||||||
|
switch(offence) {
|
||||||
|
case BAD_WORD: {
|
||||||
|
returnMessage = QString ("%1: Warning! No racial, religious, or sexually inflammatory language!\n").arg(nick);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TEXT_FLOOD_LINES: {
|
||||||
|
returnMessage = QString ("%1: Warning! You've triggered text flood (lines) protection, slow down your typing!\n").arg(nick);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CAPS_FLOOD: {
|
||||||
|
returnMessage = QString ("%1: Warning: You've triggered caps flood protection, release your caps!\n").arg(nick);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LETTER_REPEATING: {
|
||||||
|
returnMessage = QString ("%1: Warning: You've triggered letter repeating protection, stop repeating!\n").arg(nick);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case URL: {
|
||||||
|
returnMessage = QString ("%1: Warning: You've triggered url spam protection, stop posting urls!\n").arg(nick);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
returnAction = QString("warn");
|
||||||
|
}
|
||||||
|
else if(action == KICK) {
|
||||||
|
returnMessage = QString("%1 kicked! Please respect: http://chatrules.pokerth.net\n").arg(nick);
|
||||||
|
returnAction = QString("kick");
|
||||||
|
}
|
||||||
|
else if(action == KICKBAN) {
|
||||||
|
returnMessage = QString("%1 kicked and banned! Please respect: http://chatrules.pokerth.net\n").arg(nick);
|
||||||
|
returnAction = QString("kickban");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
returnAction = QString("");
|
||||||
|
returnMessage = QString("");
|
||||||
|
}
|
||||||
|
|
||||||
|
returnList << returnAction << returnMessage;
|
||||||
|
return returnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageFilter::refreshConfig() {
|
void MessageFilter::refreshConfig() {
|
||||||
|
|
||||||
// global settings
|
// global settings
|
||||||
warnLevelToKick = config->readConfigInt("WarnLevelToKick");
|
warnLevelToKick = config->readConfigInt("WarnLevelToKick");
|
||||||
|
kickNumberToBan = config->readConfigInt("KickNumberToBan");
|
||||||
// special check settings
|
|
||||||
//Bad Words
|
// special check settings
|
||||||
std::list<std::string> badWordsList = config->readConfigStringList("BadWordsList");
|
//Bad Words
|
||||||
std::list<std::string>::iterator it1;
|
std::list<std::string> badWordsList = config->readConfigStringList("BadWordsList");
|
||||||
QStringList bwList;
|
std::list<std::string>::iterator it1;
|
||||||
for(it1= badWordsList.begin(); it1 != badWordsList.end(); it1++) {
|
QStringList bwList;
|
||||||
bwList << QString::fromUtf8(it1->c_str());
|
for(it1= badWordsList.begin(); it1 != badWordsList.end(); it1++) {
|
||||||
}
|
bwList << QString::fromUtf8(it1->c_str());
|
||||||
myBadWordCheck->setBadWords(bwList);
|
}
|
||||||
|
myBadWordCheck->setBadWords(bwList);
|
||||||
std::list<std::string> urlStringsList = config->readConfigStringList("UrlStringsList");
|
|
||||||
std::list<std::string>::iterator it2;
|
std::list<std::string> urlStringsList = config->readConfigStringList("UrlStringsList");
|
||||||
QStringList urlList;
|
std::list<std::string>::iterator it2;
|
||||||
for(it2= urlStringsList.begin(); it2 != urlStringsList.end(); it2++) {
|
QStringList urlList;
|
||||||
urlList << QString::fromUtf8(it2->c_str());
|
for(it2= urlStringsList.begin(); it2 != urlStringsList.end(); it2++) {
|
||||||
}
|
urlList << QString::fromUtf8(it2->c_str());
|
||||||
myUrlCheck->setUrlStrings(urlList);
|
}
|
||||||
|
myUrlCheck->setUrlStrings(urlList);
|
||||||
std::list<std::string> urlExceptionStringsList = config->readConfigStringList("UrlExceptionStringsList");
|
|
||||||
std::list<std::string>::iterator it3;
|
std::list<std::string> urlExceptionStringsList = config->readConfigStringList("UrlExceptionStringsList");
|
||||||
QStringList urlExceptionList;
|
std::list<std::string>::iterator it3;
|
||||||
for(it3= urlExceptionStringsList.begin(); it3 != urlExceptionStringsList.end(); it3++) {
|
QStringList urlExceptionList;
|
||||||
urlExceptionList << QString::fromUtf8(it3->c_str());
|
for(it3= urlExceptionStringsList.begin(); it3 != urlExceptionStringsList.end(); it3++) {
|
||||||
}
|
urlExceptionList << QString::fromUtf8(it3->c_str());
|
||||||
myUrlCheck->setUrlExceptionStrings(urlExceptionList);
|
}
|
||||||
|
myUrlCheck->setUrlExceptionStrings(urlExceptionList);
|
||||||
myTextFloodCheck->setTextFloodLevelToTrigger(config->readConfigInt("TextFloodLevelToTrigger"));
|
|
||||||
myCapsFloodCheck->setCapsNumberToTrigger(config->readConfigInt("CapsFloodCapsNumberToTrigger"));
|
myTextFloodCheck->setTextFloodLevelToTrigger(config->readConfigInt("TextFloodLevelToTrigger"));
|
||||||
myLetterRepeatingCheck->setLetterNumberToTrigger(config->readConfigInt("LetterRepeatingNumberToTrigger"));
|
myCapsFloodCheck->setCapsNumberToTrigger(config->readConfigInt("CapsFloodCapsNumberToTrigger"));
|
||||||
|
myLetterRepeatingCheck->setLetterNumberToTrigger(config->readConfigInt("LetterRepeatingNumberToTrigger"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessageFilter::cleanKickCounterList()
|
||||||
|
{
|
||||||
|
QMapIterator<QString, ClientKickInfos> it(myClientKickCounterList);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
if(timer.elapsed().total_seconds()-it.value().lastKickTimestamp > config->readConfigInt("SecondsToForgetAboutKick")) {
|
||||||
|
qDebug() << it.key() << "removed from kick counter list" << endl;
|
||||||
|
myClientKickCounterList.remove(it.key());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <third_party/boost/timers.hpp>
|
||||||
|
|
||||||
class BadWordCheck;
|
class BadWordCheck;
|
||||||
class TextFloodCheck;
|
class TextFloodCheck;
|
||||||
@@ -19,6 +20,7 @@ public:
|
|||||||
|
|
||||||
QStringList check(unsigned, QString, QString);
|
QStringList check(unsigned, QString, QString);
|
||||||
void refreshConfig();
|
void refreshConfig();
|
||||||
|
void cleanKickCounterList();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BadWordCheck *myBadWordCheck;
|
BadWordCheck *myBadWordCheck;
|
||||||
@@ -32,12 +34,22 @@ private:
|
|||||||
int lastWarnType;
|
int lastWarnType;
|
||||||
int warnLevel;
|
int warnLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ClientKickInfos {
|
||||||
|
size_t lastKickTimestamp;
|
||||||
|
int kickNumber;
|
||||||
|
};
|
||||||
|
|
||||||
QMap<unsigned, ClientWarnInfos> myClientWarnLevelList;
|
QMap<unsigned, ClientWarnInfos> myClientWarnLevelList;
|
||||||
|
QMap<QString, ClientKickInfos> myClientKickCounterList;
|
||||||
|
|
||||||
int warnLevelToKick;
|
int warnLevelToKick;
|
||||||
|
int kickNumberToBan;
|
||||||
|
|
||||||
CleanerConfig *config;
|
CleanerConfig *config;
|
||||||
|
|
||||||
|
boost::timers::portable::second_timer timer;
|
||||||
|
QTimer *cleanTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MESSAGEFILTER_H
|
#endif // MESSAGEFILTER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user