#include "src/mod/module.h"
#include <time.h>
#include "src/users.h"
#include "src/chan.h"
#include "channels.mod/channels.h"
Go to the source code of this file.
Data Structures | |
struct | trig_data |
Defines | |
#define | MODULE_NAME "seen" |
#define | MAKING_SEEN |
Functions | |
static void | wordshift () |
static void | do_seen () |
static char * | match_trigger () |
static char * | getxtra () |
static char * | fixnick () |
static int | seen_expmem () |
static int | pub_seen (char *nick, char *host, char *hand, char *channel, char *text) |
static int | msg_seen (char *nick, char *host, struct userrec *u, char *text) |
static int | dcc_seen (struct userrec *u, int idx, char *par) |
static void | do_seen (int idx, char *prefix, char *nick, char *hand, char *channel, char *text) |
static char * | fixnick (char *nick) |
static char * | match_trigger (char *word) |
static char * | getxtra (char *hand, char *field) |
static void | wordshift (char *first, char *rest) |
static void | seen_report (int idx, int details) |
static int | server_seen_setup (char *mod) |
static int | irc_seen_setup (char *mod) |
static char * | seen_close () |
char * | seen_start () |
char * | seen_start (Function *egg_func_table) |
Variables | |
static Function * | global = 0 |
static trig_data | trigdata [] |
static char | fixit [512] |
static cmd_t | seen_pub [] |
static cmd_t | seen_dcc [] |
static cmd_t | seen_msg [] |
static cmd_t | seen_load [] |
static Function | seen_table [] |
static int dcc_seen | ( | struct userrec * | u, | |
int | idx, | |||
char * | par | |||
) | [static] |
static void do_seen | ( | int | idx, | |
char * | prefix, | |||
char * | nick, | |||
char * | hand, | |||
char * | channel, | |||
char * | text | |||
) | [static] |
Definition at line 155 of file seen.c.
References admin, chan_issplit, CHANMETA, chanuserrec::channel, chanset_t::channel, userrec::chanrec, chanset, dcc, dcc_total, DCT_CHAT, chanset_t::dname, dprintf, egg_strcasecmp, findchan_by_dname, fixnick(), get_user, get_user_by_handle, get_user_by_host, getxtra(), userrec::handle, ismember, laston_info::laston, chanuserrec::laston, laston_info::lastonplace, LOG_PUBLIC, match_trigger(), chan_t::member, chanuserrec::next, memstruct::next, chanset_t::next, memstruct::nick, now, NULL, rfc_casecmp, time_t, USERENTRY_LASTON, memstruct::userhost, userlist, and wordshift().
00157 { 00158 char stuff[512], word1[512], word2[512], whotarget[512], object[512], 00159 whoredirect[512], *oix, *lastonplace = 0; 00160 struct userrec *urec; 00161 struct chanset_t *chan; 00162 struct laston_info *li; 00163 struct chanuserrec *cr; 00164 memberlist *m = NULL; 00165 int onchan = 0, i; 00166 long tv; 00167 time_t laston = 0, work; 00168 00169 whotarget[0] = 0; 00170 whoredirect[0] = 0; 00171 object[0] = 0; 00172 00173 /* Was ANYONE specified */ 00174 if (!text[0]) { 00175 dprintf(idx, "%sUm, %s, it might help if you ask me about _someone_...\n", 00176 prefix, nick); 00177 return; 00178 } 00179 00180 wordshift(word1, text); 00181 oix = strchr(word1, '\''); 00182 /* Have we got a NICK's target? */ 00183 if (oix == word1) 00184 return; /* Skip anything starting with ' */ 00185 if (oix && *oix && ((oix[1] && (oix[1] == 's' || oix[1] == 'S') && 00186 !oix[2]) || (!oix[1] && (oix[-1] == 's' || oix[-1] == 'z' || 00187 oix[-1] == 'x' || oix[-1] == 'S' || oix[-1] == 'Z' || 00188 oix[-1] == 'X')))) { 00189 strncpy(object, word1, oix - word1); 00190 object[oix - word1] = 0; 00191 wordshift(word1, text); 00192 if (!word1[0]) { 00193 dprintf(idx, "%s%s's what, %s?\n", prefix, object, nick); 00194 return; 00195 } 00196 urec = get_user_by_handle(userlist, object); 00197 if (!urec) { 00198 chan = chanset; 00199 while (chan) { 00200 onchan = 0; 00201 m = ismember(chan, object); 00202 if (m) { 00203 onchan = 1; 00204 sprintf(stuff, "%s!%s", object, m->userhost); 00205 urec = get_user_by_host(stuff); 00206 if (!urec || !egg_strcasecmp(object, urec->handle)) 00207 break; 00208 strcat(whoredirect, object); 00209 strcat(whoredirect, " is "); 00210 strcat(whoredirect, urec->handle); 00211 strcat(whoredirect, ", and "); 00212 strcpy(object, urec->handle); 00213 break; 00214 } 00215 chan = chan->next; 00216 } 00217 if (!onchan) { 00218 dprintf(idx, "%sI don't think I know who %s is, %s.\n", 00219 prefix, object, nick); 00220 return; 00221 } 00222 } 00223 if (!egg_strcasecmp(word1, "bf") || !egg_strcasecmp(word1, "boyfriend")) { 00224 strcpy(whotarget, getxtra(object, "BF")); 00225 if (whotarget[0]) { 00226 sprintf(whoredirect, "%s boyfriend is %s, and ", 00227 fixnick(object), whotarget); 00228 goto targetcont; 00229 } 00230 dprintf(idx, 00231 "%sI don't know who %s boyfriend is, %s.\n", 00232 prefix, fixnick(object), nick); 00233 return; 00234 } 00235 if (!egg_strcasecmp(word1, "gf") || !egg_strcasecmp(word1, "girlfriend")) { 00236 strcpy(whotarget, getxtra(object, "GF")); 00237 if (whotarget[0]) { 00238 sprintf(whoredirect, "%s girlfriend is %s, and ", 00239 fixnick(object), whotarget); 00240 goto targetcont; 00241 } 00242 dprintf(idx, 00243 "%sI don't know who %s girlfriend is, %s.\n", 00244 prefix, fixnick(object), nick); 00245 return; 00246 } 00247 dprintf(idx, 00248 "%sWhy are you bothering me with questions about %s %s, %s?\n", 00249 prefix, fixnick(object), word1, nick); 00250 return; 00251 } 00252 /* Keyword "my" */ 00253 if (!egg_strcasecmp(word1, "my")) { 00254 wordshift(word1, text); 00255 if (!word1[0]) { 00256 dprintf(idx, "%sYour what, %s?\n", prefix, nick); 00257 return; 00258 } 00259 /* Do I even KNOW the requestor? */ 00260 if (hand[0] == '*' || !hand[0]) { 00261 dprintf(idx, 00262 "%sI don't know you, %s, so I don't know about your %s.\n", 00263 prefix, nick, word1); 00264 return; 00265 } 00266 /* "my boyfriend" */ 00267 if (!egg_strcasecmp(word1, "boyfriend") || !egg_strcasecmp(word1, "bf")) { 00268 strcpy(whotarget, getxtra(hand, "BF")); 00269 if (whotarget[0]) { 00270 sprintf(whoredirect, "%s, your boyfriend is %s, and ", nick, whotarget); 00271 } else { 00272 dprintf(idx, "%sI didn't know you had a boyfriend, %s\n", prefix, nick); 00273 return; 00274 } 00275 } 00276 /* "my girlfriend" */ 00277 else if (!egg_strcasecmp(word1, "girlfriend") || 00278 !egg_strcasecmp(word1, "gf")) { 00279 strcpy(whotarget, getxtra(hand, "GF")); 00280 if (whotarget[0]) { 00281 sprintf(whoredirect, "%s, your girlfriend is %s, and ", 00282 nick, whotarget); 00283 } else { 00284 dprintf(idx, "%sI didn't know you had a girlfriend, %s\n", prefix, 00285 nick); 00286 return; 00287 } 00288 } else { 00289 dprintf(idx, "%sI don't know anything about your %s, %s.\n", prefix, 00290 word1, nick); 00291 return; 00292 } 00293 } 00294 /* "your" keyword */ 00295 else if (!egg_strcasecmp(word1, "your")) { 00296 wordshift(word1, text); 00297 /* "your admin" */ 00298 if (!egg_strcasecmp(word1, "owner") || !egg_strcasecmp(word1, "admin")) { 00299 if (admin[0]) { 00300 strcpy(word2, admin); 00301 wordshift(whotarget, word2); 00302 strcat(whoredirect, "My owner is "); 00303 strcat(whoredirect, whotarget); 00304 strcat(whoredirect, ", and "); 00305 if (!egg_strcasecmp(whotarget, hand)) { 00306 strcat(whoredirect, "that's YOU"); 00307 if (!egg_strcasecmp(hand, nick)) 00308 strcat(whoredirect, "!!!"); 00309 else { 00310 strcat(whoredirect, ", "); 00311 strcat(whoredirect, nick); 00312 strcat(whoredirect, "!"); 00313 } 00314 dprintf(idx, "%s%s\n", prefix, whoredirect); 00315 return; 00316 } 00317 } else { /* owner variable munged or not set */ 00318 dprintf(idx, 00319 "%sI don't seem to recall who my owner is right now...\n", 00320 prefix); 00321 return; 00322 } 00323 } else { /* no "your" target specified */ 00324 dprintf(idx, "%sLet's not get personal, %s.\n", prefix, nick); 00325 return; 00326 } 00327 } 00328 /* Check for keyword match in the internal table */ 00329 else if (match_trigger(word1)) { 00330 sprintf(word2, "%s%s\n", prefix, match_trigger(word1)); 00331 dprintf(idx, word2, nick); 00332 return; 00333 } 00334 /* Otherwise, make the target to the first word and continue */ 00335 else 00336 strcpy(whotarget, word1); 00337 00338 targetcont: 00339 /* Looking for ones own nick? */ 00340 if (!rfc_casecmp(nick, whotarget)) { 00341 dprintf(idx, "%s%sLooking for yourself, eh %s?\n", 00342 prefix, whoredirect, nick); 00343 return; 00344 } 00345 /* Check if nick is on a channel */ 00346 chan = chanset; 00347 while (chan) { 00348 m = ismember(chan, whotarget); 00349 if (m) { 00350 onchan = 1; 00351 sprintf(word1, "%s!%s", whotarget, m->userhost); 00352 urec = get_user_by_host(word1); 00353 if (!urec || !egg_strcasecmp(whotarget, urec->handle)) 00354 break; 00355 strcat(whoredirect, whotarget); 00356 strcat(whoredirect, " is "); 00357 strcat(whoredirect, urec->handle); 00358 strcat(whoredirect, ", and "); 00359 break; 00360 } 00361 chan = chan->next; 00362 } 00363 /* Check if nick is on a channel by xref'ing to handle */ 00364 if (!onchan) { 00365 chan = chanset; 00366 while (chan) { 00367 m = chan->channel.member; 00368 while (m && m->nick[0]) { 00369 sprintf(word2, "%s!%s", m->nick, m->userhost); 00370 urec = get_user_by_host(word2); 00371 if (urec && !egg_strcasecmp(urec->handle, whotarget)) { 00372 onchan = 1; 00373 strcat(whoredirect, whotarget); 00374 strcat(whoredirect, " is "); 00375 strcat(whoredirect, m->nick); 00376 strcat(whoredirect, ", and "); 00377 strcpy(whotarget, m->nick); 00378 break; 00379 } 00380 m = m->next; 00381 } 00382 chan = chan->next; 00383 } 00384 } 00385 /* Check if the target was on the channel, but is netsplit */ 00386 chan = findchan_by_dname(channel); 00387 if (chan) { 00388 m = ismember(chan, whotarget); 00389 if (m && chan_issplit(m)) { 00390 dprintf(idx, "%s%s%s was just here, but got netsplit.\n", 00391 prefix, whoredirect, whotarget); 00392 return; 00393 } 00394 } 00395 /* Check if the target IS on the channel */ 00396 if (chan && m) { 00397 dprintf(idx, "%s%s%s is on the channel right now!\n", 00398 prefix, whoredirect, whotarget); 00399 return; 00400 } 00401 /* Target not on this channel. Check other channels */ 00402 chan = chanset; 00403 while (chan) { 00404 m = ismember(chan, whotarget); 00405 if (m && chan_issplit(m)) { 00406 dprintf(idx, 00407 "%s%s%s was just on %s, but got netsplit.\n", 00408 prefix, whoredirect, whotarget, chan->dname); 00409 return; 00410 } 00411 if (m) { 00412 dprintf(idx, 00413 "%s%s%s is on %s right now!\n", 00414 prefix, whoredirect, whotarget, chan->dname); 00415 return; 00416 } 00417 chan = chan->next; 00418 } 00419 /* Target isn't on any of my channels. */ 00420 /* See if target matches a handle in my userlist. */ 00421 urec = get_user_by_handle(userlist, whotarget); 00422 /* No match, then bail out */ 00423 if (!urec) { 00424 dprintf(idx, "%s%sI don't know who %s is.\n", 00425 prefix, whoredirect, whotarget); 00426 return; 00427 } 00428 /* We had a userlist match to a handle */ 00429 /* Is the target currently DCC CHAT to me on the botnet? */ 00430 for (i = 0; i < dcc_total; i++) { 00431 if (dcc[i].type->flags & DCT_CHAT) { 00432 if (!egg_strcasecmp(whotarget, dcc[i].nick)) { 00433 if (!rfc_casecmp(channel, dcc[i].u.chat->con_chan) && 00434 dcc[i].u.chat->con_flags & LOG_PUBLIC) { 00435 strcat(whoredirect, whotarget); 00436 strcat(whoredirect, 00437 " is 'observing' this channel right now from my party line!"); 00438 dprintf(idx, "%s%s\n", prefix, whoredirect); 00439 } else { 00440 dprintf(idx, 00441 "%s%s%s is linked to me via DCC CHAT right now!\n", 00442 prefix, whoredirect, whotarget); 00443 } 00444 return; 00445 } 00446 } 00447 } 00448 /* Target known, but nowhere to be seen. Give last IRC and botnet time */ 00449 wordshift(word1, text); 00450 if (!egg_strcasecmp(word1, "anywhere")) 00451 cr = NULL; 00452 else 00453 for (cr = urec->chanrec; cr; cr = cr->next) { 00454 if (!rfc_casecmp(cr->channel, channel)) { 00455 if (cr->laston) { 00456 laston = cr->laston; 00457 lastonplace = channel; 00458 break; 00459 } 00460 } 00461 } 00462 if (!cr) { 00463 li = get_user(&USERENTRY_LASTON, urec); 00464 if (!li || !li->lastonplace || !li->lastonplace[0]) { 00465 dprintf(idx, "%s%sI've never seen %s around.\n", 00466 prefix, whoredirect, whotarget); 00467 return; 00468 } 00469 lastonplace = li->lastonplace; 00470 laston = li->laston; 00471 } 00472 word1[0] = 0; 00473 word2[0] = 0; 00474 work = now - laston; 00475 if (work >= 86400) { 00476 tv = work / 86400; 00477 sprintf(word2, "%lu day%s, ", tv, (tv == 1) ? "" : "s"); 00478 work = work % 86400; 00479 } 00480 if (work >= 3600) { 00481 tv = work / 3600; 00482 sprintf(word2 + strlen(word2), "%lu hour%s, ", tv, (tv == 1) ? "" : "s"); 00483 work = work % 3600; 00484 } 00485 if (work >= 60) { 00486 tv = work / 60; 00487 sprintf(word2 + strlen(word2), "%lu minute%s, ", tv, 00488 (tv == 1) ? "" : "s"); 00489 } 00490 if (!word2[0] && (work < 60)) { 00491 strcpy(word2, "just moments ago!!"); 00492 } else { 00493 strcpy(word2 + strlen(word2) - 2, " ago."); 00494 } 00495 if (lastonplace[0] && (strchr(CHANMETA, lastonplace[0]) != NULL)) 00496 sprintf(word1, "on IRC channel %s", lastonplace); 00497 else if (lastonplace[0] == '@') 00498 sprintf(word1, "on %s", lastonplace + 1); 00499 else if (lastonplace[0] != 0) 00500 sprintf(word1, "on my %s", lastonplace); 00501 else 00502 strcpy(word1, "seen"); 00503 dprintf(idx, "%s%s%s was last %s %s\n", 00504 prefix, whoredirect, whotarget, word1, word2); 00505 }
static void do_seen | ( | ) | [static] |
static char* fixnick | ( | char * | nick | ) | [static] |
static char* fixnick | ( | ) | [static] |
static char* getxtra | ( | char * | hand, | |
char * | field | |||
) | [static] |
Definition at line 539 of file seen.c.
References xtra_key::data, egg_strcasecmp, user_entry::extra, find_user_entry, fixit, get_user_by_handle, xtra_key::key, xtra_key::next, user_entry::u, USERENTRY_XTRA, and userlist.
00540 { 00541 00542 struct userrec *urec; 00543 struct user_entry *ue; 00544 struct xtra_key *xk; 00545 00546 urec = get_user_by_handle(userlist, hand); 00547 if (urec) { 00548 ue = find_user_entry(&USERENTRY_XTRA, urec); 00549 if (ue) 00550 for (xk = ue->u.extra; xk; xk = xk->next) 00551 if (xk->key && !egg_strcasecmp(xk->key, field)) { 00552 if (xk->data[0] == '{' && xk->data[strlen(xk->data) - 1] == '}' && 00553 strlen(xk->data) > 2) { 00554 strncpy(fixit, &xk->data[1], strlen(xk->data) - 2); 00555 fixit[strlen(xk->data) - 2] = 0; 00556 return fixit; 00557 } else { 00558 return xk->data; 00559 } 00560 } 00561 } 00562 return ""; 00563 }
static char* getxtra | ( | ) | [static] |
static int irc_seen_setup | ( | char * | mod | ) | [static] |
Definition at line 612 of file seen.c.
References add_builtins, and find_bind_table.
Referenced by seen_start().
00613 { 00614 p_tcl_bind_list H_temp; 00615 00616 if ((H_temp = find_bind_table("pub"))) 00617 add_builtins(H_temp, seen_pub); 00618 return 0; 00619 }
static char* match_trigger | ( | char * | word | ) | [static] |
Definition at line 527 of file seen.c.
References egg_strcasecmp, trig_data::key, NULL, and trig_data::text.
static char* match_trigger | ( | ) | [static] |
static int msg_seen | ( | char * | nick, | |
char * | host, | |||
struct userrec * | u, | |||
char * | text | |||
) | [static] |
Definition at line 134 of file seen.c.
References do_seen(), DP_SERVER, userrec::handle, LOG_CMDS, and putlog.
00135 { 00136 char prefix[50]; 00137 00138 if (!u) { 00139 putlog(LOG_CMDS, "*", "[%s!%s] seen %s", nick, host, text); 00140 return 0; 00141 } 00142 putlog(LOG_CMDS, "*", "(%s!%s) !%s! SEEN %s", nick, host, u->handle, text); 00143 sprintf(prefix, "PRIVMSG %s :", nick); 00144 do_seen(DP_SERVER, prefix, nick, u->handle, "", text); 00145 return 0; 00146 }
static int pub_seen | ( | char * | nick, | |
char * | host, | |||
char * | hand, | |||
char * | channel, | |||
char * | text | |||
) | [static] |
Definition at line 121 of file seen.c.
References channel_seen, chanset_t::dname, do_seen(), DP_HELP, egg_snprintf, findchan_by_dname, chanset_t::name, and NULL.
00123 { 00124 char prefix[91]; /* sizeof(name) + strlen("PRIVMSG :") */ 00125 struct chanset_t *chan = findchan_by_dname(channel); 00126 00127 if ((chan != NULL) && channel_seen(chan)) { 00128 egg_snprintf(prefix, sizeof prefix, "PRIVMSG %s :", chan->name); 00129 do_seen(DP_HELP, prefix, nick, hand, chan->dname, text); 00130 } 00131 return 0; 00132 }
static char* seen_close | ( | ) | [static] |
Definition at line 627 of file seen.c.
References find_bind_table, H_dcc, H_load, MODULE_NAME, module_undepend, NULL, rem_builtins, and rem_help_reference.
00628 { 00629 p_tcl_bind_list H_temp; 00630 00631 rem_builtins(H_load, seen_load); 00632 rem_builtins(H_dcc, seen_dcc); 00633 rem_help_reference("seen.help"); 00634 if ((H_temp = find_bind_table("pub"))) 00635 rem_builtins(H_temp, seen_pub); 00636 if ((H_temp = find_bind_table("msg"))) 00637 rem_builtins(H_temp, seen_msg); 00638 module_undepend(MODULE_NAME); 00639 return NULL; 00640 }
static int seen_expmem | ( | ) | [static] |
Definition at line 115 of file seen.c.
Referenced by seen_report().
static void seen_report | ( | int | idx, | |
int | details | |||
) | [static] |
Definition at line 577 of file seen.c.
References dprintf, and seen_expmem().
00578 { 00579 if (details) { 00580 int size = seen_expmem(); 00581 00582 dprintf(idx, " Using %d byte%s of memory\n", size, 00583 (size != 1) ? "s" : ""); 00584 } 00585 }
char* seen_start | ( | Function * | egg_func_table | ) |
Definition at line 651 of file seen.c.
References add_builtins, add_help_reference, botnetnick, global, H_dcc, H_load, irc_seen_setup(), trig_data::key, module_depend, MODULE_NAME, module_register, module_undepend, NULL, seen_table, and server_seen_setup().
00652 { 00653 global = egg_func_table; 00654 00655 module_register(MODULE_NAME, seen_table, 2, 0); 00656 if (!module_depend(MODULE_NAME, "eggdrop", 106, 0)) { 00657 module_undepend(MODULE_NAME); 00658 return "This module requires Eggdrop 1.6.0 or later."; 00659 } 00660 add_builtins(H_load, seen_load); 00661 add_builtins(H_dcc, seen_dcc); 00662 add_help_reference("seen.help"); 00663 server_seen_setup(NULL); 00664 irc_seen_setup(NULL); 00665 trigdata[4].key = botnetnick; 00666 return NULL; 00667 }
char* seen_start | ( | ) |
static int server_seen_setup | ( | char * | mod | ) | [static] |
Definition at line 603 of file seen.c.
References add_builtins, and find_bind_table.
Referenced by seen_start().
00604 { 00605 p_tcl_bind_list H_temp; 00606 00607 if ((H_temp = find_bind_table("msg"))) 00608 add_builtins(H_temp, seen_msg); 00609 return 0; 00610 }
static void wordshift | ( | char * | first, | |
char * | rest | |||
) | [static] |
Definition at line 565 of file seen.c.
References egg_strcasecmp, and newsplit.
00566 { 00567 char *p, *q = rest; 00568 00569 do { 00570 p = newsplit(&q); 00571 strcpy(first, p); 00572 strcpy(rest, q); 00573 } while (!egg_strcasecmp(first, "and") || !egg_strcasecmp(first, "or")); 00574 }
static void wordshift | ( | ) | [static] |
char fixit[512] [static] |
{ {"server", "", server_seen_setup, 0 }, {"irc", "", irc_seen_setup, 0 }, { 0 , 0 , 0 , 0 } }
Function seen_table[] [static] |
{ (Function) seen_start, (Function) seen_close, (Function) seen_expmem, (Function) seen_report, }
Definition at line 644 of file seen.c.
Referenced by seen_start().
{ {"god", "Let's not get into a religious discussion, %s"}, {"jesus", "Let's not get into a religious discussion, %s"}, {"shit", "Here's looking at you, %s"}, {"yourself", "Yeah, whenever I look in a mirror..."}, { 0 , " You found me, %s!"}, {"elvis", "Last time I was on the moon man."}, { 0 , 0 } }