00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef lint
00021 static const char rcsid[] = "$Id: events.c,v 1.4 2005-06-09 02:56:44 stdarg Exp $";
00022 #endif
00023
00024 #include <eggdrop/eggdrop.h>
00025
00026 #include "chanserv.h"
00027
00028 typedef struct modefight {
00029 struct modefight *next;
00030 int mode, lastdir;
00031 char *chan, *firstsource, *secondsource, *lastsource, *target;
00032 time_t expire_time;
00033 } modefight_t;
00034
00035 static modefight_t *modefight_head = NULL;
00036 static int modefight_timer_id = -1;
00037
00038 static int got_join(const char *nick, const char *uhost, user_t *u, const char *chan)
00039 {
00040 channel_t *channel;
00041 int greets = 0;
00042 char *greet = NULL;
00043
00044
00045 chanserv_update_stats(CHANSERV_STAT_JOIN, chan, nick, uhost);
00046
00047 if (!u) return(0);
00048
00049
00050 channel = server->channel_lookup(chan);
00051 if (!channel) return(0);
00052 server->channel_get_int(channel, &greets, "greets", 0, NULL);
00053 if (greets <= 0) return(0);
00054 user_get_setting(u, chan, "greet", &greet);
00055 if (!greet) user_get_setting(u, NULL, "greet", &greet);
00056 if (greet) server->printserv(SERVER_NORMAL, "PRIVMSG %s :[%s] %s", chan, u->handle, greet);
00057 return(0);
00058 }
00059
00060 static int got_part(const char *nick, const char *uhost, user_t *u, const char *chan, const char *text)
00061 {
00062 chanserv_update_stats(CHANSERV_STAT_PART, chan, nick, uhost);
00063 chanserv_update_stats(CHANSERV_STAT_LEAVE, chan, nick, uhost);
00064 return(0);
00065 }
00066
00067 static int got_pub(const char *nick, const char *uhost, user_t *u, const char *chan, const char *text)
00068 {
00069 chanserv_update_stats(CHANSERV_STAT_MSG, chan, nick, uhost);
00070 chanserv_update_stats(CHANSERV_STAT_LINE, chan, nick, uhost);
00071 return(0);
00072 }
00073
00074 static int got_msg(const char *nick, const char *uhost, user_t *u, const char *text)
00075 {
00076 chanserv_update_stats(CHANSERV_STAT_MSG, NULL, nick, uhost);
00077 chanserv_update_stats(CHANSERV_STAT_LINE, NULL, nick, uhost);
00078 return(0);
00079 }
00080
00081 static void modefight_delete(modefight_t *m)
00082 {
00083 if (m->chan) free(m->chan);
00084 if (m->firstsource) free(m->firstsource);
00085 if (m->secondsource) free(m->secondsource);
00086 if (m->lastsource) free(m->lastsource);
00087 if (m->target) free(m->target);
00088 free(m);
00089 }
00090
00091 static int modefight_cleanup()
00092 {
00093 time_t now = timer_get_now_sec(NULL);
00094 modefight_t *m, *prev, *next;
00095
00096 prev = NULL;
00097 for (m = modefight_head; m; m = next) {
00098 next = m->next;
00099 if (now > m->expire_time) {
00100 if (prev) prev->next = next;
00101 else modefight_head = next;
00102 modefight_delete(m);
00103 }
00104 else prev = m;
00105 }
00106 return(0);
00107 }
00108
00109 static modefight_t *modefight_probe(const char *chan, const char *nick, const char *target, int dir, int mode, int create)
00110 {
00111 modefight_t *m;
00112 for (m = modefight_head; m; m = m->next) {
00113 if (m->mode != mode || strcasecmp(chan, m->chan)) continue;
00114 if ((target && !m->target) || (!target && m->target)) continue;
00115 if ((target && m->target) && strcasecmp(target, m->target)) continue;
00116 return(m);
00117 }
00118 if (!create) return(NULL);
00119 m = calloc(1, sizeof(*m));
00120 m->chan = strdup(chan);
00121 m->firstsource = strdup(nick);
00122 m->lastsource = strdup(nick);
00123 m->lastdir = dir;
00124 m->mode = mode;
00125 if (target) m->target = strdup(target);
00126 m->next = modefight_head;
00127 modefight_head = m;
00128 return(m);
00129 }
00130
00131 static int got_mode(const char *nick, const char *uhost, user_t *u, const char *dest, const char *change, const char *arg)
00132 {
00133 modefight_t *m;
00134 int period;
00135
00136
00137 if (server->match_botnick(dest)) return(0);
00138
00139 chanserv_update_stats(CHANSERV_STAT_MODE, dest, nick, uhost);
00140 m = modefight_probe(dest, nick, arg, *change, *(change+1), 1);
00141 chanserv_lookup_config(dest, CHANSERV_STAT_MODEFIGHT, NULL, &period);
00142 m->expire_time = timer_get_now_sec(NULL) + period;
00143 if (!m->secondsource && strcasecmp(nick, m->firstsource)) m->secondsource = strdup(nick);
00144 if (m->lastdir != *change && strcasecmp(m->lastsource, nick)) {
00145 m->lastdir = *change;
00146 str_redup(&m->lastsource, nick);
00147 chanserv_update_stats(CHANSERV_STAT_MODEFIGHT, dest, nick, uhost);
00148 }
00149 return(0);
00150 }
00151
00152 int events_init()
00153 {
00154 egg_timeval_t howlong = {1, 0};
00155
00156 bind_add_simple("join", NULL, NULL, got_join);
00157 bind_add_simple("part", NULL, NULL, got_part);
00158 bind_add_simple("pubm", NULL, NULL, got_pub);
00159 bind_add_simple("msgm", NULL, NULL, got_msg);
00160 bind_add_simple("mode", NULL, NULL, got_mode);
00161 modefight_timer_id = timer_create_repeater(&howlong, "modefight_cleanup", modefight_cleanup);
00162 return(0);
00163 }
00164
00165 int events_shutdown()
00166 {
00167 bind_rem_simple("join", NULL, NULL, got_join);
00168 bind_rem_simple("part", NULL, NULL, got_part);
00169 bind_rem_simple("pubm", NULL, NULL, got_pub);
00170 bind_rem_simple("msgm", NULL, NULL, got_msg);
00171 bind_rem_simple("mode", NULL, NULL, got_mode);
00172 timer_destroy(modefight_timer_id);
00173 return(0);
00174 }