[project @ 2005-07-05 18:48:49 by unknown_lamer]
[clinton/bobotpp.git] / source / ScriptCommands.C
CommitLineData
cb21075d 1// ScriptCommands.C -*- C++ -*-
2// Copyright (c) 1998 Etienne BERNARD
a6339323 3// Copyright (C) 2002,2005 Clinton Ebadi
cb21075d 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
ae97d6ec 17// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18// 02110-1301, USA.
cb21075d 19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#ifdef USESCRIPTS
25
26#include "Utils.H"
27#include "Server.H"
28#include "ServerList.H"
e07b6b46 29#include "ServerQueue.H"
cb21075d 30#include "ScriptCommands.H"
31#include "Interp.H"
6530edbf 32#include "DCCPerson.H"
0b7a49e2 33#include "DCCManager.H"
4edefeb6 34#include "Parser.H"
5aec4622 35#include "Commands.H"
36#include "Message.H"
cb21075d 37#include <libguile.h>
38
39#define VERIFY_STRING(par) if (!SCM_STRINGP((par))) \
40 return scm_long2num(-17)
41
42#define VERIFY_NUMBER(par) if (!SCM_NUMBERP((par))) \
43 return scm_long2num(-17)
44
45SCM
46ScriptCommands::Action(SCM channel, SCM message)
47{
48 VERIFY_STRING(channel);
49 VERIFY_STRING(message);
a6339323 50 Message m = Commands::Action(Interp::bot, Utils::scm2str(channel),
51 Utils::scm2str(message));
cb21075d 52 return scm_long2num(m.getCode());
53}
54
55SCM
56ScriptCommands::AddUser(SCM who, SCM maskChannel, SCM level,
57 SCM prot, SCM aop, SCM expire, SCM password)
58{
59 // It segfaults when not online, but otherwise appears to work
60 VERIFY_STRING (who);
61 VERIFY_STRING (maskChannel);
62 VERIFY_NUMBER (level);
63
a6339323 64 String wwho = Utils::scm2str (who);
65 String mask = Utils::scm2str (maskChannel);
cb21075d 66 String passwd;
67 std::time_t eexpire;
68
69 if (SCM_UNBNDP (password))
70 passwd = "";
71 else
72 {
73 VERIFY_STRING (password);
a6339323 74 passwd = Utils::scm2str (password);
cb21075d 75 }
76 if (SCM_UNBNDP (expire))
77 eexpire = -1;
78 else
79 {
80 VERIFY_STRING (expire);
a6339323 81 eexpire = Utils::str2time (Utils::scm2str (expire));
cb21075d 82 if (!eexpire) eexpire = -1;
83 }
84
85 int protect = scm_num2int (prot, SCM_ARG1, "ScriptCommands::AddUser");
86 bool aaop = SCM_NFALSEP (aop);
87 int llevel = scm_num2int (level, SCM_ARG1,
88 "ScriptCommands::AddUser");
89
90 Message m = Commands::AddUser (Interp::bot, wwho, mask, llevel,
91 protect, aaop, eexpire, passwd);
92
93 return scm_long2num(m.getCode ());
94}
95
96SCM
97ScriptCommands::AddServer(SCM servername, SCM port)
98{
99 int p = 6667;
100 if (SCM_NUMBERP(port))
101 p = scm_num2long(port, SCM_ARG1, "ScriptCommands::AddServer");
102 Message m = Commands::AddServer(Interp::bot,
a6339323 103 Utils::scm2str(servername),
cb21075d 104 p);
105 return scm_long2num(m.getCode());
106}
107
108SCM
109ScriptCommands::AddShit(SCM mask, SCM maskChannel, SCM level,
110 SCM expiration, SCM reason)
111{
112 // This appears to work...not much testing though
113 VERIFY_STRING (mask);
114 VERIFY_STRING (maskChannel);
115 VERIFY_NUMBER (level);
a6339323 116 String mmask = Utils::scm2str (mask);
117 String mmaskChannel = Utils::scm2str (maskChannel);
cb21075d 118 int llevel = scm_num2int (level, SCM_ARG1, "ScriptCommands::AddShit");
119 std::time_t expire;
120 String rreason;
121
122 if (SCM_UNBNDP (expiration))
123 expire = -1;
124 else
125 {
126 VERIFY_STRING (expiration);
a6339323 127 expire = Utils::str2time (Utils::scm2str (expiration));
cb21075d 128 if (!expire) expire = -1;
129 }
130 if (SCM_UNBNDP (reason))
131 rreason = "You're on my shitlist, lamer";
132 else
133 {
134 VERIFY_STRING (reason);
a6339323 135 rreason = Utils::scm2str (reason);
cb21075d 136 }
137 Message m = Commands::AddShit (Interp::bot, mmask, mmaskChannel,
138 llevel, expire, rreason);
139
140 return scm_long2num(m.getCode ());
141}
142
143SCM
144ScriptCommands::Ban(SCM channel, SCM who)
145{
146 VERIFY_STRING(channel);
147 VERIFY_STRING(who);
a6339323 148 Message m = Commands::Ban(Interp::bot, Utils::scm2str(channel),
149 Utils::scm2str(who));
cb21075d 150 return scm_long2num(m.getCode());
151}
152
4edefeb6 153SCM
154ScriptCommands::ChangeCommandLevel(SCM command, SCM level)
155{
156 VERIFY_STRING (command);
157 VERIFY_NUMBER (level);
158
159 SCM_STRING_COERCE_0TERMINATION_X (command);
160 std::string ccommand = SCM_STRING_CHARS (command);
161 unsigned int llevel = scm_num2uint (level, 0, "ScriptCommands::ChangeCommandLevel");
162
163 if (llevel > 4)
164 return SCM_BOOL_F;
165
166 std::map<std::string, class userFunction*,
167 std::less<std::string> >::const_iterator uf_iter
168 = Interp::bot->userFunctions.find (ccommand);
169 userFunction * f = 0;
170
171 if (uf_iter != Interp::bot->userFunctions.end ())
172 f = uf_iter->second;
173 else
174 return SCM_BOOL_F;
175
176 f->minLevel = llevel;
177 return SCM_BOOL_T;
178}
179
cb21075d 180SCM
181ScriptCommands::Cycle(SCM channel)
182{
183 VERIFY_STRING(channel);
a6339323 184 Message m = Commands::Cycle(Interp::bot, Utils::scm2str(channel));
cb21075d 185 return scm_long2num(m.getCode());
186}
187
188SCM
189ScriptCommands::Deban(SCM channel, SCM who)
190{
191 VERIFY_STRING(channel);
192 VERIFY_STRING(who);
a6339323 193 Message m = Commands::Deban(Interp::bot, Utils::scm2str(channel),
194 Utils::scm2str(who));
cb21075d 195 return scm_long2num(m.getCode());
196}
197
198SCM
199ScriptCommands::DelServer(SCM number)
200{
201 VERIFY_NUMBER(number);
202 Message m = Commands::DelServer(Interp::bot,
203 scm_num2long(number, SCM_ARG1,
204 "ScriptCommands::DelServer"));
205 return scm_long2num(m.getCode());
206}
207
208SCM
209ScriptCommands::DelUser(SCM who, SCM maskChannel)
210{
211 VERIFY_STRING(who);
212 VERIFY_STRING(maskChannel);
a6339323 213 Message m = Commands::DelUser(Interp::bot, Utils::scm2str(who),
214 Utils::scm2str(maskChannel));
cb21075d 215 return scm_long2num(m.getCode());
216}
217
218SCM
219ScriptCommands::DelShit(SCM who, SCM maskChannel)
220{
221 VERIFY_STRING(who);
222 VERIFY_STRING(maskChannel);
a6339323 223 Message m = Commands::DelShit(Interp::bot, Utils::scm2str(who),
224 Utils::scm2str(maskChannel));
cb21075d 225 return scm_long2num(m.getCode());
226}
227
228SCM
229ScriptCommands::Deop(SCM channel, SCM who)
230{
231 VERIFY_STRING(channel);
232 VERIFY_STRING(who);
a6339323 233 Message m = Commands::Deop(Interp::bot, Utils::scm2str(channel),
234 Utils::scm2str(who));
cb21075d 235 return scm_long2num(m.getCode());
236}
237
238SCM
239ScriptCommands::Die(SCM reason)
240{
241 String r = "Leaving";
242 if (SCM_STRINGP(reason))
a6339323 243 r = Utils::scm2str(reason);
cb21075d 244 Message m = Commands::Die(Interp::bot, r);
245 return scm_long2num(m.getCode());
246}
247
248SCM
249ScriptCommands::Do(SCM command)
250{
251 VERIFY_STRING(command);
a6339323 252 Message m = Commands::Do(Interp::bot, Utils::scm2str(command));
cb21075d 253 return scm_long2num(m.getCode());
254}
255
256SCM
257ScriptCommands::Invite(SCM channel, SCM who)
258{
259 VERIFY_STRING(channel);
260 VERIFY_STRING(who);
a6339323 261 Message m = Commands::Invite(Interp::bot, Utils::scm2str(channel),
262 Utils::scm2str(who));
cb21075d 263 return scm_long2num(m.getCode());
264}
265
266SCM
267ScriptCommands::Join(SCM channel, SCM key)
268{
269 VERIFY_STRING(channel);
270 String k = "";
271 if (SCM_STRINGP(key))
a6339323 272 k = Utils::scm2str(key);
273 Message m = Commands::Join(Interp::bot, Utils::scm2str(channel),
cb21075d 274 k);
275 return scm_long2num(m.getCode());
276}
277
278SCM
279ScriptCommands::Keep(SCM channel, SCM modes)
280{
281 VERIFY_STRING(channel);
282 VERIFY_STRING(modes);
a6339323 283 Message m = Commands::Keep(Interp::bot, Utils::scm2str(channel),
284 Utils::scm2str(modes));
cb21075d 285 return scm_long2num(m.getCode());
286}
287
288SCM
289ScriptCommands::Kick(SCM channel, SCM who, SCM reason)
290{
291 VERIFY_STRING(channel);
292 VERIFY_STRING(who);
293
294 String r = "";
295 if (SCM_STRINGP(reason))
a6339323 296 r = Utils::scm2str(reason);
cb21075d 297
a6339323 298 Message m = Commands::Kick(Interp::bot, Utils::scm2str(channel),
299 Utils::scm2str(who), r);
cb21075d 300 return scm_long2num(m.getCode());
301}
302
303SCM
304ScriptCommands::KickBan(SCM channel, SCM who, SCM reason)
305{
306 VERIFY_STRING(channel);
307 VERIFY_STRING(who);
308 String r = "";
309 if (SCM_STRINGP(reason))
a6339323 310 r = Utils::scm2str(reason);
311 Message m = Commands::KickBan(Interp::bot, Utils::scm2str(channel),
312 Utils::scm2str(who), r);
cb21075d 313 return scm_long2num(m.getCode());
314}
315
316SCM
317ScriptCommands::Lock(SCM channel)
318{
319 VERIFY_STRING(channel);
a6339323 320 Message m = Commands::Lock(Interp::bot, Utils::scm2str(channel));
cb21075d 321 return scm_long2num(m.getCode());
322}
323
324SCM
325ScriptCommands::LogPort(void)
326{
327 return Interp::bot->botInterp->logPort;
328}
329
330SCM
331ScriptCommands::Mode(SCM channel, SCM mode)
332{
333 VERIFY_STRING(channel);
334 VERIFY_STRING(mode);
a6339323 335 Message m = Commands::Mode(Interp::bot, Utils::scm2str(channel),
336 Utils::scm2str(mode));
cb21075d 337 return scm_long2num(m.getCode());
338}
339
340SCM
341ScriptCommands::Msg(SCM nick, SCM message)
342{
343 VERIFY_STRING(nick);
344 VERIFY_STRING(message);
a6339323 345 Message m = Commands::Msg(Interp::bot, Utils::scm2str(nick),
346 Utils::scm2str(message));
cb21075d 347 return scm_long2num(m.getCode());
348
349}
350
351SCM
352ScriptCommands::NextServer(void)
353{
354 Message m = Commands::NextServer(Interp::bot);
355 return scm_long2num(m.getCode());
356}
357
358SCM
359ScriptCommands::Nick(SCM nick)
360{
361 VERIFY_STRING(nick);
a6339323 362 Message m = Commands::Nick(Interp::bot, Utils::scm2str(nick));
cb21075d 363 return scm_long2num(m.getCode());
364}
365
c99c411a 366SCM
367ScriptCommands::Notice (SCM to, SCM message)
368{
369 VERIFY_STRING (to);
370 VERIFY_STRING (message);
371
372 return (scm_long2num
373 (Commands::Notice (Interp::bot,
374 Utils::scm2str (to),
375 Utils::scm2str (message)).getCode ()));
376
377}
378
cb21075d 379SCM
380ScriptCommands::Op(SCM channel, SCM who)
381{
382 VERIFY_STRING(channel);
383 VERIFY_STRING(who);
a6339323 384 Message m = Commands::Op(Interp::bot, Utils::scm2str(channel),
385 Utils::scm2str(who));
cb21075d 386 return scm_long2num(m.getCode());
387}
388
389SCM
390ScriptCommands::Part(SCM channel)
391{
392 VERIFY_STRING(channel);
a6339323 393 Message m = Commands::Part(Interp::bot, Utils::scm2str(channel));
cb21075d 394 return scm_long2num(m.getCode());
395}
396
397SCM
398ScriptCommands::Reconnect(void)
399{
400 Message m = Commands::Reconnect(Interp::bot);
401 return scm_long2num(m.getCode());
402}
403
404SCM
405ScriptCommands::Say(SCM channel, SCM message)
406{
407 VERIFY_STRING(channel);
408 VERIFY_STRING(message);
a6339323 409 Message m = Commands::Say(Interp::bot, Utils::scm2str(channel),
410 Utils::scm2str(message));
cb21075d 411 return scm_long2num(m.getCode());
412}
413
414SCM
415ScriptCommands::Server(SCM number)
416{
417 VERIFY_NUMBER(number);
418 Message m = Commands::Server(Interp::bot, gh_scm2long(number));
419 return scm_long2num(m.getCode());
420}
421
e171dcce 422SCM
423ScriptCommands::SetFloodRate(SCM rate)
424{
425 VERIFY_NUMBER(rate);
426 Message m = Commands::SetFloodRate(Interp::bot, scm_num2uint
427 (rate, 0, "SetFloodRate"));
428 return scm_long2num(m.getCode());
429}
430
cb21075d 431SCM
432ScriptCommands::SetVersion(SCM version)
433{
a6339323 434 Message m = Commands::SetVersion(Interp::bot, Utils::scm2str(version));
cb21075d 435 return scm_long2num(m.getCode());
436}
437
438SCM
439ScriptCommands::TBan(SCM channel, SCM who, SCM seconds)
440{
441 VERIFY_STRING(channel);
442 VERIFY_STRING(who);
443 VERIFY_NUMBER(seconds);
a6339323 444 Message m = Commands::TBan(Interp::bot, Utils::scm2str(channel),
445 Utils::scm2str(who), gh_scm2long(seconds));
cb21075d 446 return scm_long2num(m.getCode());
447}
448
449SCM
450ScriptCommands::TKBan(SCM channel, SCM who, SCM seconds, SCM reason)
451{
452 VERIFY_STRING(channel);
453 VERIFY_STRING(who);
454 VERIFY_NUMBER(seconds);
455 String r = "";
456 if (SCM_STRINGP(reason))
a6339323 457 r = Utils::scm2str(reason);
458 Message m = Commands::TKBan(Interp::bot, Utils::scm2str(channel),
459 Utils::scm2str(who),
cb21075d 460 gh_scm2long(seconds), r);
461 return scm_long2num(m.getCode());
462}
463
464SCM
465ScriptCommands::Topic(SCM channel, SCM topic)
466{
467 VERIFY_STRING(channel);
468 VERIFY_STRING(topic);
a6339323 469 Message m = Commands::Topic(Interp::bot, Utils::scm2str(channel),
470 Utils::scm2str(topic));
cb21075d 471 return scm_long2num(m.getCode());
472}
473
474SCM
475ScriptCommands::Unlock(SCM channel)
476{
477 VERIFY_STRING(channel);
a6339323 478 Message m = Commands::Unlock(Interp::bot, Utils::scm2str(channel));
cb21075d 479 return scm_long2num(m.getCode());
480}
481
cb21075d 482SCM
483ScriptCommands::getNickname(void)
484{
a6339323 485 return Utils::str2scm(Interp::bot->nickName);
cb21075d 486}
487
488SCM
489ScriptCommands::getServer(void)
490{
491 ::Server *serv = Interp::bot->serverList->currentServer();
492 int serverNumber = Interp::bot->serverList->currentNumber;
493
494 return gh_list(scm_long2num(serverNumber),
a6339323 495 Utils::str2scm(serv->getHostName()),
cb21075d 496 scm_long2num(serv->getPort()),
a6339323 497 Utils::str2scm(serv->getPassword()),
cb21075d 498 SCM_UNDEFINED);
499}
500
501SCM
502ScriptCommands::getServerList(void)
503{
504 SCM res = gh_list(SCM_UNDEFINED);
505 ::Server *s;
506 int i = 0;
507 std::vector<class Server *>::iterator it = Interp::bot->serverList->begin();
508
509 for ( ; it != Interp::bot->serverList->end(); ++it) {
510 s = (*it);
511 res = gh_append2(res,
512 gh_list(gh_list(scm_long2num(i++),
a6339323 513 Utils::str2scm(s->getHostName()),
cb21075d 514 scm_long2num(s->getPort()),
a6339323 515 Utils::str2scm(s->getPassword()),
cb21075d 516 SCM_UNDEFINED), SCM_UNDEFINED));
517 }
518 return res;
519}
520
521SCM
522ScriptCommands::flushQueue(void)
523{
524 if (!Interp::bot->serverConnection)
525 return SCM_BOOL_F;
526 Interp::bot->serverConnection->queue->flush();
527 return SCM_BOOL_T;
528}
529
530SCM
531ScriptCommands::flushPort(void)
532{
533 scm_flush(Interp::bot->botInterp->logPort);
534 return SCM_BOOL_T;
535}
536
537SCM
538ScriptCommands::random(SCM scm_max)
539{
540 int max = 0;
541 //srand(time(NULL));
542 if (SCM_NUMBERP(scm_max))
543 max = gh_scm2int(scm_max);
544 return scm_long2num(max ? rand() % max : 0);
545}
546
547SCM
548ScriptCommands::addCommand(SCM scm_commandName, SCM scm_function,
549 SCM scm_needsChannel, SCM scm_args,
550 SCM scm_minLevel)
551{
552 // We check that commandName is a string
553 if (!SCM_STRINGP(scm_commandName))
554 return SCM_BOOL_F;
555
556 // We check that the command does not exist
a6339323 557 String commandName = Utils::to_upper (Utils::scm2str(scm_commandName));
e07b6b46 558 if (Interp::bot->userFunctions[commandName])
559 return SCM_BOOL_F;
cb21075d 560
561 // Next we check that needsChannel is a boolean
562 if (!gh_boolean_p(scm_needsChannel))
563 return SCM_BOOL_F;
e07b6b46 564 bool needsChannel = gh_scm2bool(scm_needsChannel);
cb21075d 565
566 // We check that minLevel is an integer and that it's
567 // a valid level
568 if (!SCM_NUMBERP(scm_minLevel))
569 return SCM_BOOL_F;
570
571 int minLevel = gh_scm2long(scm_minLevel);
572 if (minLevel < User::NONE || minLevel > User::MASTER)
573 return SCM_BOOL_F;
574
575 // We check that "scm_function" is a Scheme procedure
576 if (!gh_procedure_p(scm_function))
577 return SCM_BOOL_F;
578
579 // We check that args is an integer and is between 0 and 20 (arbitrary limit)
580 if (!SCM_NUMBERP(scm_args))
581 return SCM_BOOL_F;
582
583 int args = gh_scm2long(scm_args);
584 if (args < 0 || args > 20)
585 return SCM_BOOL_F;
586
587 // We add the command in the commands list
e07b6b46 588 Interp::bot->userFunctions[commandName] =
589 new userFunction(0, minLevel, needsChannel, args, scm_function);
590
cb21075d 591 return SCM_BOOL_T;
592}
593
594SCM
595ScriptCommands::delCommand(SCM scm_commandName)
596{
597 // We check that commandName is a string
598 if (!SCM_STRINGP(scm_commandName))
599 return SCM_BOOL_F;
600
601 // We check that the command does exist
a6339323 602 String commandName = Utils::to_upper (Utils::scm2str(scm_commandName));
e07b6b46 603 if (!Interp::bot->userFunctions[commandName])
cb21075d 604 return SCM_BOOL_F;
605
606 // We delete the command
e07b6b46 607 Interp::bot->userFunctions.erase(commandName);
cb21075d 608
609 return SCM_BOOL_T;
610}
611
612SCM
fd7440f1 613ScriptCommands::AddHook(SCM type, SCM regex, SCM function, SCM pri, SCM fall,
614 SCM name)
cb21075d 615{
616 int priority = 0;
439869bf 617 bool fallt = true; // does this hook fall through?
fd7440f1 618 String rname = "DEFAULT";
cb21075d 619
620 if (!SCM_UNBNDP (pri))
621 priority = scm_num2int (pri, SCM_ARG1, "ScriptCommands::AddHook");
622 if (!SCM_UNBNDP (fall))
623 fallt = SCM_NFALSEP (fall);
fd7440f1 624 if (!SCM_UNBNDP (name))
a6339323 625 rname = Utils::scm2str (name);
cb21075d 626 return SCM_BOOL (Interp::bot->botInterp->AddHook(gh_scm2long(type),
627 regex, function,
fd7440f1 628 priority, fallt, rname));
cb21075d 629}
630
631SCM
632ScriptCommands::AddTimer(SCM when, SCM function)
633{
634 return Interp::bot->botInterp->AddTimer(gh_scm2long(when), function);
635}
636
637SCM
638ScriptCommands::DelTimer(SCM timer)
639{
e07b6b46 640 return SCM_BOOL (Interp::bot->botInterp->DelTimer(timer));
641}
642
0b7a49e2 643SCM
644ScriptCommands::sendDCCChatMessage (SCM to, SCM message)
645{
646
647 return SCM_BOOL (Interp::bot->dccConnections->sendMessage
a6339323 648 (Utils::scm2str (to),
649 Utils::scm2str (message)));
0b7a49e2 650}
651
e07b6b46 652// Message sending
653// FIXME: write these
654
655#define IQUEUE Interp::bot->serverConnection->queue
656
657SCM
658ScriptCommands::sendCTCP(SCM to, SCM command , SCM message)
659{
660 VERIFY_STRING(to);
661 VERIFY_STRING(command);
662 VERIFY_STRING(message);
663
672b7d4e 664 Commands::CTCP (Interp::bot, Utils::scm2str (to),
665 Utils::scm2str (command),
666 Utils::scm2str (message));
6b7614a8 667
e07b6b46 668 return SCM_UNSPECIFIED;
cb21075d 669}
5aec4622 670
672b7d4e 671SCM
672ScriptCommands::sendCTCPReply (SCM to, SCM command , SCM message)
673{
674 VERIFY_STRING(to);
675 VERIFY_STRING(command);
676 VERIFY_STRING(message);
677
678 Commands::CTCPReply (Interp::bot, Utils::scm2str (to),
679 Utils::scm2str (command),
680 Utils::scm2str (message));
681
682 return SCM_UNSPECIFIED;
683}
684
685
cb21075d 686#endif