reply("CSMSG_NETWORK_INFO");
reply("CSMSG_NETWORK_SERVERS", dict_size(servers));
reply("CSMSG_NETWORK_USERS", dict_size(clients));
- reply("CSMSG_NETWORK_OPERS", curr_opers.used);
+ reply("CSMSG_NETWORK_OPERS", count_opers);
reply("CSMSG_NETWORK_CHANNELS", registered_channels);
reply("CSMSG_NETWORK_LAMERS", banCount);
reply("CSMSG_NETWORK_CHANUSERS", userCount);
static CHANSERV_FUNC(cmd_ircops)
{
reply("CSMSG_STAFF_OPERS");
- send_staff_list(user, &curr_opers, FLAGS_SERVICE);
+ send_staff_list(user, &curr_opers, FLAGS_SERVICE | FLAGS_BOT);
return 1;
}
static CHANSERV_FUNC(cmd_helpers)
{
reply("CSMSG_STAFF_HELPERS");
- send_staff_list(user, &curr_helpers, FLAGS_OPER);
+ send_staff_list(user, &curr_helpers, FLAGS_OPER | FLAGS_SERVICE | FLAGS_BOT);
return 1;
}
unsigned int max_clients, invis_clients;
time_t max_clients_time;
struct userList curr_opers;
+unsigned int count_opers;
static void hash_cleanup(void *extra);
clients = dict_new();
servers = dict_new();
userList_init(&curr_opers);
+ count_opers = 0;
reg_exit_func(hash_cleanup, NULL);
}
dict_delete(clients);
dict_delete(servers);
userList_clean(&curr_opers);
+ count_opers = 0;
free(slf_list);
free(slf_list_extra);
extern time_t max_clients_time;
extern struct userList curr_opers, curr_helpers;
+extern unsigned int count_opers;
+
struct server* GetServerH(const char *name); /* using full name */
struct userNode* GetUserH(const char *nick); /* using nick */
struct chanNode* GetChannel(const char *name);
user->uplink->clients--;
user->uplink->users[user->num_local] = NULL;
- if (IsOper(user))
+ if (IsOper(user)) {
userList_remove(&curr_opers, user);
+ if (count_opers > 0 && !IsBotM(user) && !IsService(user) && !IsHideOper(user))
+ count_opers--;
+ }
/* remove from global dictionary, but not if after a collide */
if (user == dict_find(clients, user->nick, NULL))
dict_remove(clients, user->nick);
void mod_usermode(struct userNode *user, const char *mode_change) {
int add = 1;
+ long setmodes = 0;
+ int donemodes = 0;
const char *word = mode_change;
if (!user || !mode_change)
call_user_mode_funcs(user, mode_change);
+ setmodes = user->modes;
+
while (*word != ' ' && *word) word++;
while (*word == ' ') word++;
- while (1) {
+ while (!donemodes) {
#define do_user_mode(FLAG) do { if (add) user->modes |= FLAG; else user->modes &= ~FLAG; } while (0)
switch (*mode_change++) {
- case 0: case ' ': return;
+ case 0: case ' ':
+ donemodes = 1;
+ break;
case '+': add = 1; break;
case '-': add = 0; break;
case 'o':
}
#undef do_user_mode
}
+
+ // Set user mode +o
+ if (!(setmodes & FLAGS_OPER) && IsOper(user)) {
+ if (!IsBotM(user) && !IsService(user) && !IsHideOper(user))
+ count_opers++;
+ }
+
+ // Set user mode -o
+ if ((setmodes & FLAGS_OPER) && !IsOper(user)) {
+ if (count_opers > 1 && !(setmodes & FLAGS_BOT) &&
+ !(setmodes & FLAGS_SERVICE) && !(setmodes & FLAGS_HIDEOPER))
+ count_opers--;
+ }
+
+ // Set +H, +k or +B
+ if (!(setmodes & FLAGS_HIDEOPER) &&
+ !(setmodes & FLAGS_SERVICE) &&
+ !(setmodes & FLAGS_BOT) &&
+ (IsHideOper(user) || IsService(user) || IsBotM(user))) {
+ if ((setmodes & FLAGS_OPER) && IsOper(user) && count_opers > 0)
+ count_opers--;
+ }
+
+ // Set -H, -k or -B
+ if (((setmodes & FLAGS_HIDEOPER) ||
+ (setmodes & FLAGS_SERVICE) ||
+ (setmodes & FLAGS_BOT)) &&
+ !IsHideOper(user) && !IsService(user) && !IsBotM(user)) {
+ if ((setmodes & FLAGS_OPER) && IsOper(user))
+ count_opers++;
+ }
}
static int