chiark / gitweb /
topicedit: add a timeout; better error handling
[ircbot.git] / bridge.tcl
1 # Battle.net server bridge thingy
2
3 set helpfile bridgehelp
4 set bnbot_callervars {nicks}
5
6 source irccore.tcl
7 source parsecmd.tcl
8 source usebnbot.tcl
9 source stdhelp.tcl
10
11 proc privmsg_unlogged {p ischan params} {
12     global bots errorCode errorInfo line_org_endchar
13     if {$ischan} {
14         if {[catch {
15             prefix_nick
16             set text [lindex $params 1]
17             if {![string compare $line_org_endchar "\001"]} {
18                 if {[regexp {^\?ACTION (.*)\?$} $text dummy text]} {
19                     set towrite "* $n $text"
20                 } else {
21                     return
22                 }
23             } else {
24                 set towrite "\[$n] [lindex $params 1]"
25             }
26             foreach botid $bots {
27                 upvar #0 bot/$botid/chan ch
28                 puts $ch $towrite
29             }
30         } emsg]} {
31             log "error: $emsg $errorCode $errorInfo"
32         }
33         return 1
34     } else {
35         prefix_nick
36         execute_usercommand $p PRIVMSG $n $n \
37                 [lindex $params 0] [lindex $params 1]
38         return 0
39     }
40 }
41
42 proc connected {} {
43     global channel
44     sendout JOIN $channel
45 }
46
47 proc bnnick_clean {n} {
48     if {[regexp {^[-+_0-9a-zA-Z]} $n]} { return $n }
49     return "\"$n\"";
50 }
51
52 def_bnbot event {l} {
53     global channel errorCode
54     if {[regexp {^1002 JOIN ([^ ]+) \w+} $l dummy n]} {
55         set bnnicks($n) 1
56         sendprivmsg $channel "[bnnick_clean $n] has joined $bnchanfn."
57     } elseif {[regexp {^1003 LEAVE ([^ ]+) \w+$} $l dummy n]} {
58         if {![ircnick_compare $n $bnnick]} return
59         catch { unset bnnicks($n) }
60         sendprivmsg $channel "[bnnick_clean $n] has left $bnchanfn."
61     } elseif {[regexp {^1004 WHISPER ([^ ]+) \w+ "(.*)"$} $l dummy n text]} {
62         if {[catch {
63             go_usercommand "$botid $n" $bnchanfn $n $n $text
64         } rv]} {
65             if {"$errorCode" != "BLIGHT USER"} { set rv "error: $rv" }
66             bnbot_write $botid "/msg $n $rv"
67         } else {
68             set rvl {}
69             foreach mt $rv { lappend rvl [split $mt "\n"] }
70             manyset $rvl priv_msgs pub_msgs priv_acts pub_acts
71             foreach m $priv_acts { bnbot_write $botid "/msg $n The bot $m" }
72             foreach m $pub_acts { bnbot_write $botid "/me $m" }
73             foreach m $priv_msgs { bnbot_write $botid "/msg $n $m" }
74             foreach m $pub_msgs { bnbot_writemsg $botid "$n $m" }
75         }
76     } elseif {[regexp {^1001 USER ([^ ]+) \w+} $l dummy n]} {
77         if {![ircnick_compare $n $bnnick]} return
78         set bnnicks($n) 1
79     }
80 }
81
82 proc new_event {} {}
83
84 proc msg_353 {p c dest type chan nicklist} {
85     global onchan_nicks channel nick
86     catch { unset onchan_nicks }
87     foreach n $nicklist {
88         regsub {^[@+]} $n {} n
89         if {![ircnick_compare $n $nick]} continue
90         set onchan_nicks($n) 1
91     }
92 }
93
94 proc tellall {msg} {
95     global bots
96     foreach botid $bots { bnbot_writemsg $botid $msg }
97 }
98
99 proc msg_JOIN {p c chan} {
100     global onchan_nicks
101     prefix_nick
102     tellall "$n has joined $chan."
103     set onchan_nicks($n) 1
104 }
105
106 proc msg_NICK {p c newnick} {
107     global onchan_nicks
108     prefix_nick
109     kill_nick $n
110     set onchan_nicks($newnick) 1
111     tellall "$n has changed nicks to $newnick."
112 }
113
114 proc kill_nick {n} { global onchan_nicks; catch { unset onchan_nicks($n) } }
115
116 proc msg_KICK {p c chans users comment} {
117     foreach n [split $users ,] {
118         tellall "$user was kicked off $chans ($comment)"
119         kill_nick $n
120     }
121 }
122 proc msg_KILL {p c user why} {
123     tellall "$user was killed ($why)"
124     kill_nick $user
125 }
126 proc msg_PART {p c chan} {
127     prefix_nick
128     tellall "$n has left $chan."
129     kill_nick $n
130 }
131 proc msg_QUIT {p c why} {
132     prefix_nick
133     tellall "$n has signed off ($why)"
134     kill_nick $n
135 }
136
137 proc who_res {thing l} {
138     if {[llength $l]} {
139         return "$thing: [lsort -dictionary $l]"
140     } else {
141         return "$thing - empty."
142     }
143 }
144
145 def_bnbot who {} { who_res $bnchanfn [array names bnnicks] }
146
147 def_ucmd who {
148     global bots channel onchan_nicks
149     ta_nomore
150     set o [who_res "$channel (IRC)" [array names onchan_nicks]]
151     foreach botid $bots { append o "\n" [bnbot_who $botid] }
152     return [list $o]
153 }
154
155 if {[catch {
156     loadhelp
157     ensure_connecting
158     foreach botid $bots { bnbot_ensure_connecting $botid }
159 } emsg]} {
160     fail "startup: $emsg"
161 }