[project @ 2005-07-07 21:19:26 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);
c6e7af05 161 unsigned int llevel = scm_num2uint
162 (level, 0, "ScriptCommands::ChangeCommandLevel");
4edefeb6 163
164 if (llevel > 4)
165 return SCM_BOOL_F;
166
167 std::map<std::string, class userFunction*,
168 std::less<std::string> >::const_iterator uf_iter
169 = Interp::bot->userFunctions.find (ccommand);
170 userFunction * f = 0;
171
172 if (uf_iter != Interp::bot->userFunctions.end ())
173 f = uf_iter->second;
174 else
175 return SCM_BOOL_F;
176
177 f->minLevel = llevel;
178 return SCM_BOOL_T;
179}
180
c6e7af05 181SCM
182ScriptCommands::CTCP(SCM to, SCM command , SCM message)
183{
184 VERIFY_STRING(to);
185 VERIFY_STRING(command);
186 VERIFY_STRING(message);
187
188 Commands::CTCP (Interp::bot, Utils::scm2str (to),
189 Utils::scm2str (command),
190 Utils::scm2str (message));
191
192 return SCM_UNSPECIFIED;
193}
194
195SCM
196ScriptCommands::CTCPReply (SCM to, SCM command , SCM message)
197{
198 VERIFY_STRING(to);
199 VERIFY_STRING(command);
200 VERIFY_STRING(message);
201
202 Commands::CTCPReply (Interp::bot, Utils::scm2str (to),
203 Utils::scm2str (command),
204 Utils::scm2str (message));
205
206 return SCM_UNSPECIFIED;
207}
208
cb21075d 209SCM
210ScriptCommands::Cycle(SCM channel)
211{
212 VERIFY_STRING(channel);
a6339323 213 Message m = Commands::Cycle(Interp::bot, Utils::scm2str(channel));
cb21075d 214 return scm_long2num(m.getCode());
215}
216
217SCM
218ScriptCommands::Deban(SCM channel, SCM who)
219{
220 VERIFY_STRING(channel);
221 VERIFY_STRING(who);
a6339323 222 Message m = Commands::Deban(Interp::bot, Utils::scm2str(channel),
223 Utils::scm2str(who));
cb21075d 224 return scm_long2num(m.getCode());
225}
226
227SCM
228ScriptCommands::DelServer(SCM number)
229{
230 VERIFY_NUMBER(number);
231 Message m = Commands::DelServer(Interp::bot,
232 scm_num2long(number, SCM_ARG1,
233 "ScriptCommands::DelServer"));
234 return scm_long2num(m.getCode());
235}
236
237SCM
238ScriptCommands::DelUser(SCM who, SCM maskChannel)
239{
240 VERIFY_STRING(who);
241 VERIFY_STRING(maskChannel);
a6339323 242 Message m = Commands::DelUser(Interp::bot, Utils::scm2str(who),
243 Utils::scm2str(maskChannel));
cb21075d 244 return scm_long2num(m.getCode());
245}
246
247SCM
248ScriptCommands::DelShit(SCM who, SCM maskChannel)
249{
250 VERIFY_STRING(who);
251 VERIFY_STRING(maskChannel);
a6339323 252 Message m = Commands::DelShit(Interp::bot, Utils::scm2str(who),
253 Utils::scm2str(maskChannel));
cb21075d 254 return scm_long2num(m.getCode());
255}
256
257SCM
258ScriptCommands::Deop(SCM channel, SCM who)
259{
260 VERIFY_STRING(channel);
261 VERIFY_STRING(who);
a6339323 262 Message m = Commands::Deop(Interp::bot, Utils::scm2str(channel),
263 Utils::scm2str(who));
cb21075d 264 return scm_long2num(m.getCode());
265}
266
267SCM
268ScriptCommands::Die(SCM reason)
269{
270 String r = "Leaving";
271 if (SCM_STRINGP(reason))
a6339323 272 r = Utils::scm2str(reason);
cb21075d 273 Message m = Commands::Die(Interp::bot, r);
274 return scm_long2num(m.getCode());
275}
276
277SCM
278ScriptCommands::Do(SCM command)
279{
280 VERIFY_STRING(command);
a6339323 281 Message m = Commands::Do(Interp::bot, Utils::scm2str(command));
cb21075d 282 return scm_long2num(m.getCode());
283}
284
285SCM
286ScriptCommands::Invite(SCM channel, SCM who)
287{
288 VERIFY_STRING(channel);
289 VERIFY_STRING(who);
a6339323 290 Message m = Commands::Invite(Interp::bot, Utils::scm2str(channel),
291 Utils::scm2str(who));
cb21075d 292 return scm_long2num(m.getCode());
293}
294
295SCM
296ScriptCommands::Join(SCM channel, SCM key)
297{
298 VERIFY_STRING(channel);
299 String k = "";
300 if (SCM_STRINGP(key))
a6339323 301 k = Utils::scm2str(key);
302 Message m = Commands::Join(Interp::bot, Utils::scm2str(channel),
cb21075d 303 k);
304 return scm_long2num(m.getCode());
305}
306
307SCM
308ScriptCommands::Keep(SCM channel, SCM modes)
309{
310 VERIFY_STRING(channel);
311 VERIFY_STRING(modes);
a6339323 312 Message m = Commands::Keep(Interp::bot, Utils::scm2str(channel),
313 Utils::scm2str(modes));
cb21075d 314 return scm_long2num(m.getCode());
315}
316
317SCM
318ScriptCommands::Kick(SCM channel, SCM who, SCM reason)
319{
320 VERIFY_STRING(channel);
321 VERIFY_STRING(who);
322
323 String r = "";
324 if (SCM_STRINGP(reason))
a6339323 325 r = Utils::scm2str(reason);
cb21075d 326
a6339323 327 Message m = Commands::Kick(Interp::bot, Utils::scm2str(channel),
328 Utils::scm2str(who), r);
cb21075d 329 return scm_long2num(m.getCode());
330}
331
332SCM
333ScriptCommands::KickBan(SCM channel, SCM who, SCM reason)
334{
335 VERIFY_STRING(channel);
336 VERIFY_STRING(who);
337 String r = "";
338 if (SCM_STRINGP(reason))
a6339323 339 r = Utils::scm2str(reason);
340 Message m = Commands::KickBan(Interp::bot, Utils::scm2str(channel),
341 Utils::scm2str(who), r);
cb21075d 342 return scm_long2num(m.getCode());
343}
344
345SCM
346ScriptCommands::Lock(SCM channel)
347{
348 VERIFY_STRING(channel);
a6339323 349 Message m = Commands::Lock(Interp::bot, Utils::scm2str(channel));
cb21075d 350 return scm_long2num(m.getCode());
351}
352
353SCM
354ScriptCommands::LogPort(void)
355{
356 return Interp::bot->botInterp->logPort;
357}
358
359SCM
360ScriptCommands::Mode(SCM channel, SCM mode)
361{
362 VERIFY_STRING(channel);
363 VERIFY_STRING(mode);
a6339323 364 Message m = Commands::Mode(Interp::bot, Utils::scm2str(channel),
365 Utils::scm2str(mode));
cb21075d 366 return scm_long2num(m.getCode());
367}
368
369SCM
370ScriptCommands::Msg(SCM nick, SCM message)
371{
372 VERIFY_STRING(nick);
373 VERIFY_STRING(message);
a6339323 374 Message m = Commands::Msg(Interp::bot, Utils::scm2str(nick),
375 Utils::scm2str(message));
cb21075d 376 return scm_long2num(m.getCode());
377
378}
379
380SCM
381ScriptCommands::NextServer(void)
382{
383 Message m = Commands::NextServer(Interp::bot);
384 return scm_long2num(m.getCode());
385}
386
387SCM
388ScriptCommands::Nick(SCM nick)
389{
390 VERIFY_STRING(nick);
a6339323 391 Message m = Commands::Nick(Interp::bot, Utils::scm2str(nick));
cb21075d 392 return scm_long2num(m.getCode());
393}
394
c99c411a 395SCM
396ScriptCommands::Notice (SCM to, SCM message)
397{
398 VERIFY_STRING (to);
399 VERIFY_STRING (message);
400
401 return (scm_long2num
402 (Commands::Notice (Interp::bot,
403 Utils::scm2str (to),
404 Utils::scm2str (message)).getCode ()));
405
406}
407
cb21075d 408SCM
409ScriptCommands::Op(SCM channel, SCM who)
410{
411 VERIFY_STRING(channel);
412 VERIFY_STRING(who);
a6339323 413 Message m = Commands::Op(Interp::bot, Utils::scm2str(channel),
414 Utils::scm2str(who));
cb21075d 415 return scm_long2num(m.getCode());
416}
417
418SCM
419ScriptCommands::Part(SCM channel)
420{
421 VERIFY_STRING(channel);
a6339323 422 Message m = Commands::Part(Interp::bot, Utils::scm2str(channel));
cb21075d 423 return scm_long2num(m.getCode());
424}
425
426SCM
427ScriptCommands::Reconnect(void)
428{
429 Message m = Commands::Reconnect(Interp::bot);
430 return scm_long2num(m.getCode());
431}
432
433SCM
434ScriptCommands::Say(SCM channel, SCM message)
435{
436 VERIFY_STRING(channel);
437 VERIFY_STRING(message);
a6339323 438 Message m = Commands::Say(Interp::bot, Utils::scm2str(channel),
439 Utils::scm2str(message));
cb21075d 440 return scm_long2num(m.getCode());
441}
442
443SCM
444ScriptCommands::Server(SCM number)
445{
446 VERIFY_NUMBER(number);
447 Message m = Commands::Server(Interp::bot, gh_scm2long(number));
448 return scm_long2num(m.getCode());
449}
450
e171dcce 451SCM
452ScriptCommands::SetFloodRate(SCM rate)
453{
454 VERIFY_NUMBER(rate);
455 Message m = Commands::SetFloodRate(Interp::bot, scm_num2uint
456 (rate, 0, "SetFloodRate"));
457 return scm_long2num(m.getCode());
458}
459
cb21075d 460SCM
461ScriptCommands::SetVersion(SCM version)
462{
a6339323 463 Message m = Commands::SetVersion(Interp::bot, Utils::scm2str(version));
cb21075d 464 return scm_long2num(m.getCode());
465}
466
467SCM
468ScriptCommands::TBan(SCM channel, SCM who, SCM seconds)
469{
470 VERIFY_STRING(channel);
471 VERIFY_STRING(who);
472 VERIFY_NUMBER(seconds);
a6339323 473 Message m = Commands::TBan(Interp::bot, Utils::scm2str(channel),
474 Utils::scm2str(who), gh_scm2long(seconds));
cb21075d 475 return scm_long2num(m.getCode());
476}
477
478SCM
479ScriptCommands::TKBan(SCM channel, SCM who, SCM seconds, SCM reason)
480{
481 VERIFY_STRING(channel);
482 VERIFY_STRING(who);
483 VERIFY_NUMBER(seconds);
484 String r = "";
485 if (SCM_STRINGP(reason))
a6339323 486 r = Utils::scm2str(reason);
487 Message m = Commands::TKBan(Interp::bot, Utils::scm2str(channel),
488 Utils::scm2str(who),
cb21075d 489 gh_scm2long(seconds), r);
490 return scm_long2num(m.getCode());
491}
492
493SCM
494ScriptCommands::Topic(SCM channel, SCM topic)
495{
496 VERIFY_STRING(channel);
497 VERIFY_STRING(topic);
a6339323 498 Message m = Commands::Topic(Interp::bot, Utils::scm2str(channel),
499 Utils::scm2str(topic));
cb21075d 500 return scm_long2num(m.getCode());
501}
502
503SCM
504ScriptCommands::Unlock(SCM channel)
505{
506 VERIFY_STRING(channel);
a6339323 507 Message m = Commands::Unlock(Interp::bot, Utils::scm2str(channel));
cb21075d 508 return scm_long2num(m.getCode());
509}
510
c6e7af05 511SCM
512ScriptCommands::Who (SCM target)
513{
514 VERIFY_STRING (target);
515
516 Message m = Commands::Who (Interp::bot, Utils::scm2str (target));
517
518 return scm_long2num (m.getCode ());
519}
520
521SCM
522ScriptCommands::Whois (SCM nick)
523{
524 VERIFY_STRING (nick);
525
526 Message m = Commands::Whois (Interp::bot, Utils::scm2str (nick));
527
528 return scm_long2num (m.getCode ());
529}
530
cb21075d 531SCM
532ScriptCommands::getNickname(void)
533{
a6339323 534 return Utils::str2scm(Interp::bot->nickName);
cb21075d 535}
536
537SCM
538ScriptCommands::getServer(void)
539{
540 ::Server *serv = Interp::bot->serverList->currentServer();
541 int serverNumber = Interp::bot->serverList->currentNumber;
542
543 return gh_list(scm_long2num(serverNumber),
a6339323 544 Utils::str2scm(serv->getHostName()),
cb21075d 545 scm_long2num(serv->getPort()),
a6339323 546 Utils::str2scm(serv->getPassword()),
cb21075d 547 SCM_UNDEFINED);
548}
549
550SCM
551ScriptCommands::getServerList(void)
552{
553 SCM res = gh_list(SCM_UNDEFINED);
554 ::Server *s;
555 int i = 0;
528799bd 556 std::vector<class Server *>::iterator it =
557 Interp::bot->serverList->begin();
cb21075d 558
559 for ( ; it != Interp::bot->serverList->end(); ++it) {
560 s = (*it);
561 res = gh_append2(res,
562 gh_list(gh_list(scm_long2num(i++),
a6339323 563 Utils::str2scm(s->getHostName()),
cb21075d 564 scm_long2num(s->getPort()),
a6339323 565 Utils::str2scm(s->getPassword()),
cb21075d 566 SCM_UNDEFINED), SCM_UNDEFINED));
567 }
568 return res;
569}
570
571SCM
572ScriptCommands::flushQueue(void)
573{
574 if (!Interp::bot->serverConnection)
575 return SCM_BOOL_F;
576 Interp::bot->serverConnection->queue->flush();
577 return SCM_BOOL_T;
578}
579
580SCM
581ScriptCommands::flushPort(void)
582{
583 scm_flush(Interp::bot->botInterp->logPort);
584 return SCM_BOOL_T;
585}
586
587SCM
588ScriptCommands::random(SCM scm_max)
589{
590 int max = 0;
591 //srand(time(NULL));
592 if (SCM_NUMBERP(scm_max))
593 max = gh_scm2int(scm_max);
594 return scm_long2num(max ? rand() % max : 0);
595}
596
597SCM
598ScriptCommands::addCommand(SCM scm_commandName, SCM scm_function,
599 SCM scm_needsChannel, SCM scm_args,
600 SCM scm_minLevel)
601{
602 // We check that commandName is a string
603 if (!SCM_STRINGP(scm_commandName))
604 return SCM_BOOL_F;
605
606 // We check that the command does not exist
a6339323 607 String commandName = Utils::to_upper (Utils::scm2str(scm_commandName));
e07b6b46 608 if (Interp::bot->userFunctions[commandName])
609 return SCM_BOOL_F;
cb21075d 610
611 // Next we check that needsChannel is a boolean
612 if (!gh_boolean_p(scm_needsChannel))
613 return SCM_BOOL_F;
e07b6b46 614 bool needsChannel = gh_scm2bool(scm_needsChannel);
cb21075d 615
616 // We check that minLevel is an integer and that it's
617 // a valid level
618 if (!SCM_NUMBERP(scm_minLevel))
619 return SCM_BOOL_F;
620
621 int minLevel = gh_scm2long(scm_minLevel);
622 if (minLevel < User::NONE || minLevel > User::MASTER)
623 return SCM_BOOL_F;
624
625 // We check that "scm_function" is a Scheme procedure
626 if (!gh_procedure_p(scm_function))
627 return SCM_BOOL_F;
628
629 // We check that args is an integer and is between 0 and 20 (arbitrary limit)
630 if (!SCM_NUMBERP(scm_args))
631 return SCM_BOOL_F;
632
633 int args = gh_scm2long(scm_args);
634 if (args < 0 || args > 20)
635 return SCM_BOOL_F;
636
637 // We add the command in the commands list
e07b6b46 638 Interp::bot->userFunctions[commandName] =
639 new userFunction(0, minLevel, needsChannel, args, scm_function);
640
cb21075d 641 return SCM_BOOL_T;
642}
643
644SCM
645ScriptCommands::delCommand(SCM scm_commandName)
646{
647 // We check that commandName is a string
648 if (!SCM_STRINGP(scm_commandName))
649 return SCM_BOOL_F;
650
651 // We check that the command does exist
a6339323 652 String commandName = Utils::to_upper (Utils::scm2str(scm_commandName));
e07b6b46 653 if (!Interp::bot->userFunctions[commandName])
cb21075d 654 return SCM_BOOL_F;
655
656 // We delete the command
e07b6b46 657 Interp::bot->userFunctions.erase(commandName);
cb21075d 658
659 return SCM_BOOL_T;
660}
661
662SCM
fd7440f1 663ScriptCommands::AddHook(SCM type, SCM regex, SCM function, SCM pri, SCM fall,
664 SCM name)
cb21075d 665{
666 int priority = 0;
439869bf 667 bool fallt = true; // does this hook fall through?
fd7440f1 668 String rname = "DEFAULT";
cb21075d 669
670 if (!SCM_UNBNDP (pri))
671 priority = scm_num2int (pri, SCM_ARG1, "ScriptCommands::AddHook");
672 if (!SCM_UNBNDP (fall))
673 fallt = SCM_NFALSEP (fall);
fd7440f1 674 if (!SCM_UNBNDP (name))
a6339323 675 rname = Utils::scm2str (name);
cb21075d 676 return SCM_BOOL (Interp::bot->botInterp->AddHook(gh_scm2long(type),
677 regex, function,
fd7440f1 678 priority, fallt, rname));
cb21075d 679}
680
681SCM
682ScriptCommands::AddTimer(SCM when, SCM function)
683{
684 return Interp::bot->botInterp->AddTimer(gh_scm2long(when), function);
685}
686
687SCM
688ScriptCommands::DelTimer(SCM timer)
689{
e07b6b46 690 return SCM_BOOL (Interp::bot->botInterp->DelTimer(timer));
691}
692
0b7a49e2 693SCM
694ScriptCommands::sendDCCChatMessage (SCM to, SCM message)
695{
696
697 return SCM_BOOL (Interp::bot->dccConnections->sendMessage
a6339323 698 (Utils::scm2str (to),
699 Utils::scm2str (message)));
0b7a49e2 700}
701
e07b6b46 702
e07b6b46 703
6b7614a8 704
672b7d4e 705
706
cb21075d 707#endif