1 /*
2  * Copyright (C) 2000,2001  Florian Sander
3  *
4  * $Id: sensors.c (1.3.2) for AversE-XP v1.0+ 2003/12/06 [Xp-AvR] Exp $
5  */
6 
sensor_msgm(char * nick,char * uhost,char * hand,char * chan,char * rest)7 static int sensor_msgm(char *nick, char *uhost, char *hand, char *chan, char *rest)
8 {
9   int i;
10   char buf[511];
11   struct stats_memberlist *m;
12   globstats *gs;
13 
14   if (nostats(chan))
15     return 0;
16   strncpy(buf, rest, 510);
17   buf[510] = 0;
18   rest = buf;
19   gs = findglobstats(chan);
20   add_chanlog(gs, nick, rest, SL_PRIVMSG);
21   m = nick2suser(nick, chan);
22   if(!use_userfile) {
23     if (!m) {
24       putlog(LOG_LEV5, chan, "!m (%s)", nick);
25       check_for_url(nick, chan, rest);
26       return 0;
27     }
28     if (!m->user) {
29       putlog(LOG_LEV5, chan, "!m->user (%s)", nick);
30       check_for_url(nick, chan, rest);
31       return 0;
32     }
33     check_for_url(m->user->user, chan, rest);
34     if (!m->stats)
35       m->stats = initstats(chan, m->user->user);
36     nincrstats(m->stats, T_WORDS, countwords(rest));
37     nincrstats(m->stats, T_LETTERS, strlen(rest));
38     nincrstats(m->stats, T_LINES, 1);
39     i = countsmileys(rest);
40     if (i)
41       nincrstats(m->stats, T_SMILEYS, i);
42     i = countquestions(rest);
43     if (i)
44       nincrstats(m->stats, T_QUESTIONS, i);
45     addquote(hand, gs, rest, m->stats);
46     calcwordstats(hand, gs, rest, m->stats);
47   } else {
48     if (hand[0] == '*') {
49       putlog(LOG_LEV5, chan, "hand[0] == '*' (%s)", nick);
50       check_for_url(nick, chan, rest);
51       return 0;
52     }
53     check_for_url(hand, chan, rest);
54     incrstats(hand, chan, T_WORDS, countwords(rest), 0);
55     incrstats(hand, chan, T_LETTERS, strlen(rest), 0);
56     incrstats(hand, chan, T_LINES, 1, 0);
57     i = countsmileys(rest);
58     if (i)
59       incrstats(hand, chan, T_SMILEYS, i, 0);
60     i = countquestions(rest);
61     if (i)
62       incrstats(hand, chan, T_QUESTIONS, i, 0);
63     addquote(hand, gs, rest, NULL);
64     calcwordstats(hand, gs, rest, NULL);
65   }
66   return 0;
67 }
68 
sensor_minutely()69 static void sensor_minutely()
70 {
71   struct chanset_t *chan;
72   memberlist *m;
73   struct stats_chanset *ch;
74   struct stats_memberlist *mm;
75 
76   Context;
77   if (use_userfile) {
78     for (chan = chanset; chan; chan = chan->next) {
79       if (nostats(chan->dname))
80         continue;
81       if (chan->channel.members > 0) {
82         for (m = chan->channel.member; m; m = m->next) {
83           if (m->user != NULL)
84             incrstats(m->user->handle, chan->dname, T_MINUTES, 1, 0);
85           else
86             stats_autoadd(m, chan->dname);
87         }
88       }
89     }
90   } else {
91     for (ch = schans; ch; ch = ch->next) {
92       if (nostats(ch->chan))
93         continue;
94       for (mm = ch->members; mm; mm = mm->next) {
95         if (mm->user) {
96           if (!mm->stats)
97             mm->stats = initstats(ch->chan, mm->user->user);
98           if (mm->stats->flag)
99             continue;
100           nincrstats(mm->stats, T_MINUTES, 1);
101           mm->stats->flag = 1;
102         } else {
103           stats_autosadd(mm, ch);
104         }
105       }
106       for (mm = ch->members; mm; mm = mm->next)
107         if (mm->stats)
108           mm->stats->flag = 0;
109     }
110   }
111   Context;
112 }
113 
sensor_countusers()114 static void sensor_countusers()
115 {
116   struct chanset_t *chan;
117   memberlist *m;
118   struct stats_chanset *ch;
119   struct stats_memberlist *mm;
120   globstats *gs;
121   int hour, nr;
122 
123   for (chan = chanset; chan; chan = chan->next) {
124     if (chan->channel.members < 1)
125       continue;
126     nr = 0;
127     if (nostats(chan->name))
128       continue;
129     gs = findglobstats(chan->dname);
130     if (!gs)
131       continue;
132     if (use_userfile) {
133       for (m = chan->channel.member; m; m = m->next) {
134         if (!m->nick[0])
135           continue;
136         if (m->user != NULL)
137           if (matchattr(m->user, nostatsflags, chan->dname))
138             continue;
139         nr++;
140       }
141     } else {
142       ch = findschan(chan->dname);
143       if (!ch)
144         continue;
145       for (mm = ch->members; mm; mm = mm->next) {
146 	if (mm->user && !mm->user->list)
147 	  continue;
148 	nr++;
149       }
150     }
151     hour = gethour();
152     if (hour != lasthour) {
153       gs->users[S_USERSUM][hour] = nr;
154       gs->users[S_USERCOUNTS][hour] = 1;
155       lasthour = hour;
156     } else {
157       gs->users[S_USERSUM][hour] += nr;
158       if (gs->users[S_USERCOUNTS][hour] < 0)
159         gs->users[S_USERCOUNTS][hour] = 1;
160       else
161         gs->users[S_USERCOUNTS][hour]++;
162     }
163   }
164 }
165 
sensor_peak(char * channel)166 static void sensor_peak(char *channel)
167 {
168   struct chanset_t *chan;
169   memberlist *m;
170   struct stats_chanset *ch;
171   struct stats_memberlist *mm;
172   globstats *gs;
173   int users = 0;
174 
175   if (nostats(channel))
176     return;
177   gs = findglobstats(channel);
178   if (!gs)
179     return;
180   chan = findchan_by_dname(channel);
181   if (!chan)
182     return;
183   if (use_userfile) {
184     if (chan->channel.members > 0) {
185       for (m = chan->channel.member; m; m = m->next) {
186         if (!m->nick[0])
187           continue;
188         if (m->user) {
189           if (matchattr(m->user, nopeak, channel))
190             continue;
191         }
192         users++;
193       }
194     }
195   } else {
196     ch = findschan(chan->dname);
197     if (!ch)
198       return;
199     for (mm = ch->members; mm; mm = mm->next) {
200       if (mm->user && !mm->user->list)
201 	continue;
202       users++;
203     }
204   }
205   if (users > gs->peak[S_TOTAL]) {
206     gs->peak[S_TOTAL] = users;
207     putlog(LOG_MISC, "*", "New user peak in %s: %d.", channel, users);
208   }
209   if (users > gs->peak[S_TODAY])
210     gs->peak[S_TODAY] = users;
211   if (users > gs->peak[S_WEEKLY])
212     gs->peak[S_WEEKLY] = users;
213   if (users > gs->peak[S_MONTHLY])
214     gs->peak[S_MONTHLY] = users;
215 
216 }
217 
sensor_topc(char * nick,char * uhost,char * hand,char * chan,char * topic)218 static int sensor_topc(char *nick, char *uhost, char *hand, char *chan, char *topic)
219 {
220   struct stats_memberlist *m;
221 
222   Context;
223   if (nostats(chan))
224     return 0;
225   if (!use_userfile) {
226     m = nick2suser(nick, chan);
227     if (!m)
228       return 0;
229     if (!m->user)
230       return 0;
231     if (!m->stats)
232       m->stats = initstats(chan, m->user->user);
233     nincrstats(m->stats, T_TOPICS, 1);
234   } else if (hand[0] != '*')
235     incrstats(hand, chan, T_TOPICS, 1, 0);
236   addtopic(chan, topic, nick);
237   return 0;
238 }
239 
sensor_action(char * nick,char * uhost,char * hand,char * chan,char * key,char * rest)240 static int sensor_action(char *nick, char *uhost, char *hand, char *chan, char *key, char *rest)
241 {
242   char *pbuf;
243   struct stats_memberlist *m;
244 
245   if (!strchr(CHANMETA, chan[0]))
246     return 0;
247   if (nostats(chan))
248     return 0;
249   if (!use_userfile) {
250     m = nick2suser(nick, chan);
251     if (!m)
252       return 0;
253     if (!m->user)
254       return 0;
255     if (!m->stats)
256       m->stats = initstats(chan, m->user->user);
257     nincrstats(m->stats, T_ACTIONS, 1);
258   } else if (hand[0] != '*')
259     incrstats(hand, chan, T_ACTIONS, 1, 0);
260   pbuf = nmalloc(strlen(nick) + strlen(rest) + 2);
261   sprintf(pbuf, "%s %s", nick, rest);
262   sensor_msgm(nick, uhost, hand, chan, pbuf);
263   nfree(pbuf);
264   return 0;
265 }
266 
sensor_kick(char * nick,char * uhost,char * hand,char * chan,char * victim,char * reason)267 static int sensor_kick(char *nick, char *uhost, char *hand, char *chan, char *victim, char *reason)
268 {
269   struct stats_memberlist *m;
270   char *buf;
271   globstats *gs;
272 
273   if (nostats(chan))
274     return 0;
275   gs = findglobstats(chan);
276   buf = nmalloc(strlen(victim) + strlen(nick) + strlen(reason) + 23);
277   sprintf(buf, "*** %s was kicked by %s (%s)", victim, nick, reason);
278   add_chanlog(gs, nick, buf, SL_KICK);
279   save_kick(gs, buf);
280   nfree(buf);
281   skillmember(chan, victim);
282   if (!use_userfile) {
283     m = nick2suser(nick, chan);
284     if (!m)
285       return 0;
286     if (!m->user)
287       return 0;
288     if (!m->stats)
289       m->stats = initstats(chan, m->user->user);
290     nincrstats(m->stats, T_KICKS, 1);
291   } else if (hand[0] != '*')
292     incrstats(hand, chan, T_KICKS, 1, 0);
293   return 0;
294 }
295 
sensor_mode(char * nick,char * uhost,char * hand,char * chan,char * mode,char * victim)296 static int sensor_mode(char *nick, char *uhost, char *hand, char *chan, char *mode, char *victim)
297 {
298   struct stats_memberlist *m;
299   char *buf;
300 
301   if (nostats(chan))
302     return 0;
303   buf = nmalloc(strlen(nick) + strlen(mode) + strlen(victim) + 13);
304   sprintf(buf, "%s sets mode %s %s", nick, mode, victim);
305   add_chanlog(findglobstats(chan), nick, buf, SL_MODE);
306   nfree(buf);
307   if (!use_userfile) {
308     m = nick2suser(nick, chan);
309     if (!m)
310       return 0;
311     if (!m->user)
312       return 0;
313     if (!m->stats)
314       m->stats = initstats(chan, m->user->user);
315     nincrstats(m->stats, T_MODES, 1);
316     if ((mode[1] == 'b') && (mode[0] == '+'))
317       nincrstats(m->stats, T_BANS, 1);
318   } else if (hand[0] != '*') {
319     incrstats(hand, chan, T_MODES, 1, 0);
320     if ((mode[1] == 'b') && (mode[0] == '+'))
321       incrstats(hand, chan, T_BANS, 1, 0);
322   }
323   return 0;
324 }
325 
sensor_nick(char * nick,char * uhost,char * hand,char * chan,char * newnick)326 static int sensor_nick(char *nick, char *uhost, char *hand, char *chan, char *newnick)
327 {
328   struct stats_memberlist *m;
329 
330   if (nostats(chan))
331     return 0;
332   add_chanlog(findglobstats(chan), nick, newnick, SL_NICK);
333   strackmember(chan, nick, newnick);
334   if (!use_userfile) {
335     m = nick2suser(newnick, chan);
336     if (!m)
337       return 0;
338     if (!m->user)
339       return 0;
340     if (!m->stats)
341       m->stats = initstats(chan, m->user->user);
342     nincrstats(m->stats, T_NICKS, 1);
343   } else if (hand[0] != '*')
344     incrstats(hand, chan, T_NICKS, 1, 0);
345   return 0;
346 }
347 
sensor_join(char * nick,char * uhost,char * hand,char * chan)348 static int sensor_join(char *nick, char *uhost, char *hand, char *chan)
349 {
350   struct stats_memberlist *m;
351 
352   if (nostats(chan))
353     return 0;
354   add_chanlog(findglobstats(chan), nick, NULL, SL_JOIN);
355   if (match_my_nick(nick))
356     free_one_chan(chan);
357   else
358     saddmember(nick, uhost, hand, chan);
359   sensor_peak(chan);
360   if (!use_userfile) {
361     m = nick2suser(nick, chan);
362     if (!m)
363       return 0;
364     if (!m->user)
365       return 0;
366     if (!m->stats)
367       m->stats = initstats(chan, m->user->user);
368     nincrstats(m->stats, T_JOINS, 1);
369   } else if (hand[0] != '*')
370     incrstats(hand, chan, T_JOINS, 1, 0);
371   addhost(uhost, findglobstats(chan));
372   return 0;
373 }
374 
sensor_part(char * nick,char * uhost,char * hand,char * chan)375 static int sensor_part(char *nick, char *uhost, char *hand, char *chan)
376 {
377   if (nostats(chan))
378     return 0;
379   add_chanlog(findglobstats(chan), nick, NULL, SL_PART);
380   skillmember(chan, nick);
381   return 0;
382 }
383 
sensor_sign(char * nick,char * uhost,char * hand,char * chan,char * reason)384 static int sensor_sign(char *nick, char *uhost, char *hand, char *chan, char *reason)
385 {
386   if (nostats(chan))
387     return 0;
388   add_chanlog(findglobstats(chan), nick, reason, SL_QUIT);
389   skillmember(chan, nick);
390   return 0;
391 }
392 
393 static cmd_t stats_pubm[] =
394 {
395   {"*", "", (Function) sensor_msgm, "stat"},
396   {0, 0, 0, 0}
397 };
398 
399 static cmd_t stats_topc[] =
400 {
401   {"*", "", (Function) sensor_topc, "stat"},
402   {0, 0, 0, 0}
403 };
404 
405 static cmd_t stats_ctcp[] =
406 {
407   {"ACTION", "", (Function) sensor_action, "stat"},
408   {0, 0, 0, 0}
409 };
410 
411 static cmd_t stats_kick[] =
412 {
413   {"*", "", (Function) sensor_kick, "stat"},
414   {0, 0, 0, 0}
415 };
416 
417 static cmd_t stats_mode[] =
418 {
419   {"*", "", (Function) sensor_mode, "stat"},
420   {0, 0, 0, 0}
421 };
422 
423 static cmd_t stats_nick[] =
424 {
425   {"*", "", (Function) sensor_nick, "stat"},
426   {0, 0, 0, 0}
427 };
428 
429 static cmd_t stats_join[] =
430 {
431   {"*", "", (Function) sensor_join, "stat"},
432   {0, 0, 0, 0}
433 };
434 
435 static cmd_t stats_part[] =
436 {
437   {"*", "", (Function) sensor_part, "stat"},
438   {0, 0, 0, 0}
439 };
440 
441 static cmd_t stats_sign[] =
442 {
443   {"*", "", (Function) sensor_sign, "stat"},
444   {0, 0, 0, 0}
445 };
446