1 // ScriptCommands.C -*- C++ -*-
2 // Copyright (c) 1998 Etienne BERNARD
3 // Copyright (C) 2002,2005 Clinton Ebadi
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
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA
28 #include "ServerList.H"
29 #include "ServerQueue.H"
30 #include "ScriptCommands.H"
32 #include "DCCPerson.H"
33 #include "DCCManager.H"
39 #define VERIFY_STRING(par) if (!SCM_STRINGP((par))) \
40 return scm_long2num(-17)
42 #define VERIFY_NUMBER(par) if (!SCM_NUMBERP((par))) \
43 return scm_long2num(-17)
46 ScriptCommands::Action(SCM channel, SCM message)
48 VERIFY_STRING(channel);
49 VERIFY_STRING(message);
50 Message m = Commands::Action(Interp::bot, Utils::scm2str(channel),
51 Utils::scm2str(message));
52 return scm_long2num(m.getCode());
56 ScriptCommands::AddUser(SCM who, SCM maskChannel, SCM level,
57 SCM prot, SCM aop, SCM expire, SCM password)
59 // It segfaults when not online, but otherwise appears to work
61 VERIFY_STRING (maskChannel);
62 VERIFY_NUMBER (level);
64 String wwho = Utils::scm2str (who);
65 String mask = Utils::scm2str (maskChannel);
69 if (SCM_UNBNDP (password))
73 VERIFY_STRING (password);
74 passwd = Utils::scm2str (password);
76 if (SCM_UNBNDP (expire))
80 VERIFY_STRING (expire);
81 eexpire = Utils::str2time (Utils::scm2str (expire));
82 if (!eexpire) eexpire = -1;
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");
90 Message m = Commands::AddUser (Interp::bot, wwho, mask, llevel,
91 protect, aaop, eexpire, passwd);
93 return scm_long2num(m.getCode ());
97 ScriptCommands::AddServer(SCM servername, SCM port)
100 if (SCM_NUMBERP(port))
101 p = scm_num2long(port, SCM_ARG1, "ScriptCommands::AddServer");
102 Message m = Commands::AddServer(Interp::bot,
103 Utils::scm2str(servername),
105 return scm_long2num(m.getCode());
109 ScriptCommands::AddShit(SCM mask, SCM maskChannel, SCM level,
110 SCM expiration, SCM reason)
112 // This appears to work...not much testing though
113 VERIFY_STRING (mask);
114 VERIFY_STRING (maskChannel);
115 VERIFY_NUMBER (level);
116 String mmask = Utils::scm2str (mask);
117 String mmaskChannel = Utils::scm2str (maskChannel);
118 int llevel = scm_num2int (level, SCM_ARG1, "ScriptCommands::AddShit");
122 if (SCM_UNBNDP (expiration))
126 VERIFY_STRING (expiration);
127 expire = Utils::str2time (Utils::scm2str (expiration));
128 if (!expire) expire = -1;
130 if (SCM_UNBNDP (reason))
131 rreason = "You're on my shitlist, lamer";
134 VERIFY_STRING (reason);
135 rreason = Utils::scm2str (reason);
137 Message m = Commands::AddShit (Interp::bot, mmask, mmaskChannel,
138 llevel, expire, rreason);
140 return scm_long2num(m.getCode ());
144 ScriptCommands::Ban(SCM channel, SCM who)
146 VERIFY_STRING(channel);
148 Message m = Commands::Ban(Interp::bot, Utils::scm2str(channel),
149 Utils::scm2str(who));
150 return scm_long2num(m.getCode());
154 ScriptCommands::ChangeCommandLevel(SCM command, SCM level)
156 VERIFY_STRING (command);
157 VERIFY_NUMBER (level);
159 SCM_STRING_COERCE_0TERMINATION_X (command);
160 std::string ccommand = SCM_STRING_CHARS (command);
161 unsigned int llevel = scm_num2uint
162 (level, 0, "ScriptCommands::ChangeCommandLevel");
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;
172 if (uf_iter != Interp::bot->userFunctions.end ())
177 f->minLevel = llevel;
182 ScriptCommands::CTCP(SCM to, SCM command , SCM message)
185 VERIFY_STRING(command);
186 VERIFY_STRING(message);
188 Commands::CTCP (Interp::bot, Utils::scm2str (to),
189 Utils::scm2str (command),
190 Utils::scm2str (message));
192 return SCM_UNSPECIFIED;
196 ScriptCommands::CTCPReply (SCM to, SCM command , SCM message)
199 VERIFY_STRING(command);
200 VERIFY_STRING(message);
202 Commands::CTCPReply (Interp::bot, Utils::scm2str (to),
203 Utils::scm2str (command),
204 Utils::scm2str (message));
206 return SCM_UNSPECIFIED;
210 ScriptCommands::Cycle(SCM channel)
212 VERIFY_STRING(channel);
213 Message m = Commands::Cycle(Interp::bot, Utils::scm2str(channel));
214 return scm_long2num(m.getCode());
218 ScriptCommands::Deban(SCM channel, SCM who)
220 VERIFY_STRING(channel);
222 Message m = Commands::Deban(Interp::bot, Utils::scm2str(channel),
223 Utils::scm2str(who));
224 return scm_long2num(m.getCode());
228 ScriptCommands::DelServer(SCM number)
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());
238 ScriptCommands::DelUser(SCM who, SCM maskChannel)
241 VERIFY_STRING(maskChannel);
242 Message m = Commands::DelUser(Interp::bot, Utils::scm2str(who),
243 Utils::scm2str(maskChannel));
244 return scm_long2num(m.getCode());
248 ScriptCommands::DelShit(SCM who, SCM maskChannel)
251 VERIFY_STRING(maskChannel);
252 Message m = Commands::DelShit(Interp::bot, Utils::scm2str(who),
253 Utils::scm2str(maskChannel));
254 return scm_long2num(m.getCode());
258 ScriptCommands::Deop(SCM channel, SCM who)
260 VERIFY_STRING(channel);
262 Message m = Commands::Deop(Interp::bot, Utils::scm2str(channel),
263 Utils::scm2str(who));
264 return scm_long2num(m.getCode());
268 ScriptCommands::Die(SCM reason)
270 String r = "Leaving";
271 if (SCM_STRINGP(reason))
272 r = Utils::scm2str(reason);
273 Message m = Commands::Die(Interp::bot, r);
274 return scm_long2num(m.getCode());
278 ScriptCommands::Do(SCM command)
280 VERIFY_STRING(command);
281 Message m = Commands::Do(Interp::bot, Utils::scm2str(command));
282 return scm_long2num(m.getCode());
286 ScriptCommands::Invite(SCM channel, SCM who)
288 VERIFY_STRING(channel);
290 Message m = Commands::Invite(Interp::bot, Utils::scm2str(channel),
291 Utils::scm2str(who));
292 return scm_long2num(m.getCode());
296 ScriptCommands::Join(SCM channel, SCM key)
298 VERIFY_STRING(channel);
300 if (SCM_STRINGP(key))
301 k = Utils::scm2str(key);
302 Message m = Commands::Join(Interp::bot, Utils::scm2str(channel),
304 return scm_long2num(m.getCode());
308 ScriptCommands::Keep(SCM channel, SCM modes)
310 VERIFY_STRING(channel);
311 VERIFY_STRING(modes);
312 Message m = Commands::Keep(Interp::bot, Utils::scm2str(channel),
313 Utils::scm2str(modes));
314 return scm_long2num(m.getCode());
318 ScriptCommands::Kick(SCM channel, SCM who, SCM reason)
320 VERIFY_STRING(channel);
324 if (SCM_STRINGP(reason))
325 r = Utils::scm2str(reason);
327 Message m = Commands::Kick(Interp::bot, Utils::scm2str(channel),
328 Utils::scm2str(who), r);
329 return scm_long2num(m.getCode());
333 ScriptCommands::KickBan(SCM channel, SCM who, SCM reason)
335 VERIFY_STRING(channel);
338 if (SCM_STRINGP(reason))
339 r = Utils::scm2str(reason);
340 Message m = Commands::KickBan(Interp::bot, Utils::scm2str(channel),
341 Utils::scm2str(who), r);
342 return scm_long2num(m.getCode());
346 ScriptCommands::Lock(SCM channel)
348 VERIFY_STRING(channel);
349 Message m = Commands::Lock(Interp::bot, Utils::scm2str(channel));
350 return scm_long2num(m.getCode());
354 ScriptCommands::LogPort(void)
356 return Interp::bot->botInterp->logPort;
360 ScriptCommands::Mode(SCM channel, SCM mode)
362 VERIFY_STRING(channel);
364 Message m = Commands::Mode(Interp::bot, Utils::scm2str(channel),
365 Utils::scm2str(mode));
366 return scm_long2num(m.getCode());
370 ScriptCommands::Msg(SCM nick, SCM message)
373 VERIFY_STRING(message);
374 Message m = Commands::Msg(Interp::bot, Utils::scm2str(nick),
375 Utils::scm2str(message));
376 return scm_long2num(m.getCode());
381 ScriptCommands::NextServer(void)
383 Message m = Commands::NextServer(Interp::bot);
384 return scm_long2num(m.getCode());
388 ScriptCommands::Nick(SCM nick)
391 Message m = Commands::Nick(Interp::bot, Utils::scm2str(nick));
392 return scm_long2num(m.getCode());
396 ScriptCommands::Notice (SCM to, SCM message)
399 VERIFY_STRING (message);
402 (Commands::Notice (Interp::bot,
404 Utils::scm2str (message)).getCode ()));
409 ScriptCommands::Op(SCM channel, SCM who)
411 VERIFY_STRING(channel);
413 Message m = Commands::Op(Interp::bot, Utils::scm2str(channel),
414 Utils::scm2str(who));
415 return scm_long2num(m.getCode());
419 ScriptCommands::Part(SCM channel)
421 VERIFY_STRING(channel);
422 Message m = Commands::Part(Interp::bot, Utils::scm2str(channel));
423 return scm_long2num(m.getCode());
427 ScriptCommands::Reconnect(void)
429 Message m = Commands::Reconnect(Interp::bot);
430 return scm_long2num(m.getCode());
434 ScriptCommands::Say(SCM channel, SCM message)
436 VERIFY_STRING(channel);
437 VERIFY_STRING(message);
438 Message m = Commands::Say(Interp::bot, Utils::scm2str(channel),
439 Utils::scm2str(message));
440 return scm_long2num(m.getCode());
444 ScriptCommands::Server(SCM number)
446 VERIFY_NUMBER(number);
447 Message m = Commands::Server(Interp::bot, gh_scm2long(number));
448 return scm_long2num(m.getCode());
452 ScriptCommands::SetFloodRate(SCM rate)
455 Message m = Commands::SetFloodRate(Interp::bot, scm_num2uint
456 (rate, 0, "SetFloodRate"));
457 return scm_long2num(m.getCode());
461 ScriptCommands::SetVersion(SCM version)
463 Message m = Commands::SetVersion(Interp::bot, Utils::scm2str(version));
464 return scm_long2num(m.getCode());
468 ScriptCommands::TBan(SCM channel, SCM who, SCM seconds)
470 VERIFY_STRING(channel);
472 VERIFY_NUMBER(seconds);
473 Message m = Commands::TBan(Interp::bot, Utils::scm2str(channel),
474 Utils::scm2str(who), gh_scm2long(seconds));
475 return scm_long2num(m.getCode());
479 ScriptCommands::TKBan(SCM channel, SCM who, SCM seconds, SCM reason)
481 VERIFY_STRING(channel);
483 VERIFY_NUMBER(seconds);
485 if (SCM_STRINGP(reason))
486 r = Utils::scm2str(reason);
487 Message m = Commands::TKBan(Interp::bot, Utils::scm2str(channel),
489 gh_scm2long(seconds), r);
490 return scm_long2num(m.getCode());
494 ScriptCommands::Topic(SCM channel, SCM topic)
496 VERIFY_STRING(channel);
497 VERIFY_STRING(topic);
498 Message m = Commands::Topic(Interp::bot, Utils::scm2str(channel),
499 Utils::scm2str(topic));
500 return scm_long2num(m.getCode());
504 ScriptCommands::Unlock(SCM channel)
506 VERIFY_STRING(channel);
507 Message m = Commands::Unlock(Interp::bot, Utils::scm2str(channel));
508 return scm_long2num(m.getCode());
512 ScriptCommands::Who (SCM target)
514 VERIFY_STRING (target);
516 Message m = Commands::Who (Interp::bot, Utils::scm2str (target));
518 return scm_long2num (m.getCode ());
522 ScriptCommands::Whois (SCM nick)
524 VERIFY_STRING (nick);
526 Message m = Commands::Whois (Interp::bot, Utils::scm2str (nick));
528 return scm_long2num (m.getCode ());
532 ScriptCommands::getNickname(void)
534 return Utils::str2scm(Interp::bot->nickName);
538 ScriptCommands::getServer(void)
540 ::Server *serv = Interp::bot->serverList->currentServer();
541 int serverNumber = Interp::bot->serverList->currentNumber;
543 return gh_list(scm_long2num(serverNumber),
544 Utils::str2scm(serv->getHostName()),
545 scm_long2num(serv->getPort()),
546 Utils::str2scm(serv->getPassword()),
551 ScriptCommands::getServerList(void)
553 SCM res = gh_list(SCM_UNDEFINED);
556 std::vector<class Server *>::iterator it =
557 Interp::bot->serverList->begin();
559 for ( ; it != Interp::bot->serverList->end(); ++it) {
561 res = gh_append2(res,
562 gh_list(gh_list(scm_long2num(i++),
563 Utils::str2scm(s->getHostName()),
564 scm_long2num(s->getPort()),
565 Utils::str2scm(s->getPassword()),
566 SCM_UNDEFINED), SCM_UNDEFINED));
572 ScriptCommands::flushQueue(void)
574 if (!Interp::bot->serverConnection)
576 Interp::bot->serverConnection->queue->flush();
581 ScriptCommands::flushPort(void)
583 scm_flush(Interp::bot->botInterp->logPort);
588 ScriptCommands::random(SCM scm_max)
592 if (SCM_NUMBERP(scm_max))
593 max = gh_scm2int(scm_max);
594 return scm_long2num(max ? rand() % max : 0);
598 ScriptCommands::addCommand(SCM scm_commandName, SCM scm_function,
599 SCM scm_needsChannel, SCM scm_args,
602 // We check that commandName is a string
603 if (!SCM_STRINGP(scm_commandName))
606 // We check that the command does not exist
607 String commandName = Utils::to_upper (Utils::scm2str(scm_commandName));
608 if (Interp::bot->userFunctions[commandName])
611 // Next we check that needsChannel is a boolean
612 if (!gh_boolean_p(scm_needsChannel))
614 bool needsChannel = gh_scm2bool(scm_needsChannel);
616 // We check that minLevel is an integer and that it's
618 if (!SCM_NUMBERP(scm_minLevel))
621 int minLevel = gh_scm2long(scm_minLevel);
622 if (minLevel < User::NONE || minLevel > User::MASTER)
625 // We check that "scm_function" is a Scheme procedure
626 if (!gh_procedure_p(scm_function))
629 // We check that args is an integer and is between 0 and 20 (arbitrary limit)
630 if (!SCM_NUMBERP(scm_args))
633 int args = gh_scm2long(scm_args);
634 if (args < 0 || args > 20)
637 // We add the command in the commands list
638 Interp::bot->userFunctions[commandName] =
639 new userFunction(0, minLevel, needsChannel, args, scm_function);
645 ScriptCommands::delCommand(SCM scm_commandName)
647 // We check that commandName is a string
648 if (!SCM_STRINGP(scm_commandName))
651 // We check that the command does exist
652 String commandName = Utils::to_upper (Utils::scm2str(scm_commandName));
653 if (!Interp::bot->userFunctions[commandName])
656 // We delete the command
657 Interp::bot->userFunctions.erase(commandName);
663 ScriptCommands::AddHook(SCM type, SCM regex, SCM function, SCM pri, SCM fall,
667 bool fallt = true; // does this hook fall through?
668 String rname = "DEFAULT";
670 if (!SCM_UNBNDP (pri))
671 priority = scm_num2int (pri, SCM_ARG1, "ScriptCommands::AddHook");
672 if (!SCM_UNBNDP (fall))
673 fallt = SCM_NFALSEP (fall);
674 if (!SCM_UNBNDP (name))
675 rname = Utils::scm2str (name);
676 return SCM_BOOL (Interp::bot->botInterp->AddHook(gh_scm2long(type),
678 priority, fallt, rname));
682 ScriptCommands::AddTimer(SCM when, SCM function)
684 return Interp::bot->botInterp->AddTimer(gh_scm2long(when), function);
688 ScriptCommands::DelTimer(SCM timer)
690 return SCM_BOOL (Interp::bot->botInterp->DelTimer(timer));
694 ScriptCommands::sendDCCChatMessage (SCM to, SCM message)
697 return SCM_BOOL (Interp::bot->dccConnections->sendMessage
698 (Utils::scm2str (to),
699 Utils::scm2str (message)));