4
0

sensors.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /*
  2. * Copyright (C) 2000,2001 Florian Sander
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "../settings.h"
  19. static void sensor_peak(struct stats_chan *chan);
  20. static void sensor_text(struct stats_chan *chan, char *nick, char *text)
  21. {
  22. int i, hour;
  23. char buf[511];
  24. struct stats_member *m;
  25. Assert(chan);
  26. Assert(chan->stats);
  27. if (nostats(chan->chan))
  28. return;
  29. strncpy(buf, text, 510);
  30. buf[510] = 0;
  31. text = buf;
  32. hour = gethour();
  33. chan->stats->activity[hour]++;
  34. add_chanlog(chan->stats, nick, text, SL_PRIVMSG);
  35. m = schan_members_find(&chan->members, nick);
  36. if (!m) {
  37. check_for_url(nick, chan->chan, text);
  38. return;
  39. }
  40. m->last = now;
  41. // increase spoken lines (needed for autoadd)
  42. // if there's no link to the stats, call initstats() which either
  43. // returns an existing stats struct, or initializes a new one
  44. m->spoken_lines++;
  45. if (!m->stats && m->user) {
  46. m->stats = initstats(chan->chan, m->user->user);
  47. }
  48. if (!m->stats || !m->user) {
  49. check_for_url(nick, chan->chan, text);
  50. return;
  51. }
  52. check_for_url(m->user->user, chan->chan, text);
  53. m->stats->lastspoke = now;
  54. nincrstats(m->stats, T_WORDS, countwords(text));
  55. nincrstats(m->stats, T_LETTERS, strlen(text));
  56. nincrstats(m->stats, T_LINES, 1);
  57. i = countsmileys(text);
  58. if (i)
  59. nincrstats(m->stats, T_SMILEYS, i);
  60. i = countquestions(text);
  61. if (i)
  62. nincrstats(m->stats, T_QUESTIONS, i);
  63. addquote(m->stats, text);
  64. /* always use calcwordstats() at the end, since
  65. * it splits the string */
  66. calcwordstats(m->stats, text);
  67. return;
  68. }
  69. static void sensor_topic(char *nick, struct stats_chan *chan, char *topic)
  70. {
  71. struct stats_member *m;
  72. Context;
  73. Assert(chan);
  74. if (nostats(chan->chan))
  75. return;
  76. m = schan_members_find(&chan->members, nick);
  77. if (m && m->stats)
  78. nincrstats(m->stats, T_TOPICS, 1);
  79. addtopic(chan->chan, topic, nick);
  80. return;
  81. }
  82. static void sensor_action(char *nick, struct stats_chan *chan, char *text)
  83. {
  84. char *pbuf;
  85. struct stats_member *m;
  86. Assert(chan);
  87. if (nostats(chan->chan))
  88. return;
  89. m = schan_members_find(&chan->members, nick);
  90. if (!m)
  91. return;
  92. if (!m->stats)
  93. return;
  94. nincrstats(m->stats, T_ACTIONS, 1);
  95. pbuf = nmalloc(strlen(nick) + strlen(text) + 2);
  96. sprintf(pbuf, "%s %s", nick, text);
  97. sensor_text(chan, nick, pbuf);
  98. nfree(pbuf);
  99. return;
  100. }
  101. static void sensor_kick(char *nick, struct stats_chan *chan, char *victim, char *reason)
  102. {
  103. struct stats_member *m;
  104. char *buf;
  105. Assert(chan);
  106. if (nostats(chan->chan))
  107. return;
  108. Assert(chan->stats);
  109. buf = nmalloc(strlen(victim) + strlen(nick) + strlen(reason) + 23);
  110. sprintf(buf, "*** %s was kicked by %s (%s)", victim, nick, reason);
  111. add_chanlog(chan->stats, nick, buf, SL_KICK);
  112. save_kick(chan->stats, buf);
  113. nfree(buf);
  114. m = schan_members_find(&chan->members, nick);
  115. if (!m)
  116. return;
  117. if (!m->stats)
  118. return;
  119. nincrstats(m->stats, T_KICKS, 1);
  120. }
  121. static void sensor_mode(char *nick, struct stats_chan *chan, char *mode, char *victim)
  122. {
  123. struct stats_member *m;
  124. char *buf;
  125. Assert(chan);
  126. if (nostats(chan->chan))
  127. return;
  128. Assert(mode);
  129. Assert(chan->stats);
  130. if (mode[1] != 'k') {
  131. // log everything except key changes (you don't want your channel
  132. // key displayed on the webpages, do you?
  133. buf = nmalloc(strlen(nick) + strlen(mode) + strlen(victim) + 13);
  134. sprintf(buf, "%s sets mode %s %s", nick, mode, victim);
  135. add_chanlog(chan->stats, nick, buf, SL_MODE);
  136. nfree(buf);
  137. }
  138. m = schan_members_find(&chan->members, nick);
  139. if (!m)
  140. return;
  141. if (!m->stats)
  142. return;
  143. nincrstats(m->stats, T_MODES, 1);
  144. if ((mode[1] == 'b') && (mode[0] == '+'))
  145. nincrstats(m->stats, T_BANS, 1);
  146. }
  147. static void sensor_nick(char *nick, struct stats_chan *chan, char *newnick)
  148. {
  149. struct stats_member *m;
  150. Assert(chan);
  151. if (nostats(chan->chan))
  152. return;
  153. Assert(chan->stats);
  154. add_chanlog(chan->stats, nick, newnick, SL_NICK);
  155. m = schan_members_find(&chan->members, nick);
  156. if (!m)
  157. return;
  158. if (!m->stats)
  159. return;
  160. nincrstats(m->stats, T_NICKS, 1);
  161. }
  162. static void sensor_join(char *nick, char *uhost, struct stats_chan *chan)
  163. {
  164. struct stats_member *m;
  165. Assert(chan);
  166. if (nostats(chan->chan))
  167. return;
  168. Assert(chan->stats);
  169. add_chanlog(chan->stats, nick, "", SL_JOIN);
  170. sensor_peak(chan);
  171. m = schan_members_find(&chan->members, nick);
  172. if (!m)
  173. return;
  174. if (!m->stats)
  175. return;
  176. nincrstats(m->stats, T_JOINS, 1);
  177. addhost(uhost, chan->stats);
  178. }
  179. static void sensor_left(char *nick, struct stats_chan *chan, int type)
  180. {
  181. Assert(chan);
  182. if (nostats(chan->chan))
  183. return;
  184. Assert(chan->stats);
  185. add_chanlog(chan->stats, nick, "", type);
  186. }
  187. /* sensor_minutely():
  188. * - increases the spent time for each registered user
  189. * - if the time already got increased (if the user has a clone
  190. * in the channel, for example) then it won't be increased again
  191. * (thanks to Zev for this idea)
  192. * - if the user is not registered, stats_autosadd() gets called to
  193. * check if we might want to add him/her
  194. * - count how many users there are in the chan
  195. */
  196. static void sensor_minutely()
  197. {
  198. struct stats_chan *chan;
  199. struct stats_member *m;
  200. int nr, hour;
  201. globstats *gs;
  202. Context;
  203. for (chan = schan_getfirst(); chan; chan = schan_getnext()) {
  204. if (nostats(chan->chan))
  205. continue;
  206. nr = 0;
  207. gs = chan->stats;
  208. for (m = schan_members_getfirst(&chan->members); m; m = schan_members_getnext(&chan->members)) {
  209. if (m->stats) {
  210. if (m->stats->flag)
  211. continue;
  212. if (m->user && suser_list(m->user))
  213. nr++;
  214. nincrstats(m->stats, T_MINUTES, 1);
  215. m->stats->flag = 1;
  216. } else
  217. stats_autosadd(m, chan);
  218. }
  219. for (m = schan_members_getfirst(&chan->members); m; m = schan_members_getnext(&chan->members))
  220. if (m->stats)
  221. m->stats->flag = 0;
  222. hour = gethour();
  223. if (hour != lasthour) {
  224. gs->users[S_USERSUM][hour] = nr;
  225. gs->users[S_USERCOUNTS][hour] = 1;
  226. lasthour = hour;
  227. } else {
  228. gs->users[S_USERSUM][hour] += nr;
  229. if (gs->users[S_USERCOUNTS][hour] < 0)
  230. gs->users[S_USERCOUNTS][hour] = 1;
  231. else
  232. gs->users[S_USERCOUNTS][hour]++;
  233. }
  234. }
  235. }
  236. static void sensor_peak(struct stats_chan *chan)
  237. {
  238. struct stats_member *m;
  239. int users = 0;
  240. globstats *gs;
  241. Assert(chan);
  242. Assert(chan->stats);
  243. /* if (nostats(chan->chan))
  244. return; */
  245. gs = chan->stats;
  246. for (m = schan_members_getfirst(&chan->members); m; m = schan_members_getnext(&chan->members)) {
  247. if (m->user && !suser_list(m->user))
  248. continue;
  249. users++;
  250. }
  251. if (users > gs->peak[S_TOTAL]) {
  252. gs->peak[S_TOTAL] = users;
  253. putlog(LOG_MISC, "*", "New user peak in %s: %d.", chan->chan, users);
  254. }
  255. if (users > gs->peak[S_TODAY])
  256. gs->peak[S_TODAY] = users;
  257. if (users > gs->peak[S_WEEKLY])
  258. gs->peak[S_WEEKLY] = users;
  259. if (users > gs->peak[S_MONTHLY])
  260. gs->peak[S_MONTHLY] = users;
  261. }