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