From e8d727a45b58314260ec4785262d646484583d3b Mon Sep 17 00:00:00 2001 From: pk910 Date: Sat, 17 Sep 2011 01:27:45 +0200 Subject: [PATCH] added mode +-b to cmd_mode --- bot_NeonServ.c | 3 ++ cmd_neonserv_mode.c | 78 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/bot_NeonServ.c b/bot_NeonServ.c index 7c1571b..4a423b0 100644 --- a/bot_NeonServ.c +++ b/bot_NeonServ.c @@ -173,6 +173,9 @@ static const struct default_language_entry msgtab[] = { {"NS_MODE_INVALID", "\002%c\002 is an invalid set of channel modes."}, {"NS_MODE_LOCKED", "Modes conflicting with \002%s\002 are not allowed in %s."}, {"NS_MODE_DONE", "Channel modes are now \002%s\002."}, + {"NS_MODE_ENFOPS", "You may not op or deop users on \002%s\002."}, + {"NS_MODE_ENFVOICE", "You may not voice or devoice users on \002%s\002."}, + {"NS_MODE_CANBAN", "You may not ban or unban users on \002%s\002."}, {NULL, NULL} }; diff --git a/cmd_neonserv_mode.c b/cmd_neonserv_mode.c index 8358997..ac593ab 100644 --- a/cmd_neonserv_mode.c +++ b/cmd_neonserv_mode.c @@ -36,11 +36,13 @@ static USERLIST_CALLBACK(neonserv_cmd_mode_userlist_lookup) { static void neonserv_cmd_mode_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *mode) { MYSQL_ROW row, defaults = NULL; - int i, arg, add = 1; + int i, arg, add = 1, skip = 0; unsigned int modetype; int db_canop, db_canvoice, db_canban, db_enfmodes; struct ModeNode *modelock = createModeNode(NULL), *changemodes = createModeNode(NULL); struct ModeBuffer *modeBuf; + struct UserNode *cuser; + struct ChanUser *chanuser; modeBuf = initModeBuffer(client, chan); printf_mysql_query("SELECT `channel_canop`, `channel_canvoice`, `channel_canban`, `channel_enfmodes`, `channel_modes` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id); row = mysql_fetch_row(mysql_use()); @@ -87,15 +89,21 @@ static void neonserv_cmd_mode_async1(struct ClientSocket *client, struct ClientS return; } carg = argv[arg++]; - if(uaccess < (modeStr[i] == 'o' ? db_canop : db_canvoice)) { - reply(textclient, user, "NS_MODE_ENFOPS", chan->name); - if(modeStr[i] == 'o') db_canop = -1; - else db_canvoice = -1; - break; + if(modeStr[i] == 'o') { + if(uaccess < db_canop) { + reply(textclient, user, "NS_MODE_ENFOPS", chan->name); + db_canop = -1; + break; + } + if(db_canop == -1) break; + } else { + if(uaccess < db_canvoice) { + reply(textclient, user, "NS_MODE_ENFVOICE", chan->name); + db_canvoice = -1; + break; + } + if(db_canvoice == -1) break; } - if((modeStr[i] == 'o' ? db_canop : db_canvoice) == -1) break; - struct UserNode *cuser; - struct ChanUser *chanuser; cuser = searchUserByNick(carg); if(!cuser) { //check for an invisible user @@ -125,7 +133,57 @@ static void neonserv_cmd_mode_async1(struct ClientSocket *client, struct ClientS modeBufferSet(modeBuf, add, modeStr[i], carg); break; case 'b': - + if(arg == argc) { + reply(textclient, user, "NS_MODE_INVALID", modeStr[i]); + return; + } + carg = argv[arg++]; + if(uaccess < db_canban) { + reply(textclient, user, "NS_MODE_CANBAN", chan->name); + db_canban = -1; + break; + } + if(db_canban == -1) break; + char hostmask_buffer[NICKLEN+USERLEN+HOSTLEN+3]; + char usermask[NICKLEN+USERLEN+HOSTLEN+3]; + struct BanNode *ban; + int match_count = 0; + carg = make_banmask(carg, hostmask_buffer); + if(add) { + for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) { + cuser = chanuser->user; + sprintf(usermask, "%s!%s@%s", cuser->nick, cuser->ident, cuser->host); + if(!match(carg, usermask)) { + if(isNetworkService(chanuser->user)) { + reply(textclient, user, "NS_SERVICE_IMMUNE", chanuser->user->nick); + skip = 1; + break; + } + if(isUserProtected(chan, cuser, user)) { + reply(textclient, user, "NS_USER_PROTECTED", cuser->nick); + skip = 1; + break; + } + match_count++; + if(match_count > 4 && (match_count * 3) > chan->usercount && !isGodMode(user)) { + skip = 1; + reply(textclient, user, "NS_LAME_MASK", carg); + break; + } + } + } + } else { + skip = 1; + for(ban = chan->bans; ban; ban = ban->next) { + if(!match(carg, ban->mask)) { + skip = 0; + break; + } + } + } + if(!skip) { + modeBufferSet(modeBuf, add, 'b', carg); + } break; default: modetype = getModeType(modelock, modeStr[i]); -- 2.20.1