From c955324b8d2e776fc73b5ed16a26c1c5a3482a09 Mon Sep 17 00:00:00 2001 From: pk910 Date: Wed, 14 Sep 2011 23:35:30 +0200 Subject: [PATCH] added cmd_resync --- bot_NeonServ.c | 10 ++-- cmd_neonserv_resync.c | 118 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 cmd_neonserv_resync.c diff --git a/bot_NeonServ.c b/bot_NeonServ.c index de1d56e..502d7cb 100644 --- a/bot_NeonServ.c +++ b/bot_NeonServ.c @@ -166,6 +166,7 @@ static const struct default_language_entry msgtab[] = { {"NS_UNREGISTER_NOT_REGISTERED", "\002%s\002 is not registered with %s."}, {"NS_UNREGISTER_DONE", "\002%s\002 unregistered."}, {"NS_RECOVER_DONE", "\002%s\002 has been recovered."}, + {"NS_RESYNC_DONE", "Synchronized users in \002%s\002 with the userlist."}, {NULL, NULL} }; @@ -218,7 +219,7 @@ INCLUDE ALL CMD's HERE //#include "cmd_neonserv_peek.c" #include "cmd_neonserv_set.c" /* TODO: parse, check and set modelock */ //#include "cmd_neonserv_events.c" -//#include "cmd_neonserv_resync.c" +#include "cmd_neonserv_resync.c" //#include "cmd_neonserv_help.c" //#include "cmd_neonserv_version.c" #include "cmd_neonserv_chanservsync.c" @@ -352,11 +353,12 @@ void init_NeonServ() { register_command(BOTID, "netinfo", neonserv_cmd_netinfo, 0, 0, NULL, 0); register_command(BOTID, "topic", neonserv_cmd_topic, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_changetopic", 0); register_command(BOTID, "chanservsync", neonserv_cmd_chanservsync, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH,"500", 0); + register_command(BOTID, "resync", neonserv_cmd_resync, 0, CMDFLAG_REQUIRE_CHAN | CMDFLAG_REGISTERED_CHAN | CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, "#channel_canresync", 0); register_command(BOTID, "trace", neonserv_cmd_trace, 1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH, NULL, 400); - register_command(BOTID, "register", neonserv_cmd_register, 2, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM, NULL, 100); - register_command(BOTID, "unregister", neonserv_cmd_unregister,1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM, NULL, 100); - register_command(BOTID, "recover", neonserv_cmd_recover, 1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM, NULL, 100); + register_command(BOTID, "register", neonserv_cmd_register, 2, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG, NULL, 100); + register_command(BOTID, "unregister", neonserv_cmd_unregister,1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG, NULL, 100); + register_command(BOTID, "recover", neonserv_cmd_recover, 1, CMDFLAG_REQUIRE_AUTH | CMDFLAG_CHECK_AUTH | CMDFLAG_CHAN_PARAM | CMDFLAG_OPLOG, NULL, 100); start_bots(); bind_bot_ready(neonserv_bot_ready); diff --git a/cmd_neonserv_resync.c b/cmd_neonserv_resync.c new file mode 100644 index 0000000..a05c0ee --- /dev/null +++ b/cmd_neonserv_resync.c @@ -0,0 +1,118 @@ + +/* +* argv[0] - usermask +* argv[1] - min access +* argv[2] - max access +*/ +static USERLIST_CALLBACK(neonserv_cmd_resync_userlist_lookup); +static void neonserv_cmd_resync_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *usermask, int min_access, int max_access); + +struct neonserv_cmd_resync_cache { + struct ClientSocket *client, *textclient; + struct UserNode *user; + char *usermask; + int min_access; + int max_access; +}; + +static CMD_BIND(neonserv_cmd_resync) { + int min_access = 1, max_access = 500; + char *usermask = NULL; + if(argc > 0) + usermask = argv[0]; + if(argc > 2) { + min_access = atoi(argv[1]); + max_access = atoi(argv[2]); + } + struct neonserv_cmd_resync_cache *cache = malloc(sizeof(*cache)); + if (!cache) { + perror("malloc() failed"); + return; + } + cache->client = client; + cache->textclient = getTextBot(); + cache->user = user; + cache->usermask = (usermask ? strdup(usermask) : NULL); + cache->min_access = min_access; + cache->max_access = max_access; + get_userlist_with_invisible(chan, neonserv_cmd_resync_userlist_lookup, cache); +} + +static USERLIST_CALLBACK(neonserv_cmd_resync_userlist_lookup) { + struct neonserv_cmd_resync_cache *cache = data; + neonserv_cmd_resync_async1(cache->client, cache->textclient, cache->user, chan, cache->usermask, cache->min_access, cache->max_access); + if(cache->usermask) + free(cache->usermask); + free(cache); +} + +static void neonserv_cmd_resync_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *usermask, int min_access, int max_access) { + MYSQL_RES *res; + MYSQL_ROW row, defaults; + int i; + int resync_op = 1; + int resync_voice = 1; + if(usermask && usermask[0] == '@') { + resync_voice = 0; + usermask++; + } else if(usermask && usermask[0] == '+') { + resync_op = 0; + usermask++; + } + struct ChanUser *chanuser; + int db_enfops, db_enfvoice; + printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id); + row = mysql_fetch_row(mysql_use()); + if(row[0] == NULL || row[1] == NULL) { + printf_mysql_query("SELECT `channel_getop`, `channel_getvoice` FROM `channels` WHERE `channel_name` = 'defaults'"); + defaults = mysql_fetch_row(mysql_use()); + } + db_enfops = atoi((row[0] ? row[0] : defaults[0])); + db_enfvoice = atoi((row[1] ? row[1] : defaults[1])); + printf_mysql_query("SELECT `chanuser_access`, `user_user`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' ORDER BY `chanuser_access` DESC, `user_user` ASC", chan->channel_id); + res = mysql_use(); + char *db_users[mysql_num_rows(res)]; + int db_access[mysql_num_rows(res)]; + int db_flags[mysql_num_rows(res)]; + int db_count = 0; + while ((row = mysql_fetch_row(res)) != NULL) { + db_users[db_count] = row[1]; + db_access[db_count] = atoi(row[0]); + db_flags[db_count] = atoi(row[2]); + db_count++; + } + int caccess, cflags; + struct ModeBuffer *modeBuf; + modeBuf = initModeBuffer(client, chan); + for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) { + caccess = 0; + cflags = 0; + if((chanuser->user->flags & USERFLAG_ISAUTHED)) { + for(i = 0; i < db_count; i++) { + if(!stricmp(db_users[i], chanuser->user->auth)) { + caccess = db_access[i]; + cflags = db_flags[i]; + break; + } + } + } + if((usermask && match(usermask, row[1])) || caccess < min_access || caccess > max_access) continue; + if(caccess >= db_enfops) { + if(!(chanuser->flags & CHANUSERFLAG_OPPED) && resync_op) + modeBufferOp(modeBuf, chanuser->user->nick); + } else if(caccess >= db_enfvoice) { + if((chanuser->flags & CHANUSERFLAG_OPPED) && resync_op) + modeBufferDeop(modeBuf, chanuser->user->nick); + if(!(chanuser->flags & CHANUSERFLAG_VOICED) && resync_voice) + modeBufferVoice(modeBuf, chanuser->user->nick); + } else { + if((chanuser->flags & CHANUSERFLAG_OPPED) && resync_op) + modeBufferDeop(modeBuf, chanuser->user->nick); + if((chanuser->flags & CHANUSERFLAG_VOICED) && resync_voice) + modeBufferDevoice(modeBuf, chanuser->user->nick); + } + + } + freeModeBuffer(modeBuf); + reply(textclient, user, "NS_RESYNC_DONE", chan->name); +} -- 2.20.1