749b7530b7a9097af8c1a23970aaaafe04903584
[NeonServV5.git] / cmd_neonserv_trim.c
1
2 /*
3 * argv[0]  target (format: minaccess-maxaccess/users/bans)
4 * argv[1]  duration
5 */
6 static USERLIST_CALLBACK(neonserv_cmd_trim_userlist_lookup);
7 static void neonserv_cmd_trim_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, int min_access, int max_access, int duration);
8
9 struct neonserv_cmd_trim_cache {
10     struct ClientSocket *client, *textclient;
11     struct UserNode *user;
12     struct Event *event;
13     int min_access;
14     int max_access;
15     int duration;
16 };
17
18 static CMD_BIND(neonserv_cmd_trim) {
19     if(stricmp(argv[0], "bans") && !checkChannelAccess(user, chan, "channel_candel", 0, 0)) {
20         if(isGodMode(user)) {
21             event->flags |= CMDFLAG_OPLOG;
22         } else {
23             reply(getTextBot(), user, "NS_ACCESS_DENIED");
24             return;
25         }
26     }
27     int min_access, max_access;
28     if(!stricmp(argv[0], "users")) {
29         min_access = 1;
30         max_access = getChannelAccess(user, chan, 0) - 1;
31     } else if(!stricmp(argv[0], "bans")) {
32         if(!checkChannelAccess(user, chan, "channel_staticban", 0, 0)) {
33             if(isGodMode(user)) {
34                 event->flags |= CMDFLAG_OPLOG;
35             } else {
36                 reply(getTextBot(), user, "NS_ACCESS_DENIED");
37                 return;
38             }
39         }
40         //TODO: TRIM BANS
41         return;
42     } else {
43         char *seperator = strstr(argv[0], "-");
44         if(seperator) {
45             *seperator = '\0';
46             seperator++;
47             min_access = atoi(argv[0]);
48             max_access = atoi(seperator);
49             if(max_access < min_access) {
50                 reply(getTextBot(), user, "NS_INVALID_ACCESS_RANGE", min_access, max_access);
51                 return;
52             }
53         } else {
54             min_access = atoi(argv[0]);
55             max_access = min_access;
56         }
57         if(max_access >= getChannelAccess(user, chan, 0)) {
58             if(isGodMode(user)) {
59                 event->flags |= CMDFLAG_OPLOG;
60             } else {
61                 reply(getTextBot(), user, "NS_NO_ACCESS");
62                 return;
63             }
64         }
65     }
66     //parse duration...
67     int duration = strToTime(user, argv[1]);
68     if(duration < 30) {
69         reply(getTextBot(), user, "NS_TRIM_DURATION_TOO_SHORT", 30);
70         return;
71     }
72     struct neonserv_cmd_trim_cache *cache = malloc(sizeof(*cache));
73     if (!cache) {
74         perror("malloc() failed");
75         return;
76     }
77     cache->client = client;
78     cache->textclient = getTextBot();
79     cache->user = user;
80     cache->event = event;
81     cache->min_access = min_access;
82     cache->max_access = max_access;
83     cache->duration = duration;
84     get_userlist_with_invisible(chan, neonserv_cmd_trim_userlist_lookup, cache);
85 }
86
87 static USERLIST_CALLBACK(neonserv_cmd_trim_userlist_lookup) {
88     struct neonserv_cmd_trim_cache *cache = data;
89     //got userlist
90     neonserv_cmd_trim_async1(cache->client, cache->textclient, cache->user, chan, cache->event, cache->min_access, cache->max_access, cache->duration);
91     free(cache);
92 }
93
94 static void neonserv_cmd_trim_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, int min_access, int max_access, int duration) {
95     MYSQL_RES *res;
96     MYSQL_ROW row;
97     int trim_count = 0, is_here;
98     struct ChanUser *chanuser;
99     printf_mysql_query("SELECT `chanuser_seen`, `user_user`, `chanuser_id` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `chanuser_access` >= '%d' AND `chanuser_access` <= '%d'", chan->channel_id, min_access, max_access);
100     res = mysql_use();
101     while ((row = mysql_fetch_row(res)) != NULL) {
102         if(!strcmp(row[0], "0") || time(0) - atoi(row[0]) >= duration) {
103             //check if the user is currently in the channel
104             is_here = 0;
105             for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
106                 if((chanuser->user->flags & USERFLAG_ISAUTHED) && !strcmp(chanuser->user->auth, row[1])) {
107                     is_here = 1;
108                     break;
109                 }
110             }
111             if(!is_here) {
112                 //delete the user
113                 trim_count++;
114                 printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_id` = '%s'", row[2]);
115             }
116         }
117     }
118     char timeBuf[MAXLEN];
119     reply(getTextBot(), user, "NS_TRIM_DONE", trim_count, min_access, max_access, chan->name, timeToStr(user, duration, 3, timeBuf));
120     if(trim_count)
121         logEvent(event);
122 }