]> Pileus Git - ~andy/rhawk/blob - rhawk
Fix number regex again
[~andy/rhawk] / rhawk
1 #!awk -f
2
3 @include "irc.awk"
4 @include "json.awk"
5 @include "spades.awk"
6 #@include "email.awk"
7
8 # Initialization
9 BEGIN {
10         json_load("var/login.json",     login);
11         json_load("var/nounicode.json", nounicode);
12         json_load("var/nocolor.json",   nocolor);
13
14         OWNER = login["owner"];
15
16         connect(login["server"],  \
17                 login["nick"],    \
18                 login["channel"], \
19                 login["auth"],    \
20                 login["pass"])
21
22         delete login
23
24         if (FIRST) {
25                 join("#rhtest")
26                 join("#rhspades")
27                 join("#sfvlug")
28         }
29 }
30
31 # Admin
32 AUTH == OWNER && TO == NICK && /^die in a fire/ {
33         say("Ack, argh, barasdjf..")
34         quit()
35 }
36
37 AUTH == OWNER && TO == NICK && /^reload/ {
38         say("Reloading..")
39         reload()
40 }
41
42 AUTH == OWNER && TO == NICK && /^rejoin/ {
43         reply("joining..")
44         join("#rhnoise")
45         next
46 }
47
48 AUTH == OWNER && TO == NICK && /^(join|part)/ {
49         if (match(MSG, /(join|part) +(#+\w+)/, arr)) {
50                 if (arr[1] == "join") join(arr[2]);
51                 if (arr[1] == "part") part(arr[2]);
52                 next
53         }
54 }
55
56 AUTH == OWNER && TO == NICK && /^\.msg/ {
57         match(MSG, /.*\.msg +(#*\w+) +(.*)/, arr)
58         send("PRIVMSG " arr[1] " :" arr[2])
59 }
60
61 # Kick handling
62 CMD == "KICK" && ARG[2] == NICK {
63         kick_delay = (kick_delay + 2) * 2
64         system("sleep " kick_delay)
65         join(DST)
66         reply("I feel happy!")
67 }
68
69 # Identify bots
70 FROM ~ /bo+t$|rhnoise/ {
71         bots[FROM] = 1
72 }
73
74 CMD == "NICK" && FROM in bots {
75         bots[MSG] = FROM
76 }
77
78
79 # Fancy output
80 /[Uu]nicode :-?\(/ {
81         nounicode[FROM] = 1
82         json_save("var/nounicode.json", nounicode);
83 }
84
85 /[Uu]nicode :-?\)/ {
86         delete nounicode[FROM]
87         json_save("var/nounicode.json", nounicode);
88 }
89
90 /[Cc]olors :-?\(/ {
91         nocolor[FROM] = 1
92         json_save("var/nocolor.json", nocolor);
93 }
94
95 /[Cc]olors :-?\)/ {
96         delete nocolor[FROM]
97         json_save("var/nocolor.json", nocolor);
98 }
99
100 # SFV Lug
101 function email(to, from, subj, body, sendmail)
102 {
103         from     = NICK "<andy@pileus.org>"
104         subj     = "Update sfvlug.org!"
105         body     = "The next SFVLUG meeting is TBA!"
106         sendmail = "/usr/sbin/sendmail '" to "'"
107         print "To: " to        | sendmail
108         print "From: " from    | sendmail
109         print "Subject: " subj | sendmail
110         print ""               | sendmail
111         print body             | sendmail
112         say("Topic out of date, emailing " to);
113         close(sendmail)
114 }
115
116 BEGIN { pollchan = "#sfvlug" }
117 (CMD == "PING"    && systime()-lastpoll > 60*60*24) ||
118 (CMD == "PRIVMSG" && /^\.poll/) {
119         if (!TOPICS[pollchan]) {
120                 debug("Unknown topic for " pollchan);
121                 send("TOPIC " pollchan)
122                 next
123         }
124         _curl     = "curl -s http://sfvlug.org/"
125         _day      = "(Sun|Mon|Tue|Wed|Thu|Fri|Sat)"
126         _web_tba  = "next meeting is: TBA"
127         _web_ptrn = "next meeting.*" _day "\\w+[, ]+([A-Z]\\w+) +([0-9]+)[, ]+([0-9]+)"
128         _irc_ptrn = _day "\\w*[, ]+([A-Z]\\w+) +([0-9]+)"
129         while (_curl | getline _line) {
130                 #if (match(_line, _web_tba))
131                 #       email("Brian <brian@zimage.com>");
132                 if (match(_line, _web_ptrn, _parts)) {
133                         _date  = _parts[1] " " _parts[2] " " _parts[3]
134                         _topic = TOPICS[pollchan]
135                         sub(_irc_ptrn, _date, _topic)
136                         if (_topic != TOPICS[pollchan])
137                                 topic(pollchan, TOPICS[pollchan] = _topic)
138                         else
139                                 debug("topic is already correct")
140                         break
141                 }
142         }
143         lastpoll = systime()
144         close(_curl)
145 }
146
147 # Versin/Uptime
148 function head(cmd, var) {
149         cmd | getline var
150         close(cmd)
151         return var
152 }
153 function uptime(time,  fmt) {
154         fmt = "%d:%02d:%02d:%02d"
155         fmt = "%d days %02d:%02d:%02d"
156         return sprintf(fmt,
157                 time / (60*60*24),
158                 time / (60*60   ) % 24,
159                 time / (60      ) % 60,
160                 time / (1       ) % 60)
161 }
162 BEGIN {
163         up_version = head("git describe --always --dirty")
164         up_author  = head("git log -n1 --format=format:%an")
165         up_message = head("git log -n1 --format=format:%s")
166         up_reload  = systime();
167 }
168 /^\.(version|rev)/ {
169         say("version: " up_version " - " up_author " - " up_message)
170 }
171 /^\.uptime/ {
172         _now = systime();
173         say("uptime: " uptime(_now - START) ", " \
174             "reload: " uptime(_now - up_reload))
175 }
176
177 # Auth info
178 /^\.auth/ {
179         _who = $2 ? $2 : FROM
180         if (_who in USERS)
181                 say("nick=" USERS[_who]["nick"] " " \
182                     "user=" USERS[_who]["user"] " " \
183                     "auth=" USERS[_who]["auth"] " " \
184                     "real=" USERS[_who]["real"] " " \
185                     "host=" USERS[_who]["host"])
186         else
187                 say("no auth info for " _who)
188 }
189
190 # GeoIP Lookup
191 function geoip(ip,  dat, cmd, line, parts) {
192         dat = "/usr/share/GeoIP/GeoIPCity.dat"
193
194         cmd = "geoiplookup -f " dat " " ip
195         cmd | getline line
196         close(cmd)
197
198         if (split(line, parts, /[:,] /) >= 9)
199                 return parts[8] ","  parts[9] " -- " \
200                        parts[6] ", " parts[4] ", " parts[3]
201         else
202                 return "not found"
203 }
204
205 /^\.geoip (([0-9a-zA-Z_.-]+) *)*$/ {
206         for (_i=2; _i<=NF; _i++) {
207                 if ($_i in USERS)
208                         say(geoip(USERS[$_i]["host"]) " -- " \
209                             $_i " -> " USERS[$_i]["host"])
210                 else
211                         say(geoip($_i) " -- " $_i)
212         }
213 }
214
215 # Fortune
216 TO == NICK && /^/               { extra = ""   }
217 TO == NICK && /^\.?fortune.*-o/ { extra = "-o" }
218 TO == NICK && /^\.?fortune/     {
219         gsub(/.*\.?fortune *|-[a-z]* *|[^a-zA-Z0-9 ]/, "", MSG)
220         cmd = "fortune " extra " " (MSG ? "-m '" MSG "'" : "-s")
221         _lines = 0
222         while (cmd | getline _fortune && _lines < 5) {
223                 say(_fortune)
224                 _lines++
225         }
226         close(cmd)
227         next
228 }
229
230 /\<[Bb][Oo][Ff][Hh]\>/ {
231         _cmd = "fortune bofh-excuses"
232         _cmd | getline _fortune
233         _cmd | getline _fortune
234         _cmd | getline _fortune
235         close(_cmd)
236         say(_fortune)
237         next
238 }
239
240 # Morse code
241 BEGIN {
242         morse["/"      ] = " "
243         morse[".-.-.-" ] = "."
244         morse["--..--" ] = ","
245         morse["..--.." ] = "?"
246         morse[".----." ] = "'"
247         morse["-.-.--" ] = "!"
248         morse["-..-."  ] = "/"
249         morse["-.--."  ] = "("
250         morse["-.--.-" ] = ")"
251         morse[".-..."  ] = "&"
252         morse["---..." ] = ":"
253         morse["-.-.-." ] = ";"
254         morse["-...-"  ] = "="
255         morse[".-.-."  ] = "+"
256         morse["-....-" ] = "-"
257         morse["..--.-" ] = "_"
258         morse[".-..-." ] = "\""
259         morse["...-..-"] = "$"
260         morse[".--.-." ] = "@"
261         morse[".-"     ] = "a"
262         morse["-..."   ] = "b"
263         morse["-.-."   ] = "c"
264         morse["-.."    ] = "d"
265         morse["."      ] = "e"
266         morse["..-."   ] = "f"
267         morse["--."    ] = "g"
268         morse["...."   ] = "h"
269         morse[".."     ] = "i"
270         morse[".---"   ] = "j"
271         morse["-.-"    ] = "k"
272         morse[".-.."   ] = "l"
273         morse["--"     ] = "m"
274         morse["-."     ] = "n"
275         morse["---"    ] = "o"
276         morse[".--."   ] = "p"
277         morse["--.-"   ] = "q"
278         morse[".-."    ] = "r"
279         morse["..."    ] = "s"
280         morse["-"      ] = "t"
281         morse["..-"    ] = "u"
282         morse["...-"   ] = "v"
283         morse[".--"    ] = "w"
284         morse["-..-"   ] = "x"
285         morse["-.--"   ] = "y"
286         morse["--.."   ] = "z"
287         morse["-----"  ] = "0"
288         morse[".----"  ] = "1"
289         morse["..---"  ] = "2"
290         morse["...--"  ] = "3"
291         morse["....-"  ] = "4"
292         morse["....."  ] = "5"
293         morse["-...."  ] = "6"
294         morse["--..."  ] = "7"
295         morse["---.."  ] = "8"
296         morse["----."  ] = "9"
297 }
298
299 /^\.morse/ {
300         gsub(/[^.\-\/]/, " ")
301         _str = ""
302         for (i=2; i<=NF; i++)
303                 if ($i in morse)
304                         _str = _str morse[$i]
305         if (_str)
306                 reply(_str)
307         else
308                 reply("hush it, you pile of bologna")
309 }
310
311 # Noise
312 AUTH == OWNER && /^go go gadget woop/ {
313         for (i=20; i>0; i--)
314                 say(".delay " i " seconds; .woop " i)
315 }
316
317 function woop(msg) {
318         gsub(/[^Oo]/, "", $1)
319         _len = length($1)
320         if (_len == 2)
321                 _len = 10
322         if ($2)
323                 _len = $2
324         _woop = msg
325         for (i=1; i<_len; i++)
326                 _woop = _woop " " msg
327         say(_woop)
328 }
329
330 TO == NICK && /^[Ww][Oo]+[Pp] *([0-9]*)/ {
331         woop("WOOP")
332 }
333
334 /^~WOOP *([0-9]*)/ {
335         woop("(00/")
336 }
337
338 /^~woop *([0-9]*)/ {
339         woop("^H^P^P^O")
340 }
341
342 TO == NICK && DST ~ /^#/ {
343         #say("Hello, " FROM)
344 }
345
346 /^\.nestroyeti/ {
347         say(sprintf("Temperature: %4.1f F Humidity: %2d%%",
348                 rand()*20+65, rand()*20+40))
349 }
350
351 #DST != "#sfvlug" &&
352 !(FROM in bots) &&
353 CMD == "PRIVMSG" &&
354 MSG !~ /^\./ &&
355 /awk/ {
356         say("Awk, awk, awk! I'm a bird!")
357 }
358
359 !(FROM in bots) &&
360 ((TO == NICK && /(help|halp)/) ||
361  /^[^.](help|halp)/) {
362         reply("Nothing can help you now..")
363 }
364
365 /(\<[Hh][Oo]\>.*){3}/ {
366         say("\00309Merry \00304Christmas!")
367 }
368
369 !(FROM in bots) &&
370 tolower($0) ~ /\<cloud\>/ {
371         _cmd = "shuf clouds.txt"
372         _cmd | getline _cloud
373         close(_cmd)
374         say(_cloud)
375 }
376
377 /^headshot [Cc]hristmas/ {
378         say(".load Christmas")
379         say(".jingle")
380         say(".unload Christmas")
381 }
382
383 FROM == "rhnoise" && $2 == "slaps" && $3 == NICK {
384         say(".spin")
385 }
386
387 /^[Aa]nd now[.,]/ {
388         say("And now...");
389         say("THE LARCH");
390 }
391
392 /(for what|that for)\?$/ {
393         say("For great justice!");
394 }
395
396 /\<nazi/ {
397         say("And now it's...");
398         say("Springtime for Hitler and Germany!");
399 }
400
401 # God damn commands
402 FROM == "rhnoise" && load_mod {
403         say(".load " load_mod)
404         say("rhnoise: You slag!")
405 }
406 // {
407         load_mod = ""
408 }
409 (TO  ==  "rhnoise" && /^load \w+/) ||
410 (DST == "#rhniose" && /^\.load [a-z]\w+/) {
411         gsub(/[^a-zA-Z0-9_]/, " ")
412         load_mod = toupper(substr($2,1,1)) substr($2,2);
413 }
414
415 (DST == "#rhnoise" && /^\.line /) {
416         sub(/\./, "!");
417         say($0);
418         say("scalawag: You slag!")
419 }
420
421 (DST == "#rhnoise" && /^\.qdb 268$/) {
422         say(".diediedie");
423         next
424 }
425 (DST == "#rhnoise" && /\.qdb *268/) {
426         say(".slap " FROM);
427         next
428 }
429
430 # Decrementer
431 BEGIN {
432         user_scores[0] = 1;
433         delete user_scores
434 }
435
436 /^\.(scores|scoreboard)$/ {
437         delete user_scores
438 }
439
440 FROM == "rhnoise" && !length(user_scores) {
441         if (split(MSG, _parts, /, /)) {
442                 for (_i=1; _i<=length(_parts); _i++) {
443                         split(_parts[_i], _tmp, ": ");
444                         user_scores[_i]["user"]  = _tmp[1];
445                         user_scores[_i]["score"] = _tmp[2];
446                 }
447         }
448 }
449
450 length(user_scores) &&
451 tolower($0) ~ /\<nuclear launch detected\>/ {
452         _count = 0;
453         for (_i=1; _i<=length(user_scores); _i++) {
454                 _user  = user_scores[_i]["user"];
455                 _score = user_scores[_i]["score"];
456                 if (_user in USERS) continue
457                 if (_score ==  1) { say(_user "--"); _count++; }
458                 if (_score == -1) { say(_user "++"); _count++; }
459         }
460         if (_count) {
461                 delete user_scores;
462                 say(".scores");
463         } else {
464                 say("looks like you're safe.. for now..");
465         }
466 }
467
468 # Vote relay
469 DST != "#rhnoise" && /\<[a-zA-Z0-9_]{3,16}(\+\+|--)/ {
470         say("#rhnoise", "(" DST ") " FROM ": " MSG);
471 }
472
473 # Misc
474 { fflush("") }
475
476 # vim: ft=awk