From e41ecc826adb84945c10a7a3663805d63a6370e5 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 16 Aug 2012 01:48:30 +0200 Subject: [PATCH] added sort function to cmd_nicklist --- .../NeonServ.mod/cmd_neonserv_nicklist.c | 217 ++++++++++-------- 1 file changed, 122 insertions(+), 95 deletions(-) diff --git a/src/modules/NeonServ.mod/cmd_neonserv_nicklist.c b/src/modules/NeonServ.mod/cmd_neonserv_nicklist.c index 3e858d0..c978247 100644 --- a/src/modules/NeonServ.mod/cmd_neonserv_nicklist.c +++ b/src/modules/NeonServ.mod/cmd_neonserv_nicklist.c @@ -80,25 +80,62 @@ static USERLIST_CALLBACK(neonserv_cmd_nicklist_userlist_lookup) { 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) { @@ -107,106 +144,96 @@ static void neonserv_cmd_nicklist_async1(struct ClientSocket *client, struct Cli } 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++) { -- 2.20.1