made cmd_voice checking invisible users
[NeonServV5.git] / cmd_neonserv_voice.c
1
2 /*
3 * argv[0-*]    nicks
4 */
5 static USERLIST_CALLBACK(neonserv_cmd_voice_userlist_lookup);
6 static void neonserv_cmd_voice_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nicks);
7
8 struct neonserv_cmd_voice_cache {
9     struct ClientSocket *client, *textclient;
10     struct UserNode *user;
11     char *nicks;
12 };
13
14 static CMD_BIND(neonserv_cmd_voice) {
15     struct neonserv_cmd_voice_cache *cache = malloc(sizeof(*cache));
16     if (!cache) {
17         perror("malloc() failed");
18         return;
19     }
20     cache->client = client;
21     cache->textclient = getTextBot();
22     cache->user = user;
23     cache->nicks = strdup(merge_argv(argv, 0, argc));
24     get_userlist_with_invisible(chan, neonserv_cmd_voice_userlist_lookup, cache);
25 }
26
27 static USERLIST_CALLBACK(neonserv_cmd_voice_userlist_lookup) {
28     struct neonserv_cmd_voice_cache *cache = data;
29     neonserv_cmd_voice_async1(cache->client, cache->textclient, cache->user, chan, cache->nicks);
30     free(cache->nicks);
31     free(cache);
32 }
33
34 static void neonserv_cmd_voice_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, char *nicks) {
35     int total_users = 0, done_users = 0;
36     struct UserNode *cuser;
37     struct ChanUser *chanuser;
38     struct ModeBuffer *modeBuf;
39     modeBuf = initModeBuffer(client, chan);
40     char *a, *b = nicks;
41     do {
42         a = strstr(b, " ");
43         if(a) *a = '\0';
44         total_users++;
45         cuser = searchUserByNick(b);
46         if(!cuser) {
47             //check for an invisible user
48             for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
49                 if(!stricmp(chanuser->user->nick, b)) {
50                     cuser = chanuser->user;
51                     break;
52                 }
53             }
54             if(!cuser) continue;
55         } else {
56             chanuser = getChanUser(cuser, chan);
57             if(!chanuser) continue;
58         }
59         done_users++;
60         if(chanuser->flags & CHANUSERFLAG_VOICED) continue;
61         modeBufferVoice(modeBuf, b);
62         if(a) {
63             b = a+1;
64         }
65     } while(a);
66     freeModeBuffer(modeBuf);
67     if(done_users == total_users)
68         reply(textclient, user, "NS_VOICE_DONE", chan->name);
69     else
70         reply(textclient, user, "NS_VOICE_FAIL", client->user->nick);
71 }