From d7d01bdc5c667a1fafd95241282b58e03b4caa5b Mon Sep 17 00:00:00 2001 From: rburchell Date: Mon, 9 Feb 2009 21:01:05 +0000 Subject: Squashed commit: merge next (1.9.1) back to trunk. SVN users, NOTE: THIS WILL NOT BUILD, NOR SHOULD YOU RUN IT YET. git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@1953 5417fbe8-f217-4b02-8779-1006273d7864 --- src/actions.c | 43 +- src/botserv.c | 18 +- src/channels.c | 37 +- src/chanserv.c | 24 +- src/commands.c | 132 ++--- src/core/bs_act.c | 102 ++-- src/core/bs_assign.c | 115 ++-- src/core/bs_badwords.c | 323 ++++++---- src/core/bs_bot.c | 178 +++--- src/core/bs_botlist.c | 110 ++-- src/core/bs_fantasy.c | 79 --- src/core/bs_fantasy_kick.c | 87 --- src/core/bs_fantasy_kickban.c | 89 --- src/core/bs_fantasy_owner.c | 78 --- src/core/bs_fantasy_seen.c | 128 ---- src/core/bs_help.c | 44 +- src/core/bs_info.c | 451 +++++++------- src/core/bs_kick.c | 598 +++++++++---------- src/core/bs_say.c | 112 ++-- src/core/bs_set.c | 300 +++++----- src/core/bs_unassign.c | 75 +-- src/core/cs_access.c | 748 +++++++++++------------ src/core/cs_akick.c | 852 ++++++++++++++------------- src/core/cs_ban.c | 317 +++++----- src/core/cs_clear.c | 596 ++++++++++--------- src/core/cs_drop.c | 145 +++-- src/core/cs_forbid.c | 153 ++--- src/core/cs_getkey.c | 105 ++-- src/core/cs_getpass.c | 124 ++-- src/core/cs_help.c | 94 +-- src/core/cs_identify.c | 131 +++-- src/core/cs_info.c | 301 ++++------ src/core/cs_invite.c | 111 ++-- src/core/cs_kick.c | 173 +++--- src/core/cs_logout.c | 2 +- src/core/cs_register.c | 4 +- src/core/cs_sendpass.c | 2 +- src/core/cs_set.c | 12 +- src/core/cs_topic.c | 2 +- src/core/cs_xop.c | 2 +- src/core/he_help.c | 63 +- src/core/hs_del.c | 86 +-- src/core/hs_delall.c | 98 +-- src/core/hs_group.c | 140 +++-- src/core/hs_help.c | 49 +- src/core/hs_list.c | 260 ++++---- src/core/hs_off.c | 77 +-- src/core/hs_on.c | 106 ++-- src/core/hs_set.c | 257 ++++---- src/core/hs_setall.c | 255 ++++---- src/core/ms_cancel.c | 112 ++-- src/core/ms_check.c | 144 ++--- src/core/ms_del.c | 271 +++++---- src/core/ms_help.c | 52 +- src/core/ms_info.c | 370 ++++++------ src/core/ms_list.c | 220 +++---- src/core/ms_read.c | 224 +++---- src/core/ms_rsend.c | 135 +++-- src/core/ms_send.c | 54 +- src/core/ms_sendall.c | 101 ++-- src/core/ms_set.c | 446 +++++++------- src/core/ms_staff.c | 96 +-- src/core/ns_access.c | 246 ++++---- src/core/ns_alist.c | 258 ++++---- src/core/ns_drop.c | 202 ++++--- src/core/ns_forbid.c | 171 +++--- src/core/ns_getemail.c | 99 ++-- src/core/ns_getpass.c | 125 ++-- src/core/ns_ghost.c | 136 +++-- src/core/ns_group.c | 512 ++++++++-------- src/core/ns_help.c | 74 ++- src/core/ns_identify.c | 231 ++++---- src/core/ns_info.c | 423 +++++++------ src/core/ns_list.c | 336 +++++------ src/core/ns_logout.c | 162 ++--- src/core/ns_recover.c | 171 +++--- src/core/ns_register.c | 757 +++++++++++++----------- src/core/ns_release.c | 149 +++-- src/core/ns_saset.c | 918 ++++++++++++++++------------- src/core/ns_sendpass.c | 139 ++--- src/core/ns_set.c | 820 ++++++++++++++------------ src/core/ns_status.c | 90 +-- src/core/ns_suspend.c | 262 +++++---- src/core/ns_update.c | 77 ++- src/core/os_admin.c | 258 ++++---- src/core/os_akill.c | 381 ++++++------ src/core/os_chankill.c | 158 +++-- src/core/os_chanlist.c | 132 +++-- src/core/os_clearmodes.c | 427 +++++++------- src/core/os_defcon.c | 192 +++--- src/core/os_global.c | 69 ++- src/core/os_help.c | 51 +- src/core/os_ignore.c | 198 ++++--- src/core/os_jupe.c | 87 +-- src/core/os_kick.c | 103 ++-- src/core/os_logonnews.c | 94 --- src/core/os_mode.c | 104 ++-- src/core/os_modinfo.c | 118 ++-- src/core/os_modlist.c | 298 +++++----- src/core/os_modload.c | 94 +-- src/core/os_modunload.c | 92 +-- src/core/os_news.c | 336 +++++++++++ src/core/os_noop.c | 116 ++-- src/core/os_oline.c | 114 ++-- src/core/os_oper.c | 263 ++++++--- src/core/os_opernews.c | 87 --- src/core/os_quit.c | 64 +- src/core/os_randomnews.c | 54 -- src/core/os_raw.c | 64 +- src/core/os_reload.c | 68 ++- src/core/os_restart.c | 76 +-- src/core/os_session.c | 380 +++++++++++- src/core/os_set.c | 336 +++++++---- src/core/os_shutdown.c | 64 +- src/core/os_sqline.c | 355 ++++++----- src/core/os_staff.c | 142 ++--- src/core/os_stats.c | 587 +++++++++--------- src/core/os_svsnick.c | 150 ++--- src/core/os_szline.c | 339 ++++++----- src/core/os_umode.c | 126 ++-- src/core/os_update.c | 49 +- src/core/os_userlist.c | 136 ++--- src/core/ss_main.c | 45 +- src/hostserv.c | 7 +- src/init.c | 49 +- src/main.c | 224 +------ src/memory.c | 16 - src/messages.c | 2 +- src/misc.c | 2 +- src/module.cpp | 14 +- src/modulemanager.cpp | 18 +- src/modules.c | 102 +--- src/modules/cs_appendtopic.c | 266 ++++----- src/modules/cs_enforce.c | 778 ++++++++++++------------ src/modules/cs_tban.c | 210 +++---- src/modules/hs_request.c | 1308 +++++++++++++++++++++-------------------- src/modules/ns_maxemail.c | 166 +++--- src/modules/os_info.c | 955 +++++++++++++++--------------- src/news.c | 158 ----- src/nickserv.c | 14 +- src/process.c | 8 +- src/protocol/bahamut.c | 1 - src/protocol/inspircd11.c | 1 - src/protocol/inspircd12.cpp | 31 +- src/protocol/ratbox.c | 11 +- src/protocol/unreal32.c | 11 +- src/sessions.c | 305 ---------- src/users.c | 275 ++++----- src/windows.cpp | 27 + 149 files changed, 14553 insertions(+), 14184 deletions(-) delete mode 100644 src/core/bs_fantasy.c delete mode 100644 src/core/bs_fantasy_kick.c delete mode 100644 src/core/bs_fantasy_kickban.c delete mode 100644 src/core/bs_fantasy_owner.c delete mode 100644 src/core/bs_fantasy_seen.c delete mode 100644 src/core/os_logonnews.c create mode 100644 src/core/os_news.c delete mode 100644 src/core/os_opernews.c delete mode 100644 src/core/os_randomnews.c create mode 100644 src/windows.cpp (limited to 'src') diff --git a/src/actions.c b/src/actions.c index 25bea0091..6b96c66fa 100644 --- a/src/actions.c +++ b/src/actions.c @@ -180,8 +180,8 @@ void common_unban(ChannelInfo * ci, char *nick) for (ban = ci->c->bans->entries; ban; ban = next) { next = ban->next; - if (entry_match(ban, u->nick, u->username, u->host, ip) || - entry_match(ban, u->nick, u->username, u->vhost, ip)) { + if (entry_match(ban, u->nick, u->GetIdent().c_str(), u->host, ip) || + entry_match(ban, u->nick, u->GetIdent().c_str(), u->vhost, ip)) { ircdproto->SendMode(whosends(ci), ci->name, "-b %s", ban->mask); if (ircdcap->tsmode) av[3] = ban->mask; @@ -224,42 +224,3 @@ void common_svsmode(User * u, const char *modes, const char *arg) /*************************************************************************/ -/** - * Get the vhost for the user, if set else return the host, on ircds without - * vhost this returns the host - * @param u user to get the vhost for - * @return vhost - */ -char *common_get_vhost(User * u) -{ - if (!u) - return NULL; - - if (ircd->vhostmode && (u->mode & ircd->vhostmode)) - return u->vhost; - else if (ircd->vhost && u->vhost) - return u->vhost; - else - return u->host; -} - -/*************************************************************************/ - -/** - * Get the vident for the user, if set else return the ident, on ircds without - * vident this returns the ident - * @param u user to get info the vident for - * @return vident - */ -char *common_get_vident(User * u) -{ - if (!u) - return NULL; - - if (ircd->vhostmode && (u->mode & ircd->vhostmode)) - return u->vident; - else if (ircd->vident && u->vident) - return u->vident; - else - return u->username; -} diff --git a/src/botserv.c b/src/botserv.c index e671006e2..96b017bcd 100644 --- a/src/botserv.c +++ b/src/botserv.c @@ -421,14 +421,22 @@ void botchanmsgs(User * u, ChannelInfo * ci, char *buf) /* Strip off the fantasy character */ cmd++; - if (check_access(u, ci, CA_FANTASIA)) + if (check_access(u, ci, CA_FANTASIA)) + { + std::string bbuf = std::string(cmd) + " " + ci->name; + if (params) + { + bbuf += " "; + bbuf += params; + } + chanserv(u, const_cast(bbuf.c_str())); // XXX Unsafe cast, this needs reviewing -- CyberBotX event_name = EVENT_BOT_FANTASY; + } if (params) send_event(event_name, 4, cmd, u->nick, ci->name, params); else - send_event(event_name, 3, cmd, u->nick, ci->name); - } + send_event(event_name, 3, cmd, u->nick, ci->name);} } } @@ -596,8 +604,8 @@ static BanData *get_ban_data(Channel * c, User * u) if (!c || !u) return NULL; - snprintf(mask, sizeof(mask), "%s@%s", u->username, - common_get_vhost(u)); + snprintf(mask, sizeof(mask), "%s@%s", u->GetIdent().c_str(), + u->GetDisplayedHost().c_str()); for (bd = c->bd; bd; bd = next) { if (now - bd->last_use > BSKeepData) { diff --git a/src/channels.c b/src/channels.c index 4d5c08b5a..ab5e0b3a8 100644 --- a/src/channels.c +++ b/src/channels.c @@ -174,27 +174,6 @@ void chan_set_modes(const char *source, Channel * chan, int ac, const char **av, alog("debug: Changing modes for %s to %s", chan->name, merge_args(ac, av)); - u = finduser(source); - if (u && (chan_get_user_status(chan, u) & CUS_DEOPPED)) { - char *s; - - if (debug) - alog("debug: Removing instead of setting due to DEOPPED flag"); - - /* Swap adding and removing of the modes */ - for (s = const_cast(av[0]); *s; s++) { // XXX Unsafe cast, this needs reviewing -- CyberBotX - if (*s == '+') - *s = '-'; - else if (*s == '-') - *s = '+'; - } - - /* Set the resulting mode buffer */ - ircdproto->SendMode(whosends(chan->ci), chan->name, merge_args(ac, av)); - - return; - } - ac--; while ((mode = *modes++)) { @@ -256,8 +235,6 @@ void chan_set_modes(const char *source, Channel * chan, int ac, const char **av, if (add) { chan_set_user_status(chan, user, cum->status); /* If this does +o, remove any DEOPPED flag */ - if (cum->status & CUS_OP) - chan_remove_user_status(chan, user, CUS_DEOPPED); } else { chan_remove_user_status(chan, user, cum->status); } @@ -1471,7 +1448,6 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) strcat(modebuf, "o"); strcat(userbuf, " "); strcat(userbuf, user->nick); - rem_modes |= CUS_DEOPPED; } else { add_modes &= ~CUS_OP; } @@ -1510,7 +1486,6 @@ void chan_set_correct_modes(User * user, Channel * c, int give_modes) strcat(modebuf, "o"); strcat(userbuf, " "); strcat(userbuf, user->nick); - add_modes |= CUS_DEOPPED; } if (rem_modes & CUS_HALFOP) { strcat(modebuf, "h"); @@ -2122,7 +2097,7 @@ EList *list_create() * @param ip IP to match against, set to 0 to not match this * @return 1 for a match, 0 for no match */ -int entry_match(Entry * e, char *nick, char *user, char *host, uint32 ip) +int entry_match(Entry * e, const char *nick, const char *user, const char *host, uint32 ip) { /* If we don't get an entry, or it s an invalid one, no match ~ Viper */ if (!e || e->type == ENTRYTYPE_NONE) @@ -2160,7 +2135,7 @@ int entry_match(Entry * e, char *nick, char *user, char *host, uint32 ip) * @param ip IP to match against, set to 0 to not match this * @return 1 for a match, 0 for no match */ -int entry_match_mask(Entry * e, char *mask, uint32 ip) +int entry_match_mask(Entry * e, const char *mask, uint32 ip) { char *hostmask, *nick, *user, *host; int res; @@ -2201,7 +2176,7 @@ int entry_match_mask(Entry * e, char *mask, uint32 ip) * @param ip The ip to match * @return Returns the first matching entry, if none, NULL is returned. */ -Entry *elist_match(EList * list, char *nick, char *user, char *host, +Entry *elist_match(EList * list, const char *nick, const char *user, const char *host, uint32 ip) { Entry *e; @@ -2225,7 +2200,7 @@ Entry *elist_match(EList * list, char *nick, char *user, char *host, * @param ip The ip to match * @return Returns the first matching entry, if none, NULL is returned. */ -Entry *elist_match_mask(EList * list, char *mask, uint32 ip) +Entry *elist_match_mask(EList * list, const char *mask, uint32 ip) { char *hostmask, *nick, *user, *host; Entry *res; @@ -2291,9 +2266,9 @@ Entry *elist_match_user(EList * list, User * u) ip = str_is_ip(host); /* Match what we ve got against the lists.. */ - res = elist_match(list, u->nick, u->username, u->host, ip); + res = elist_match(list, u->nick, u->GetIdent().c_str(), u->host, ip); if (!res) - elist_match(list, u->nick, u->username, u->vhost, ip); + elist_match(list, u->nick, u->GetIdent().c_str(), u->vhost, ip); if (host) delete [] host; diff --git a/src/chanserv.c b/src/chanserv.c index eff790d49..ee3b96e97 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -1197,7 +1197,7 @@ int check_kick(User * user, const char *chan, time_t chants) kick: if (debug) alog("debug: channel: AutoKicking %s!%s@%s from %s", user->nick, - user->username, user->host, chan); + user->GetIdent().c_str(), user->host, chan); /* Remember that the user has not been added to our channel user list * yet, so we check whether the channel does not exist OR has no user @@ -1968,22 +1968,24 @@ int get_idealban(ChannelInfo * ci, User * u, char *ret, int retlen) if (!ci || !u || !ret || retlen == 0) return 0; + std::string vident = u->GetIdent(); + switch (ci->bantype) { case 0: - snprintf(ret, retlen, "*!%s@%s", common_get_vident(u), - common_get_vhost(u)); + snprintf(ret, retlen, "*!%s@%s", vident.c_str(), + u->GetDisplayedHost().c_str()); return 1; case 1: - snprintf(ret, retlen, "*!%s%s@%s", - (strlen(common_get_vident(u)) < - (*(common_get_vident(u)) == - '~' ? USERMAX + 1 : USERMAX) ? "*" : ""), - (*(common_get_vident(u)) == - '~' ? common_get_vident(u) + 1 : common_get_vident(u)), - common_get_vhost(u)); + if (vident[0] == '~') + snprintf(ret, retlen, "*!*%s@%s", + vident.c_str(), u->GetDisplayedHost().c_str()); + else + snprintf(ret, retlen, "*!%s@%s", + vident.c_str(), u->GetDisplayedHost().c_str()); + return 1; case 2: - snprintf(ret, retlen, "*!*@%s", common_get_vhost(u)); + snprintf(ret, retlen, "*!*@%s", u->GetDisplayedHost().c_str()); return 1; case 3: mask = create_mask(u); diff --git a/src/commands.c b/src/commands.c index 52b74b488..17b6629b3 100644 --- a/src/commands.c +++ b/src/commands.c @@ -29,8 +29,8 @@ Command *lookup_cmd(Command * list, char *cmd) { Command *c; - for (c = list; c->name; c++) { - if (stricmp(c->name, cmd) == 0) { + for (c = list; ; c++) { + if (stricmp(c->name.c_str(), cmd) == 0) { return c; } } @@ -48,39 +48,66 @@ Command *lookup_cmd(Command * list, char *cmd) * @param cmd Command * @return void */ -void mod_run_cmd(char *service, User * u, CommandHash * cmdTable[], - const char *cmd) +void mod_run_cmd(char *service, User * u, CommandHash * cmdTable[], const char *cmd) { Command *c = findCommand(cmdTable, cmd); int retVal = 0; Command *current; - if (c && c->routine) { - if ((checkDefCon(DEFCON_OPER_ONLY) - || checkDefCon(DEFCON_SILENT_OPER_ONLY)) && !is_oper(u)) { - if (!checkDefCon(DEFCON_SILENT_OPER_ONLY)) { - notice_lang(service, u, OPER_DEFCON_DENIED); - } - } else { - if ((c->has_priv == NULL) || c->has_priv(u)) { - retVal = c->routine(u); - if (retVal == MOD_CONT) { - current = c->next; - while (current && retVal == MOD_CONT) { - retVal = current->routine(u); - current = current->next; - } - } - } else { - notice_lang(service, u, ACCESS_DENIED); - alog("Access denied for %s with service %s and command %s", - u->nick, service, cmd); - } - } - } else { - if ((!checkDefCon(DEFCON_SILENT_OPER_ONLY)) || is_oper(u)) { + if (!c) + { + if ((!checkDefCon(DEFCON_SILENT_OPER_ONLY)) || is_oper(u)) + { notice_lang(service, u, UNKNOWN_COMMAND_HELP, cmd, service); } + return; + } + + if ((checkDefCon(DEFCON_OPER_ONLY) || checkDefCon(DEFCON_SILENT_OPER_ONLY)) && !is_oper(u)) + { + if (!checkDefCon(DEFCON_SILENT_OPER_ONLY)) + { + notice_lang(service, u, OPER_DEFCON_DENIED); + return; + } + } + + if (c->has_priv != NULL && !c->has_priv(u)) + { + notice_lang(service, u, ACCESS_DENIED); + alog("Access denied for %s with service %s and command %s", u->nick, service, cmd); + return; + } + + std::vector params; + std::string curparam; + char *s = NULL; + while ((s = strtok(NULL, " "))) + { + if (params.size() < c->MaxParams) + params.push_back(s); + else + curparam += s; + } + + if (!curparam.empty()) + params.push_back(curparam); + + if (params.size() < c->MinParams) + { + c->OnBadSyntax(u); + return; + } + + retVal = c->Execute(u, params); + if (retVal == MOD_CONT) + { + current = c->next; + while (current && retVal == MOD_CONT) + { + retVal = current->Execute(u, params); + current = current->next; + } } } @@ -124,7 +151,7 @@ void mod_help_cmd(char *service, User * u, CommandHash * cmdTable[], { Command *c = findCommand(cmdTable, cmd); Command *current; - int has_had_help = 0; + bool has_had_help = false; int cont = MOD_CONT; const char *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL; @@ -134,52 +161,9 @@ void mod_help_cmd(char *service, User * u, CommandHash * cmdTable[], p2 = current->help_param2; p3 = current->help_param3; p4 = current->help_param4; - if (current->helpmsg_all >= 0) { - notice_help(service, u, current->helpmsg_all, p1, p2, p3, p4); - has_had_help = 1; - } else if (current->all_help) { - cont = current->all_help(u); - has_had_help = 1; - } - if (is_services_root(u)) { - if (current->helpmsg_root >= 0) { - notice_help(service, u, current->helpmsg_root, p1, p2, p3, - p4); - has_had_help = 1; - } else if (current->root_help) { - cont = current->root_help(u); - has_had_help = 1; - } - } else if (is_services_admin(u)) { - if (current->helpmsg_admin >= 0) { - notice_help(service, u, current->helpmsg_admin, p1, p2, p3, - p4); - has_had_help = 1; - } else if (current->admin_help) { - cont = current->admin_help(u); - has_had_help = 1; - } - } else if (is_services_oper(u)) { - if (current->helpmsg_oper >= 0) { - notice_help(service, u, current->helpmsg_oper, p1, p2, p3, - p4); - has_had_help = 1; - } else if (current->oper_help) { - cont = current->oper_help(u); - has_had_help = 1; - } - } else { - if (current->helpmsg_reg >= 0) { - notice_help(service, u, current->helpmsg_reg, p1, p2, p3, - p4); - has_had_help = 1; - } else if (current->regular_help) { - cont = current->regular_help(u); - has_had_help = 1; - } - } + has_had_help = current->OnHelp(u, ""); // XXX: this needs finishing to actually pass a subcommand } - if (has_had_help == 0) { + if (has_had_help == false) { notice_lang(service, u, NO_HELP_AVAILABLE, cmd); } else { do_help_limited(service, u, c); diff --git a/src/core/bs_act.c b/src/core/bs_act.c index 0f2e34af2..f37f2d942 100644 --- a/src/core/bs_act.c +++ b/src/core/bs_act.c @@ -15,21 +15,78 @@ #include "module.h" -int do_act(User * u); void myBotServHelp(User * u); +class CommandBSAct : public Command +{ + public: + CommandBSAct() : Command("ACT", 2, 2) + { + + } + + CommandReturn Execute(User *u, std::vector ¶ms) + { + ChannelInfo *ci; + + if (!(ci = cs_findchan(params[0].c_str()))) + { + notice_lang(s_BotServ, u, CHAN_X_NOT_REGISTERED, params[0].c_str()); + return MOD_CONT; + } + + if (ci->flags & CI_VERBOTEN) + { + notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, ci->name); + return MOD_CONT; + } + + if (!ci->bi) + { + notice_help(s_BotServ, u, BOT_NOT_ASSIGNED); + return MOD_CONT; + } + + if (!ci->c || ci->c->usercount < BSMinUsers) + { + notice_lang(s_BotServ, u, BOT_NOT_ON_CHANNEL, ci->name); + return MOD_CONT; + } + + if (!check_access(u, ci, CA_SAY)) + { + notice_lang(s_BotServ, u, ACCESS_DENIED); + return MOD_CONT; + } + + size_t i = 0; + while ((i = params[1].find_first_of("\001"), i) && i != std::string::npos) + { + params[1].erase(i, 1); + } + + ircdproto->SendAction(ci->bi, ci->name, "%s", params[1].c_str()); + ci->bi->lastmsg = time(NULL); + if (LogBot && LogChannel && logchan && !debug && findchan(LogChannel)) + ircdproto->SendPrivmsg(ci->bi, LogChannel, "ACT %s %s %s", u->nick, ci->name, params[1].c_str()); + return MOD_CONT; + } + + void OnBadSyntax(User *u) + { + syntax_error(s_BotServ, u, "ACT", BOT_ACT_SYNTAX); + } +}; + class BSAct : public Module { public: BSAct(const std::string &modname, const std::string &creator) : Module(modname, creator) { - Command *c; - this->SetAuthor("Anope"); this->SetVersion("$Id$"); this->SetType(CORE); - c = createCommand("ACT", do_act, NULL, BOT_HELP_ACT, -1, -1, -1, -1); - this->AddCommand(BOTSERV, c, MOD_UNIQUE); + this->AddCommand(BOTSERV, new CommandBSAct(), MOD_UNIQUE); this->SetBotHelp(myBotServHelp); } @@ -45,39 +102,4 @@ void myBotServHelp(User * u) notice_lang(s_BotServ, u, BOT_HELP_CMD_ACT); } -/** - * The /bs act command. - * @param u The user who issued the command - * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. - **/ -int do_act(User * u) -{ - ChannelInfo *ci; - - char *chan = strtok(NULL, " "); - char *text = strtok(NULL, ""); - - if (!chan || !text) - syntax_error(s_BotServ, u, "ACT", BOT_ACT_SYNTAX); - else if (!(ci = cs_findchan(chan))) - notice_lang(s_BotServ, u, CHAN_X_NOT_REGISTERED, chan); - else if (ci->flags & CI_VERBOTEN) - notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, chan); - else if (!ci->bi) - notice_help(s_BotServ, u, BOT_NOT_ASSIGNED); - else if (!ci->c || ci->c->usercount < BSMinUsers) - notice_lang(s_BotServ, u, BOT_NOT_ON_CHANNEL, ci->name); - else if (!check_access(u, ci, CA_SAY)) - notice_lang(s_BotServ, u, ACCESS_DENIED); - else { - strnrepl(text, BUFSIZE, "\001", ""); - ircdproto->SendAction(ci->bi, ci->name, "%s", text); - ci->bi->lastmsg = time(NULL); - if (LogBot && LogChannel && logchan && !debug && findchan(LogChannel)) - ircdproto->SendPrivmsg(ci->bi, LogChannel, "ACT %s %s %s", - u->nick, ci->name, text); - } - return MOD_CONT; -} - MODULE_INIT("bs_act", BSAct) diff --git a/src/core/bs_assign.c b/src/core/bs_assign.c index 396031662..f9927e25d 100644 --- a/src/core/bs_assign.c +++ b/src/core/bs_assign.c @@ -15,21 +15,90 @@ #include "module.h" -int do_assign(User * u); void myBotServHelp(User * u); +class CommandBSAssign : public Command +{ + public: + CommandBSAssign() : Command("ASSIGN", 1, 1) + { + } + + CommandReturn Execute(User *u, std::vector ¶ms) + { + char *chan = strtok(NULL, " "); + char *nick = strtok(NULL, " "); + BotInfo *bi; + ChannelInfo *ci; + + if (readonly) + { + notice_lang(s_BotServ, u, BOT_ASSIGN_READONLY); + return MOD_CONT; + } + + if (!(bi = findbot(nick))) + { + notice_lang(s_BotServ, u, BOT_DOES_NOT_EXIST, nick); + return MOD_CONT; + } + + if (bi->flags & BI_PRIVATE && !is_oper(u)) + { + notice_lang(s_BotServ, u, PERMISSION_DENIED); + return MOD_CONT; + } + + if (!(ci = cs_findchan(chan))) + { + notice_lang(s_BotServ, u, CHAN_X_NOT_REGISTERED, chan); + return MOD_CONT; + } + + if (ci->flags & CI_VERBOTEN) + { + notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, chan); + return MOD_CONT; + } + + if ((ci->bi) && (stricmp(ci->bi->nick, nick) == 0)) + { + notice_lang(s_BotServ, u, BOT_ASSIGN_ALREADY, ci->bi->nick, chan); + return MOD_CONT; + } + + if ((ci->botflags & BS_NOBOT) || (!check_access(u, ci, CA_ASSIGN) && !is_services_admin(u))) + { + notice_lang(s_BotServ, u, PERMISSION_DENIED); + return MOD_CONT; + } + + bi->Assign(u, ci); + notice_lang(s_BotServ, u, BOT_ASSIGN_ASSIGNED, bi->nick, ci->name); + return MOD_CONT; + } + + bool OnHelp(User *u, const std::string &subcommand) + { + notice_lang(s_BotServ, u, BOT_HELP_ASSIGN); + return true; + } + + void OnSyntaxError(User *u) + { + syntax_error(s_BotServ, u, "ASSIGN", BOT_ASSIGN_SYNTAX); + } +}; + class BSAssign : public Module { public: BSAssign(const std::string &modname, const std::string &creator) : Module(modname, creator) { - Command *c; - this->SetAuthor("Anope"); this->SetVersion("$Id$"); this->SetType(CORE); - c = createCommand("ASSIGN", do_assign, NULL, BOT_HELP_ASSIGN, -1, -1, -1, -1); - this->AddCommand(BOTSERV, c, MOD_UNIQUE); + this->AddCommand(BOTSERV, new CommandBSAssign, MOD_UNIQUE); this->SetBotHelp(myBotServHelp); } @@ -44,40 +113,4 @@ void myBotServHelp(User * u) notice_lang(s_BotServ, u, BOT_HELP_CMD_ASSIGN); } -/** - * The /bs assign command. - * @param u The user who issued the command - * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. - **/ -int do_assign(User * u) -{ - char *chan = strtok(NULL, " "); - char *nick = strtok(NULL, " "); - BotInfo *bi; - ChannelInfo *ci; - - if (readonly) - notice_lang(s_BotServ, u, BOT_ASSIGN_READONLY); - else if (!chan || !nick) - syntax_error(s_BotServ, u, "ASSIGN", BOT_ASSIGN_SYNTAX); - else if (!(bi = findbot(nick))) - notice_lang(s_BotServ, u, BOT_DOES_NOT_EXIST, nick); - else if (bi->flags & BI_PRIVATE && !is_oper(u)) - notice_lang(s_BotServ, u, PERMISSION_DENIED); - else if (!(ci = cs_findchan(chan))) - notice_lang(s_BotServ, u, CHAN_X_NOT_REGISTERED, chan); - else if (ci->flags & CI_VERBOTEN) - notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, chan); - else if ((ci->bi) && (stricmp(ci->bi->nick, nick) == 0)) - notice_lang(s_BotServ, u, BOT_ASSIGN_ALREADY, ci->bi->nick, chan); - else if ((ci->botflags & BS_NOBOT) - || (!check_access(u, ci, CA_ASSIGN) && !is_services_admin(u))) - notice_lang(s_BotServ, u, PERMISSION_DENIED); - else { - bi->Assign(u, ci); - notice_lang(s_BotServ, u, BOT_ASSIGN_ASSIGNED, bi->nick, ci->name); - } - return MOD_CONT; -} - MODULE_INIT("bs_assign", BSAssign) diff --git a/src/core/bs_badwords.c b/src/core/bs_badwords.c index 8a37e9816..41050dc93 100644 --- a/src/core/bs_badwords.c +++ b/src/core/bs_badwords.c @@ -15,80 +15,65 @@ #include "module.h" -int do_badwords(User * u); void myBotServHelp(User * u); int badwords_del_callback(User * u, int num, va_list args); int badwords_list(User * u, int index, ChannelInfo * ci, int *sent_header); int badwords_list_callback(User * u, int num, va_list args); -class BSBadwords : public Module +class CommandBSBadwords : public Command { - public: - BSBadwords(const std::string &modname, const std::string &creator) : Module(modname, creator) + private: + CommandReturn DoList(User *u, ChannelInfo *ci, const char *word) { - Command *c; - - this->SetAuthor("Anope"); - this->SetVersion("$Id$"); - this->SetType(CORE); + int sent_header = 0; + int i = 0; - c = createCommand("BADWORDS", do_badwords, NULL, BOT_HELP_BADWORDS, -1, -1, -1, -1); - this->AddCommand(BOTSERV, c, MOD_UNIQUE); + if (ci->bwcount == 0) + { + notice_lang(s_BotServ, u, BOT_BADWORDS_LIST_EMPTY, ci->name); + return MOD_CONT; + } + if (word && strspn(word, "1234567890,-") == strlen(word)) + { + process_numlist(word, NULL, badwords_list_callback, u, ci, &sent_header); + } + else + { + for (i = 0; i < ci->bwcount; i++) + { + if (!(ci->badwords[i].in_use)) + continue; + if (word && ci->badwords[i].word + && !match_wild_nocase(word, ci->badwords[i].word)) + continue; + badwords_list(u, i, ci, &sent_header); + } + } + if (!sent_header) + notice_lang(s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name); - this->SetBotHelp(myBotServHelp); + return MOD_CONT; } -}; - - -/** - * Add the help response to Anopes /bs help output. - * @param u The user who is requesting help - **/ -void myBotServHelp(User * u) -{ - notice_lang(s_BotServ, u, BOT_HELP_CMD_BADWORDS); -} - -/** - * The /bs badwords command. - * @param u The user who issued the command - * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. - **/ -int do_badwords(User * u) -{ - char *chan = strtok(NULL, " "); - char *cmd = strtok(NULL, " "); - char *word = strtok(NULL, ""); - ChannelInfo *ci; - BadWord *bw; - - unsigned i; - int need_args = (cmd - && (!stricmp(cmd, "LIST") || !stricmp(cmd, "CLEAR"))); - - if (!cmd || (need_args ? 0 : !word)) { - syntax_error(s_BotServ, u, "BADWORDS", BOT_BADWORDS_SYNTAX); - } else if (!(ci = cs_findchan(chan))) { - notice_lang(s_BotServ, u, CHAN_X_NOT_REGISTERED, chan); - } else if (ci->flags & CI_VERBOTEN) { - notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, chan); - } else if (!check_access(u, ci, CA_BADWORDS) - && (!need_args || !is_services_admin(u))) { - notice_lang(s_BotServ, u, ACCESS_DENIED); - } else if (stricmp(cmd, "ADD") == 0) { - + + CommandReturn DoAdd(User *u, ChannelInfo *ci, const char *word) + { char *opt, *pos; int type = BW_ANY; + unsigned i = 0; + BadWord *bw; - if (readonly) { + if (readonly) + { notice_lang(s_BotServ, u, BOT_BADWORDS_DISABLED); return MOD_CONT; } pos = strrchr(word, ' '); - if (pos) { + if (pos) + { opt = pos + 1; - if (*opt) { + if (*opt) + { if (!stricmp(opt, "SINGLE")) type = BW_SINGLE; else if (!stricmp(opt, "START")) @@ -100,26 +85,33 @@ int do_badwords(User * u) } } - for (bw = ci->badwords, i = 0; i < ci->bwcount; bw++, i++) { + for (bw = ci->badwords, i = 0; i < ci->bwcount; bw++, i++) + { if (bw->word && ((BSCaseSensitive && (!strcmp(bw->word, word))) || (!BSCaseSensitive - && (!stricmp(bw->word, word))))) { + && (!stricmp(bw->word, word))))) + { notice_lang(s_BotServ, u, BOT_BADWORDS_ALREADY_EXISTS, bw->word, ci->name); return MOD_CONT; } } - for (i = 0; i < ci->bwcount; i++) { + for (i = 0; i < ci->bwcount; i++) + { if (!ci->badwords[i].in_use) break; } - if (i == ci->bwcount) { - if (i < BSBadWordsMax) { + if (i == ci->bwcount) + { + if (i < BSBadWordsMax) + { ci->bwcount++; ci->badwords = static_cast(srealloc(ci->badwords, sizeof(BadWord) * ci->bwcount)); - } else { + } + else + { notice_lang(s_BotServ, u, BOT_BADWORDS_REACHED_LIMIT, BSBadWordsMax); return MOD_CONT; @@ -131,50 +123,57 @@ int do_badwords(User * u) bw->type = type; notice_lang(s_BotServ, u, BOT_BADWORDS_ADDED, bw->word, ci->name); + return MOD_CONT; + } - } else if (stricmp(cmd, "DEL") == 0) { + CommandReturn DoDelete(User *u, ChannelInfo *ci, const char *word) + { int deleted = 0, a, b; - - if (readonly) { - notice_lang(s_BotServ, u, BOT_BADWORDS_DISABLED); - return MOD_CONT; - } + int i; + BadWord *bw; /* Special case: is it a number/list? Only do search if it isn't. */ - if (isdigit(*word) && strspn(word, "1234567890,-") == strlen(word)) { + if (isdigit(*word) && strspn(word, "1234567890,-") == strlen(word)) + { int count, last = -1; - deleted = - process_numlist(word, &count, badwords_del_callback, u, ci, - &last); - if (!deleted) { - if (count == 1) { - notice_lang(s_BotServ, u, BOT_BADWORDS_NO_SUCH_ENTRY, - last, ci->name); - } else { - notice_lang(s_BotServ, u, BOT_BADWORDS_NO_MATCH, - ci->name); + deleted = process_numlist(word, &count, badwords_del_callback, u, ci, &last); + if (!deleted) + { + if (count == 1) + { + notice_lang(s_BotServ, u, BOT_BADWORDS_NO_SUCH_ENTRY, last, ci->name); + } + else + { + notice_lang(s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name); } - } else if (deleted == 1) { - notice_lang(s_BotServ, u, BOT_BADWORDS_DELETED_ONE, - ci->name); - } else { - notice_lang(s_BotServ, u, BOT_BADWORDS_DELETED_SEVERAL, - deleted, ci->name); } - } else { - for (i = 0; i < ci->bwcount; i++) { - if (ci->badwords[i].in_use - && !stricmp(ci->badwords[i].word, word)) + else if (deleted == 1) + { + notice_lang(s_BotServ, u, BOT_BADWORDS_DELETED_ONE, ci->name); + } + else + { + notice_lang(s_BotServ, u, BOT_BADWORDS_DELETED_SEVERAL, deleted, ci->name); + } + } + else + { + + for (i = 0; i < ci->bwcount; i++) + { + if (!ci->badwords[i].in_use) break; } - if (i == ci->bwcount) { - notice_lang(s_BotServ, u, BOT_BADWORDS_NOT_FOUND, word, - chan); + + if (i == ci->bwcount) + { + notice_lang(s_BotServ, u, BOT_BADWORDS_NOT_FOUND, word, ci->name); return MOD_CONT; } + bw = &ci->badwords[i]; - notice_lang(s_BotServ, u, BOT_BADWORDS_DELETED, bw->word, - ci->name); + notice_lang(s_BotServ, u, BOT_BADWORDS_DELETED, bw->word, ci->name); if (bw->word) delete [] bw->word; bw->word = NULL; @@ -205,8 +204,8 @@ int do_badwords(User * u) } /* After reordering only the entries at the end could still be empty. * We ll free the places no longer in use... - Viper */ - for (int j = ci->bwcount - 1; j >= 0; j--) { - if (ci->badwords[j].in_use) + for (i = ci->bwcount - 1; i >= 0; i--) { + if (ci->badwords[i].in_use) break; ci->bwcount--; } @@ -214,50 +213,124 @@ int do_badwords(User * u) static_cast(srealloc(ci->badwords,sizeof(BadWord) * ci->bwcount)); } - } else if (stricmp(cmd, "LIST") == 0) { - int sent_header = 0; + return MOD_CONT; + } + + CommandReturn DoClear(User *u, ChannelInfo *ci, const char *word) + { + int i; + for (i = 0; i < ci->bwcount; i++) + if (ci->badwords[i].word) + delete [] ci->badwords[i].word; - if (ci->bwcount == 0) { - notice_lang(s_BotServ, u, BOT_BADWORDS_LIST_EMPTY, chan); + free(ci->badwords); + ci->badwords = NULL; + ci->bwcount = 0; + + notice_lang(s_BotServ, u, BOT_BADWORDS_CLEAR); + return MOD_CONT; + } + public: + CommandBSBadwords() : Command("BADWORDS", 2, 3) + { + } + + CommandReturn Execute(User *u, std::vector ¶ms) + { + const char *chan = params[0].c_str(); + const char *cmd = params[1].c_str(); + const char *word = params[2].c_str(); + ChannelInfo *ci; + int need_args = (cmd + && (!stricmp(cmd, "LIST") || !stricmp(cmd, "CLEAR"))); + + if (!cmd || (need_args ? 0 : !word)) + { + this->OnSyntaxError(u); return MOD_CONT; } - if (word && strspn(word, "1234567890,-") == strlen(word)) { - process_numlist(word, NULL, badwords_list_callback, u, ci, - &sent_header); - } else { - for (i = 0; i < ci->bwcount; i++) { - if (!(ci->badwords[i].in_use)) - continue; - if (word && ci->badwords[i].word - && !match_wild_nocase(word, ci->badwords[i].word)) - continue; - badwords_list(u, i, ci, &sent_header); - } + + if (!(ci = cs_findchan(chan))) + { + notice_lang(s_BotServ, u, CHAN_X_NOT_REGISTERED, chan); + return MOD_CONT; } - if (!sent_header) - notice_lang(s_BotServ, u, BOT_BADWORDS_NO_MATCH, chan); - } else if (stricmp(cmd, "CLEAR") == 0) { + if (ci->flags & CI_VERBOTEN) + { + notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, chan); + return MOD_CONT; + } - if (readonly) { - notice_lang(s_BotServ, u, BOT_BADWORDS_DISABLED); + if (!check_access(u, ci, CA_BADWORDS) && (!need_args || !is_services_admin(u))) + { + notice_lang(s_BotServ, u, ACCESS_DENIED); return MOD_CONT; } - for (i = 0; i < ci->bwcount; i++) - if (ci->badwords[i].word) - delete [] ci->badwords[i].word; + if (readonly) + { + notice_lang(s_BotServ, u, BOT_BADWORDS_DISABLED); + return MOD_CONT; + } - free(ci->badwords); - ci->badwords = NULL; - ci->bwcount = 0; + if (stricmp(cmd, "ADD") == 0) + { + return this->DoAdd(u, ci, word); + } + else if (stricmp(cmd, "DEL") == 0) + { + return this->DoDelete(u, ci, word); + } + else if (stricmp(cmd, "LIST") == 0) + { + return this->DoList(u, ci, word); + } + else if (stricmp(cmd, "CLEAR") == 0) + { + return this->DoClear(u, ci, word); + } + else + { + this->OnSyntaxError(u); + } + return MOD_CONT; + } - notice_lang(s_BotServ, u, BOT_BADWORDS_CLEAR); + bool OnHelp(User *u, const std::string &subcommand) + { + notice_lang(s_BotServ, u, BOT_HELP_BADWORDS); + return true; + } - } else { + void OnSyntaxError(User *u) + { syntax_error(s_BotServ, u, "BADWORDS", BOT_BADWORDS_SYNTAX); } - return MOD_CONT; +}; + +class BSBadwords : public Module +{ + public: + BSBadwords(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + this->AddCommand(BOTSERV, new CommandBSBadwords, MOD_UNIQUE); + + this->SetBotHelp(myBotServHelp); + } +}; + + +/** + * Add the help response to Anopes /bs help output. + * @param u The user who is requesting help + **/ +void myBotServHelp(User * u) +{ + notice_lang(s_BotServ, u, BOT_HELP_CMD_BADWORDS); } int badwords_del_callback(User * u, int num, va_list args) diff --git a/src/core/bs_bot.c b/src/core/bs_bot.c index 92514950a..45de014ce 100644 --- a/src/core/bs_bot.c +++ b/src/core/bs_bot.c @@ -15,72 +15,23 @@ #include "module.h" -int do_bot(User * u); void myBotServHelp(User * u); -class BSBot : public Module -{ - public: - BSBot(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - Command *c; - - this->SetAuthor("Anope"); - this->SetVersion("$Id$"); - this->SetType(CORE); - - c = createCommand("BOT", do_bot, is_services_admin, -1, -1, -1, BOT_SERVADMIN_HELP_BOT, BOT_SERVADMIN_HELP_BOT); - this->AddCommand(BOTSERV, c, MOD_UNIQUE); - - this->SetBotHelp(myBotServHelp); - } -}; - - -/** - * Add the help response to Anopes /bs help output. - * @param u The user who is requesting help - **/ -void myBotServHelp(User * u) -{ - if (is_services_admin(u)) { - notice_lang(s_BotServ, u, BOT_HELP_CMD_BOT); - } -} - -/** - * The /bs bot command. - * @param u The user who issued the command - * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. - **/ -int do_bot(User * u) +class CommandBSBot : public Command { - BotInfo *bi; - char *cmd = strtok(NULL, " "); - char *ch = NULL; - - if (!cmd) - { - syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); - return MOD_CONT; - } - - if (readonly) - { - notice_lang(s_BotServ, u, BOT_BOT_READONLY); - return MOD_CONT; - } - - if (!stricmp(cmd, "ADD")) + private: + CommandReturn DoAdd(User *u, std::vector ¶ms) { - char *nick = strtok(NULL, " "); - char *user = strtok(NULL, " "); - char *host = strtok(NULL, " "); - char *real = strtok(NULL, ""); + const char *nick = params[1].c_str(); + const char *user = params[2].c_str(); + const char *host = params[3].c_str(); + const char *real = params[4].c_str(); + const char *ch = NULL; + BotInfo *bi; if (!nick || !user || !host || !real) { - syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); + this->OnSyntaxError(u); return MOD_CONT; } @@ -182,18 +133,22 @@ int do_bot(User * u) bi->host, bi->real); send_event(EVENT_BOT_CREATE, 1, bi->nick); + return MOD_CONT; } - else if (!stricmp(cmd, "CHANGE")) + + CommandReturn DoChange(User *u, std::vector ¶ms) { - char *oldnick = strtok(NULL, " "); - char *nick = strtok(NULL, " "); - char *user = strtok(NULL, " "); - char *host = strtok(NULL, " "); - char *real = strtok(NULL, ""); + const char *oldnick = params[1].c_str(); + const char *nick = params[2].c_str(); + const char *user = params[3].c_str(); + const char *host = params[4].c_str(); + const char *real = params[5].c_str(); + const char *ch = NULL; + BotInfo *bi; if (!oldnick || !nick) { - syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); + this->OnSyntaxError(u); return MOD_CONT; } @@ -351,14 +306,17 @@ int do_bot(User * u) oldnick, bi->nick, bi->user, bi->host, bi->real); send_event(EVENT_BOT_CHANGE, 1, bi->nick); + return MOD_CONT; } - else if (!stricmp(cmd, "DEL")) - { - char *nick = strtok(NULL, " "); + + CommandReturn DoDel(User *u, std::vector ¶ms) + { + const char *nick = params[1].c_str(); + BotInfo *bi; if (!nick) { - syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); + this->OnSyntaxError(u); return MOD_CONT; } @@ -379,12 +337,88 @@ int do_bot(User * u) ircdproto->SendSQLineDel(bi->nick); delete bi; notice_lang(s_BotServ, u, BOT_BOT_DELETED, nick); + return MOD_CONT; } - else + public: + CommandBSBot() : Command("BOT", 1, 5) + { + } + + CommandReturn Execute(User *u, std::vector ¶ms) + { + const char *cmd = strtok(NULL, " "); + + if (!cmd) + { + this->OnSyntaxError(u); + return MOD_CONT; + } + + if (readonly) + { + notice_lang(s_BotServ, u, BOT_BOT_READONLY); + return MOD_CONT; + } + + if (!stricmp(cmd, "ADD")) + { + return this->DoAdd(u, params); + } + else if (!stricmp(cmd, "CHANGE")) + { + return this->DoChange(u, params); + } + else if (!stricmp(cmd, "DEL")) + { + return this->DoDel(u, params); + } + else + this->OnSyntaxError(u); + + return MOD_CONT; + } + + bool OnHelp(User *u, const std::string &subcommand) + { + if (!is_services_admin(u) && !is_services_root(u)) + return false; + + notice_lang(s_BotServ, u, BOT_SERVADMIN_HELP_BOT); + return true; + } + + void OnSyntaxError(User *u) + { syntax_error(s_BotServ, u, "BOT", BOT_BOT_SYNTAX); + } +}; - return MOD_CONT; +class BSBot : public Module +{ + public: + BSBot(const std::string &modname, const std::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetVersion("$Id$"); + this->SetType(CORE); + this->AddCommand(BOTSERV, new CommandBSBot(), MOD_UNIQUE); + + this->SetBotHelp(myBotServHelp); + } +}; + + +/** + * Add the help response to Anopes /bs help output. + * @param u The user who is requesting help + **/ +void myBotServHelp(User * u) +{ + if (is_services_admin(u)) { + notice_lang(s_BotServ, u, BOT_HELP_CMD_BOT); + } } + MODULE_INIT("bs_bot", BSBot) diff --git a/src/core/bs_botlist.c b/src/core/bs_botlist.c index e1aac321b..c9f4fc350 100644 --- a/src/core/bs_botlist.c +++ b/src/core/bs_botlist.c @@ -15,21 +15,74 @@ #include "module.h" -int do_botlist(User * u); void myBotServHelp(User * u); +class CommandBSBotList : public Command +{ + public: + CommandBSBotList() : Command("BOTLIST", 0, 0) + { + } + + CommandReturn Execute(User *u, std::vector ¶ms) + { + int i, count = 0; + BotInfo *bi; + + if (!nbots) { + notice_lang(s_BotServ, u, BOT_BOTLIST_EMPTY); + return MOD_CONT; + } + + for (i = 0; i < 256; i++) { + for (bi = botlists[i]; bi; bi = bi->next) { + if (!(bi->flags & BI_PRIVATE)) { + if (!count) + notice_lang(s_BotServ, u, BOT_BOTLIST_HEADER); + count++; + notice_user(s_BotServ, u, " %-15s (%s@%s)", bi->nick, + bi->user, bi->host); + } + } + } + + if (is_oper(u) && count < nbots) { + notice_lang(s_BotServ, u, BOT_BOTLIST_PRIVATE_HEADER); + + for (i = 0; i < 256; i++) { + for (bi = botlists[i]; bi; bi = bi->next) { + if (bi->flags & BI_PRIVATE) { + notice_user(s_BotServ, u, " %-15s (%s@%s)", + bi->nick, bi->user, bi->host); + count++; + } + } + } + } + + if (!count) + notice_lang(s_BotServ, u, BOT_BOTLIST_EMPTY); + else + notice_lang(s_BotServ, u, BOT_BOTLIST_FOOTER, count); + return MOD_CONT; + } + + bool OnHelp(User *u, const std::string &subcommand) + { + notice_lang(s_BotServ, u, BOT_HELP_BOTLIST); + return true; + } +}; + class BSBotList : public Module { public: BSBotList(const std::string &modname, const std::string &creator) : Module(modname, creator) { - Command *c; - this->SetAuthor("Anope"); this->SetVersion("$Id$"); this->SetType(CORE); - c = createCommand("BOTLIST", do_botlist, NULL, BOT_HELP_BOTLIST, -1, -1, -1, -1); - this->AddCommand(BOTSERV, c, MOD_UNIQUE); + this->AddCommand(BOTSERV, new CommandBSBotList(), MOD_UNIQUE); this->SetBotHelp(myBotServHelp); } @@ -45,52 +98,5 @@ void myBotServHelp(User * u) notice_lang(s_BotServ, u, BOT_HELP_CMD_BOTLIST); } -/** - * The /bs botlist command. - * @param u The user who issued the command - * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. - **/ -int do_botlist(User * u) -{ - int i, count = 0; - BotInfo *bi; - - if (!nbots) { - notice_lang(s_BotServ, u, BOT_BOTLIST_EMPTY); - return MOD_CONT; - } - - for (i = 0; i < 256; i++) { - for (bi = botlists[i]; bi; bi = bi->next) { - if (!(bi->flags & BI_PRIVATE)) { - if (!count) - notice_lang(s_BotServ, u, BOT_BOTLIST_HEADER); - count++; - notice_user(s_BotServ, u, " %-15s (%s@%s)", bi->nick, - bi->user, bi->host); - } - } - } - - if (is_oper(u) && count < nbots) { - notice_lang(s_BotServ, u, BOT_BOTLIST_PRIVATE_HEADER); - - for (i = 0; i < 256; i++) { - for (bi = botlists[i]; bi; bi = bi->next) { - if (bi->flags & BI_PRIVATE) { - notice_user(s_BotServ, u, " %-15s (%s@%s)", - bi->nick, bi->user, bi->host); - count++; - } - } - } - } - - if (!count) - notice_lang(s_BotServ, u, BOT_BOTLIST_EMPTY); - else - notice_lang(s_BotServ, u, BOT_BOTLIST_FOOTER, count); - return MOD_CONT; -} MODULE_INIT("bs_botlist", BSBotList) diff --git a/src/core/bs_fantasy.c b/src/core/bs_fantasy.c deleted file mode 100644 index 7c6240597..000000000 --- a/src/core/bs_fantasy.c +++ /dev/null @@ -1,79 +0,0 @@ -/* BotServ core fantasy functions - * - * (C) 2003-2009 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * $Id$ - * - */ -/*************************************************************************/ - -#include "module.h" - -int do_fantasy(int argc, char **argv); - -class BSFantasy : public Module -{ - public: - BSFantasy(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - EvtHook *hook; - - this->SetAuthor("Anope"); - this->SetVersion("$Id$"); - this->SetType(CORE); - hook = createEventHook(EVENT_BOT_FANTASY, do_fantasy); - this->AddEventHook(hook); - } -}; - -/** - * Handle all csmodeutils fantasy commands. - * @param argc Argument count - * @param argv Argument list - * @return MOD_CONT or MOD_STOP - **/ -int do_fantasy(int argc, char **argv) -{ - User *u; - ChannelInfo *ci; - CSModeUtil *util = csmodeutils; - char *target; - - if (argc < 3) - return MOD_CONT; - - do { - if (stricmp(argv[0], util->bsname) == 0) { - /* This could have been moved to its own module - however it would require more coding to handle the pass holders - similar to how PROTECT is done - */ - if (!ircd->halfop) { - if (!stricmp(argv[0], "halfop") || !stricmp(argv[0], "dehalfop")) { - return MOD_CONT; - } - } - u = finduser(argv[1]); - ci = cs_findchan(argv[2]); - if (!u || !ci) - return MOD_CONT; - - target = ((argc == 4) ? argv[3] : NULL); - - if (!target && check_access(u, ci, util->levelself)) - bot_raw_mode(u, ci, util->mode, u->nick); - else if (target && check_access(u, ci, util->level)) - bot_raw_mode(u, ci, util->mode, target); - } - } while ((++util)->name != NULL); - - return MOD_CONT; -} - -MODULE_INIT("bs_fantasy", BSFantasy) diff --git a/src/core/bs_fantasy_kick.c b/src/core/bs_fantasy_kick.c deleted file mode 100644 index 3471ac597..000000000 --- a/src/core/bs_fantasy_kick.c +++ /dev/null @@ -1,87 +0,0 @@ -/* BotServ core fantasy functions - * - * (C) 2003-2009 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * $Id$ - * - */ -/*************************************************************************/ - -#include "module.h" - -int do_fantasy(int argc, char **argv); - -class BSFantasyKick : public Module -{ - public: - BSFantasyKick(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - EvtHook *hook; - - this->SetAuthor("Anope"); - this->SetVersion("$Id$"); - this->SetType(CORE); - - hook = createEventHook(EVENT_BOT_FANTASY, do_fantasy); - this->AddEventHook(hook); - } -}; - -/** - * Handle kick/k fantasy commands. - * @param argc Argument count - * @param argv Argument list - * @return MOD_CONT or MOD_STOP - **/ -int do_fantasy(int argc, char **argv) -{ - User *u, *u2; - ChannelInfo *ci; - char *target = NULL; - char *reason = NULL; - - if (argc < 3) - return MOD_CONT; - - if ((stricmp(argv[0], "kick") == 0) || (stricmp(argv[0], "k") == 0)) { - u = finduser(argv[1]); - ci = cs_findchan(argv[2]); - if (!u || !ci) - return MOD_CONT; - - if (argc >= 4) { - target = myStrGetToken(argv[3], ' ', 0); - reason = myStrGetTokenRemainder(argv[3], ' ', 1); - } - if (!target && check_access(u, ci, CA_KICKME)) { - bot_raw_kick(u, ci, u->nick, "Requested"); - } else if (target && check_access(u, ci, CA_KICK)) { - if (!stricmp(target, ci->bi->nick)) - bot_raw_kick(u, ci, u->nick, "Oops!"); - else { - u2 = finduser(target); - if (u2 && ci->c && is_on_chan(ci->c, u2)) { - if (!reason && !is_protected(u2)) - bot_raw_kick(u, ci, target, "Requested"); - else if (!is_protected(u2)) - bot_raw_kick(u, ci, target, reason); - } - } - } - } - - if (target) - delete [] target; - if (reason) - delete [] reason; - - return MOD_CONT; -} - -MODULE_INIT("bs_fantasy_kick", BSFantasyKick) diff --git a/src/core/bs_fantasy_kickban.c b/src/core/bs_fantasy_kickban.c deleted file mode 100644 index 3b3eb20ce..000000000 --- a/src/core/bs_fantasy_kickban.c +++ /dev/null @@ -1,89 +0,0 @@ -/* BotServ core fantasy functions - * - * (C) 2003-2009 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * $Id$ - * - */ -/*************************************************************************/ - -#include "module.h" - -int do_fantasy(int argc, char **argv); - -class BSFantasyKickBan : public Module -{ - public: - BSFantasyKickBan(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - EvtHook *hook; - - this->SetAuthor("Anope"); - this->SetVersion("$Id$"); - this->SetType(CORE); - - hook = createEventHook(EVENT_BOT_FANTASY, do_fantasy); - this->AddEventHook(hook); - } -}; - - -/** - * Handle kickban/kb fantasy commands. - * @param argc Argument count - * @param argv Argument list - * @return MOD_CONT or MOD_STOP - **/ -int do_fantasy(int argc, char **argv) -{ - User *u, *u2; - ChannelInfo *ci; - char *target = NULL; - char *reason = NULL; - - if (argc < 3) - return MOD_CONT; - - if ((stricmp(argv[0], "kickban") == 0) - || (stricmp(argv[0], "kb") == 0)) { - u = finduser(argv[1]); - ci = cs_findchan(argv[2]); - if (!u || !ci) - return MOD_CONT; - - if (argc >= 4) { - target = myStrGetToken(argv[3], ' ', 0); - reason = myStrGetTokenRemainder(argv[3], ' ', 1); - } - if (!target && check_access(u, ci, CA_BANME)) { - bot_raw_ban(u, ci, u->nick, "Requested"); - } else if (target && check_access(u, ci, CA_BAN)) { - if (stricmp(target, ci->bi->nick) == 0) { - bot_raw_ban(u, ci, u->nick, "Oops!"); - } else { - u2 = finduser(target); - if (u2 && ci->c && is_on_chan(ci->c, u2)) { - if (!reason && !is_protected(u2)) - bot_raw_ban(u, ci, target, "Requested"); - else if (!is_protected(u2)) - bot_raw_ban(u, ci, target, reason); - } - } - } - } - - if (target) - delete [] target; - if (reason) - delete [] reason; - - return MOD_CONT; -} - -MODULE_INIT("bs_fantasy_kickban", BSFantasyKickBan) diff --git a/src/core/bs_fantasy_owner.c b/src/core/bs_fantasy_owner.c deleted file mode 100644 index f0155592d..000000000 --- a/src/core/bs_fantasy_owner.c +++ /dev/null @@ -1,78 +0,0 @@ -/* BotServ core fantasy functions - * - * (C) 2003-2009 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * $Id$ - * - */ -/*************************************************************************/ - -#include "module.h" - -int do_fantasy(int argc, char **argv); - -class BSFantasyOwner : public Module -{ - public: - BSFantasyOwner(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - EvtHook *hook; - - this->SetAuthor("Anope"); - this->SetVersion("$Id$"); - this->SetType(CORE); - - /* No need to load of we don't support owner */ - if (!ircd->owner) - { - throw ModuleException("Your ircd doesn't support the owner channelmode; bs_fantasy_owner won't be loaded"); - } - - hook = createEventHook(EVENT_BOT_FANTASY, do_fantasy); - this->AddEventHook(hook); - } -}; - - -/** - * Handle owner/deowner fantasy commands. - * @param argc Argument count - * @param argv Argument list - * @return MOD_CONT or MOD_STOP - **/ -int do_fantasy(int argc, char **argv) -{ - User *u; - ChannelInfo *ci; - - if (argc < 3) - return MOD_CONT; - - if (stricmp(argv[0], "deowner") == 0) { - u = finduser(argv[1]); - ci = cs_findchan(argv[2]); - if (!u || !ci) - return MOD_CONT; - - if (is_founder(u, ci)) - bot_raw_mode(u, ci, ircd->ownerunset, u->nick); - } else if (stricmp(argv[0], "owner") == 0) { - u = finduser(argv[1]); - ci = cs_findchan(argv[2]); - if (!u || !ci) - return MOD_CONT; - - if (is_founder(u, ci)) - bot_raw_mode(u, ci, ircd->ownerset, u->nick); - } - - return MOD_CONT; -} - -MODULE_INIT("bs_fantasy_owner", BSFantasyOwner) diff --git a/src/core/bs_fantasy_seen.c b/src/core/bs_fantasy_seen.c deleted file mode 100644 index 5ef7b914e..000000000 --- a/src/core/bs_fantasy_seen.c +++ /dev/null @@ -1,128 +0,0 @@ -/* BotServ core fantasy functions - * - * (C) 2003-2009 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * $Id$ - * - */ -/*************************************************************************/ - -#include "module.h" - -int do_fantasy(int argc, char **argv); - -class BSFantasySeen : public Module -{ - public: - BSFantasySeen(const std::string &modname, const std::string &creator) : Module(modname, creator) - { - EvtHook *hook; - - this->SetAuthor("Anope"); - this->SetVersion("$Id$"); - this->SetType(CORE); - - hook = createEventHook(EVENT_BOT_FANTASY, do_fantasy); - this->AddEventHook(hook); - } -}; - -/** - * Handle seen fantasy command. - * @param argc Argument count - * @param argv Argument list - * @return MOD_CONT or MOD_STOP - **/ -int do_fantasy(int argc, char **argv) -{ - User *u; - ChannelInfo *ci; - User *u2; - NickAlias *na; - ChanAccess *access; - char buf[BUFSIZE]; - char *target = NULL; - - if (argc < 4) - return MOD_CONT; - - if (stricmp(argv[0], "seen") == 0) { - u = finduser(argv[1]); - ci = cs_findchan(argv[2]); - if (!u || !ci) - return MOD_CONT; - - target = myStrGetToken(argv[3], ' ', 0); - - if (stricmp(ci->bi->nick, target) == 0) { - /* If we look for the bot */ - snprintf(buf, sizeof(buf), getstring(u->na, BOT_SEEN_BOT), - u->nick); - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", buf); - } else if (!(na = findnick(target)) || (na->status & NS_VERBOTEN)) { - /* If the nick is not registered or forbidden */ - snprintf(buf, sizeof(buf), getstring(u->na, BOT_SEEN_UNKNOWN), - target); - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", buf); - } else if ((u2 = nc_on_chan(ci->c, na->nc))) { - /* If the nick we're looking for is on the channel, - * there are three possibilities: it's yourself, - * it's the nick we look for, it's an alias of the - * nick we look for. - */ - if (u == u2 || (u->na && u->na->nc == na->nc)) - snprintf(buf, sizeof(buf), getstring(u->na, BOT_SEEN_YOU), - u->nick); - else if (!stricmp(u2->nick, target)) - snprintf(buf, sizeof(buf), - getstring(u->na, BOT_SEEN_ON_CHANNEL), u2->nick); - else - snprintf(buf, sizeof(buf), - getstring(u->na, BOT_SEEN_ON_CHANNEL_AS), target, - u2->nick); - - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", buf); - } else if ((access = get_access_entry(na->nc, ci))) { - /* User is on the access list but not present actually. - Special case: if access->last_seen is 0 it's that we - never seen the user. - */ - if (access->last_seen) { - char durastr[192]; - duration(u->na, durastr, sizeof(durastr), - time(NULL) - access->last_seen); - snprintf(buf, sizeof(buf), getstring(u->na, BOT_SEEN_ON), - target, durastr); - } else { - snprintf(buf, sizeof(buf), - getstring(u->na, BOT_SEEN_NEVER), target); - } - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", buf); - } else if (na->nc == ci->founder) { - /* User is the founder of the channel */ - char durastr[192]; - duration(u->na, durastr, sizeof(durastr), - time(NULL) - na->last_seen); - snprintf(buf, sizeof(buf), getstring(u->na, BOT_SEEN_ON), - target, durastr); - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", buf); - } else { - /* All other cases */ - snprintf(buf, sizeof(buf), getstring(u->na, BOT_SEEN_UNKNOWN), - target); - ircdproto->SendPrivmsg(ci->bi, ci->name, "%s", buf); - } - /* free myStrGetToken(ed) variable target (#851) */ - if (target) delete [] target; - } - - return MOD_CONT; -} - -MODULE_INIT("bs_fantasy_seen", BSFantasySeen) diff --git a/src/core/bs_help.c b/src/core/bs_help.c index cd73ee093..480dd62f7 100644 --- a/src/core/bs_help.c +++ b/src/core/bs_help.c @@ -15,41 +15,39 @@ #include "module.h" -int do_help(User * u); +class CommandBSHelp : public Command +{ + public: + CommandBSHelp() : Command("HELP", 1, 1) + { + } + + CommandReturn Execute(User *u, std::vector ¶ms) + { + mod_help_cmd(s_BotServ, u, BOTSERV, params[0].c_str()); + return MOD_CONT; + } + + void OnSyntaxError(User *u) + { + notice_help(s_BotServ, u, BOT_HELP); + moduleDisplayHelp(4, u); + notice_help(s_BotServ, u, BOT_HELP_FOOTER, BSMinUsers); + } +}; class BSHelp : public Module { public: BSHelp(const std::string &modname, const std::string &creator) : Module(modname, creator) { - Command *c; - this->SetAuthor("Anope"); this->SetVersion("$Id$"); this->SetType(CORE); - c = createCommand("HELP", do_help, NULL, -1, -1, -1, -1, -1); - this->AddCommand(BOTSERV, c, MOD_UNIQUE); + this->AddCommand(BOTSERV, new CommandBSHelp(), MOD_UNIQUE); } }; -/** - * The /bs help command. - * @param u The user who issued the command - * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. - **/ -int do_help(User * u) -{ - char *cmd = strtok(NULL, ""); - - if (!cmd) { - notice_help(s_BotServ, u, BOT_HELP); - moduleDisplayHelp(4, u); - notice_help(s_BotServ, u, BOT_HELP_FOOTER, BSMinUsers); - } else { - mod_help_cmd(s_BotServ, u, BOTSERV, cmd); - } - return MOD_CONT; -} MODULE_INIT("bs_help", BSHelp) diff --git a/src/core/bs_info.c b/src/core/bs_info.c index 985ff6dd3..c6acd204d 100644 --- a/src/core/bs_info.c +++ b/src/core/bs_info.c @@ -15,255 +15,262 @@ #include "module.h" -int do_info(User * u); -void send_bot_channels(User * u, BotInfo * bi); void myBotServHelp(User * u); -class BSInfo : public Module +class CommandBSInfo : public Command { - public: - BSInfo(const std::string &modname, const std::string &creator) : Module(modname, creator) + private: + void send_bot_channels(User * u, BotInfo * bi) { - Command *c; - - this->SetAuthor("Anope"); - this->SetVersion("$Id$"); - this->SetType(CORE); - c = createCommand("INFO", do_info, NULL, BOT_HELP_INFO, -1, -1, -1, -1); - this->AddCommand(BOTSERV, c, MOD_UNIQUE); - - this->SetBotHelp(myBotServHelp); - } -}; + int i; + ChannelInfo *ci; + char buf[307], *end; + *buf = 0; + end = buf; -/** - * Add the help response to Anopes /bs help output. - * @param u The user who is requesting help - **/ -void myBotServHelp(User * u) -{ - notice_lang(s_BotServ, u, BOT_HELP_CMD_INFO); -} + for (i = 0; i < 256; i++) { + for (ci = chanlists[i]; ci; ci = ci->next) { + if (ci->bi == bi) { + if (strlen(buf) + strlen(ci->name) > 300) { + notice_user(s_BotServ, u, "%s", buf); + *buf = 0; + end = buf; + } + end += + snprintf(end, sizeof(buf) - (end - buf), " %s ", + ci->name); + } + } + } -/** - * The /bs info command. - * @param u The user who issued the command - * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. - **/ -int do_info(User * u) -{ - BotInfo *bi; - ChannelInfo *ci; - char *query = strtok(NULL, " "); + if (*buf) + notice_user(s_BotServ, u, "%s", buf); + return; + } + public: + CommandBSInfo() : Command("INFO", 1, 1) + { + } - int need_comma = 0, is_servadmin = is_services_admin(u); - char buf[BUFSIZE], *end; - const char *commastr = getstring(u->na, COMMA_SPACE); + CommandReturn Execute(User *u, std::vector ¶ms) + { + BotInfo *bi; + ChannelInfo *ci; + char *query = strtok(NULL, " "); - if (!query) - syntax_error(s_BotServ, u, "INFO", BOT_INFO_SYNTAX); - else if ((bi = findbot(query))) { - struct tm *tm; + int need_comma = 0, is_servadmin = is_services_admin(u); + char buf[BUFSIZE], *end; + const char *commastr = getstring(u->na, COMMA_SPACE); - notice_lang(s_BotServ, u, BOT_INFO_BOT_HEADER, bi->nick); - notice_lang(s_BotServ, u, BOT_INFO_BOT_MASK, bi->user, bi->host); - notice_lang(s_BotServ, u, BOT_INFO_BOT_REALNAME, bi->real); - tm = localtime(&bi->created); - strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); - notice_lang(s_BotServ, u, BOT_INFO_BOT_CREATED, buf); - notice_lang(s_BotServ, u, BOT_INFO_BOT_OPTIONS, - getstring(u->na, - (bi-> - flags & BI_PRIVATE) ? BOT_INFO_OPT_PRIVATE : - BOT_INFO_OPT_NONE)); - notice_lang(s_BotServ, u, BOT_INFO_BOT_USAGE, bi->chancount); + if ((bi = findbot(query))) { + struct tm *tm; - if (is_services_admin(u)) - send_bot_channels(u, bi); - } else if ((ci = cs_findchan(query))) { - if (!is_servadmin && !is_founder(u, ci)) { - notice_lang(s_BotServ, u, PERMISSION_DENIED); - return MOD_CONT; - } - if (ci->flags & CI_VERBOTEN) { - notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, query); - return MOD_CONT; - } + notice_lang(s_BotServ, u, BOT_INFO_BOT_HEADER, bi->nick); + notice_lang(s_BotServ, u, BOT_INFO_BOT_MASK, bi->user, bi->host); + notice_lang(s_BotServ, u, BOT_INFO_BOT_REALNAME, bi->real); + tm = localtime(&bi->created); + strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); + notice_lang(s_BotServ, u, BOT_INFO_BOT_CREATED, buf); + notice_lang(s_BotServ, u, BOT_INFO_BOT_OPTIONS, + getstring(u->na, + (bi-> + flags & BI_PRIVATE) ? BOT_INFO_OPT_PRIVATE : + BOT_INFO_OPT_NONE)); + notice_lang(s_BotServ, u, BOT_INFO_BOT_USAGE, bi->chancount); - notice_lang(s_BotServ, u