cb21075d |
1 | // Bot.C -*- C++ -*- |
2 | // Copyright (c) 1997, 1998 Etienne BERNARD |
3 | // Copyright (C) 2002 Clinton Ebadi |
4 | |
5 | // This program is free software; you can redistribute it and/or modify |
6 | // it under the terms of the GNU General Public License as published by |
7 | // the Free Software Foundation; either version 2 of the License, or |
8 | // any later version. |
9 | |
10 | // This program is distributed in the hope that it will be useful, |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | // GNU General Public License for more details. |
14 | |
15 | // You should have received a copy of the GNU General Public License |
16 | // along with this program; if not, write to the Free Software |
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. |
18 | |
19 | #include <fstream> |
91dddabd |
20 | #include <algorithm> |
cb21075d |
21 | #include <iomanip> |
22 | #include <cstring> |
23 | #include <cstdlib> |
24 | #include <cstdio> |
25 | #include <sys/time.h> |
26 | #include <sys/types.h> |
27 | #include <unistd.h> |
28 | |
29 | #include "Bot.H" |
30 | #include "DCCConnection.H" |
31 | #include "StringTokenizer.H" |
32 | #include "ServerConnection.H" |
33 | #include "Utils.H" |
e07b6b46 |
34 | #include "UserCommands.H" |
6530edbf |
35 | #include "DCCManager.H" |
cb21075d |
36 | |
37 | #define DEFAULT_NICKNAME "Bobot" |
38 | #define DEFAULT_USERNAME "bobot" |
39 | #define DEFAULT_IRCNAME "I'm a bobot++!" |
40 | #define DEFAULT_COMMANDCHAR '!' |
41 | #define DEFAULT_USERLISTFILENAME "bot.users" |
42 | #define DEFAULT_SHITLISTFILENAME "bot.shit" |
43 | #define DEFAULT_HELPFILENAME "bot.help" |
44 | #define DEFAULT_SCRIPTLOGFILENAME "script.log" |
45 | #define DEFAULT_LOGFILENAME "bot.log" |
439869bf |
46 | #define DEFAULT_LOGDIR getenv ("HOME") + String("/.bobotpp/logs/") |
cb21075d |
47 | #define DEFAULT_INITFILENAME "bot.init" |
48 | #ifdef USESCRIPTS |
49 | #define DEFAULT_AUTOEXECFILENAME "bot.autoexec" |
50 | #endif |
51 | |
52 | Bot::Bot(String filename, bool debug_on) |
53 | : nickName(DEFAULT_NICKNAME), |
54 | wantedNickName(DEFAULT_NICKNAME), |
55 | userName(DEFAULT_USERNAME), |
56 | ircName(DEFAULT_IRCNAME), |
57 | versionString(VERSION_STRING), |
58 | userHost(""), |
59 | localIP(""), |
60 | commandChar(DEFAULT_COMMANDCHAR), |
61 | configFileName(filename), |
62 | userListFileName(DEFAULT_USERLISTFILENAME), |
63 | shitListFileName(DEFAULT_SHITLISTFILENAME), |
64 | logFileName(DEFAULT_LOGFILENAME), |
439869bf |
65 | logs_dir (DEFAULT_LOGDIR), |
cb21075d |
66 | helpFileName(DEFAULT_HELPFILENAME), |
67 | initFileName(DEFAULT_INITFILENAME), |
68 | #ifdef USESCRIPTS |
69 | scriptLogFileName(DEFAULT_SCRIPTLOGFILENAME), |
70 | autoexecFileName(DEFAULT_AUTOEXECFILENAME), |
71 | #endif |
72 | connected(false), |
73 | debug(debug_on), stop(false), sentPing(false), |
74 | startTime(time(NULL)), currentTime(startTime), |
75 | lastNickNameChange(startTime), lastChannelJoin(startTime), |
76 | serverConnection(0), sentUserhostID(0), receivedUserhostID(0) |
77 | { |
cb21075d |
78 | #ifdef HAVE_STL_CLEAR |
79 | wantedChannels.clear(); |
80 | ignoredUserhosts.clear(); |
81 | spyList.clear(); |
82 | userhostMap.clear(); |
83 | #endif |
84 | |
e07b6b46 |
85 | init_user_functions (); |
cb21075d |
86 | |
be3612f3 |
87 | set_log_dir (logs_dir); |
88 | set_log_file (logFileName); |
89 | |
90 | |
cb21075d |
91 | channelList = new ChannelList(); |
92 | serverList = new ServerList(); |
93 | readConfig(); |
94 | userList = new UserList(userListFileName); |
95 | shitList = new ShitList(shitListFileName); |
96 | todoList = new TodoList(); |
6530edbf |
97 | dccConnections = new DCCManager (); |
cb21075d |
98 | |
99 | // Let's read the alias file |
100 | std::ifstream initFile(initFileName); |
101 | |
102 | if (initFile) { |
103 | String temp, alias, command; |
cb21075d |
104 | int line = 0; |
105 | while (initFile >> temp, temp.length() != 0) { |
106 | line++; |
107 | StringTokenizer st(temp); |
108 | temp = temp.trim(); |
109 | if (temp[0]=='#') continue; |
110 | if (st.countTokens(' ') != 2) { |
111 | std::cerr << "Error when reading alias file (" << initFileName |
112 | << ") line " << line << "...\n"; |
113 | continue; |
114 | } |
115 | alias = st.nextToken().toUpper(); |
116 | command = st.nextToken().toUpper(); |
117 | |
118 | // Does the function already exist ? |
e07b6b46 |
119 | if (!userFunctions[alias]) |
120 | { |
121 | if (userFunction *u = userFunctions[command]) |
122 | userFunctions[alias] = |
123 | new |
124 | userFunction(u->function, |
125 | u->minLevel, |
126 | u->needsChannelName); |
127 | } |
cb21075d |
128 | } |
129 | } |
130 | |
e07b6b46 |
131 | |
cb21075d |
132 | std::srand (std::time (0)); // srand for bot-random |
133 | #ifdef USESCRIPTS |
439869bf |
134 | botInterp = new BotInterp(this, logs_dir + scriptLogFileName); |
cb21075d |
135 | botInterp->LoadScript(autoexecFileName); |
136 | #endif |
137 | } |
138 | |
139 | Bot::~Bot() |
140 | { |
cb21075d |
141 | Person *p; |
142 | while (spyList.size() != 0) { |
143 | p = (*spyList.begin()).second; |
144 | spyList.erase(spyList.begin()); |
145 | delete p; |
146 | } |
6530edbf |
147 | delete dccConnections; |
e07b6b46 |
148 | destroy_user_functions (); |
149 | |
cb21075d |
150 | wantedChannel *w; |
151 | while (wantedChannels.size() != 0) { |
152 | w = (*wantedChannels.begin()).second; |
153 | wantedChannels.erase(wantedChannels.begin()); |
154 | delete w; |
155 | } |
156 | userList->save(); |
157 | shitList->save(); |
158 | delete channelList; |
159 | delete userList; |
160 | delete todoList; |
161 | delete serverList; |
162 | delete shitList; |
163 | delete serverConnection; |
164 | logLine("Stopping log."); |
165 | logFile.close(); |
166 | } |
167 | |
168 | void |
169 | Bot::logLine(String line) |
170 | { |
171 | tm *d; |
172 | std::time_t current_time = time(0); |
173 | |
174 | d = localtime(¤t_time); |
175 | logFile << "[" << std::setfill('0') << std::setw(2) |
176 | << d->tm_mday << "/" << std::setfill('0') << std::setw(2) |
177 | << d->tm_mon + 1 << "/" |
178 | << d->tm_year + 1900 << " - " << std::setfill('0') << std::setw(2) |
179 | << d->tm_hour << ":" << std::setfill('0') << std::setw(2) |
180 | << d->tm_min << ":" << std::setfill('0') << std::setw(2) |
181 | << d->tm_sec << "] " |
182 | << line |
183 | << std::endl; |
184 | } |
185 | |
186 | void |
187 | Bot::readConfig() |
188 | { |
189 | std::ifstream file(configFileName); |
190 | String temp; |
191 | int line = 1; |
192 | |
193 | if (!file) { |
194 | logLine(String("I cannot find the file ") + configFileName); |
195 | return; |
196 | } |
197 | |
198 | while (!file.eof()) { |
199 | |
200 | file >> temp; |
201 | |
202 | if (temp.length() == 0 || temp[0] == '#') { |
203 | line++; |
204 | continue; |
205 | } |
206 | |
207 | StringTokenizer st(temp); |
208 | String command = st.nextToken('=').trim().toUpper(); |
209 | String parameters = st.nextToken('=').trim(); |
210 | |
211 | if (command == "NICK" || command == "NICKNAME") |
212 | nickName = wantedNickName = parameters; |
213 | else if (command == "USERNAME") |
214 | userName = parameters; |
215 | else if (command == "IRCNAME" || command == "REALNAME") |
216 | ircName = parameters; |
217 | else if (command == "CMDCHAR" || command == "COMMAND") |
218 | commandChar = parameters[0]; |
219 | else if (command == "USERLIST") |
220 | userListFileName = parameters; |
221 | else if (command == "SHITLIST") |
222 | shitListFileName = parameters; |
223 | else if (command == "CHANNEL") { |
224 | if (parameters.indexOf(':') == -1) { |
225 | std::cout << "Warning. The 'channel' syntax has changed." |
226 | << " Please see the README file for more information." |
227 | << " I will use compatibility mode, but you're really" |
228 | << " missing something.\n"; |
229 | StringTokenizer st2(parameters); |
230 | String name = st2.nextToken().toLower(); |
231 | String key = st2.nextToken(); |
232 | wantedChannels[name] = new wantedChannel("", "", key); |
233 | } else { |
234 | StringTokenizer st2(parameters); |
235 | String name = st2.nextToken(':').toLower(); |
236 | String mode = st2.nextToken(':'); |
237 | String keep = st2.nextToken(':'); |
238 | String key = st2.nextToken(':'); |
239 | wantedChannels[name] = new wantedChannel(mode, keep, key); |
240 | } |
241 | } |
242 | else if (command == "LOGFILE") |
be3612f3 |
243 | { |
fd7440f1 |
244 | if (parameters != logFileName) |
be3612f3 |
245 | { |
fd7440f1 |
246 | if (parameters[0] == '/') |
247 | { |
248 | set_log_dir ("/"); |
249 | set_log_file (parameters.subString (1)); |
250 | } |
251 | else |
252 | set_log_file (parameters); |
be3612f3 |
253 | } |
be3612f3 |
254 | } |
cb21075d |
255 | #ifdef USESCRIPTS |
256 | else if (command == "SCRIPTLOGFILE") |
257 | scriptLogFileName = parameters; |
258 | else if (command == "AUTOEXECFILE") |
259 | autoexecFileName = parameters; |
260 | #endif |
261 | else if (command == "INITFILE") |
262 | initFileName = parameters; |
263 | else if (command == "LOCALIP") |
264 | localIP = parameters; |
265 | else if (command == "SERVER") { |
266 | if (parameters.indexOf(' ') == -1) |
267 | serverList->addServer(new Server(parameters)); |
268 | else { |
269 | StringTokenizer st2(parameters); |
270 | String name = st2.nextToken(); |
271 | int port = std::atoi(st2.nextToken()); |
272 | serverList->addServer(new Server(name, |
273 | port, |
274 | st2.nextToken())); |
275 | } |
276 | } |
277 | else { |
278 | logLine(String("Syntax error in file ") + configFileName + |
279 | ", line " + String((long)line)); |
280 | file.close(); |
281 | std::exit(1); |
282 | } |
283 | |
284 | line++; |
285 | } |
286 | |
287 | file.close(); |
288 | } |
289 | |
290 | void |
291 | Bot::run() |
292 | { |
293 | nextServer(); |
294 | |
295 | while (!stop) { |
296 | waitForInput(); // This is the main event loop |
6530edbf |
297 | dccConnections->checkStale (); |
cb21075d |
298 | if (!serverConnection->queue->flush()) |
299 | nextServer(); |
300 | } |
301 | } |
302 | |
303 | void |
304 | Bot::waitForInput() |
305 | { |
306 | #ifdef _HPUX_SOURCE |
307 | int rd; |
308 | #else |
309 | fd_set rd; |
310 | #endif |
311 | struct timeval timer; |
312 | |
313 | int sock = serverConnection->getFileDescriptor(); |
314 | int maxSocketNumber = sock; |
315 | |
316 | #ifdef _HPUX_SOURCE |
317 | rd = sock; |
318 | #else |
319 | FD_ZERO(&rd); |
320 | FD_SET(sock, &rd); |
321 | #endif |
322 | |
6530edbf |
323 | DCC_MAP* dccmap = dccConnections->MAP (); |
324 | for (DCC_MAP::iterator it = dccmap->begin (); |
325 | it != dccmap->end(); ++it) { |
326 | int s = it->second->DCC()->getFileDescriptor(); |
cb21075d |
327 | #ifdef _HPUX_SOURCE |
328 | rd |= s; |
329 | #else |
330 | FD_SET(s, &rd); |
331 | #endif |
332 | if (s > maxSocketNumber) |
333 | maxSocketNumber = s; |
334 | } |
335 | |
336 | timer.tv_sec = 1; |
337 | timer.tv_usec = 0; |
338 | |
339 | switch (select(maxSocketNumber + 1, &rd, NULL, NULL, &timer)) { |
340 | case 0: /* timeout */ |
341 | break; |
342 | case -1: /* error */ |
343 | break; |
344 | default: /* normal */ |
345 | #ifdef _HPUX_SOURCE |
346 | if (rd & sock) |
347 | #else |
348 | if (FD_ISSET(sock, &rd)) |
349 | #endif |
350 | if (serverConnection->handleInput()) |
351 | nextServer(); |
352 | |
6530edbf |
353 | // std::list<DCCConnection *>::iterator it = dccConnections.begin(); |
354 | // std::list<DCCConnection *>::iterator it2; |
355 | |
356 | // while (it != dccConnections.end()) { |
357 | // it2 = it; |
358 | // ++it; |
359 | // #ifdef _HPUX_SOURCE |
360 | // if (rd & (*it2)->getFileDescriptor()) { |
361 | // #else |
362 | // if (FD_ISSET((*it2)->getFileDescriptor(), &rd)) { |
363 | // #endif |
364 | // if ((*it2)->handleInput()) { |
365 | // delete *it2; |
366 | // dccConnections.erase(it2); |
367 | // } |
368 | // } |
369 | // } |
370 | // } |
371 | dccConnections->checkInput (rd); |
cb21075d |
372 | } |
373 | |
374 | if (currentTime < std::time(NULL)) { // Actions that we do each second |
375 | currentTime = std::time(NULL); |
376 | for (std::map<String, unsigned int, std::less<String> >::iterator |
377 | it = ignoredUserhosts.begin(); |
378 | it != ignoredUserhosts.end(); ++it) |
379 | if ((*it).second > 0) |
380 | (*it).second--; |
381 | |
382 | String line; |
383 | while ((line = todoList->getNext()) != "") { |
384 | serverConnection->queue->sendChannelMode(line); |
385 | } |
386 | #ifdef USESCRIPTS |
387 | botInterp->RunTimers(currentTime); |
388 | #endif |
389 | |
390 | #ifdef USESCRIPTS |
391 | tm *thisTime = localtime(¤tTime); |
392 | if (thisTime->tm_sec == 0) { |
393 | char s[6]; |
394 | sprintf(s, "%2d:%2d", thisTime->tm_hour, thisTime->tm_min); |
395 | botInterp->RunHooks(Hook::TIMER, String(s), |
396 | gh_list(Utils::string2SCM(String(s)), SCM_UNDEFINED)); |
397 | } |
398 | #endif |
399 | |
400 | } |
401 | |
402 | if (currentTime >= (time_t)(lastNickNameChange + Bot::NICK_CHANGE) && |
403 | nickName != wantedNickName) { |
404 | lastNickNameChange = currentTime; |
405 | serverConnection->queue->sendNick(wantedNickName); |
406 | } |
407 | |
408 | if (currentTime >= (std::time_t)(lastChannelJoin + Bot::CHANNEL_JOIN)) { |
409 | lastChannelJoin = currentTime; |
410 | for (std::map<String, wantedChannel *, std::less<String> >::iterator it = |
411 | wantedChannels.begin(); it != wantedChannels.end(); |
412 | ++it) |
413 | if (channelList->getChannel((*it).first) == 0) |
414 | serverConnection->queue->sendJoin((*it).first, (*it).second->key); |
415 | } |
416 | |
6530edbf |
417 | // std::list<DCCConnection *>::iterator it2; |
cb21075d |
418 | |
6530edbf |
419 | // for (std::list<DCCConnection *>::iterator it = dccConnections.begin(); |
420 | // it != dccConnections.end(); ) { |
421 | // it2 = it; |
422 | // ++it; |
423 | // if ((*it2)->autoRemove && currentTime >= (std::time_t)((*it2)->lastSpoken + Bot::DCC_DELAY)) { |
424 | // delete *it2; |
425 | // dccConnections.erase(it2); |
426 | // } |
427 | // } |
cb21075d |
428 | |
429 | if (currentTime >= (std::time_t)(serverConnection->serverLastSpoken + Bot::PING_TIME) && !sentPing) { |
430 | serverConnection->queue->sendPing("Testing connection"); |
431 | sentPing = true; |
432 | } |
433 | |
434 | if (currentTime >= (std::time_t)(serverConnection->serverLastSpoken + Bot::TIMEOUT)) { |
435 | sentPing = false; |
436 | nextServer(); |
437 | } |
438 | } |
439 | |
440 | // We can change server if we will not lose op on a channel |
441 | bool |
442 | Bot::canChangeServer() |
443 | { |
444 | String channel; |
445 | Channel *c; |
446 | |
447 | for (std::map<String, Channel *, std::less<String> >::iterator it = |
448 | channelList->begin(); |
449 | it != channelList->end(); ++it) { |
450 | channel = (*it).first; |
451 | c = channelList->getChannel(channel); |
452 | if (c->countOp == 1 && |
453 | c->count > 1 && this->iAmOp(channel)) |
454 | return false; |
455 | } |
456 | return true; |
457 | } |
458 | |
459 | void |
460 | Bot::nextServer() |
461 | { |
462 | bool cont = false; |
463 | |
464 | if (channelList) |
465 | channelList->clear(); |
466 | |
467 | if (serverConnection) |
468 | userList->removeFirst(); |
469 | |
470 | delete serverConnection; |
471 | |
472 | do { |
473 | Server * s = serverList->nextServer(); |
474 | if (!s) { |
475 | std::cout << "No server found. Exiting..." << std::endl; |
476 | std::exit(1); |
477 | } |
478 | serverConnection = new ServerConnection(this, s, localIP); |
479 | if (!serverConnection->connect()) { |
480 | cont = true; |
481 | // We sleep 10 seconds, to avoid connection flood |
482 | sleep(10); |
483 | delete serverConnection; |
484 | } else { |
485 | cont = false; |
486 | } |
487 | } while (cont); |
488 | } |
489 | |
490 | void |
491 | Bot::reconnect() |
492 | { |
493 | if (channelList) |
494 | channelList->clear(); |
495 | |
496 | userList->removeFirst(); |
497 | |
498 | delete serverConnection; |
499 | |
500 | serverConnection = |
501 | new ServerConnection(this, serverList->currentServer(), localIP); |
502 | |
503 | serverConnection->connect(); |
504 | } |
505 | |
506 | void |
507 | Bot::connect(int serverNumber) |
508 | { |
509 | if (channelList) |
510 | channelList->clear(); |
511 | |
512 | userList->removeFirst(); |
513 | |
514 | delete serverConnection; |
515 | |
516 | serverConnection = |
517 | new ServerConnection(this, serverList->get(serverNumber), localIP); |
518 | |
519 | serverConnection->connect(); |
520 | } |
521 | |
522 | void |
523 | Bot::addDCC(Person * from, unsigned long address, int port) |
524 | { |
fed59248 |
525 | DCCConnection * d = new DCCConnection(this, from->getAddress (), |
cb21075d |
526 | address, port); |
527 | |
528 | if (!d->connect()) |
fd7440f1 |
529 | { |
530 | logLine ("DCC Connection failed from " + from->getAddress ()); |
531 | return; |
532 | } |
fed59248 |
533 | logLine ("DCC CHAT accepted from" + from->getAddress ()); |
6530edbf |
534 | dccConnections->addConnection (d); |
cb21075d |
535 | } |
536 | |
537 | void |
538 | Bot::rehash() |
539 | { |
fed59248 |
540 | for (std::map<String, Channel *, std::less<String> >::iterator it = |
541 | channelList->begin(); |
cb21075d |
542 | it != channelList->end(); ++it) |
543 | serverConnection->queue->sendWho((*it).first); |
544 | } |
545 | |
546 | String |
547 | Bot::getUserhost(String channel, String nick) |
548 | { |
549 | Channel *c; |
550 | |
551 | if (channel == "") |
552 | c = 0; |
553 | else |
554 | c = channelList->getChannel(channel); |
555 | |
556 | nick = nick.toLower(); |
557 | |
558 | |
559 | if (c && c->hasNick(nick)) |
560 | return c->getUser(nick)->userhost; |
561 | |
562 | unsigned long num = sentUserhostID++; |
563 | |
564 | serverConnection->queue->sendUserhost(nick); |
565 | userhostMap[num] = "+"; |
566 | |
567 | while (userhostMap[num] == "+") { |
568 | waitForInput(); |
569 | serverConnection->queue->flush(); |
570 | } |
571 | |
572 | // We have got our answer |
573 | String res = userhostMap[num]; |
574 | userhostMap.erase(num); |
575 | |
576 | return res; |
577 | } |
578 | |
579 | bool |
580 | Bot::iAmOp(String channel) |
581 | { |
582 | User * me = channelList->getChannel(channel)->getUser(nickName); |
583 | return (me->mode & User::OP_MODE); |
584 | } |
e07b6b46 |
585 | |
586 | void |
587 | Bot::init_user_functions () |
588 | { |
589 | // User Functions |
590 | #define uf(f, l, b) new userFunction (f, l, b); |
591 | userFunctions["ACTION"] = uf (UserCommands::Action, User::USER, true); |
592 | userFunctions["ADDUSER"] = uf (UserCommands::AddUser, User::FRIEND, false); |
593 | userFunctions["ADDSERVER"] = uf (UserCommands::AddServer, User::FRIEND, |
594 | false); |
595 | userFunctions["ADDSHIT"] = uf (UserCommands::AddShit, User::FRIEND, false); |
596 | userFunctions["ALIAS"] = uf (UserCommands::Alias, User::MASTER, false); |
597 | userFunctions["BAN"] = uf (UserCommands::Ban, User::USER, true); |
598 | userFunctions["BANLIST"] = uf (UserCommands::BanList, User::USER, true); |
599 | userFunctions["CHANNELS"] = |
600 | uf (UserCommands::Channels, User::FRIEND, false); |
601 | userFunctions["CYCLE"] = uf (UserCommands::Cycle, User::FRIEND, true); |
602 | userFunctions["DCCLIST"] = uf (UserCommands::DCCList, User::FRIEND, false); |
603 | userFunctions["DEBAN"] = uf (UserCommands::Deban, User::USER, true); |
604 | userFunctions["DELSERVER"] = uf (UserCommands::DelServer, User::FRIEND, |
605 | false); |
606 | userFunctions["DELUSER"] = uf (UserCommands::DelUser, User::FRIEND, false); |
607 | userFunctions["DELSHIT"] = uf (UserCommands::DelShit, User::FRIEND, false); |
608 | userFunctions["DEOP"] = uf (UserCommands::Deop, User::TRUSTED_USER, true); |
609 | userFunctions["DIE"] = uf (UserCommands::Die, User::MASTER, false); |
610 | userFunctions["DO"] = uf (UserCommands::Do, User::MASTER, false); |
611 | #ifdef USESCRIPTS |
612 | userFunctions["EXECUTE"] = uf (UserCommands::Execute, User::MASTER, false); |
613 | #endif |
614 | userFunctions["HELP"] = uf (UserCommands::Help, User::NONE, false); |
615 | userFunctions["IDENT"] = uf (UserCommands::Ident, User::NONE, true); |
616 | userFunctions["INVITE"] = uf (UserCommands::Invite, User::USER, true); |
617 | userFunctions["JOIN"] = uf (UserCommands::Join, User::FRIEND, false); |
618 | userFunctions["KEEP"] = uf (UserCommands::Keep, User::FRIEND, true); |
619 | userFunctions["KICK"] = uf (UserCommands::Kick, User::USER, true); |
620 | userFunctions["KICKBAN"] = uf (UserCommands::KickBan, User::USER, true); |
621 | userFunctions["LOAD"] = uf (UserCommands::Load, User::FRIEND, false); |
622 | #ifdef USESCRIPTS |
623 | userFunctions["LOADSCRIPT"] = uf (UserCommands::LoadScript, User::MASTER, |
624 | false); |
625 | #endif |
626 | userFunctions["LOCK"] = uf (UserCommands::Lock, User::FRIEND, true); |
627 | userFunctions["MODE"] = uf (UserCommands::Mode, User::FRIEND, true); |
628 | userFunctions["MSG"] = uf (UserCommands::Msg, User::USER, false); |
629 | userFunctions["NAMES"] = uf (UserCommands::Names, User::USER, true); |
630 | userFunctions["NEXTSERVER"] = uf (UserCommands::NextServer, User::FRIEND, |
631 | false); |
632 | userFunctions["NICK"] = uf (UserCommands::Nick, User::FRIEND, false); |
633 | userFunctions["NSLOOKUP"] = uf (UserCommands::NsLookup, User::USER, false); |
634 | userFunctions["OP"] = uf (UserCommands::Op, User::TRUSTED_USER, true); |
635 | userFunctions["PART"] = uf (UserCommands::Part, User::FRIEND, true); |
636 | userFunctions["PASSWORD"] = uf (UserCommands::Password, User::USER, true); |
637 | userFunctions["RECONNECT"] = |
638 | uf (UserCommands::Reconnect, User::FRIEND, false); |
639 | userFunctions["RSPYMESSAGE"] = |
640 | uf (UserCommands::RSpyMessage, User::USER, false); |
641 | userFunctions["SAVE"] = uf (UserCommands::Save, User::FRIEND, false); |
642 | userFunctions["SAY"] = uf (UserCommands::Say, User::USER, true); |
643 | userFunctions["SERVER"] = uf (UserCommands::Server, User::FRIEND, false); |
644 | userFunctions["SERVERLIST"] = |
645 | uf (UserCommands::ServerList, User::FRIEND, false); |
646 | userFunctions["SETVERSION"] = |
647 | uf (UserCommands::SetVersion, User::MASTER, false); |
648 | userFunctions["SHITLIST"] = |
649 | uf (UserCommands::ShitList, User::FRIEND, false); |
650 | userFunctions["SPYLIST"] = uf (UserCommands::SpyList, User::USER, false); |
651 | userFunctions["SPYMESSAGE"] = |
652 | uf (UserCommands::SpyMessage, User::USER, false); |
653 | userFunctions["STATS"] = uf (UserCommands::Stats, User::FRIEND, true); |
654 | userFunctions["TBAN"] = uf (UserCommands::TBan, User::USER, true); |
655 | userFunctions["TKBAN"] = uf (UserCommands::TKBan, User::USER, true); |
656 | userFunctions["TOPIC"] = uf (UserCommands::Topic, User::USER, true); |
657 | userFunctions["UNLOCK"] = uf (UserCommands::Unlock, User::FRIEND, true); |
658 | userFunctions["USERLIST"] = |
659 | uf (UserCommands::UserList, User::FRIEND, false); |
660 | userFunctions["WHO"] = uf (UserCommands::Who, User::NONE, true); |
661 | userFunctions["WHOIS"] = uf (UserCommands::Whois, User::FRIEND, true); |
662 | #undef uf |
663 | } |
664 | |
665 | namespace |
666 | { |
667 | void erase_userf (std::pair<std::string, class userFunction*> it) |
668 | { |
669 | delete it.second; |
670 | } |
671 | } |
672 | |
673 | void |
674 | Bot::destroy_user_functions () |
675 | { |
91dddabd |
676 | std::for_each (userFunctions.begin (), |
e07b6b46 |
677 | userFunctions.end (), |
678 | erase_userf); |
679 | userFunctions.erase (userFunctions.begin (), |
680 | userFunctions.end ()); |
681 | } |
be3612f3 |
682 | |
683 | void |
684 | Bot::set_log_file (String name) |
685 | { |
686 | logFileName = name; |
fd7440f1 |
687 | logFile.close (); |
688 | logFile.clear (); |
be3612f3 |
689 | #if HAVE_IOSBASE |
690 | logFile.open(logs_dir + logFileName, std::ios_base::out | |
691 | std::ios_base::ate | std::ios_base::app); |
692 | #else |
693 | logFile.open(logs_dir + logFileName, ios::out | ios::ate |
694 | | ios::app); |
695 | #endif |
696 | |
697 | logLine("Starting log."); |
698 | } |
699 | |
700 | void |
701 | Bot::set_log_dir (String dir) |
702 | { |
703 | logs_dir = dir; |
704 | } |