f696a80fabea1012fb3fafb0a59aaae723accda6
[NeonServV5.git] / src / event_neonserv_topic.c
1
2 struct neonserv_event_topic_cache {
3     struct ClientSocket *client;
4     struct UserNode *user;
5     struct ChanNode *chan;
6     char *new_topic;
7 };
8
9 static USERAUTH_CALLBACK(neonserv_event_topic_nick_lookup);
10 static void neonserv_event_topic_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, const char *new_topic);
11
12 static void neonserv_event_topic(struct UserNode *user, struct ChanNode *chan, const char *new_topic) {
13     struct ClientSocket *client = getBotForChannel(chan);
14     if(!client) return; //we can't "see" this event
15     if(user->flags & (USERFLAG_ISBOT | USERFLAG_ISIRCOP)) return; 
16     loadChannelSettings(chan);
17     if(!(chan->flags & CHANFLAG_CHAN_REGISTERED)) return;
18     if(!(user->flags & USERFLAG_ISAUTHED)) {
19         struct neonserv_event_topic_cache *cache = malloc(sizeof(*cache));
20         if (!cache) {
21             perror("malloc() failed");
22             return;
23         }
24         cache->client = client;
25         cache->user = user;
26         cache->chan = chan;
27         cache->new_topic = strdup(new_topic);
28         get_userauth(user, neonserv_event_topic_nick_lookup, cache);
29     } else
30         neonserv_event_topic_async1(client, user, chan, new_topic);
31 }
32
33 static USERAUTH_CALLBACK(neonserv_event_topic_nick_lookup) {
34     struct neonserv_event_topic_cache *cache = data;
35     if(user) {
36         neonserv_event_topic_async1(cache->client, cache->user, cache->chan, cache->new_topic);
37     }
38     free(cache->new_topic);
39     free(cache);
40 }
41
42 static void neonserv_event_topic_async1(struct ClientSocket *client, struct UserNode *user, struct ChanNode *chan, const char *new_topic) {
43     MYSQL_RES *res;
44     MYSQL_ROW row, defaultrow = NULL, chanuserrow;
45     int uaccess = 0;
46     printf_mysql_query("SELECT `channel_changetopic`, `channel_topicsnarf` FROM `channels` WHERE `channel_id` = '%d'", chan->channel_id);
47     res = mysql_use();
48     if ((row = mysql_fetch_row(res)) == NULL) return;
49     if(!row[0] || !row[1]) {
50         printf_mysql_query("SELECT `channel_changetopic`, `channel_topicsnarf` FROM `channels` WHERE `channel_name` = 'defaults'");
51         res = mysql_use();
52         defaultrow = mysql_fetch_row(res);
53     }
54     int changetopic = atoi((row[0] ? row[0] : defaultrow[0]));
55     int topicsnarf = atoi((row[1] ? row[1] : defaultrow[1]));
56     if((user->flags & USERFLAG_ISAUTHED)) {
57         printf_mysql_query("SELECT `chanuser_access`, `chanuser_flags` FROM `chanusers` LEFT JOIN `users` ON `chanuser_uid` = `user_id` WHERE `chanuser_cid` = '%d' AND `user_user` = '%s'", chan->channel_id, escape_string(user->auth));
58         res = mysql_use();
59         chanuserrow = mysql_fetch_row(res);
60         if(chanuserrow)
61             uaccess = ((atoi(chanuserrow[1]) & DB_CHANUSER_SUSPENDED) ? 0 : atoi(chanuserrow[0]));
62     }
63     if(uaccess < changetopic) {
64         //undo topic change
65         struct ClientSocket *textclient = ((client->flags & SOCKET_FLAG_PREFERRED) ? client : get_prefered_bot(client->botid));
66         struct ChanUser *chanuser = getChanUser(user, chan);
67         if(!chanuser) return; //flying super cow?
68         if(time(0) - chanuser->changeTime > BOTWAR_DETECTION_TIME) {
69             chanuser->changeTime = time(0);
70             chanuser->chageEvents = 1;
71         } else {
72             chanuser->chageEvents++;
73             if(chanuser->chageEvents >= BOTWAR_DETECTION_EVENTS || chanuser->chageEvents < 0) {
74                 //BOTWAR!
75                 chanuser->changeTime = time(0);
76                 if(chanuser->chageEvents > 0) {
77                     putsock(client, "NOTICE @%s :%s %s", chan->name, get_language_string(user, "NS_BOTWAR_DETECTED"), (BOTWAR_ALERT_CHAN ? get_language_string(user, "NS_BOTWAR_REPORTED") : ""));
78                     if(BOTWAR_ALERT_CHAN) {
79                         struct ChanNode *alertchan = getChanByName(BOTWAR_ALERT_CHAN);
80                         struct ClientSocket *alertclient;
81                         if(alertchan && (alertclient = getBotForChannel(chan)) != NULL) {
82                             char msgBuf[MAXLEN];
83                             putsock(alertclient, "PRIVMSG %s :%s", alertchan->name, build_language_string(NULL, msgBuf, "NS_BOTWAR_ALERT", chan->name, user->nick));
84                         }
85                     }
86                 }
87                 chanuser->chageEvents = -2;
88                 return;
89             }
90         }
91         reply(textclient, user, "NS_TOPIC_ACCESS", chan->name);
92         putsock(client, "TOPIC %s :%s", chan->name, chan->topic);
93     } else if(uaccess >= topicsnarf) {
94         printf_mysql_query("UPDATE `channels` SET `channel_defaulttopic` = '%s' WHERE `channel_id` = '%d'", escape_string(new_topic), chan->channel_id);
95     }
96 }
97