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