`botclass` int(10) NOT NULL,
`textbot` tinyint(1) NOT NULL,
`queue` tinyint(1) NOT NULL,
+ `secret` tinyint(1) NOT NULL,
`defaulttrigger` varchar(10) NOT NULL,
`max_channels` int(5) NOT NULL,
`register_priority` int(2) NOT NULL,
ALTER TABLE `users` ADD `user_block_invites` TINYINT NOT NULL AFTER `user_reply_privmsg`;
-- version: 19
+
+ALTER TABLE `bots` ADD `secret` TINYINT( 1 ) NOT NULL AFTER `queue`;
+
+-- version: 20
SYNCHRONIZE(cache_sync);
struct ChanUser *cchanuser, *last;
//remove it from the user's channel-list
- if(!(chanuser->flags & CHANUSERFLAG_INVISIBLE)) {
- last = NULL;
- for(cchanuser = chanuser->user->channel; cchanuser; cchanuser = cchanuser->next_chan) {
- if(cchanuser == chanuser) {
- if(last)
- last->next_chan = chanuser->next_chan;
- else
- chanuser->user->channel = chanuser->next_chan;
- break;
- } else
- last = cchanuser;
- }
+ last = NULL;
+ for(cchanuser = chanuser->user->channel; cchanuser; cchanuser = cchanuser->next_chan) {
+ if(cchanuser == chanuser) {
+ if(last)
+ last->next_chan = chanuser->next_chan;
+ else
+ chanuser->user->channel = chanuser->next_chan;
+ break;
+ } else
+ last = cchanuser;
}
//remove it from the channel's user-list
#define SOCKET_FLAG_CHANGENICK 0x800
#define SOCKET_FLAG_REQUEST_INVITE 0x1000
#define SOCKET_FLAG_REQUEST_OP 0x2000
+#define SOCKET_FLAG_SECRET_BOT 0x4000
#define SOCKET_HAVE_BOTCLASSVALUE1 0x10000000
#define SOCKET_HAVE_BOTCLASSVALUE2 0x20000000
}
}
+static void increase_viscount_butone(struct ChanNode *chan, struct ChanUser *ignore) {
+ struct ChanUser *chanuser;
+
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(chanuser == ignore)
+ continue;
+ chanuser->visCount++;
+ }
+}
+
+static void decrease_viscount_butone(struct ChanNode *chan, struct ChanUser *ignore) {
+ struct ChanUser *chanuser, *next_chanuser;
+
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next_chanuser) {
+ next_chanuser = getChannelUsers(chan, chanuser);
+ if(chanuser == ignore)
+ continue;
+ chanuser->visCount--;
+ if(chanuser->visCount <= 0)
+ delChanUser(chanuser, 1);
+ }
+}
+
static USERLIST_CALLBACK(got_channel_userlist) {
struct ChanUser *chanuser = data;
+
+ increase_viscount_butone(chanuser->chan, chanuser);
+
event_join(chanuser);
}
event_registered(user, from);
user->flags &= ~USERFLAG_WAS_REGISTERING;
+ } else if(!(chan->flags & CHANFLAG_RECEIVED_USERLIST)) {
+ if(!isBot(user)) {
+ DESYNCHRONIZE(cache_sync);
+ return 1; //ignore join
+ }
+
+ chanuser = addChanUser(chan, user);
+ chanuser->visCount = 1;
+
+ if(isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible
+ chanuser->flags |= CHANUSERFLAG_INVISIBLE;
+
+ get_userlist_with_invisible(chan, 0, got_channel_userlist, chanuser);
} else if(!isUserOnChan(user, chan)) {
//join user to an existing channel
chanuser = addChanUser(chan, user);
chanuser->visCount = 1;
- if(isBot(user) && isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible
- chanuser->flags |= CHANUSERFLAG_INVISIBLE;
+ if(isBot(user)) {
+ if(isModeSet(chan->modes, 'D')) //if the bot joins a channel it could also be invisible
+ chanuser->flags |= CHANUSERFLAG_INVISIBLE;
+ increase_viscount_butone(chan, chanuser);
+ }
event_join(chanuser);
//user is already in the channel
chanuser = getChanUser(user, chan);
chanuser->visCount++;
+
+ if(isBot(user) && !(chanuser->flags & CHANUSERFLAG_INVISIBLE))
+ increase_viscount_butone(chan, chanuser);
+
//if multiple bots see the user, it can't be invisible
chanuser->flags &= ~CHANUSERFLAG_INVISIBLE;
}
DESYNCHRONIZE(cache_sync);
return 0;
}
+ if(isBot(user) && user == client->user)
+ decrease_viscount_butone(chan, chanuser);
chanuser->visCount--;
if(chanuser->visCount == 0) {
delChanUser(chanuser, 0); //not free, yet!
DESYNCHRONIZE(cache_sync);
return 0;
}
+ if(isBot(target) && target == client->user)
+ decrease_viscount_butone(chan, chanuser);
chanuser->visCount--;
if(chanuser->visCount == 0) {
delChanUser(chanuser, 0); //not free, yet!
for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) {
next_chanuser = getUserChannels(user, chanuser);
chanuser->visCount--;
- if(chanuser->visCount == 0) {
+ if(chanuser->visCount <= 0) {
delChanUser(chanuser, 0); //not free, yet!
event_part(chanuser, 1, argv[0]);
if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING))
struct ChanUser *chanuser, *next_chanuser;
for(chanuser = getUserChannels(user, NULL); chanuser; chanuser = next_chanuser) {
next_chanuser = getUserChannels(user, chanuser);
+ decrease_viscount_butone(chanuser->chan, chanuser);
chanuser->visCount--;
- if(chanuser->visCount == 0) {
+ if(chanuser->visCount <= 0) {
delChanUser(chanuser, 0); //not free, yet!
event_part(chanuser, 1, "QUIT");
- if((chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST) && !(chanuser->chan->flags & CHANFLAG_REJOINING))
- check_full_rejoin(chanuser->chan);
+ if(chanuser->chan->flags & CHANFLAG_RECEIVED_USERLIST)
+ checkChannelVisibility(chanuser->chan);
freeChanUser(chanuser);
}
}
#define WHOQUEUETYPE_CHECKTYPE 0x07
#define WHOQUEUETYPE_FOUND 0x08
-#define MAXCALLBACKS 3
+#define MAXCALLBACKS 10
struct WHOQueueEntry {
char type;
MYSQL_RES *res, *res2;
MYSQL_ROW row;
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '0' AND `active` = '1'");
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '0' AND `active` = '1'");
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->botid = 0;
client->clientid = atoi(row[7]);
connect_socket(client);
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_SILENT;
client->botid = BOTID;
client->clientid = atoi(row[7]);
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
client->botid = BOTID;
client->clientid = atoi(row[7]);
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_SILENT;
client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
client->botid = BOTID;
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_SILENT;
client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
client->botid = BOTID;
{"NS_NICKLIST_STATE", "State"},
{"NS_NICKLIST_ACCESS", "Access"},
{"NS_NICKLIST_SYNC", "use `nicklist sync` to fix all red and orange entrys in the list above (add opped users with %d and voiced with %d access)"},
+ {"NS_NICKLIST_ACCESS_BOT", "Bot"},
+ {"NS_NICKLIST_ACCESS_OPER", "Operator"},
{"NS_SETBOT_UNKNOWN", "`%d` is an unknown botid."}, /* {ARGS: 50} */
{"NS_SETBOT_HEADER", "$bSettings for botid `%d`:$b"}, /* {ARGS: 50} */
{"NS_SETBOT_SETTING", "$b%s$b is an unknown bot setting."}, /* {ARGS: "strangeSetting"} */
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client = create_socket(row[3], atoi(row[4]), row[10], row[5], row[0], row[1], row[2]);
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
client->botid = BOTID;
client->clientid = atoi(row[7]);
* argv[1] (optional) nick mask
*/
static USERLIST_CALLBACK(neonserv_cmd_nicklist_userlist_lookup);
-static void neonserv_cmd_nicklist_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask, int syncusers);
+static void neonserv_cmd_nicklist_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask, int flags);
static void neonserv_cmd_nicklist_synchronize_user(struct ChanNode *chan, struct UserNode *user, int access);
+#define NEONSERV_CMD_NICKLIST_FLAG_SYNCUSERS 0x01
+#define NEONSERV_CMD_NICKLIST_FLAG_NOWHO 0x02
+#define NEONSERV_CMD_NICKLIST_FLAG_VISCOUNT 0x04
+
struct neonserv_cmd_nicklist_cache {
struct ClientSocket *client, *textclient;
struct UserNode *user;
struct Event *event;
char *nickmask;
- int syncusers;
+ int flags;
};
CMD_BIND(neonserv_cmd_nicklist) {
- int syncusers = 0;
- if(argc && !stricmp(argv[0], "sync")) {
- if(!checkChannelAccess(user, chan, "channel_canadd", 0)) {
- if(isGodMode(user)) {
- event->flags |= CMDFLAG_OPLOG;
- } else {
- reply(textclient, user, "NS_ACCESS_DENIED");
- return;
+ int flags = 0;
+ while(argc) {
+ if(!stricmp(argv[0], "sync")) {
+ if(!checkChannelAccess(user, chan, "channel_canadd", 0)) {
+ if(isGodMode(user)) {
+ event->flags |= CMDFLAG_OPLOG;
+ } else {
+ reply(textclient, user, "NS_ACCESS_DENIED");
+ return;
+ }
}
- }
+ flags |= NEONSERV_CMD_NICKLIST_FLAG_SYNCUSERS;
+ event->flags |= CMDFLAG_LOG;
+ } else if(argc && !stricmp(argv[0], "nowho") && isGodMode(user)) {
+ flags |= NEONSERV_CMD_NICKLIST_FLAG_NOWHO;
+ } else if(argc && !stricmp(argv[0], "viscount") && isGodMode(user)) {
+ flags |= NEONSERV_CMD_NICKLIST_FLAG_VISCOUNT;
+ } else
+ break;
argv++;
argc--;
- syncusers = 1;
- event->flags |= CMDFLAG_LOG;
}
- if(argc && !stricmp(argv[0], "nowho") && isGodMode(user)) {
- argv++;
- argc--;
- neonserv_cmd_nicklist_async1(client, textclient, user, chan, event, (argc ? argv[0] : NULL), syncusers);
+ if(flags & NEONSERV_CMD_NICKLIST_FLAG_NOWHO) {
+ neonserv_cmd_nicklist_async1(client, textclient, user, chan, event, (argc ? argv[0] : NULL), flags);
return;
}
struct neonserv_cmd_nicklist_cache *cache = malloc(sizeof(*cache));
cache->nickmask = strdup(argv[0]);
} else
cache->nickmask = NULL;
- cache->syncusers = syncusers;
+ cache->flags = flags;
get_userlist_with_invisible(chan, module_id, neonserv_cmd_nicklist_userlist_lookup, cache);
}
static USERLIST_CALLBACK(neonserv_cmd_nicklist_userlist_lookup) {
struct neonserv_cmd_nicklist_cache *cache = data;
- neonserv_cmd_nicklist_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nickmask, cache->syncusers);
+ neonserv_cmd_nicklist_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->nickmask, cache->flags);
if(cache->nickmask)
free(cache->nickmask);
free(cache);
}
-static void neonserv_cmd_nicklist_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask, int syncusers) {
+static int neonserv_cmd_nicklist_sort_flags[] = {
+ CHANUSERFLAG_OPPED | CHANUSERFLAG_HALFOPPED | CHANUSERFLAG_VOICED,
+ CHANUSERFLAG_OPPED | CHANUSERFLAG_HALFOPPED,
+ CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED,
+ CHANUSERFLAG_OPPED,
+ CHANUSERFLAG_HALFOPPED | CHANUSERFLAG_VOICED,
+ CHANUSERFLAG_HALFOPPED,
+ CHANUSERFLAG_VOICED,
+ CHANUSERFLAG_INVISIBLE,
+ 0
+};
+
+static int neonserv_cmd_nicklist_sort(const void *a, const void *b) {
+ const struct ChanUser *chanuser_a = *((struct ChanUser * const *) a);
+ const struct ChanUser *chanuser_b = *((struct ChanUser * const *) b);
+ int i_a = 0, i_b = 0;
+ while((chanuser_a->flags & (CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED | CHANUSERFLAG_INVISIBLE)) != neonserv_cmd_nicklist_sort_flags[i_a] && neonserv_cmd_nicklist_sort_flags[i_a])
+ i_a++;
+ while((chanuser_b->flags & (CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED | CHANUSERFLAG_INVISIBLE)) != neonserv_cmd_nicklist_sort_flags[i_b] && neonserv_cmd_nicklist_sort_flags[i_b])
+ i_b++;
+ if(i_a == i_b) {
+ return stricmp(chanuser_a->user->nick, chanuser_b->user->nick);
+ } else
+ return i_a - i_b;
+}
+
+static void neonserv_cmd_nicklist_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *nickmask, int flags) {
MYSQL_RES *res;
MYSQL_ROW row, defaults = NULL;
struct Table *table;
- table = table_init(3, chan->usercount + 1, 0);
- char *content[3];
+ char *content[4];
+ int userlistlen, i, j;
+ int db_enfops, db_enfvoice;
+ int caccess, synced_user, accessbufpos;
+ struct ChanUser *chanusers[chan->usercount];
+ struct ChanUser *chanuser;
+ struct ClientSocket *bot;
+ int chanuser_count;
+ char statebuf[5];
+ char accessbuf[50];
+ char viscountbuf[5];
+ int uaccess;
+
+ i = 3;
+ if(flags & NEONSERV_CMD_NICKLIST_FLAG_VISCOUNT) {
+ i++;
+ content[3] = "VisCount";
+ }
+ table = table_init(i, chan->usercount + 1, 0);
content[0] = get_language_string(user, "NS_NICKLIST_NICK");
content[1] = get_language_string(user, "NS_NICKLIST_STATE");
content[2] = get_language_string(user, "NS_NICKLIST_ACCESS");
table_add(table, content);
+
printf_mysql_query("SELECT `chanuser_access`, `user_user`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d'", chan->channel_id);
res = mysql_use();
- int userlistlen = mysql_num_rows(res);
- int i = 0;
+ userlistlen = mysql_num_rows(res);
+ i = 0;
MYSQL_ROW userlist[userlistlen];
while ((row = mysql_fetch_row(res)) != NULL) {
userlist[i++] = row;
}
- 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) {
}
db_enfops = atoi((row[0] ? row[0] : defaults[0]));
db_enfvoice = atoi((row[1] ? row[1] : defaults[1]));
- int caccess = getChannelAccess(user, chan);
- int synced_user = 0;
- struct ChanUser *chanuser;
- int sort_nicklist[] = {
- CHANUSERFLAG_OPPED | CHANUSERFLAG_HALFOPPED | CHANUSERFLAG_VOICED,
- CHANUSERFLAG_OPPED | CHANUSERFLAG_HALFOPPED,
- CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED,
- CHANUSERFLAG_OPPED,
- CHANUSERFLAG_HALFOPPED | CHANUSERFLAG_VOICED,
- CHANUSERFLAG_HALFOPPED,
- CHANUSERFLAG_VOICED,
- CHANUSERFLAG_INVISIBLE,
- 0
- };
- int *sort_pos = sort_nicklist;
- int sort_flags;
- do {
- sort_flags = *(sort_pos++);
- char statebuf[5];
- char accessbuf[9];
- int uaccess;
- int stateset = 0;
- for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
- if((chanuser->flags & (CHANUSERFLAG_OPPED | CHANUSERFLAG_VOICED | CHANUSERFLAG_INVISIBLE)) != sort_flags) continue;
- if(nickmask && match(nickmask, chanuser->user->nick)) continue;
- if(!stateset) {
- if((chanuser->flags & CHANUSERFLAG_INVISIBLE)) statebuf[stateset++] = '<';
- if((chanuser->flags & CHANUSERFLAG_OPPED)) statebuf[stateset++] = '@';
- if((chanuser->flags & CHANUSERFLAG_HALFOPPED)) statebuf[stateset++] = '%';
- if((chanuser->flags & CHANUSERFLAG_VOICED)) statebuf[stateset++] = '+';
- statebuf[stateset++] = '\0';
- }
- content[0] = chanuser->user->nick;
- content[1] = statebuf;
- uaccess = 0;
- if(chanuser->user->flags & USERFLAG_ISAUTHED) {
- for(i = 0; i < userlistlen; i++) {
- if(!stricmp(chanuser->user->auth, userlist[i][1])) {
- uaccess = atoi(userlist[i][0]);
- if((((chanuser->flags & CHANUSERFLAG_OPPED) && uaccess < db_enfops) || ((chanuser->flags & CHANUSERFLAG_VOICED) && uaccess < db_enfvoice)) && !isNetworkService(chanuser->user)) {
- if(syncusers) {
- if((chanuser->flags & CHANUSERFLAG_OPPED) && (db_enfops < caccess || isGodMode(user))) {
- if(db_enfops >= caccess)
- event->flags |= CMDFLAG_OPLOG;
- uaccess = db_enfops;
- } else if((chanuser->flags & CHANUSERFLAG_VOICED) && (caccess < db_enfvoice || isGodMode(user))) {
- if(db_enfvoice >= caccess)
- event->flags |= CMDFLAG_OPLOG;
- uaccess = db_enfvoice;
- } else {
- //fail...
- sprintf(accessbuf, "\00307%d\003", uaccess);
- break;
- }
- neonserv_cmd_nicklist_synchronize_user(chan, chanuser->user, uaccess);
- sprintf(accessbuf, "\00309%d\003", uaccess);
- synced_user = 1;
+
+ chanuser_count = 0;
+ for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+ if(nickmask && match(nickmask, chanuser->user->nick)) continue;
+ chanusers[chanuser_count++] = chanuser;
+ }
+ qsort(chanusers, chanuser_count, sizeof(struct ChanUser *), neonserv_cmd_nicklist_sort);
+
+ caccess = getChannelAccess(user, chan);
+ synced_user = 0;
+ for(i = 0; i < chanuser_count; i++) {
+ chanuser = chanusers[i];
+
+ content[0] = chanuser->user->nick;
+
+ j = 0;
+ if((chanuser->flags & CHANUSERFLAG_INVISIBLE)) statebuf[j++] = '<';
+ if((chanuser->flags & CHANUSERFLAG_OPPED)) statebuf[j++] = '@';
+ if((chanuser->flags & CHANUSERFLAG_HALFOPPED)) statebuf[j++] = '%';
+ if((chanuser->flags & CHANUSERFLAG_VOICED)) statebuf[j++] = '+';
+ statebuf[j++] = '\0';
+ content[1] = statebuf;
+
+ uaccess = 0;
+ if(chanuser->user->flags & USERFLAG_ISAUTHED) {
+ for(j = 0; j < userlistlen; j++) {
+ if(!stricmp(chanuser->user->auth, userlist[j][1])) {
+ uaccess = atoi(userlist[j][0]);
+ if((((chanuser->flags & CHANUSERFLAG_OPPED) && uaccess < db_enfops) || ((chanuser->flags & CHANUSERFLAG_VOICED) && uaccess < db_enfvoice)) && !isNetworkService(chanuser->user)) {
+ if(flags & NEONSERV_CMD_NICKLIST_FLAG_SYNCUSERS) {
+ if((chanuser->flags & CHANUSERFLAG_OPPED) && (db_enfops < caccess || isGodMode(user))) {
+ if(db_enfops >= caccess)
+ event->flags |= CMDFLAG_OPLOG;
+ uaccess = db_enfops;
+ } else if((chanuser->flags & CHANUSERFLAG_VOICED) && (caccess < db_enfvoice || isGodMode(user))) {
+ if(db_enfvoice >= caccess)
+ event->flags |= CMDFLAG_OPLOG;
+ uaccess = db_enfvoice;
} else {
- synced_user = 1;
- sprintf(accessbuf, "\00307%d\003", uaccess);
+ //fail...
+ accessbufpos = sprintf(accessbuf, "\00307%d\003", uaccess);
+ break;
}
- } else if((uaccess >= db_enfops && !(chanuser->flags & CHANUSERFLAG_OPPED)) || (uaccess >= db_enfvoice && !(chanuser->flags & CHANUSERFLAG_OPPED_OR_VOICED)))
- sprintf(accessbuf, "\00303%d\003", uaccess);
- else
- sprintf(accessbuf, "%d", uaccess);
- break;
- }
+ neonserv_cmd_nicklist_synchronize_user(chan, chanuser->user, uaccess);
+ accessbufpos = sprintf(accessbuf, "\00309%d\003", uaccess);
+ synced_user = 1;
+ } else {
+ synced_user = 1;
+ accessbufpos = sprintf(accessbuf, "\00307%d\003", uaccess);
+ }
+ } else if((uaccess >= db_enfops && !(chanuser->flags & CHANUSERFLAG_OPPED)) || (uaccess >= db_enfvoice && !(chanuser->flags & CHANUSERFLAG_OPPED_OR_VOICED)))
+ accessbufpos = sprintf(accessbuf, "\00303%d\003", uaccess);
+ else
+ accessbufpos = sprintf(accessbuf, "%d", uaccess);
+ break;
}
}
- if(!uaccess && (chanuser->flags & CHANUSERFLAG_OPPED_OR_VOICED) && !isNetworkService(chanuser->user)) {
- if(syncusers) {
- if((chanuser->flags & CHANUSERFLAG_OPPED) && (db_enfops < caccess || isGodMode(user))) {
- if(db_enfops >= caccess)
- event->flags |= CMDFLAG_OPLOG;
- uaccess = db_enfops;
- } else if((chanuser->flags & CHANUSERFLAG_VOICED) && (db_enfvoice < caccess || isGodMode(user))) {
- if(db_enfvoice >= caccess)
- event->flags |= CMDFLAG_OPLOG;
- uaccess = db_enfvoice;
- } else {
- uaccess = 0;
- sprintf(accessbuf, "\003040\003");
- }
- if(uaccess && (chanuser->user->flags & USERFLAG_ISAUTHED)) {
- neonserv_cmd_nicklist_synchronize_user(chan, chanuser->user, uaccess);
- sprintf(accessbuf, "\00309%d\003", uaccess);
- synced_user = 1;
- } else if(uaccess) {
- sprintf(accessbuf, "\003040\003");
- }
+ }
+ if(!uaccess && (chanuser->flags & CHANUSERFLAG_OPPED_OR_VOICED) && !isNetworkService(chanuser->user)) {
+ if(flags & NEONSERV_CMD_NICKLIST_FLAG_SYNCUSERS) {
+ if((chanuser->flags & CHANUSERFLAG_OPPED) && (db_enfops < caccess || isGodMode(user))) {
+ if(db_enfops >= caccess)
+ event->flags |= CMDFLAG_OPLOG;
+ uaccess = db_enfops;
+ } else if((chanuser->flags & CHANUSERFLAG_VOICED) && (db_enfvoice < caccess || isGodMode(user))) {
+ if(db_enfvoice >= caccess)
+ event->flags |= CMDFLAG_OPLOG;
+ uaccess = db_enfvoice;
} else {
+ uaccess = 0;
+ accessbufpos = sprintf(accessbuf, "\003040\003");
+ }
+ if(uaccess && (chanuser->user->flags & USERFLAG_ISAUTHED)) {
+ neonserv_cmd_nicklist_synchronize_user(chan, chanuser->user, uaccess);
+ accessbufpos = sprintf(accessbuf, "\00309%d\003", uaccess);
synced_user = 1;
- sprintf(accessbuf, "\003040\003");
+ } else if(uaccess) {
+ accessbufpos = sprintf(accessbuf, "\003040\003");
}
- } else if(!uaccess)
- sprintf(accessbuf, "0");
- content[2] = accessbuf;
- table_add(table, content);
+ } else {
+ synced_user = 1;
+ accessbufpos = sprintf(accessbuf, "\003040\003");
+ }
+ } else if(!uaccess)
+ accessbufpos = sprintf(accessbuf, "0");
+ j = 0;
+ if(isBot(chanuser->user)) {
+ //check if bot is secret
+ for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+ if(bot->user == chanuser->user)
+ break;
+ }
+ if(bot && !(bot->flags & SOCKET_FLAG_SECRET_BOT)) {
+ if(j)
+ accessbufpos += sprintf(accessbuf+accessbufpos, ", ");
+ else {
+ accessbufpos += sprintf(accessbuf+accessbufpos, " (");
+ j = 1;
+ }
+ accessbufpos += sprintf(accessbuf+accessbufpos, "%s", get_language_string(user, "NS_NICKLIST_ACCESS_BOT"));
+ }
}
- } while(sort_flags != 0);
+ if(chanuser->user->flags & USERFLAG_ISIRCOP) {
+ if(j)
+ accessbufpos += sprintf(accessbuf+accessbufpos, ", ");
+ else {
+ accessbufpos += sprintf(accessbuf+accessbufpos, " (");
+ j = 1;
+ }
+ accessbufpos += sprintf(accessbuf+accessbufpos, "%s", get_language_string(user, "NS_NICKLIST_ACCESS_OPER"));
+ }
+ if(j)
+ accessbufpos += sprintf(accessbuf+accessbufpos, ")");
+ content[2] = accessbuf;
+ if(flags & NEONSERV_CMD_NICKLIST_FLAG_VISCOUNT) {
+ sprintf(viscountbuf, "%d", chanuser->visCount);
+ content[3] = viscountbuf;
+ }
+ table_add(table, content);
+ }
+
//send the table
char **table_lines = table_end(table);
for(i = 0; i < table->entrys; i++) {
reply(textclient, user, "NS_TABLE_COUNT", table->length - 1);
table_free(table);
if(synced_user) {
- if(!syncusers)
+ if(!(flags & NEONSERV_CMD_NICKLIST_FLAG_SYNCUSERS))
reply(textclient, user, "NS_NICKLIST_SYNC", db_enfops, db_enfvoice);
else
logEvent(event);
MYSQL_ROW row;
if(type == MODSTATE_STARTSTOP) {
- printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
+ printf_mysql_query("SELECT `nick`, `ident`, `realname`, `server`, `port`, `pass`, `textbot`, `id`, `queue`, `ssl`, `bind`, `secret` FROM `bots` WHERE `botclass` = '%d' AND `active` = '1'", BOTID);
res = mysql_use();
while ((row = mysql_fetch_row(res)) != NULL) {
client->flags |= (strcmp(row[6], "0") ? SOCKET_FLAG_PREFERRED : 0);
client->flags |= (strcmp(row[8], "0") ? SOCKET_FLAG_USE_QUEUE : 0);
client->flags |= (strcmp(row[9], "0") ? SOCKET_FLAG_SSL : 0);
+ client->flags |= (strcmp(row[11], "0") ? SOCKET_FLAG_SECRET_BOT : 0);
client->flags |= SOCKET_FLAG_REQUEST_INVITE | SOCKET_FLAG_REQUEST_OP;
client->botid = BOTID;
client->clientid = atoi(row[7]);
struct Table *table;
MYSQL_RES *res, *res2;
MYSQL_ROW row, row2;
- printf_mysql_query("SELECT `active`, `nick`, `server`, `port`, `pass`, `botclass`, `textbot`, `queue`, `defaulttrigger`, `max_channels`, `register_priority`, `id` FROM `bots`");
+ printf_mysql_query("SELECT `active`, `nick`, `server`, `port`, `pass`, `botclass`, `textbot`, `queue`, `defaulttrigger`, `max_channels`, `register_priority`, `id`, `secret` FROM `bots`");
res = mysql_use();
table = table_init(7, mysql_num_rows(res) + 1, 0);
char *content[7];
botflags[flagspos++] = 't';
if(!strcmp(row[7], "1"))
botflags[flagspos++] = 'q';
+ if(!strcmp(row[12], "1"))
+ botflags[flagspos++] = 's';
botflags[flagspos] = '\0';
content[4] = botflags;
printf_mysql_query("SELECT COUNT(*) FROM `bot_channels` WHERE `botid` = '%s'", row[11]);
static int global_cmd_setbot_class(struct ClientSocket *textclient, struct UserNode *user, MYSQL_ROW bot, char *value);
static int global_cmd_setbot_queue(struct ClientSocket *textclient, struct UserNode *user, MYSQL_ROW bot, char *value);
static int global_cmd_setbot_prefered(struct ClientSocket *textclient, struct UserNode *user, MYSQL_ROW bot, char *value);
+static int global_cmd_setbot_secret(struct ClientSocket *textclient, struct UserNode *user, MYSQL_ROW bot, char *value);
static int global_cmd_setbot_maxchan(struct ClientSocket *textclient, struct UserNode *user, MYSQL_ROW bot, char *value);
static int global_cmd_setbot_priority(struct ClientSocket *textclient, struct UserNode *user, MYSQL_ROW bot, char *value);
static int global_cmd_setbot_trigger(struct ClientSocket *textclient, struct UserNode *user, MYSQL_ROW bot, char *value);
MYSQL_RES *res;
MYSQL_ROW row;
int botid = atoi(argv[0]);
- printf_mysql_query("SELECT `active`, `nick`, `server`, `port`, `pass`, `botclass`, `textbot`, `queue`, `defaulttrigger`, `max_channels`, `register_priority`, `bind`, `ident`, `realname`, `ssl`, `id` FROM `bots` WHERE `id` = '%d'", botid);
+ printf_mysql_query("SELECT `active`, `nick`, `server`, `port`, `pass`, `botclass`, `textbot`, `queue`, `defaulttrigger`, `max_channels`, `register_priority`, `bind`, `ident`, `realname`, `ssl`, `id`, `secret` FROM `bots` WHERE `id` = '%d'", botid);
res = mysql_use();
if(!(row = mysql_fetch_row(res))) {
reply(textclient, user, "NS_SETBOT_UNKNOWN", botid);
else if(!stricmp(argv[1], "botclass")) log_event = global_cmd_setbot_class(textclient, user, row, value);
else if(!stricmp(argv[1], "queue")) log_event = global_cmd_setbot_queue(textclient, user, row, value);
else if(!stricmp(argv[1], "prefered")) log_event = global_cmd_setbot_prefered(textclient, user, row, value);
+ else if(!stricmp(argv[1], "secret")) log_event = global_cmd_setbot_secret(textclient, user, row, value);
else if(!stricmp(argv[1], "maxchan")) log_event = global_cmd_setbot_maxchan(textclient, user, row, value);
else if(!stricmp(argv[1], "priority")) log_event = global_cmd_setbot_priority(textclient, user, row, value);
else if(!stricmp(argv[1], "trigger")) log_event = global_cmd_setbot_trigger(textclient, user, row, value);
global_cmd_setbot_class(textclient, user, row, NULL);
global_cmd_setbot_queue(textclient, user, row, NULL);
global_cmd_setbot_prefered(textclient, user, row, NULL);
+ global_cmd_setbot_secret(textclient, user, row, NULL);
global_cmd_setbot_maxchan(textclient, user, row, NULL);
global_cmd_setbot_priority(textclient, user, row, NULL);
global_cmd_setbot_trigger(textclient, user, row, NULL);
return ret;
}
+static int global_cmd_setbot_secret(struct ClientSocket *textclient, struct UserNode *user, MYSQL_ROW bot, char *value) {
+ int val = (strcmp(bot[16], "0") ? 1 : 0);
+ int ret = 0;
+ if(value) {
+ if(!strcmp(value, "0") || !stricmp(value, "off") || !stricmp(value, get_language_string(user, "NS_SET_OFF"))) {
+ val = 0;
+ } else if(!strcmp(value, "1") || !stricmp(value, "on") || !stricmp(value, get_language_string(user, "NS_SET_ON"))) {
+ val = 1;
+ } else {
+ reply(textclient, user, "NS_SET_INVALID_BOOLEAN", value);
+ return 0;
+ }
+ struct ClientSocket *client;
+ for(client = getBots(0, NULL); client; client = getBots(0, client)) {
+ if(client->clientid == atoi(bot[15])) {
+ if(val)
+ client->flags |= SOCKET_FLAG_SECRET_BOT;
+ else
+ client->flags &= ~SOCKET_FLAG_SECRET_BOT;
+ break;
+ }
+ }
+ printf_mysql_query("UPDATE `bots` SET `secret` = '%d' WHERE `id` = '%s'", val, bot[15]);
+ ret = 1;
+ }
+ reply(textclient, user, "\002SECRET \002 %s", get_language_string(user, (val ? "NS_SET_ON" : "NS_SET_OFF")));
+ return ret;
+}
+
static int global_cmd_setbot_maxchan(struct ClientSocket *textclient, struct UserNode *user, MYSQL_ROW bot, char *value) {
int val = atoi(bot[9]);
int ret = 0;
*/
#include "mysqlConn.h"
-#define DATABASE_VERSION "19"
+#define DATABASE_VERSION "20"
static void show_mysql_error();
if(table->contents[row][col][i] == '\002') j++;
else if(table->contents[row][col][i] == '\003') {
j++;
- for(k = 1; k < 2; k++) {
+ for(k = 1; k <= 2; k++) {
if(isdigit(table->contents[row][col][i+k]))
j++;
else