free(cache);
}
+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 syncusers) {
MYSQL_RES *res;
MYSQL_ROW row, defaults = NULL;
struct Table *table;
- table = table_init(3, chan->usercount + 1, 0);
char *content[3];
+ int userlistlen, i, j;
+ int db_enfops, db_enfvoice;
+ int caccess, synced_user;
+ struct ChanUser *chanusers[chan->usercount];
+ struct ChanUser *chanuser;
+ int chanuser_count;
+ char statebuf[5];
+ char accessbuf[9];
+ int uaccess;
+
+ table = table_init(3, 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(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;
+ //fail...
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);
+ sprintf(accessbuf, "\00309%d\003", uaccess);
+ synced_user = 1;
+ } else {
+ synced_user = 1;
+ sprintf(accessbuf, "\00307%d\003", uaccess);
+ }
+ } 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;
}
}
- 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(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");
}
- } else if(!uaccess)
- sprintf(accessbuf, "0");
- content[2] = accessbuf;
- table_add(table, content);
- }
- } while(sort_flags != 0);
+ } else {
+ synced_user = 1;
+ sprintf(accessbuf, "\003040\003");
+ }
+ } else if(!uaccess)
+ sprintf(accessbuf, "0");
+ content[2] = accessbuf;
+
+ table_add(table, content);
+ }
+
//send the table
char **table_lines = table_end(table);
for(i = 0; i < table->entrys; i++) {