3 * The main chanserv core file.
8 #include "../core/hooks.h"
9 #include "../core/schedule.h"
10 #include "../lib/version.h"
12 MODULE_VERSION(QVERSION
);
16 int chanserv_init_status
;
19 sstring
*cs_quitreason
;
21 void chanservfreestuff();
22 void chanservfinishinit(int hooknum
, void *arg
);
23 static void cs_hourlyfunc(void *arg
);
25 DBModuleIdentifier q9dbid
;
27 void chanservdumpstuff(void *arg
) {
28 dumplastjoindata("lastjoin.dump");
32 /* Register the nick extension - the others are registered in the db module */
33 chanservnext
=registernickext("nickserv");
40 if (chanservext
!=-1 && chanservnext
!=-1 && chanservaext
!=-1) {
41 /* Set up the chantypes */
42 chantypes
=(sstring
**)malloc(CHANTYPES
*sizeof(sstring
*));
43 chantypes
[0]=getsstring("(unspecified)",20);
44 chantypes
[1]=getsstring("clan",20);
45 chantypes
[2]=getsstring("league",20);
46 chantypes
[3]=getsstring("private",20);
47 chantypes
[4]=getsstring("special",20);
48 chantypes
[5]=getsstring("gamesite",20);
49 chantypes
[6]=getsstring("game",20);
50 chantypes
[7]=getsstring("upgrade",20);
51 chantypes
[8]=getsstring("partner",20);
53 /* And the log system */
56 /* Set up the command handler, and built in commands */
57 chanservcommandinit();
58 chanservaddcommand("showcommands", 0, 1, cs_doshowcommands
, "Lists available commands.","Usage: SHOWCOMMANDS [<mask>]\nPrints a list of commands currently available to you, where:\nmask - Mask of commands to list (* or ? are wildcards). If no mask is specified,\n all available commands are displayed.");
59 chanservaddcommand("quit", QCMD_DEV
, 1, cs_doquit
, "Makes the bot QUIT and \"reconnect\".","");
60 chanservaddcommand("setquitreason", QCMD_DEV
, 1, cs_dosetquitreason
, "Sets the reason to be sent when quitting due to an unload.","");
61 chanservaddcommand("rename", QCMD_DEV
, 1, cs_dorename
, "Changes the bot's name.","");
62 chanservaddcommand("rehash", QCMD_DEV
, 0, cs_dorehash
, "Reloads all text from database.","");
63 /* Make "HELP" take 2 arguments so things like "HELP chanflags #channel" work. Any junk after the command will go into arg 2 and be ignored. */
64 chanservaddcommand("help", 0, 2, cs_dohelp
, "Displays help on a specific command.","Usage: HELP <command>\nShows help for a command, where:\ncommand - the command to show help for.\nFor a list of available commands, see SHOWCOMMANDS.\n");
65 chanservaddcommand("version", 0, 1, cs_doversion
, "Show Version.","Usage: VERSION\nShows the version number of the running bot.");
67 chanservaddctcpcommand("ping",cs_doctcpping
);
68 chanservaddctcpcommand("version",cs_doctcpversion
);
69 chanservaddctcpcommand("gender",cs_doctcpgender
);
71 registerhook(HOOK_CHANSERV_DBLOADED
, chanservfinishinit
);
73 /* Now that the database is in a separate module it might be loaded already. */
75 chanservfinishinit(HOOK_CHANSERV_DBLOADED
, NULL
);
79 void chanservfinishinit(int hooknum
, void *arg
) {
80 Error("chanserv",ERR_INFO
,"Database loaded, finishing initialisation.");
82 deregisterhook(HOOK_CHANSERV_DBLOADED
, chanservfinishinit
);
84 readlastjoindata("lastjoin.dump");
86 /* Schedule the dumps */
87 schedulerecurring(time(NULL
)+DUMPINTERVAL
,0,DUMPINTERVAL
,chanservdumpstuff
,NULL
);
88 schedulerecurring(time(NULL
)+5,0,5,csdb_flushchannelcounters
,NULL
);
90 chanserv_init_status
= CS_INIT_NOUSER
;
92 /* Register the user */
93 scheduleoneshot(time(NULL
)+1,&chanservreguser
,NULL
);
96 void chanserv_finalinit() {
101 for (i
=0;i
<NICKHASHSIZE
;i
++)
102 for (np
=nicktable
[i
];np
;np
=nnp
) {
107 /* Register core hooks */
108 registerhook(HOOK_NICK_NEWNICK
, cs_handlenick
);
109 registerhook(HOOK_NICK_ACCOUNT
, cs_handlenick
);
110 registerhook(HOOK_NICK_LOSTNICK
, cs_handlelostnick
);
111 registerhook(HOOK_NICK_SETHOST
, cs_handlesethost
);
112 registerhook(HOOK_CHANNEL_NEWCHANNEL
, cs_handlenewchannel
);
113 registerhook(HOOK_CHANNEL_LOSTCHANNEL
, cs_handlelostchannel
);
114 registerhook(HOOK_CHANNEL_JOIN
, cs_handlejoin
);
115 registerhook(HOOK_CHANNEL_CREATE
, cs_handlejoin
);
116 registerhook(HOOK_CHANNEL_MODECHANGE
, cs_handlemodechange
);
117 registerhook(HOOK_CHANNEL_BURST
, cs_handleburst
);
118 registerhook(HOOK_CHANNEL_TOPIC
, cs_handletopicchange
);
119 registerhook(HOOK_CHANNEL_LOSTNICK
, cs_handlechanlostuser
);
121 chanserv_init_status
= CS_INIT_READY
;
122 triggerhook(HOOK_CHANSERV_RUNNING
, NULL
);
124 /* run every 60 minutes, first one 5 minutes after start */
125 schedulerecurring(time(NULL
)+60*5,0,3600,cs_hourlyfunc
,NULL
);
127 Error("chanserv",ERR_INFO
,"Ready to roll.");
131 csdb_flushchannelcounters(NULL
);
135 deleteallschedules(cs_hourlyfunc
);
136 deleteallschedules(cs_timerfunc
);
137 deleteallschedules(chanservreguser
);
138 deleteallschedules(chanservdumpstuff
);
139 deleteallschedules(chanservdgline
);
140 deleteallschedules(csdb_flushchannelcounters
);
142 if (chanservext
>-1 && chanservnext
>-1 && chanservaext
>-1) {
144 for (i
=0;i
<CHANTYPES
;i
++)
145 freesstring(chantypes
[i
]);
150 /* Free everything */
151 if (chanservnext
!=-1) {
152 releasenickext(chanservnext
);
156 deregisterlocaluser(chanservnick
, cs_quitreason
?cs_quitreason
->content
:"Leaving");
158 freesstring(cs_quitreason
);
160 deregisterhook(HOOK_NICK_NEWNICK
, cs_handlenick
);
161 deregisterhook(HOOK_NICK_ACCOUNT
, cs_handlenick
);
162 deregisterhook(HOOK_NICK_LOSTNICK
, cs_handlelostnick
);
163 deregisterhook(HOOK_NICK_SETHOST
, cs_handlesethost
);
164 deregisterhook(HOOK_CHANNEL_NEWCHANNEL
, cs_handlenewchannel
);
165 deregisterhook(HOOK_CHANNEL_LOSTCHANNEL
, cs_handlelostchannel
);
166 deregisterhook(HOOK_CHANNEL_JOIN
, cs_handlejoin
);
167 deregisterhook(HOOK_CHANNEL_CREATE
, cs_handlejoin
);
168 deregisterhook(HOOK_CHANNEL_MODECHANGE
, cs_handlemodechange
);
169 deregisterhook(HOOK_CHANNEL_BURST
, cs_handleburst
);
170 deregisterhook(HOOK_CHANNEL_TOPIC
, cs_handletopicchange
);
171 deregisterhook(HOOK_CHANNEL_LOSTNICK
, cs_handlechanlostuser
);
172 /* deregisterhook(HOOK_CHANNEL_OPPED, cs_handleopchange);
173 deregisterhook(HOOK_CHANNEL_DEOPPED, cs_handleopchange);
174 deregisterhook(HOOK_CHANNEL_DEVOICED, cs_handleopchange);
175 deregisterhook(HOOK_CHANNEL_BANSET, cs_handlenewban); */
176 deregisterhook(HOOK_CHANSERV_DBLOADED
, chanservfinishinit
); /* for safety */
178 chanservremovecommand("showcommands", cs_doshowcommands
);
179 chanservremovecommand("quit", cs_doquit
);
180 chanservremovecommand("setquitreason", cs_dosetquitreason
);
181 chanservremovecommand("rename", cs_dorename
);
182 chanservremovecommand("rehash", cs_dorehash
);
183 chanservremovecommand("help", cs_dohelp
);
184 chanservremovecommand("version", cs_doversion
);
185 chanservremovectcpcommand("ping",cs_doctcpping
);
186 chanservremovectcpcommand("version",cs_doctcpversion
);
187 chanservremovectcpcommand("gender",cs_doctcpgender
);
188 chanservcommandclose();
191 chanservcryptofree();
196 static void cs_hourlyfunc(void *arg
) {
197 int i
, total
= 0, touched
= 0, toorecent
= 0;
198 chanindex
*cip
, *ncip
;
200 time_t t
= time(NULL
);
202 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
203 for (cip
=chantable
[i
];cip
;cip
=ncip
) {
205 if (!(rcp
=cip
->exts
[chanservext
]))
210 if(cip
->channel
&& cs_ischannelactive(cip
->channel
, rcp
)) {
212 if (rcp
->lastcountersync
< (t
- COUNTERSYNCINTERVAL
)) {
213 csdb_updatechannelcounters(rcp
);
214 rcp
->lastcountersync
=t
;
223 cs_log(NULL
,"hourly update active completed, %d seen, %d touched, %d too recent to update.",total
,touched
,toorecent
);