X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Fmodules%2FNeonServ.mod%2Fcmd_neonserv_unvisited.c;h=5f1572e17ee823fc4075f1ce1f8359d064bf9768;hb=ee39770362f69ced5b52104b622582e882af0b77;hp=5e639b2836bce8cfb861cbb1330d22610b8c9ef9;hpb=689da1db7e2517c187ce76c6c553e20d630a7f36;p=NeonServV5.git diff --git a/src/modules/NeonServ.mod/cmd_neonserv_unvisited.c b/src/modules/NeonServ.mod/cmd_neonserv_unvisited.c index 5e639b2..5f1572e 100644 --- a/src/modules/NeonServ.mod/cmd_neonserv_unvisited.c +++ b/src/modules/NeonServ.mod/cmd_neonserv_unvisited.c @@ -1,4 +1,4 @@ -/* cmd_neonserv_unvisited.c - NeonServ v5.4 +/* cmd_neonserv_unvisited.c - NeonServ v5.6 * Copyright (C) 2011-2012 Philipp Kreil (pk910) * * This program is free software: you can redistribute it and/or modify @@ -16,36 +16,75 @@ */ #include "cmd_neonserv.h" +#include "../botid.h" struct neonserv_cmd_unvisited_cache { struct ClientSocket *client, *textclient; struct UserNode *user; - int duration; + int duration, unregister_matches; int who_count, matches; }; static USERLIST_CALLBACK(neonserv_cmd_unvisited_userlist_lookup); -static int neonserv_cmd_unvisited_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, int duration); +static void neonserv_check_unvisited(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, int duration, int unregister_matches); +static int neonserv_cmd_unvisited_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, int duration, int unregister_matches); static void neonserv_cmd_unvisited_async2(struct neonserv_cmd_unvisited_cache *cache); +static void neonserv_cmd_unvisited_unreg(struct ClientSocket *client, char *channel); +static TIMEQ_CALLBACK(neonserv_check_unvisited_timer); CMD_BIND(neonserv_cmd_unvisited) { int duration = (argc ? strToTime(user, argv[0]) : 60*60*24*7*3); - reply(getTextBot(), user, "NS_SEARCH_HEADER"); + reply(textclient, user, "NS_SEARCH_HEADER"); + int unreg = 0; + if(argc > 1 && !stricmp(argv[1], "unregister")) + unreg = 1; + neonserv_check_unvisited(client, textclient, user, duration, unreg); +} + +void neonserv_cmd_unvisited_init() { + if(!timeq_name_exists("neonserv_unvisited")) + timeq_add_name("neonserv_unvisited", 1200, module_id, neonserv_check_unvisited_timer, NULL); +} + +static TIMEQ_CALLBACK(neonserv_check_unvisited_timer) { + char tmp[200]; + char *modname = get_module_name(module_id); + sprintf(tmp, "modules.%s.chan_expire_freq", modname); + char *check_freq_str = get_string_field(tmp); + int check_freq; + if(!check_freq_str || (check_freq = strToTime(NULL, check_freq_str)) < (60*60)) { + timeq_add_name("neonserv_unvisited", 1800, module_id, neonserv_check_unvisited_timer, NULL); + return; + } + sprintf(tmp, "modules.%s.chan_expire_delay", modname); + char *check_expire_str = get_string_field(tmp); + int duration; + if(!check_expire_str || (duration = strToTime(NULL, check_expire_str)) < 60*60*24*7) return; + neonserv_check_unvisited(NULL, NULL, NULL, duration, 1); +} + +static void neonserv_check_unvisited(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, int duration, int unregister_matches) { MYSQL_RES *res, *res2; MYSQL_ROW row, row2; struct ChanNode *channel; struct neonserv_cmd_unvisited_cache *cache = malloc(sizeof(*cache)); if (!cache) { - perror("malloc() failed"); + printf_log("neonserv", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__); return; } cache->client = client; - cache->textclient = getTextBot(); + cache->textclient = textclient; cache->user = user; cache->duration = duration; + cache->unregister_matches = unregister_matches; cache->who_count = 1; /* small fake to prevent the cache to be freed too early */ cache->matches = 0; - printf_mysql_query("SELECT `channel_id`, `channel_name`, `channel_nodelete` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` LEFT JOIN `users` ON `channel_registrator` = `user_id` WHERE `botid` = '%d'", client->botid); + int botid; + if(client) + botid = client->botid; + else + botid = NEONSERV_BOTID; + printf_mysql_query("SELECT `channel_id`, `channel_name`, `channel_nodelete` FROM `bot_channels` LEFT JOIN `channels` ON `chanid` = `channel_id` LEFT JOIN `users` ON `channel_registrator` = `user_id` WHERE `botid` = '%d'", botid); res = mysql_use(); while ((row = mysql_fetch_row(res)) != NULL) { if(!strcmp(row[2], "1")) continue; @@ -59,11 +98,14 @@ CMD_BIND(neonserv_cmd_unvisited) { channel->channel_id = atoi(row[0]); get_userlist_with_invisible(channel, module_id, neonserv_cmd_unvisited_userlist_lookup, cache); } else { - reply(getTextBot(), user, "%s", row[1]); + if(textclient) + reply(textclient, user, "%s", row[1]); + if(unregister_matches) + neonserv_cmd_unvisited_unreg(client, row[1]); cache->matches++; } } - cache->who_count--; //see fix on line 46 + cache->who_count--; //see fix on line 78 if(cache->who_count == 0) { neonserv_cmd_unvisited_async2(cache); } @@ -71,7 +113,7 @@ CMD_BIND(neonserv_cmd_unvisited) { static USERLIST_CALLBACK(neonserv_cmd_unvisited_userlist_lookup) { struct neonserv_cmd_unvisited_cache *cache = data; - if(neonserv_cmd_unvisited_async1(cache->client, cache->textclient, cache->user, chan, cache->duration)) + if(neonserv_cmd_unvisited_async1(cache->client, cache->textclient, cache->user, chan, cache->duration, cache->unregister_matches)) cache->matches++; cache->who_count--; if(cache->who_count == 0) { @@ -79,7 +121,7 @@ static USERLIST_CALLBACK(neonserv_cmd_unvisited_userlist_lookup) { } } -static int neonserv_cmd_unvisited_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, int duration) { +static int neonserv_cmd_unvisited_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, int duration, int unregister_matches) { struct ChanUser *chanuser; MYSQL_RES *res2; MYSQL_ROW row2; @@ -97,12 +139,74 @@ static int neonserv_cmd_unvisited_async1(struct ClientSocket *client, struct Cli } } if(!active) { - reply(textclient, user, "%s", chan->name); + if(textclient) + reply(textclient, user, "%s", chan->name); + if(unregister_matches) + neonserv_cmd_unvisited_unreg(client, chan->name); } return !active; } static void neonserv_cmd_unvisited_async2(struct neonserv_cmd_unvisited_cache *cache) { - reply(cache->textclient, cache->user, "NS_TABLE_COUNT", cache->matches); + if(cache->textclient) + reply(cache->textclient, cache->user, "NS_TABLE_COUNT", cache->matches); free(cache); } + +static void neonserv_cmd_unvisited_unreg(struct ClientSocket *client, char *channel) { + MYSQL_RES *res; + MYSQL_ROW row; + int sync_neonspam_unreg = get_int_field("General.sync_neonspam_unreg"); + int botid; + if(client) + botid = client->botid; + else + botid = NEONSERV_BOTID; + printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended`, `channels`.`channel_nodelete` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `channel_name` = '%s' AND `botclass` = '%d'", escape_string(channel), botid); + res = mysql_use(); + if ((row = mysql_fetch_row(res)) == NULL) { + return; + } + int clientid = atoi(row[0]); + struct ClientSocket *bot; + for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { + if(bot->clientid == clientid) + break; + } + if(!strcmp(row[3], "1")) return; + printf_mysql_query("DELETE FROM `bot_channels` WHERE `id` = '%s'", row[1]); + if(bot && strcmp(row[2], "1")) { + putsock(bot, "PART %s :Channel unregistered.", channel); + } + if(botid == NEONSERV_BOTID && sync_neonspam_unreg) { + botid = NEONSPAM_BOTID; + printf_mysql_query("SELECT `botid`, `bot_channels`.`id`, `suspended` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` LEFT JOIN `channels` ON `chanid` = `channel_id` WHERE `channel_name` = '%s' AND `botclass` = '%d'", escape_string(channel), botid); + res = mysql_use(); + if ((row = mysql_fetch_row(res)) == NULL) { + return; + } + clientid = atoi(row[0]); + for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) { + if(bot->clientid == clientid) + break; + } + printf_mysql_query("DELETE FROM `bot_channels` WHERE `id` = '%s'", row[1]); + if(bot && strcmp(row[2], "1")) { + putsock(bot, "PART %s :Channel unregistered.", channel); + } + } + if(botid == NEONSERV_BOTID) { + char setting[128]; + sprintf(setting, "modules.%s.auto_backup_unregister", get_module_name(module_id)); + if(get_int_field(setting)) + module_global_cmd_unregister_neonbackup(channel); + } + char *alertchan = get_string_field("General.alertchan"); + if(alertchan) { + struct ChanNode *alertchan_chan = getChanByName(alertchan); + struct ClientSocket *alertclient; + if(alertchan_chan && (alertclient = getChannelBot(alertchan_chan, 0)) != NULL) { + putsock(alertclient, "PRIVMSG %s :Unregistered %s (unvisited)", alertchan_chan->name, channel); + } + } +}