Added a new feature to ignore channels/nicks which you do not want to have logged and replayed. Ignores are wildcard based and nick ignores includes the mask which allows you to block an entire ip address/hostname and or nick name.
This commit is contained in:
parent
b0ed19fe38
commit
3cf9cf5bd7
@ -31,4 +31,15 @@ BEGIN;
|
|||||||
INSERT INTO `settings` VALUES ('replayAll', '0'), ('logLimit', '1'), ('logLevel', '1');
|
INSERT INTO `settings` VALUES ('replayAll', '0'), ('logLimit', '1'), ('logLevel', '1');
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for `ignorelist`
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `ignorelist`;
|
||||||
|
CREATE TABLE `ignorelist` (
|
||||||
|
`rowid` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`type` text,
|
||||||
|
`target` text,
|
||||||
|
PRIMARY KEY (`rowid`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
SET FOREIGN_KEY_CHECKS = 1;
|
SET FOREIGN_KEY_CHECKS = 1;
|
||||||
|
322
logmysql.cpp
322
logmysql.cpp
@ -40,6 +40,9 @@ public:
|
|||||||
AddCommand("ReplayAll", static_cast<CModCommand::ModCmdFunc>(&CLogMySQL::ReplayAllCommand), "[1|0]", "Replay all messages stored.");
|
AddCommand("ReplayAll", static_cast<CModCommand::ModCmdFunc>(&CLogMySQL::ReplayAllCommand), "[1|0]", "Replay all messages stored.");
|
||||||
AddCommand("LogLimit", static_cast<CModCommand::ModCmdFunc>(&CLogMySQL::LogLimitCommand), "[0-9]+", "Limit the amount of items to store into the log.");
|
AddCommand("LogLimit", static_cast<CModCommand::ModCmdFunc>(&CLogMySQL::LogLimitCommand), "[0-9]+", "Limit the amount of items to store into the log.");
|
||||||
AddCommand("LogLevel", static_cast<CModCommand::ModCmdFunc>(&CLogMySQL::LogLevelCommand), "[0-4]", "Log level.");
|
AddCommand("LogLevel", static_cast<CModCommand::ModCmdFunc>(&CLogMySQL::LogLevelCommand), "[0-4]", "Log level.");
|
||||||
|
AddCommand("AddIgnore", static_cast<CModCommand::ModCmdFunc>(&CLogMySQL::AddIgnoreCommand), "Type[nick|chan] Target", "Add to ignore list.");
|
||||||
|
AddCommand("RemoveIgnore", static_cast<CModCommand::ModCmdFunc>(&CLogMySQL::RemoveIgnoreCommand), "Type[nick|chan] Target", "Remove from ignore list.");
|
||||||
|
AddCommand("IgnoreList", static_cast<CModCommand::ModCmdFunc>(&CLogMySQL::IgnoreListCommand), "", "View what is currently ignored.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostCommand(const CString &sLine) {
|
void HostCommand(const CString &sLine) {
|
||||||
@ -196,6 +199,88 @@ public:
|
|||||||
PutModule("LogLevel is "+now+"set to: "+setting);
|
PutModule("LogLevel is "+now+"set to: "+setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddIgnoreCommand(const CString &sLine) {
|
||||||
|
CString type = sLine.Token(1);
|
||||||
|
CString target = sLine.Token(2);
|
||||||
|
bool help = sLine.Equals("HELP");
|
||||||
|
|
||||||
|
if (help) {
|
||||||
|
PutModule("Inorder to add an ignore, you must choose what type of ignore it is which can ether be a nick or a chan.");
|
||||||
|
PutModule("Nicks are matched with wildcards against the full mask.");
|
||||||
|
PutModule("Channels are matched by #channel which can contain wildcards.");
|
||||||
|
} else if (!type.empty() && !target.empty()) {
|
||||||
|
if (type.Equals("nick"))
|
||||||
|
type = "nick";
|
||||||
|
else if (type.Equals("chan") || type.Equals("channel"))
|
||||||
|
type = "chan";
|
||||||
|
else
|
||||||
|
type = "";
|
||||||
|
|
||||||
|
if (type.empty()) {
|
||||||
|
PutModule("Unknown type. If you need help, type \"AddIgnore help\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AddIgnore(type, target))
|
||||||
|
PutModule("Successfully added \""+target+"\" to the ignore list.");
|
||||||
|
else
|
||||||
|
PutModule("Failed, maybe it already existed?");
|
||||||
|
} else {
|
||||||
|
PutModule("If you need help, type \"AddIgnore help\".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveIgnoreCommand(const CString &sLine) {
|
||||||
|
CString type = sLine.Token(1);
|
||||||
|
CString target = sLine.Token(2);
|
||||||
|
bool help = sLine.Equals("HELP");
|
||||||
|
|
||||||
|
if (help) {
|
||||||
|
PutModule("Inorder to remove an ignore, you must specify the type and the exact pattren used to add it. If you need to find what currently exists, type \"IgnoreList\".");
|
||||||
|
} else if (!type.empty() && !target.empty()) {
|
||||||
|
if (type.Equals("nick"))
|
||||||
|
type = "nick";
|
||||||
|
else if (type.Equals("chan") || type.Equals("channel"))
|
||||||
|
type = "chan";
|
||||||
|
else
|
||||||
|
type = "";
|
||||||
|
|
||||||
|
if (type.empty()) {
|
||||||
|
PutModule("Unknown type. If you need help, type \"RemoveIgnore help\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RemoveIgnore(type, target))
|
||||||
|
PutModule("Successfully removed \""+target+"\" from the ignore list.");
|
||||||
|
else
|
||||||
|
PutModule("Failed, maybe it does not exist?");
|
||||||
|
} else {
|
||||||
|
PutModule("If you need help, type \"RemoveIgnore help\".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IgnoreListCommand(const CString &sLine) {
|
||||||
|
if (nickIgnoreList.size()==0) {
|
||||||
|
PutModule("The nick ignore list is currently empty.");
|
||||||
|
} else {
|
||||||
|
PutModule("Nick ignore list contains:");
|
||||||
|
|
||||||
|
for (vector<CString>::iterator it=nickIgnoreList.begin(); it<nickIgnoreList.end(); it++) {
|
||||||
|
PutModule(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PutModule("---");
|
||||||
|
if (chanIgnoreList.size()==0) {
|
||||||
|
PutModule("The channel ignore list is currently empty.");
|
||||||
|
} else {
|
||||||
|
PutModule("Channel ignore list contains:");
|
||||||
|
|
||||||
|
for (vector<CString>::iterator it=chanIgnoreList.begin(); it<chanIgnoreList.end(); it++) {
|
||||||
|
PutModule(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
|
virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
|
||||||
connected = true;
|
connected = true;
|
||||||
databaseConnected = false;
|
databaseConnected = false;
|
||||||
@ -237,45 +322,51 @@ public:
|
|||||||
cout << "LogMySQL: Database connected.\n";
|
cout << "LogMySQL: Database connected.\n";
|
||||||
|
|
||||||
MYSQL_RES *settings = mysql_list_tables(database, "settings");
|
MYSQL_RES *settings = mysql_list_tables(database, "settings");
|
||||||
MYSQL_RES *messages = mysql_list_tables(database, "messages");
|
if (mysql_num_rows(settings)==0) {
|
||||||
if (mysql_num_rows(settings)==0 || mysql_num_rows(messages)==0) {
|
|
||||||
cout << "Creating tables\n";
|
|
||||||
MYSQL_STMT *statement = mysql_stmt_init(database);
|
MYSQL_STMT *statement = mysql_stmt_init(database);
|
||||||
int status = mysql_stmt_prepare(statement, "DROP TABLE IF EXISTS `settings`", 31);
|
int status = mysql_stmt_prepare(statement, "CREATE TABLE `settings` (`name` text,`value` text)", 50);
|
||||||
if (status==0) {
|
if (status==0) {
|
||||||
mysql_stmt_execute(statement);
|
mysql_stmt_execute(statement);
|
||||||
mysql_stmt_close(statement);
|
mysql_stmt_close(statement);
|
||||||
}
|
|
||||||
statement = mysql_stmt_init(database);
|
|
||||||
status = mysql_stmt_prepare(statement, "CREATE TABLE `settings` (`name` text,`value` text)", 50);
|
|
||||||
if (status==0) {
|
|
||||||
mysql_stmt_execute(statement);
|
|
||||||
mysql_stmt_close(statement);
|
|
||||||
}
|
|
||||||
statement = mysql_stmt_init(database);
|
|
||||||
status = mysql_stmt_prepare(statement, "DROP TABLE IF EXISTS `messages`", 31);
|
|
||||||
if (status==0) {
|
|
||||||
mysql_stmt_execute(statement);
|
|
||||||
mysql_stmt_close(statement);
|
|
||||||
}
|
|
||||||
statement = mysql_stmt_init(database);
|
|
||||||
status = mysql_stmt_prepare(statement, "CREATE TABLE `messages` (`rowid` int UNSIGNED AUTO_INCREMENT,`target` text,`nick` text,`type` text,`message` longblob,`time` decimal(20,5) UNSIGNED,PRIMARY KEY (`rowid`))", 170);
|
|
||||||
if (status==0) {
|
|
||||||
mysql_stmt_execute(statement);
|
|
||||||
mysql_stmt_close(statement);
|
|
||||||
}
|
|
||||||
SetSetting("replayAll","0");
|
SetSetting("replayAll","0");
|
||||||
SetSetting("logLimit","1");
|
SetSetting("logLimit","1");
|
||||||
SetSetting("logLevel","1");
|
SetSetting("logLevel","1");
|
||||||
|
SetSetting("version","1");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (settings!=NULL)
|
if (settings!=NULL)
|
||||||
mysql_free_result(settings);
|
mysql_free_result(settings);
|
||||||
|
MYSQL_RES *messages = mysql_list_tables(database, "messages");
|
||||||
|
if (mysql_num_rows(messages)==0) {
|
||||||
|
MYSQL_STMT *statement = mysql_stmt_init(database);
|
||||||
|
int status = mysql_stmt_prepare(statement, "CREATE TABLE `messages` (`rowid` int UNSIGNED AUTO_INCREMENT,`target` text,`nick` text,`type` text,`message` longblob,`time` decimal(20,5) UNSIGNED,PRIMARY KEY (`rowid`))", 170);
|
||||||
|
if (status==0) {
|
||||||
|
mysql_stmt_execute(statement);
|
||||||
|
mysql_stmt_close(statement);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (messages!=NULL)
|
if (messages!=NULL)
|
||||||
mysql_free_result(messages);
|
mysql_free_result(messages);
|
||||||
|
MYSQL_RES *ignorelist = mysql_list_tables(database, "ignorelist");
|
||||||
|
if (mysql_num_rows(ignorelist)==0) {
|
||||||
|
MYSQL_STMT *statement = mysql_stmt_init(database);
|
||||||
|
int status = mysql_stmt_prepare(statement, "CREATE TABLE `ignorelist` (`rowid` int UNSIGNED AUTO_INCREMENT,`type` text,`target` text,PRIMARY KEY (`rowid`))", 111);
|
||||||
|
if (status==0) {
|
||||||
|
mysql_stmt_execute(statement);
|
||||||
|
mysql_stmt_close(statement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ignorelist!=NULL)
|
||||||
|
mysql_free_result(ignorelist);
|
||||||
|
|
||||||
replayAll = atoi(GetSetting("replayAll").c_str());
|
replayAll = atoi(GetSetting("replayAll").c_str());
|
||||||
logLimit = strtoul(GetSetting("logLimit").c_str(), NULL, 10);
|
logLimit = strtoul(GetSetting("logLimit").c_str(), NULL, 10);
|
||||||
logLevel = atoi(GetSetting("logLevel").c_str());
|
logLevel = atoi(GetSetting("logLevel").c_str());
|
||||||
|
|
||||||
|
unsigned long version = strtoul(GetSetting("version").c_str(), NULL, 10);
|
||||||
|
if (version==0)
|
||||||
|
SetSetting("version","1");
|
||||||
} else {
|
} else {
|
||||||
cout << "LogMySQL: Database unable to connect.\n";
|
cout << "LogMySQL: Database unable to connect.\n";
|
||||||
}
|
}
|
||||||
@ -295,6 +386,8 @@ public:
|
|||||||
void AddMessage(const CString& target, const CString& nick, const CString& type, const CString& message) {
|
void AddMessage(const CString& target, const CString& nick, const CString& type, const CString& message) {
|
||||||
if (!databaseConnected)
|
if (!databaseConnected)
|
||||||
return;
|
return;
|
||||||
|
if (IsIgnored("nick",nick) || (target.Left(1).Equals("#") && IsIgnored("chan",target)))
|
||||||
|
return;
|
||||||
MYSQL_STMT *statement = mysql_stmt_init(database);
|
MYSQL_STMT *statement = mysql_stmt_init(database);
|
||||||
int status = mysql_stmt_prepare(statement, "INSERT INTO `messages` (`target`, `nick`, `type`, `message`, `time`) VALUES (?,?,?,?,?)", 87);
|
int status = mysql_stmt_prepare(statement, "INSERT INTO `messages` (`target`, `nick`, `type`, `message`, `time`) VALUES (?,?,?,?,?)", 87);
|
||||||
if (status!=0)
|
if (status!=0)
|
||||||
@ -611,8 +704,186 @@ public:
|
|||||||
mysql_stmt_close(statement);
|
mysql_stmt_close(statement);
|
||||||
return stringValue;
|
return stringValue;
|
||||||
}
|
}
|
||||||
//Server stuff
|
|
||||||
|
|
||||||
|
void UpdateIgnoreLists() {
|
||||||
|
if (!databaseConnected)
|
||||||
|
return;
|
||||||
|
nickIgnoreList.clear();
|
||||||
|
MYSQL_STMT *statement = mysql_stmt_init(database);
|
||||||
|
int status = mysql_stmt_prepare(statement, "SELECT `target` FROM `ignorelist` WHERE `type`='nick'", 53);
|
||||||
|
if (status==0) {
|
||||||
|
status = mysql_stmt_execute(statement);
|
||||||
|
if (status==0) {
|
||||||
|
MYSQL_RES *result = mysql_stmt_result_metadata(statement);
|
||||||
|
unsigned int dataCount = mysql_num_fields(result);
|
||||||
|
if (dataCount==1) {
|
||||||
|
MYSQL_FIELD *fields = mysql_fetch_fields(result);
|
||||||
|
|
||||||
|
unsigned long length;
|
||||||
|
char targetData[fields[0].length];
|
||||||
|
MYSQL_BIND results[1];
|
||||||
|
memset(results, 0, sizeof(results));
|
||||||
|
results[0].buffer_type = MYSQL_TYPE_STRING;
|
||||||
|
results[0].buffer = (void *)targetData;
|
||||||
|
results[0].buffer_length = fields[0].length;
|
||||||
|
results[0].length = &length;
|
||||||
|
|
||||||
|
status = mysql_stmt_bind_result(statement, results);
|
||||||
|
if (status==0) {
|
||||||
|
while (true) {
|
||||||
|
status = mysql_stmt_fetch(statement);
|
||||||
|
if (status!=0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
CString ignore = CString(targetData, length);
|
||||||
|
nickIgnoreList.push_back(ignore);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mysql_free_result(result);
|
||||||
|
}
|
||||||
|
mysql_stmt_close(statement);
|
||||||
|
}
|
||||||
|
chanIgnoreList.clear();
|
||||||
|
statement = mysql_stmt_init(database);
|
||||||
|
status = mysql_stmt_prepare(statement, "SELECT `target` FROM `ignorelist` WHERE `type`='chan'", 53);
|
||||||
|
if (status==0) {
|
||||||
|
status = mysql_stmt_execute(statement);
|
||||||
|
if (status==0) {
|
||||||
|
MYSQL_RES *result = mysql_stmt_result_metadata(statement);
|
||||||
|
unsigned int dataCount = mysql_num_fields(result);
|
||||||
|
if (dataCount==1) {
|
||||||
|
MYSQL_FIELD *fields = mysql_fetch_fields(result);
|
||||||
|
|
||||||
|
unsigned long length;
|
||||||
|
char targetData[fields[0].length];
|
||||||
|
MYSQL_BIND results[1];
|
||||||
|
memset(results, 0, sizeof(results));
|
||||||
|
results[0].buffer_type = MYSQL_TYPE_STRING;
|
||||||
|
results[0].buffer = (void *)targetData;
|
||||||
|
results[0].buffer_length = fields[0].length;
|
||||||
|
results[0].length = &length;
|
||||||
|
|
||||||
|
status = mysql_stmt_bind_result(statement, results);
|
||||||
|
if (status==0) {
|
||||||
|
while (true) {
|
||||||
|
status = mysql_stmt_fetch(statement);
|
||||||
|
if (status!=0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
CString ignore = CString(targetData, length);
|
||||||
|
chanIgnoreList.push_back(ignore);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mysql_free_result(result);
|
||||||
|
}
|
||||||
|
mysql_stmt_close(statement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool AddIgnore(const CString& type, const CString& target) {
|
||||||
|
if (!IgnoreExists(type, target)) {
|
||||||
|
MYSQL_STMT *statement = mysql_stmt_init(database);
|
||||||
|
int status = mysql_stmt_prepare(statement, "INSERT INTO `ignorelist` (`type`, `target`) VALUES (?,?)", 56);
|
||||||
|
if (status!=0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MYSQL_BIND bind[2];
|
||||||
|
memset(bind, 0, sizeof(bind));
|
||||||
|
|
||||||
|
bind[0].buffer_type = MYSQL_TYPE_STRING;
|
||||||
|
bind[0].buffer = (void*)type.c_str();
|
||||||
|
bind[0].buffer_length = type.length();
|
||||||
|
bind[0].is_null = false;
|
||||||
|
|
||||||
|
bind[1].buffer_type = MYSQL_TYPE_STRING;
|
||||||
|
bind[1].buffer = (void*)target.c_str();
|
||||||
|
bind[1].buffer_length = target.length();
|
||||||
|
bind[1].is_null = false;
|
||||||
|
|
||||||
|
status = mysql_stmt_bind_param(statement, bind);
|
||||||
|
if (status!=0) {
|
||||||
|
mysql_stmt_close(statement);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_stmt_execute(statement);
|
||||||
|
mysql_stmt_close(statement);
|
||||||
|
|
||||||
|
if (type.Equals("nick"))
|
||||||
|
nickIgnoreList.push_back(target);
|
||||||
|
else if (type.Equals("chan"))
|
||||||
|
chanIgnoreList.push_back(target);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool RemoveIgnore(const CString& type, const CString& target) {
|
||||||
|
if (IgnoreExists(type, target)) {
|
||||||
|
MYSQL_STMT *statement = mysql_stmt_init(database);
|
||||||
|
int status = mysql_stmt_prepare(statement, "DELETE FROM `ignorelist` WHERE `type`=? AND `target`=?", 54);
|
||||||
|
if (status!=0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MYSQL_BIND bind[2];
|
||||||
|
memset(bind, 0, sizeof(bind));
|
||||||
|
|
||||||
|
bind[0].buffer_type = MYSQL_TYPE_STRING;
|
||||||
|
bind[0].buffer = (void*)type.c_str();
|
||||||
|
bind[0].buffer_length = type.length();
|
||||||
|
bind[0].is_null = false;
|
||||||
|
|
||||||
|
bind[1].buffer_type = MYSQL_TYPE_STRING;
|
||||||
|
bind[1].buffer = (void*)target.c_str();
|
||||||
|
bind[1].buffer_length = target.length();
|
||||||
|
bind[1].is_null = false;
|
||||||
|
|
||||||
|
status = mysql_stmt_bind_param(statement, bind);
|
||||||
|
if (status!=0) {
|
||||||
|
mysql_stmt_close(statement);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_stmt_execute(statement);
|
||||||
|
mysql_stmt_close(statement);
|
||||||
|
|
||||||
|
UpdateIgnoreLists();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool IgnoreExists(const CString& type, const CString& target) {
|
||||||
|
if (type.Equals("nick")) {
|
||||||
|
for (vector<CString>::iterator it=nickIgnoreList.begin(); it<nickIgnoreList.end(); it++) {
|
||||||
|
if (target.Equals(*it))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (type.Equals("chan")) {
|
||||||
|
for (vector<CString>::iterator it=chanIgnoreList.begin(); it<chanIgnoreList.end(); it++) {
|
||||||
|
if (target.Equals(*it))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool IsIgnored(const CString& type, const CString& target) {
|
||||||
|
if (type.Equals("nick")) {
|
||||||
|
for (vector<CString>::iterator it=nickIgnoreList.begin(); it<nickIgnoreList.end(); it++) {
|
||||||
|
if (target.WildCmp(*it))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (type.Equals("chan")) {
|
||||||
|
for (vector<CString>::iterator it=chanIgnoreList.begin(); it<chanIgnoreList.end(); it++) {
|
||||||
|
if (target.WildCmp(*it))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Server stuff
|
||||||
virtual void OnIRCDisconnected() {
|
virtual void OnIRCDisconnected() {
|
||||||
if (connected) {
|
if (connected) {
|
||||||
connected = false;
|
connected = false;
|
||||||
@ -955,6 +1226,9 @@ private:
|
|||||||
bool replayAll;
|
bool replayAll;
|
||||||
unsigned long logLimit;
|
unsigned long logLimit;
|
||||||
int logLevel;
|
int logLevel;
|
||||||
|
|
||||||
|
vector<CString> nickIgnoreList;
|
||||||
|
vector<CString> chanIgnoreList;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> void TModInfo<CLogMySQL>(CModInfo& Info) {
|
template<> void TModInfo<CLogMySQL>(CModInfo& Info) {
|
||||||
|
274
logsqlite.cpp
274
logsqlite.cpp
@ -33,6 +33,9 @@ public:
|
|||||||
AddCommand("ReplayAll", static_cast<CModCommand::ModCmdFunc>(&CLogSQLite::ReplayAllCommand), "[1|0]", "Replay all messages stored.");
|
AddCommand("ReplayAll", static_cast<CModCommand::ModCmdFunc>(&CLogSQLite::ReplayAllCommand), "[1|0]", "Replay all messages stored.");
|
||||||
AddCommand("LogLimit", static_cast<CModCommand::ModCmdFunc>(&CLogSQLite::LogLimitCommand), "[0-9]+", "Limit the amount of items to store into the log.");
|
AddCommand("LogLimit", static_cast<CModCommand::ModCmdFunc>(&CLogSQLite::LogLimitCommand), "[0-9]+", "Limit the amount of items to store into the log.");
|
||||||
AddCommand("LogLevel", static_cast<CModCommand::ModCmdFunc>(&CLogSQLite::LogLevelCommand), "[0-4]", "Log level.");
|
AddCommand("LogLevel", static_cast<CModCommand::ModCmdFunc>(&CLogSQLite::LogLevelCommand), "[0-4]", "Log level.");
|
||||||
|
AddCommand("AddIgnore", static_cast<CModCommand::ModCmdFunc>(&CLogSQLite::AddIgnoreCommand), "Type[nick|chan] Target", "Add to ignore list.");
|
||||||
|
AddCommand("RemoveIgnore", static_cast<CModCommand::ModCmdFunc>(&CLogSQLite::RemoveIgnoreCommand), "Type[nick|chan] Target", "Remove from ignore list.");
|
||||||
|
AddCommand("IgnoreList", static_cast<CModCommand::ModCmdFunc>(&CLogSQLite::IgnoreListCommand), "", "View what is currently ignored.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplayCommand(const CString &sLine) {
|
void ReplayCommand(const CString &sLine) {
|
||||||
@ -109,41 +112,157 @@ public:
|
|||||||
PutModule("LogLevel is "+now+"set to: "+setting);
|
PutModule("LogLevel is "+now+"set to: "+setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddIgnoreCommand(const CString &sLine) {
|
||||||
|
CString type = sLine.Token(1);
|
||||||
|
CString target = sLine.Token(2);
|
||||||
|
bool help = sLine.Equals("HELP");
|
||||||
|
|
||||||
|
if (help) {
|
||||||
|
PutModule("Inorder to add an ignore, you must choose what type of ignore it is which can ether be a nick or a chan.");
|
||||||
|
PutModule("Nicks are matched with wildcards against the full mask.");
|
||||||
|
PutModule("Channels are matched by #channel which can contain wildcards.");
|
||||||
|
} else if (!type.empty() && !target.empty()) {
|
||||||
|
if (type.Equals("nick"))
|
||||||
|
type = "nick";
|
||||||
|
else if (type.Equals("chan") || type.Equals("channel"))
|
||||||
|
type = "chan";
|
||||||
|
else
|
||||||
|
type = "";
|
||||||
|
|
||||||
|
if (type.empty()) {
|
||||||
|
PutModule("Unknown type. If you need help, type \"AddIgnore help\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AddIgnore(type, target))
|
||||||
|
PutModule("Successfully added \""+target+"\" to the ignore list.");
|
||||||
|
else
|
||||||
|
PutModule("Failed, maybe it already existed?");
|
||||||
|
} else {
|
||||||
|
PutModule("If you need help, type \"AddIgnore help\".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveIgnoreCommand(const CString &sLine) {
|
||||||
|
CString type = sLine.Token(1);
|
||||||
|
CString target = sLine.Token(2);
|
||||||
|
bool help = sLine.Equals("HELP");
|
||||||
|
|
||||||
|
if (help) {
|
||||||
|
PutModule("Inorder to remove an ignore, you must specify the type and the exact pattren used to add it. If you need to find what currently exists, type \"IgnoreList\".");
|
||||||
|
} else if (!type.empty() && !target.empty()) {
|
||||||
|
if (type.Equals("nick"))
|
||||||
|
type = "nick";
|
||||||
|
else if (type.Equals("chan") || type.Equals("channel"))
|
||||||
|
type = "chan";
|
||||||
|
else
|
||||||
|
type = "";
|
||||||
|
|
||||||
|
if (type.empty()) {
|
||||||
|
PutModule("Unknown type. If you need help, type \"RemoveIgnore help\".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RemoveIgnore(type, target))
|
||||||
|
PutModule("Successfully removed \""+target+"\" from the ignore list.");
|
||||||
|
else
|
||||||
|
PutModule("Failed, maybe it does not exist?");
|
||||||
|
} else {
|
||||||
|
PutModule("If you need help, type \"RemoveIgnore help\".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IgnoreListCommand(const CString &sLine) {
|
||||||
|
if (nickIgnoreList.size()==0) {
|
||||||
|
PutModule("The nick ignore list is currently empty.");
|
||||||
|
} else {
|
||||||
|
PutModule("Nick ignore list contains:");
|
||||||
|
|
||||||
|
for (vector<CString>::iterator it=nickIgnoreList.begin(); it<nickIgnoreList.end(); it++) {
|
||||||
|
PutModule(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PutModule("---");
|
||||||
|
if (chanIgnoreList.size()==0) {
|
||||||
|
PutModule("The channel ignore list is currently empty.");
|
||||||
|
} else {
|
||||||
|
PutModule("Channel ignore list contains:");
|
||||||
|
|
||||||
|
for (vector<CString>::iterator it=chanIgnoreList.begin(); it<chanIgnoreList.end(); it++) {
|
||||||
|
PutModule(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
|
virtual bool OnLoad(const CString& sArgs, CString& sMessage) {
|
||||||
connected = true;
|
connected = true;
|
||||||
|
|
||||||
CString savePath = GetSavePath();
|
CString savePath = GetSavePath();
|
||||||
savePath += "/log.sqlite";
|
savePath += "/log.sqlite";
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
FILE *fp = fopen(savePath.c_str(), "rb");
|
|
||||||
if (fp!=NULL) {
|
|
||||||
found = true;
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_open(savePath.c_str(), &database);
|
sqlite3_open(savePath.c_str(), &database);
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
sqlite3_stmt *result;
|
sqlite3_stmt *result;
|
||||||
int status = sqlite3_prepare(database, "CREATE TABLE `settings` (`name` text, `value` text)", -1, &result, NULL);
|
int status = sqlite3_prepare(database, "SELECT `name` FROM `sqlite_master` WHERE `name`='settings'", -1, &result, NULL);
|
||||||
|
if (status==SQLITE_OK) {
|
||||||
|
status = SQLITE_BUSY;
|
||||||
|
while (status==SQLITE_BUSY) {
|
||||||
|
status = sqlite3_step(result);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
if (status!=SQLITE_ROW) {
|
||||||
|
status = sqlite3_prepare(database, "CREATE TABLE `settings` (`name` text, `value` text)", -1, &result, NULL);
|
||||||
if (status==SQLITE_OK) {
|
if (status==SQLITE_OK) {
|
||||||
sqlite3_step(result);
|
sqlite3_step(result);
|
||||||
sqlite3_finalize(result);
|
sqlite3_finalize(result);
|
||||||
|
|
||||||
|
SetSetting("replayAll","0");
|
||||||
|
SetSetting("logLimit","1");
|
||||||
|
SetSetting("logLevel","1");
|
||||||
|
SetSetting("version","1");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
status = sqlite3_prepare(database, "SELECT `name` FROM `sqlite_master` WHERE `name`='messages'", -1, &result, NULL);
|
||||||
|
if (status==SQLITE_OK) {
|
||||||
|
status = SQLITE_BUSY;
|
||||||
|
while (status==SQLITE_BUSY) {
|
||||||
|
status = sqlite3_step(result);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
if (status!=SQLITE_ROW) {
|
||||||
status = sqlite3_prepare(database, "CREATE TABLE `messages` (`target` text, `nick` text, `type` text, `message` text, `time` real(20,5))", -1, &result, NULL);
|
status = sqlite3_prepare(database, "CREATE TABLE `messages` (`target` text, `nick` text, `type` text, `message` text, `time` real(20,5))", -1, &result, NULL);
|
||||||
if (status==SQLITE_OK) {
|
if (status==SQLITE_OK) {
|
||||||
sqlite3_step(result);
|
sqlite3_step(result);
|
||||||
sqlite3_finalize(result);
|
sqlite3_finalize(result);
|
||||||
}
|
}
|
||||||
SetSetting("replayAll","0");
|
}
|
||||||
SetSetting("logLimit","1");
|
}
|
||||||
SetSetting("logLevel","1");
|
status = sqlite3_prepare(database, "SELECT `name` FROM `sqlite_master` WHERE `name`='ignorelist'", -1, &result, NULL);
|
||||||
|
if (status==SQLITE_OK) {
|
||||||
|
status = SQLITE_BUSY;
|
||||||
|
while (status==SQLITE_BUSY) {
|
||||||
|
status = sqlite3_step(result);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
if (status!=SQLITE_ROW) {
|
||||||
|
status = sqlite3_prepare(database, "CREATE TABLE `ignorelist` (`type` text, `target` text)", -1, &result, NULL);
|
||||||
|
if (status==SQLITE_OK) {
|
||||||
|
sqlite3_step(result);
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
replayAll = atoi(GetSetting("replayAll").c_str());
|
replayAll = atoi(GetSetting("replayAll").c_str());
|
||||||
logLimit = strtoul(GetSetting("logLimit").c_str(), NULL, 10);
|
logLimit = strtoul(GetSetting("logLimit").c_str(), NULL, 10);
|
||||||
logLevel = atoi(GetSetting("logLevel").c_str());
|
logLevel = atoi(GetSetting("logLevel").c_str());
|
||||||
|
|
||||||
|
unsigned long version = strtoul(GetSetting("version").c_str(), NULL, 10);
|
||||||
|
if (version==0)
|
||||||
|
SetSetting("version","1");
|
||||||
|
|
||||||
|
UpdateIgnoreLists();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +289,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AddMessage(const CString& target, const CString& nick, const CString& type, const CString& message) {
|
void AddMessage(const CString& target, const CString& nick, const CString& type, const CString& message) {
|
||||||
|
if (IsIgnored("nick",nick) || (target.Left(1).Equals("#") && IsIgnored("chan",target)))
|
||||||
|
return;
|
||||||
sqlite3_stmt *result;
|
sqlite3_stmt *result;
|
||||||
int status = sqlite3_prepare(database, "INSERT INTO `messages` (`target`, `nick`, `type`, `message`, `time`) VALUES (?,?,?,?,?)", -1, &result, NULL);
|
int status = sqlite3_prepare(database, "INSERT INTO `messages` (`target`, `nick`, `type`, `message`, `time`) VALUES (?,?,?,?,?)", -1, &result, NULL);
|
||||||
if (status!=SQLITE_OK)
|
if (status!=SQLITE_OK)
|
||||||
@ -355,8 +476,132 @@ public:
|
|||||||
sqlite3_finalize(result);
|
sqlite3_finalize(result);
|
||||||
return stringValue;
|
return stringValue;
|
||||||
}
|
}
|
||||||
//Server stuff
|
|
||||||
|
|
||||||
|
|
||||||
|
void UpdateIgnoreLists() {
|
||||||
|
nickIgnoreList.clear();
|
||||||
|
sqlite3_stmt *result;
|
||||||
|
int status = sqlite3_prepare(database, "SELECT `target` FROM `ignorelist` WHERE `type`='nick'", -1, &result, NULL);
|
||||||
|
if (status==SQLITE_OK) {
|
||||||
|
while (true) {
|
||||||
|
status = SQLITE_BUSY;
|
||||||
|
while (status==SQLITE_BUSY) {
|
||||||
|
status = sqlite3_step(result);
|
||||||
|
}
|
||||||
|
if (status!=SQLITE_ROW)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int dataCount = sqlite3_data_count(result);
|
||||||
|
if (dataCount!=1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
CString ignore = CString((const char *)sqlite3_column_text(result, 0));
|
||||||
|
nickIgnoreList.push_back(ignore);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
}
|
||||||
|
chanIgnoreList.clear();
|
||||||
|
status = sqlite3_prepare(database, "SELECT `target` FROM `ignorelist` WHERE `type`='chan'", -1, &result, NULL);
|
||||||
|
if (status==SQLITE_OK) {
|
||||||
|
while (true) {
|
||||||
|
status = SQLITE_BUSY;
|
||||||
|
while (status==SQLITE_BUSY) {
|
||||||
|
status = sqlite3_step(result);
|
||||||
|
}
|
||||||
|
if (status!=SQLITE_ROW)
|
||||||
|
break;
|
||||||
|
|
||||||
|
int dataCount = sqlite3_data_count(result);
|
||||||
|
if (dataCount!=1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
CString ignore = CString((const char *)sqlite3_column_text(result, 0));
|
||||||
|
chanIgnoreList.push_back(ignore);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool AddIgnore(const CString& type, const CString& target) {
|
||||||
|
if (!IgnoreExists(type, target)) {
|
||||||
|
sqlite3_stmt *result;
|
||||||
|
int status = sqlite3_prepare(database, "INSERT INTO `ignorelist` (`type`, `target`) VALUES (?,?)", -1, &result, NULL);
|
||||||
|
if (status!=SQLITE_OK)
|
||||||
|
return false;
|
||||||
|
status = sqlite3_bind_text(result, 1, type.c_str(), type.length(), SQLITE_STATIC);
|
||||||
|
if (status!=SQLITE_OK) {
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
status = sqlite3_bind_text(result, 2, target.c_str(), target.length(), SQLITE_STATIC);
|
||||||
|
if (status!=SQLITE_OK) {
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sqlite3_step(result);
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
|
||||||
|
if (type.Equals("nick"))
|
||||||
|
nickIgnoreList.push_back(target);
|
||||||
|
else if (type.Equals("chan"))
|
||||||
|
chanIgnoreList.push_back(target);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool RemoveIgnore(const CString& type, const CString& target) {
|
||||||
|
if (IgnoreExists(type, target)) {
|
||||||
|
sqlite3_stmt *result;
|
||||||
|
int status = sqlite3_prepare(database, "DELETE FROM `ignorelist` WHERE `type`=? AND `target`=?", -1, &result, NULL);
|
||||||
|
if (status!=SQLITE_OK)
|
||||||
|
return false;
|
||||||
|
status = sqlite3_bind_text(result, 1, type.c_str(), type.length(), SQLITE_STATIC);
|
||||||
|
if (status!=SQLITE_OK) {
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
status = sqlite3_bind_text(result, 2, target.c_str(), target.length(), SQLITE_STATIC);
|
||||||
|
if (status!=SQLITE_OK) {
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sqlite3_step(result);
|
||||||
|
sqlite3_finalize(result);
|
||||||
|
|
||||||
|
UpdateIgnoreLists();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool IgnoreExists(const CString& type, const CString& target) {
|
||||||
|
if (type.Equals("nick")) {
|
||||||
|
for (vector<CString>::iterator it=nickIgnoreList.begin(); it<nickIgnoreList.end(); it++) {
|
||||||
|
if (target.Equals(*it))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (type.Equals("chan")) {
|
||||||
|
for (vector<CString>::iterator it=chanIgnoreList.begin(); it<chanIgnoreList.end(); it++) {
|
||||||
|
if (target.Equals(*it))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool IsIgnored(const CString& type, const CString& target) {
|
||||||
|
if (type.Equals("nick")) {
|
||||||
|
for (vector<CString>::iterator it=nickIgnoreList.begin(); it<nickIgnoreList.end(); it++) {
|
||||||
|
if (target.WildCmp(*it))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (type.Equals("chan")) {
|
||||||
|
for (vector<CString>::iterator it=chanIgnoreList.begin(); it<chanIgnoreList.end(); it++) {
|
||||||
|
if (target.WildCmp(*it))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Server stuff
|
||||||
virtual void OnIRCDisconnected() {
|
virtual void OnIRCDisconnected() {
|
||||||
if (connected) {
|
if (connected) {
|
||||||
connected = false;
|
connected = false;
|
||||||
@ -647,6 +892,9 @@ private:
|
|||||||
bool replayAll;
|
bool replayAll;
|
||||||
unsigned long logLimit;
|
unsigned long logLimit;
|
||||||
int logLevel;
|
int logLevel;
|
||||||
|
|
||||||
|
vector<CString> nickIgnoreList;
|
||||||
|
vector<CString> chanIgnoreList;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> void TModInfo<CLogSQLite>(CModInfo& Info) {
|
template<> void TModInfo<CLogSQLite>(CModInfo& Info) {
|
||||||
|
Loading…
Reference in New Issue
Block a user