-/* cmd_neonserv_nicklist.c - NeonServ v5.5
+/* cmd_neonserv_nicklist.c - NeonServ v5.6
* Copyright (C) 2011-2012 Philipp Kreil (pk910)
*
* This program is free software: you can redistribute it and/or modify
* 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));
if (!cache) {
- perror("malloc() failed");
+ printf_log("neonserv", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
return;
}
cache->client = client;
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);
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) {
+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;
- char *content[3];
+ char *content[4];
int userlistlen, i, j;
int db_enfops, db_enfvoice;
- int caccess, synced_user;
+ int caccess, synced_user, accessbufpos;
struct ChanUser *chanusers[chan->usercount];
struct ChanUser *chanuser;
+ struct ClientSocket *bot;
int chanuser_count;
char statebuf[5];
- char accessbuf[9];
+ char accessbuf[50];
+ char viscountbuf[50];
int uaccess;
- table = table_init(3, chan->usercount + 1, 0);
+ 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");
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(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_enfvoice;
} else {
//fail...
- sprintf(accessbuf, "\00307%d\003", uaccess);
+ accessbufpos = sprintf(accessbuf, "\00307%d\003", uaccess);
break;
}
neonserv_cmd_nicklist_synchronize_user(chan, chanuser->user, uaccess);
- sprintf(accessbuf, "\00309%d\003", uaccess);
+ accessbufpos = sprintf(accessbuf, "\00309%d\003", uaccess);
synced_user = 1;
} else {
synced_user = 1;
- sprintf(accessbuf, "\00307%d\003", uaccess);
+ 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)))
- sprintf(accessbuf, "\00303%d\003", uaccess);
+ accessbufpos = sprintf(accessbuf, "\00303%d\003", uaccess);
else
- sprintf(accessbuf, "%d", uaccess);
+ accessbufpos = sprintf(accessbuf, "%d", uaccess);
break;
}
}
}
if(!uaccess && (chanuser->flags & CHANUSERFLAG_OPPED_OR_VOICED) && !isNetworkService(chanuser->user)) {
- if(syncusers) {
+ 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_enfvoice;
} else {
uaccess = 0;
- sprintf(accessbuf, "\003040\003");
+ accessbufpos = 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);
+ accessbufpos = sprintf(accessbuf, "\00309%d\003", uaccess);
synced_user = 1;
} else if(uaccess) {
- sprintf(accessbuf, "\003040\003");
+ accessbufpos = sprintf(accessbuf, "\003040\003");
}
} else {
synced_user = 1;
- sprintf(accessbuf, "\003040\003");
+ if(((chanuser->flags & CHANUSERFLAG_OPPED) && db_enfops > uaccess) || ((chanuser->flags & CHANUSERFLAG_VOICED) && db_enfvoice > uaccess))
+ accessbufpos = sprintf(accessbuf, "\003040\003");
+ else
+ accessbufpos = sprintf(accessbuf, "0");
}
} else if(!uaccess)
- sprintf(accessbuf, "0");
+ 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"));
+ }
+ }
+ 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) {
+ if(chanuser->flags & CHANUSERFLAG_PARTING)
+ sprintf(viscountbuf, "%d (\003P\003 %d)", chanuser->visCount, chanuser->old_visCount);
+ else
+ sprintf(viscountbuf, "%d", chanuser->visCount);
+ content[3] = viscountbuf;
+ }
table_add(table, content);
}
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);