pubcmds.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  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. static int nopubstats(char *chan)
  19. {
  20. if (!chan) {
  21. debug0("WARNING: nopubstats() called with NULL pointer");
  22. return 1;
  23. }
  24. #if EGG_IS_MIN_VER(10503)
  25. if (ngetudef("nopubstats", chan))
  26. return 1;
  27. #endif
  28. return 0;
  29. }
  30. static int quietstats(char *chan)
  31. {
  32. if (!chan) {
  33. debug0("WARNING: quietstats() called with NULL pointer");
  34. return 1;
  35. }
  36. #if EGG_IS_MIN_VER(10503)
  37. if (ngetudef("quietstats", chan))
  38. return 1;
  39. #endif
  40. return 0;
  41. }
  42. static int pub_top10(char *nick, char *host, char *hand,
  43. char *channel, char *text)
  44. {
  45. if (nopubstats(channel))
  46. return 1;
  47. putlog(LOG_CMDS, channel, "<<%s>> !%s! top10 %s", nick, hand, text);
  48. tell_top(channel, channel, nick, text, 1, 10, 0);
  49. return 1;
  50. }
  51. static int pub_top20(char *nick, char *host, char *hand,
  52. char *channel, char *text)
  53. {
  54. if (nopubstats(channel))
  55. return 1;
  56. putlog(LOG_CMDS, channel, "<<%s>> !%s! top20 %s", nick, hand, text);
  57. tell_top(channel, channel, nick, text, 11, 20, 0);
  58. return 1;
  59. }
  60. static int pub_ttop10(char *nick, char *host, char *hand,
  61. char *channel, char *text)
  62. {
  63. if (nopubstats(channel))
  64. return 1;
  65. putlog(LOG_CMDS, channel, "<<%s>> !%s! ttop10 %s", nick, hand, text);
  66. tell_top(channel, channel, nick, text, 1, 10, 1);
  67. return 1;
  68. }
  69. static int pub_ttop20(char *nick, char *host, char *hand,
  70. char *channel, char *text)
  71. {
  72. if (nopubstats(channel))
  73. return 1;
  74. putlog(LOG_CMDS, channel, "<<%s>> !%s! ttop20 %s", nick, hand, text);
  75. tell_top(channel, channel, nick, text, 11, 20, 1);
  76. return 1;
  77. }
  78. static void tell_top(char *channel, char *dest, char *nick, char *type, int from, int to, int today)
  79. {
  80. char t[50], *result, *tosend, *slang, *slangtype;
  81. int i, ti, pi;
  82. struct stats_global *l;
  83. struct stats_local *ll;
  84. #if EGG_IS_MIN_VER(10500)
  85. struct chanset_t *chan;
  86. #endif
  87. Context;
  88. filt(type);
  89. if (stat_flood())
  90. return;
  91. #if EGG_IS_MIN_VER(10500)
  92. if (!strcasecmp(channel, dest)) {
  93. chan = findchan_by_dname(dest);
  94. if (chan)
  95. dest = chan->name;
  96. }
  97. #endif
  98. l = findglobstats(channel);
  99. if (!l) {
  100. debug1("StatMod: Can't do topx for %s, no such entry in linked list", channel);
  101. return;
  102. }
  103. if (!strncasecmp(type, "word ", 5)) {
  104. tell_top_word(channel, dest, nick, type, from, to, l);
  105. return;
  106. }
  107. if (!type[0] || (strlen(type) > 45))
  108. strcpy(t, "words");
  109. else
  110. strcpy(t, type);
  111. ti = slangtypetoi(t);
  112. setslglobs(l->chan, l->peak[today], 0, l->started);
  113. if ((ti < 0) && (ti != T_WPL) && (ti != T_IDLE)) {
  114. slang = SLNOSUCHTYPE;
  115. if (quietstats(dest)) { /* if dest != chan, we want a PRIVMSG anyway */
  116. tosend = nmalloc(15 + strlen(nick) + strlen(slang) + 1);
  117. sprintf(tosend, "NOTICE %s :%s\n", nick, slang);
  118. } else {
  119. tosend = nmalloc(16 + strlen(dest) + strlen(slang) + 1);
  120. sprintf(tosend, "PRIVMSG %s :%s\n", dest, slang);
  121. }
  122. dprintf(DP_HELP, "%s", tosend);
  123. nfree(tosend);
  124. return;
  125. }
  126. sortstats(l, ti, today);
  127. slglobint = to;
  128. slang = getslang(1001 + today);
  129. slangtype = getslangtype(t);
  130. result = nmalloc(strlen(slang) + strlen(slangtype) + 1);
  131. sprintf(result, slang, slangtype);
  132. i = 1;
  133. // pi = (T_WPL * (-1)) + TOTAL_TYPES - 1; // THIS APPEARS WRONG... DOUBLE-CHECK LATER!!!
  134. if (ti < 0)
  135. pi = (ti * -1) + (TOTAL_TYPES - 1);
  136. else
  137. pi = ti;
  138. for (ll = l->slocal[today][pi]; ll; ll = ll->snext[today][pi]) {
  139. if (!listsuser(ll, channel))
  140. continue;
  141. if ((ti >= 0) && !ll->values[today][ti])
  142. break;
  143. if ((i >= from) && (i <= to)) {
  144. if (ti >= 0) {
  145. // how much should I alloc for an integer? *sigh*
  146. // I'll just use 10... should be enough
  147. result = nrealloc(result, strlen(result) + 10 + 5 + strlen(ll->user) + 10 + 1);
  148. sprintf(result, "%s %d. %s(%ld)", result, i, ll->user, ll->values[today][ti]);
  149. } else if (ti == T_WPL) {
  150. result = nrealloc(result, strlen(result) + 10 + 5 + strlen(ll->user) + 10 + 1);
  151. if (ll->values[today][T_LINES])
  152. sprintf(result, "%s %d. %s(%.2f)", result, i, ll->user, (float) ll->values[today][T_WORDS] / (float) ll->values[today][T_LINES]);
  153. else
  154. sprintf(result, "%s %d. %s(0)", result, i, ll->user);
  155. } else if (ti == T_IDLE) {
  156. result = nrealloc(result, strlen(result) + 10 + 5 + strlen(ll->user) + 10 + 1);
  157. if (ll->values[today][T_LINES])
  158. sprintf(result, "%s %d. %s(%.2f)", result, i, ll->user, (float) ll->values[today][T_MINUTES] / (float) ll->values[today][T_LINES]);
  159. else
  160. sprintf(result, "%s %d. %s(0)", result, i, ll->user);
  161. } else {
  162. result = nrealloc(result, strlen(result) + 11 + 10 + 1);
  163. sprintf(result, "%s ERROR (%d)", result, ti);
  164. }
  165. }
  166. i++;
  167. }
  168. if (quietstats(dest)) {
  169. tosend = nmalloc(12 + strlen(nick) + strlen(result) + 1);
  170. sprintf(tosend, "NOTICE %s :%s\n", nick, result);
  171. } else {
  172. tosend = nmalloc(13 + strlen(dest) + strlen(result) + 1);
  173. sprintf(tosend, "PRIVMSG %s :%s\n", dest, result);
  174. }
  175. dprintf(DP_HELP, "%s", tosend);
  176. nfree(tosend);
  177. nfree(result);
  178. Context;
  179. }
  180. static void tell_top_word(char *channel, char *dest, char *nick, char *type, int from, int to, globstats *gs)
  181. {
  182. locstats *e;
  183. char *result, *tosend, *slang;
  184. int i = 1, itype;
  185. Context;
  186. newsplit(&type);
  187. strlower(type);
  188. setword(gs, type);
  189. sortstats(gs, T_WORDS, 1);
  190. slglobint = to;
  191. setslglobs(gs->chan, gs->peak[S_TODAY], 0, gs->started);
  192. slang = SLTOPWORD;
  193. result = nmalloc(strlen(slang) + strlen(type) + 1);
  194. sprintf(result, slang, type);
  195. itype = (T_WORDS * (-1)) + TOTAL_TYPES - 1;
  196. for (e = gs->slocal[S_TODAY][itype]; e; e = e->snext[S_TODAY][itype]) {
  197. if (!listsuser(e, channel))
  198. continue;
  199. if ((i > to) || !e->word)
  200. break;
  201. if (i >= from) {
  202. result = nrealloc(result, strlen(result) + 13 + 10 + strlen(e->user) + 10 + 1);
  203. sprintf(result, "%s %d. %s(%d)", result, i, e->user, e->word->nr);
  204. }
  205. i++;
  206. }
  207. if (quietstats(dest)) {
  208. tosend = nmalloc(15 + strlen(nick) + strlen(result) + 1);
  209. sprintf(tosend, "NOTICE %s :%s\n", nick, result);
  210. } else {
  211. tosend = nmalloc(16 + strlen(dest) + strlen(result) + 1);
  212. sprintf(tosend, "PRIVMSG %s :%s\n", dest, result);
  213. }
  214. dprintf(DP_HELP, "%s", tosend);
  215. nfree(result);
  216. nfree(tosend);
  217. Context;
  218. }
  219. static int pub_place(char *nick, char *host, char *hand,
  220. char *channel, char *text)
  221. {
  222. Context;
  223. if (nopubstats(channel))
  224. return 1;
  225. putlog(LOG_CMDS, channel, "<<%s>> !%s! place %s", nick, hand, text);
  226. tell_place(nick, channel, hand, channel, text, S_TOTAL);
  227. Context;
  228. return 1;
  229. }
  230. static int pub_tplace(char *nick, char *host, char *hand,
  231. char *channel, char *text)
  232. {
  233. Context;
  234. if (nopubstats(channel))
  235. return 1;
  236. putlog(LOG_CMDS, channel, "<<%s>> !%s! tplace %s", nick, hand, text);
  237. tell_place(nick, channel, hand, channel, text, S_TODAY);
  238. Context;
  239. return 1;
  240. }
  241. static void tell_place(char *nick, char *dest, char *hand, char *channel, char *text, int today)
  242. {
  243. globstats *gs;
  244. locstats *ls;
  245. struct stats_memberlist *m;
  246. struct stats_userlist *su;
  247. struct userrec *u;
  248. char *who, *slang;
  249. int place = 0;
  250. int itype;
  251. #if EGG_IS_MIN_VER(10500)
  252. struct chanset_t *chan;
  253. #endif
  254. Context;
  255. // at first, check for flood...
  256. if (stat_flood())
  257. return;
  258. // .. now init vars ...
  259. m = NULL;
  260. u = NULL;
  261. su = NULL;
  262. who = slang = NULL;
  263. // ... get the global stat-struct for the channel ...
  264. gs = findglobstats(channel);
  265. // .. and init langsystem (stuff like peak and staring time
  266. // shouldn't be needed)
  267. setslglobs(channel, 0, countstatmembers(gs), 0);
  268. #if EGG_IS_MIN_VER(10500)
  269. // make sure that we're going to send to the right chan (!sa23hCHAN is WRONG)
  270. if (!strcasecmp(channel, dest)) {
  271. chan = findchan_by_dname(dest);
  272. if (chan)
  273. dest = chan->name;
  274. }
  275. #endif
  276. // if there is no parameter, just default to "words"
  277. if (!text[0]) {
  278. itype = T_WORDS;
  279. // else try resolving the type
  280. } else {
  281. itype = slangtypetoi(text);
  282. }
  283. // if we have a valid type now, then the parameter does not
  284. // specify a username, so let's use the triggering user as target.
  285. if (itype != T_ERROR) {
  286. // use_userfile is true, so grab the handle
  287. if (use_userfile) {
  288. who = nmalloc(strlen(hand) + 1);
  289. strcpy(who, hand);
  290. } else {
  291. // try grabbing the correct username from the userdatabase...
  292. m = nick2suser(nick, channel);
  293. if (m && m->user) {
  294. who = nmalloc(strlen(m->user->user) + 1);
  295. strcpy(who, m->user->user);
  296. // if the user is not found, use "*", which identifies
  297. // a non-existant user
  298. } else {
  299. who = nmalloc(2);
  300. strcpy(who, "*");
  301. }
  302. }
  303. // if who is "*", then the user isn't in any database. Serve him an error.
  304. if (who[0] == '*') {
  305. setslnick(nick);
  306. if (quietstats(dest)) {
  307. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOSTATSABOUTYOU);
  308. } else {
  309. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOSTATSABOUTYOU);
  310. }
  311. if (who)
  312. nfree(who);
  313. return;
  314. }
  315. } else { // itype == T_ERROR, parameter must be a username
  316. itype = T_WORDS;
  317. if (use_userfile) { // grab user from egg-userfile
  318. u = get_user_by_handle(userlist, text);
  319. if (u) {
  320. who = nmalloc(strlen(u->handle) + 1);
  321. strcpy(who, u->handle);
  322. } else {
  323. // oops, user not found!
  324. setslnick(text);
  325. if (quietstats(dest)) {
  326. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOSTATSABOUTSOMEONE);
  327. } else {
  328. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOSTATSABOUTSOMEONE);
  329. }
  330. // no need to free anything, we didn't allocate anything, yet
  331. Assert(!who);
  332. return;
  333. }
  334. } else { // grab user from stats-userbase
  335. // first check if nick is on chan (faster)
  336. m = nick2suser(text, channel);
  337. if (m && m->user) {
  338. who = nmalloc(strlen(m->user->user) + 1);
  339. strcpy(who, m->user->user);
  340. } else {
  341. // no success, yet? ok, then search through the complete database...
  342. su = findsuser_by_name(text);
  343. if (su) {
  344. who = nmalloc(strlen(su->user) + 1);
  345. strcpy(who, su->user);
  346. } else {
  347. // still no success? Poor user... serve him an error.
  348. setslnick(text);
  349. if (quietstats(dest)) {
  350. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOSTATSABOUTSOMEONE);
  351. } else {
  352. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOSTATSABOUTSOMEONE);
  353. }
  354. Assert(!who);
  355. return;
  356. }
  357. }
  358. }
  359. }
  360. if (!gs) {
  361. Assert(who);
  362. nfree(who);
  363. debug1("Stats.mod: Couldn't exec !place, I don't have any statistics in %s.", channel);
  364. return;
  365. }
  366. // sort the stats
  367. sortstats(gs, itype, today);
  368. // if itype is < 0, get the modified itype that we need for accessing the data
  369. if (itype < 0)
  370. itype = (TOTAL_TYPES - 1) + (itype * -1);
  371. // now calculate the place
  372. for (ls = gs->slocal[today][itype]; ls; ls = ls->snext[today][itype]) {
  373. if (!listsuser(ls, channel))
  374. continue;
  375. place++;
  376. if (!rfc_casecmp(who, ls->user))
  377. break;
  378. }
  379. // if ls is NULL now, then the user doesn't have any stats in this chan
  380. if (!ls) {
  381. setslnick(who);
  382. if (quietstats(dest)) {
  383. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOSTATSABOUTSOMEONE);
  384. } else {
  385. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOSTATSABOUTSOMEONE);
  386. }
  387. } else {
  388. // stats found, so let's output them
  389. setslnick(who);
  390. slglobint = place;
  391. // there are 4 slang-entries for today, this week, etc
  392. slang = getslang(1012 + today);
  393. if (quietstats(dest)) {
  394. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, slang);
  395. } else {
  396. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, slang);
  397. }
  398. }
  399. Assert(who);
  400. nfree(who);
  401. Context;
  402. }
  403. static int pub_stat(char *nick, char *host, char *hand,
  404. char *channel, char *text)
  405. {
  406. Context;
  407. if (nopubstats(channel))
  408. return 1;
  409. putlog(LOG_CMDS, channel, "<<%s>> !%s! stat %s", nick, hand, text);
  410. tell_stat(nick, channel, hand, channel, text, S_TOTAL);
  411. Context;
  412. return 1;
  413. }
  414. static int pub_tstat(char *nick, char *host, char *hand,
  415. char *channel, char *text)
  416. {
  417. Context;
  418. if (nopubstats(channel))
  419. return 1;
  420. putlog(LOG_CMDS, channel, "<<%s>> !%s! tstat %s", nick, hand, text);
  421. tell_stat(nick, channel, hand, channel, text, S_TODAY);
  422. Context;
  423. return 1;
  424. }
  425. static void tell_stat(char *nick, char *dest, char *hand, char *channel, char *text, int today)
  426. {
  427. locstats *ls;
  428. char *who, *tosend, what[128], *pwhat, *type, *dur, *stmp;
  429. int itype, first;
  430. struct stats_memberlist *m;
  431. struct userrec *u;
  432. struct stats_userlist *su;
  433. #if EGG_IS_MIN_VER(10500)
  434. struct chanset_t *chan;
  435. #endif
  436. Context;
  437. if (stat_flood())
  438. return;
  439. who = tosend = type = dur = NULL;
  440. setslglobs(channel, 0, 0, 0);
  441. #if EGG_IS_MIN_VER(10500)
  442. if (!strcasecmp(channel, dest)) {
  443. chan = findchan_by_dname(dest);
  444. if (chan)
  445. dest = chan->name;
  446. }
  447. #endif
  448. if (text[0] == 0) {
  449. if (use_userfile) {
  450. who = nmalloc(strlen(hand) + 1);
  451. strcpy(who, hand);
  452. } else {
  453. m = nick2suser(nick, channel);
  454. if (m && m->user) {
  455. who = nmalloc(strlen(m->user->user) + 1);
  456. strcpy(who, m->user->user);
  457. } else {
  458. who = nmalloc(2);
  459. strcpy(who, "*");
  460. }
  461. }
  462. } else {
  463. if (use_userfile) { // grab user from egg-userfile
  464. u = get_user_by_handle(userlist, text);
  465. if (u) {
  466. who = nmalloc(strlen(u->handle) + 1);
  467. strcpy(who, u->handle);
  468. } else {
  469. // oops, user not found!
  470. setslnick(text);
  471. if (quietstats(dest)) {
  472. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOSTATSABOUTSOMEONE);
  473. } else {
  474. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOSTATSABOUTSOMEONE);
  475. }
  476. // no need to free anything, we didn't allocate anything, yet
  477. Assert(!who);
  478. return;
  479. }
  480. } else { // grab user from stats-userbase
  481. // first check if nick is on chan (faster)
  482. m = nick2suser(text, channel);
  483. if (m && m->user) {
  484. who = nmalloc(strlen(m->user->user) + 1);
  485. strcpy(who, m->user->user);
  486. } else {
  487. // no success, yet? ok, then search through the complete database...
  488. su = findsuser_by_name(text);
  489. if (su) {
  490. who = nmalloc(strlen(su->user) + 1);
  491. strcpy(who, su->user);
  492. } else {
  493. // still no success? Poor user... serve him an error.
  494. setslnick(text);
  495. if (quietstats(dest)) {
  496. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOSTATSABOUTSOMEONE);
  497. } else {
  498. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOSTATSABOUTSOMEONE);
  499. }
  500. Assert(!who);
  501. return;
  502. }
  503. }
  504. }
  505. }
  506. setslglobs(channel, 0, 0, 0);
  507. if (who[0] == '*') {
  508. setslnick(nick);
  509. if (quietstats(dest))
  510. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOSTATSABOUTYOU);
  511. else
  512. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOSTATSABOUTYOU);
  513. nfree(who);
  514. return;
  515. }
  516. ls = findlocstats(channel, who);
  517. if (!ls) {
  518. setslnick(who);
  519. if (quietstats(dest))
  520. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOSTATSABOUTSOMEONE);
  521. else
  522. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOSTATSABOUTSOMEONE);
  523. } else {
  524. if (quietstats(dest)) {
  525. tosend = nmalloc(14 + strlen(nick) + strlen(who) + 1);
  526. sprintf(tosend, "NOTICE %s :%s:", nick, who);
  527. } else {
  528. tosend = nmalloc(15 + strlen(dest) + strlen(who) + 1);
  529. sprintf(tosend, "PRIVMSG %s :%s:", dest, who);
  530. }
  531. what[0] = 0;
  532. pwhat = what;
  533. strncpy(pwhat, stat_reply, 127);
  534. pwhat[127] = 0;
  535. first = 1;
  536. while (strlen(pwhat) > 0) {
  537. type = newsplit(&pwhat);
  538. itype = typetoi(type);
  539. if ((itype < 0) && (itype != T_WPL) && (itype != T_IDLE))
  540. continue;
  541. if (!first) {
  542. // if this isn't the first run, attach a "," to the string to
  543. // seperate the values.
  544. tosend = nrealloc(tosend, strlen(tosend) + 1 + 1);
  545. strcat(tosend, ",");
  546. } else {
  547. first = 0;
  548. }
  549. if (itype == T_MINUTES) {
  550. dur = stats_duration(ls->values[today][T_MINUTES] * 60);
  551. stmp = getslangtype("minutes");
  552. tosend = nrealloc(tosend, strlen(tosend) + 3 + strlen(stmp) + strlen(dur) + 1);
  553. sprintf(tosend, "%s %s: %s", tosend, stmp, dur);
  554. } else if (itype >= 0) {
  555. // same as usual: use 10 bytes for the integer-string
  556. stmp = getslangtype(type);
  557. tosend = nrealloc(tosend, 8 + strlen(tosend) + 10 + strlen(stmp));
  558. sprintf(tosend, "%s %ld %s", tosend, ls->values[today][itype], stmp);
  559. } else if ((itype == T_WPL) && (ls->values[today][T_LINES] != 0)) {
  560. stmp = getslangtype("wpl");
  561. tosend = nrealloc(tosend, strlen(tosend) + 2 + 10 + strlen(stmp) + 1);
  562. sprintf(tosend, "%s %.2f %s", tosend, (float) ls->values[today][T_WORDS] / (float) ls->values[today][T_LINES], stmp);
  563. } else if ((itype == T_IDLE) && (ls->values[today][T_LINES] != 0)) {
  564. stmp = getslangtype("idle");
  565. tosend = nrealloc(tosend, strlen(tosend) + 2 + 10 + strlen(stmp) + 1);
  566. sprintf(tosend, "%s %.2f %s", tosend, (float) ls->values[today][T_MINUTES] / (float) ls->values[today][T_LINES], stmp);
  567. }
  568. }
  569. dprintf(DP_HELP, "%s.\n", tosend);
  570. nfree(tosend);
  571. }
  572. nfree(who);
  573. Context;
  574. }
  575. static int pub_wordstats(char *nick, char *host, char *hand,
  576. char *channel, char *text)
  577. {
  578. Context;
  579. if (nopubstats(channel))
  580. return 1;
  581. putlog(LOG_CMDS, channel, "<<%s>> !%s! wordstats %s", nick, hand, text);
  582. tell_wordstats(nick, channel, hand, channel, text);
  583. Context;
  584. return 0;
  585. }
  586. static void tell_wordstats(char *nick, char *dest, char *hand, char *channel, char *text)
  587. {
  588. locstats *ls;
  589. wordstats *ws;
  590. char *who, *tosend, *slang;
  591. int i;
  592. #if EGG_IS_MIN_VER(10500)
  593. struct chanset_t *chan;
  594. #endif
  595. Context;
  596. filt(text);
  597. if (stat_flood())
  598. return;
  599. #if EGG_IS_MIN_VER(10500)
  600. if (!strcasecmp(channel, dest)) {
  601. chan = findchan_by_dname(dest);
  602. if (chan)
  603. dest = chan->name;
  604. }
  605. #endif
  606. if (text[0] == 0) {
  607. who = nmalloc(strlen(hand) + 1);
  608. strcpy(who, hand);
  609. } else {
  610. who = nmalloc(strlen(text) + 1);
  611. strcpy(who, text);
  612. }
  613. setslglobs(channel, 0, 0, 0);
  614. if (who[0] == '*') {
  615. setslnick(nick);
  616. if (quietstats(dest))
  617. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOSTATSABOUTYOU);
  618. else
  619. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOSTATSABOUTYOU);
  620. nfree(who);
  621. return;
  622. }
  623. ls = findlocstats(channel, who);
  624. if (!ls) {
  625. setslnick(who);
  626. if (quietstats(dest))
  627. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOSTATSABOUTSOMEONE);
  628. else
  629. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOSTATSABOUTSOMEONE);
  630. } else {
  631. slgloblocstats = ls;
  632. if (!ls->words) {
  633. setslnick(who);
  634. if (quietstats(dest))
  635. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, SLNOWORDSTATS);
  636. else
  637. dprintf(DP_HELP, "PRIVMSG %s :%s\n", dest, SLNOWORDSTATS);
  638. } else {
  639. slang = SLUSERSMOSTUSEDWORDS;
  640. if (quietstats(dest)) {
  641. tosend = nmalloc(13 + strlen(nick) + strlen(slang) + 1);
  642. sprintf(tosend, "NOTICE %s :%s", nick, slang);
  643. } else {
  644. tosend = nmalloc(14 + strlen(dest) + strlen(slang) + 1);
  645. sprintf(tosend, "PRIVMSG %s :%s", dest, slang);
  646. }
  647. i = 0;
  648. sortwordstats(ls, NULL);
  649. ws = ls->words;
  650. while (ws && (i < 10)) {
  651. i++;
  652. tosend = nrealloc(tosend, 14 + strlen(tosend) + 5 + strlen(ws->word) + 10 + 1);
  653. sprintf(tosend, "%s %d. %s (%d)", tosend, i, ws->word, ws->nr);
  654. ws = ws->next;
  655. }
  656. dprintf(DP_HELP, "%s\n", tosend);
  657. nfree(tosend);
  658. }
  659. }
  660. nfree(who);
  661. Context;
  662. }
  663. static int pub_topwords(char *nick, char *host, char *hand,
  664. char *channel, char *text)
  665. {
  666. Context;
  667. if (nopubstats(channel))
  668. return 1;
  669. putlog(LOG_CMDS, channel, "<<%s>> !%s! topwords %s", nick, hand, text);
  670. tell_topwords(nick, channel, hand, channel);
  671. Context;
  672. return 0;
  673. }
  674. static void tell_topwords(char *nick, char *dest, char *hand, char *channel)
  675. {
  676. globstats *gs;
  677. wordstats *ws;
  678. char *tosend, *slang;
  679. int i;
  680. #if EGG_IS_MIN_VER(10500)
  681. struct chanset_t *chan;
  682. #endif
  683. Context;
  684. if (stat_flood())
  685. return;
  686. #if EGG_IS_MIN_VER(10500)
  687. if (!strcasecmp(channel, dest)) {
  688. chan = findchan_by_dname(dest);
  689. if (chan)
  690. dest = chan->name;
  691. }
  692. #endif
  693. gs = findglobstats(channel);
  694. if (!gs) {
  695. if (quietstats(dest))
  696. dprintf(DP_HELP, "NOTICE %s :I don't have any stats in %s\n", nick, channel);
  697. else
  698. dprintf(DP_HELP, "PRIVMSG %s :%s, I don't have any stats in %s\n", dest, nick, channel);
  699. return;
  700. }
  701. do_globwordstats(gs);
  702. ws = gs->words;
  703. if (!ws) {
  704. if (quietstats(dest))
  705. dprintf(DP_HELP, "NOTICE %s :I don't have any wordstats in %s\n", nick, channel);
  706. else
  707. dprintf(DP_HELP, "PRIVMSG %s :I don't have any wordstats in %s\n", dest, channel);
  708. return;
  709. }
  710. setslglobs(gs->chan, gs->peak[S_TODAY], 0, gs->started);
  711. setslnick(nick);
  712. slang = SLCHANSMOSTUSEDWORDS;
  713. if (quietstats(dest)) {
  714. tosend = nmalloc(13 + strlen(nick) + strlen(slang) + 1);
  715. sprintf(tosend, "NOTICE %s :%s", nick, slang);
  716. } else {
  717. tosend = nmalloc(14 + strlen(dest) + strlen(slang) + 1);
  718. sprintf(tosend, "PRIVMSG %s :%s", dest, slang);
  719. }
  720. i = 0;
  721. while (ws && (i < 10)) {
  722. i++;
  723. tosend = nrealloc(tosend, 14 + strlen(tosend) + 5 + strlen(ws->word) + 10);
  724. sprintf(tosend, "%s %d. %s (%d)", tosend, i, ws->word, ws->nr);
  725. ws = ws->next;
  726. }
  727. dprintf(DP_HELP, "%s\n", tosend);
  728. nfree(tosend);
  729. Context;
  730. }
  731. static int stat_flood()
  732. {
  733. if (!maxstat_thr || !maxstat_time)
  734. return 0;
  735. if ((now - mstat_time) > maxstat_time) {
  736. mstat_time = now;
  737. mstat_thr = 0;
  738. }
  739. mstat_thr++;
  740. if (mstat_thr > maxstat_thr)
  741. return 1;
  742. return 0;
  743. }
  744. static cmd_t stats_pub[] =
  745. {
  746. {"!top10", "", pub_top10, 0},
  747. {"!ttop10", "", pub_ttop10, 0},
  748. {"!top20", "", pub_top20, 0},
  749. {"!ttop20", "", pub_ttop20, 0},
  750. {"!place", "", pub_place, 0},
  751. {"!tplace", "", pub_tplace, 0},
  752. {"!stat", "", pub_stat, 0},
  753. {"!tstat", "", pub_tstat, 0},
  754. {"!wordstats", "", pub_wordstats, 0},
  755. {"!topwords", "", pub_topwords, 0},
  756. {0, 0, 0, 0}
  757. };