Make lots more happen in a script

Not only does message processing happen in a script, but you must launch an
external program to connect out.  This allows you to use netcat, socat, gnutls,
or whatever other crazy thing you come up with.
This commit is contained in:
Neale Pickett 2010-12-14 17:13:52 -07:00
parent 90d91a8979
commit c3bf9bb173
3 changed files with 155 additions and 30 deletions

116
bot.ml
View File

@ -1,7 +1,3 @@
type bot = {
store: Infobot.t;
}
let debug = prerr_endline let debug = prerr_endline
let file_descr_of_int (i:int) = let file_descr_of_int (i:int) =
@ -10,7 +6,6 @@ let file_descr_of_int (i:int) =
let write iobuf command args text = let write iobuf command args text =
let cmd = Command.create None command args text in let cmd = Command.create None command args text in
debug ("--> " ^ (Command.as_string cmd));
Iobuf.write iobuf cmd Iobuf.write iobuf cmd
let msg iobuf recip text = let msg iobuf recip text =
@ -48,11 +43,68 @@ let extern_callback iobuf sender forum text =
in in
f lines f lines
let handle_privmsg bot iobuf sender forum text = let nick_of_nuhost s =
if text.[0] == '.' then try
Irc.nick (Irc.nuhost_of_string s)
with Not_found ->
s
let handle_command outbuf handle_cmd thisbuf cmd =
let (prefix, command, args, trailing) = Command.as_tuple cmd in
let (sender, forum) =
match (prefix, command, args, trailing) with
| (Some suhost, "PRIVMSG", [target], _)
| (Some suhost, "NOTICE", [target], _) ->
let sender = nick_of_nuhost suhost in
let forum = if Irc.is_channel target then target else sender in
(sender, forum)
(* Here's why the IRC protocol blows: *)
| (Some suhost, "PART", [forum], _)
| (Some suhost, "JOIN", [forum], _)
| (Some suhost, "MODE", forum :: _, _)
| (Some suhost, "INVITE", _, Some forum)
| (Some suhost, "TOPIC", forum :: _, _)
| (Some suhost, "KICK", forum :: _, _) ->
(nick_of_nuhost suhost, forum)
| (Some suhost, "JOIN", [], Some chan) ->
(nick_of_nuhost suhost, chan)
| (Some _, "NICK", [sender], _) ->
(sender, sender)
| (Some suhost, "QUIT", _, _)
| (Some suhost, _, _, _) ->
let sender = nick_of_nuhost suhost in
(sender, sender)
| (_, "PING", _, Some text) ->
write outbuf "PONG" [] (Some text);
("", "")
| (None, _, _, _) ->
("", "")
in
let pfx =
match prefix with
| Some txt -> txt
| None -> ""
in
let text =
match trailing with
| Some txt -> txt
| None -> ""
in
let argv =
Array.append
[|handle_cmd; sender; forum; pfx; command|]
(Array.of_list args)
in
Process.create_canned Process.create_canned
(Iobuf.dispatcher iobuf) (Iobuf.dispatcher thisbuf)
text text
<<<<<<< master:bot.ml
(extern_callback iobuf sender forum) (extern_callback iobuf sender forum)
"./helper" "./helper"
[|"./helper"; sender; forum|] [|"./helper"; sender; forum|]
@ -79,6 +131,12 @@ let handle_command bot outbuf thisbuf cmd =
msg outbuf chan "hi asl" msg outbuf chan "hi asl"
| _ -> | _ ->
() ()
=======
(extern_callback outbuf sender forum)
handle_cmd
argv
>>>>>>> local:bot.ml
let discard_command iobuf cmd = () let discard_command iobuf cmd = ()
@ -86,6 +144,7 @@ let handle_error iobuf str =
prerr_endline ("!!! " ^ str) prerr_endline ("!!! " ^ str)
let main () = let main () =
<<<<<<< master:bot.ml
let bot = {store = Infobot.create "info.cdb"} in let bot = {store = Infobot.create "info.cdb"} in
let dispatcher = Dispatch.create () in let dispatcher = Dispatch.create () in
@ -93,19 +152,48 @@ let main () =
Process.spawn "socat" [|"socat"; Process.spawn "socat" [|"socat";
"STDIO"; "STDIO";
"OPENSSL:woozle.org:697,verify=0"|] "OPENSSL:woozle.org:697,verify=0"|]
=======
let handler = ref "/bin/true" in
let inputfn = ref "" in
let nick = ref "bot" in
let user = ref "bot" in
let mode = ref "+i" in
let realname = ref "I'm a little printf, short and stdout" in
let connect = ref [||] in
let append_connect s = connect := Array.append !connect [|s|] in
let speclist =
[
("-n", Arg.Set_string nick, "Nickname");
("-u", Arg.Set_string user, "Username");
("-m", Arg.Set_string mode, "Mode");
("-r", Arg.Set_string realname, "Real name");
("-a", Arg.Set_string handler, "IRC message handler");
("-i", Arg.Set_string inputfn, "Command FIFO");
]
>>>>>>> local:bot.ml
in in
let iobuf_out = Iobuf.create dispatcher conn_out "collab_out" let usage = "usage: bot [OPTIONS] CONNECT-COMMAND [ARGS ...]" in
Arg.parse speclist append_connect usage;
if (Array.length !connect) < 1 then begin
prerr_endline "Error: must specify connect command.";
prerr_endline "";
prerr_endline "Run with --help for usage information.";
exit 64 (* EX_USAGE *)
end;
let dispatcher = Dispatch.create () in
let conn_out, conn_in = Process.spawn (!connect).(0) !connect in
let iobuf_out = Iobuf.create dispatcher conn_out "out"
discard_command discard_command
handle_error handle_error
in in
let _ = Iobuf.create dispatcher conn_in "collab_in" let _ = Iobuf.create dispatcher conn_in "in"
(handle_command bot iobuf_out) (handle_command iobuf_out !handler)
handle_error handle_error
in in
write iobuf_out "NICK" ["zinc"] None; write iobuf_out "NICK" [!nick] None;
write iobuf_out "USER" ["zinc"; "zinc"; "zinc"] (Some "I'm a little printf, short and stdout"); write iobuf_out "USER" [!user; !mode; "merf"] (Some !realname);
Dispatch.run dispatcher Dispatch.run dispatcher
let _ = let _ =
main () main ()

View File

@ -8,7 +8,6 @@ let spawn prog args =
Unix.close fd0_exit; Unix.close fd0_exit;
Unix.dup2 fd1_entr Unix.stdout; Unix.dup2 fd1_entr Unix.stdout;
Unix.dup2 fd1_entr Unix.stderr;
Unix.close fd1_entr; Unix.close fd1_entr;
Unix.close fd1_exit; Unix.close fd1_exit;
@ -54,6 +53,8 @@ let canned_handler d p fd event =
p.finished (String.sub p.stdout 0 p.stdout_pos) p.finished (String.sub p.stdout 0 p.stdout_pos)
end end
| Dispatch.Output -> | Dispatch.Output ->
begin
try
let len = let len =
Unix.write fd p.stdin p.stdin_pos Unix.write fd p.stdin p.stdin_pos
((String.length p.stdin) - p.stdin_pos) ((String.length p.stdin) - p.stdin_pos)
@ -63,6 +64,10 @@ let canned_handler d p fd event =
Unix.close fd; Unix.close fd;
Dispatch.delete d fd Dispatch.delete d fd
end end
with Unix.Unix_error _ ->
Unix.close fd;
Dispatch.delete d fd
end
| Dispatch.Exception -> | Dispatch.Exception ->
() ()
@ -95,6 +100,9 @@ let rec sigchld s =
with Unix.Unix_error (Unix.ECHILD, _, _) -> with Unix.Unix_error (Unix.ECHILD, _, _) ->
() ()
let _ = let sigpipe s = ()
Sys.set_signal Sys.sigchld (Sys.Signal_handle sigchld)
let _ =
Sys.set_signal Sys.sigchld (Sys.Signal_handle sigchld);
Sys.set_signal Sys.sigpipe (Sys.Signal_handle sigpipe)

29
rollforinitiative.py Executable file
View File

@ -0,0 +1,29 @@
#!/usr/bin/env python
import re
import sys
import random
if __name__ == '__main__':
roll = sys.argv[1]
m = re.match('^(?P<rolls>\d+)d(?P<sides>\d+)(x(?P<multiplier>\d+))?$', roll)
if m:
rolls = int(m.group('rolls'))
sides = int(m.group('sides'))
if m.group('multiplier'):
multiplier = int(m.group('multiplier'))
else:
multiplier = 1
dice = []
acc = 0
for i in range(rolls):
n = random.randint(1, sides)
dice.append(n)
acc += n
acc *= multiplier
if rolls > 1:
print '%s: %d %r' % (roll, acc, dice)
else:
print '%s: %d' % (roll, acc)