ref: 777033348977a2350f2a9d051f33711acabfc79e
parent: 46e3bc47f9e4e925efd9ad90455535b5a50d2c65
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Oct 17 06:15:32 EDT 2019
Improve usability, error handling.
--- a/irc.myr
+++ b/irc.myr
@@ -33,9 +33,6 @@
| `std.Ok 0: closed(irc, srv, "eof")
| `std.Ok n: srv.nbuf += n
;;
- if srv.death == 0
- srv.ping = std.now()
- ;;
while true
match nextln(irc, srv)
@@ -46,6 +43,8 @@
(src, cmd, args) = parse(ln)
a0 = args.len > 0 ? args[0] : ""
uppercase(cmd)
+ srv.ping = std.now()
+
match cmd
| "001": srvmsg(irc, args)
| "002": srvmsg(irc, args)
@@ -62,6 +61,7 @@
| "372": srvmsg(irc, args)
| "376": srvmsg(irc, args)
| "333": srvmsg(irc, args)
+ | "328": srvmsg(irc, args)
| "470": srvmsg(irc, args)
| "332": topic(irc, srv, args)
| "353": addusers(irc, srv, args)
@@ -69,6 +69,7 @@
| "PART": delchanuser(irc, srv, src, args)
| "366": shownames(irc, srv, args, 1)
| "401": badmsg(irc, srv, args, ln)
+ | "477": receivemsg(irc, srv, src, args.len > 0 ? args[1:] : args)
| "NOTICE": receivemsg(irc, srv, src, args)
| "PRIVMSG": receivemsg(irc, srv, src, args)
| "PING": send(irc, srv, "PONG :{}\r\n", a0)@@ -292,11 +293,20 @@
}
-const displayname = {src- match std.strfind(src, "!")
- | `std.Some i: -> src[:i]
- | `std.None: -> src
+const displayname = {s+ while true
+ match std.decode(s)
+ | '@': s = s[1:]
+ | '%': s = s[1:]
+ | '+': s = s[1:]
+ | '~': s = s[1:]
+ | _: break;
+ ;;
;;
+ match std.strfind(s, "!")
+ | `std.Some i: -> s[:i]
+ | `std.None: -> s
+ ;;
}
const freechan = {chan@@ -347,27 +357,40 @@
}
const changenick = {irc, args- if args.len != 1
+ var n, s
+
+ if args.len == 1
+ match cursrv(irc)
+ | `std.Some srv:
+ n = &srv.nick
+ s = srv.ds
+ | `std.None:
+ n = &irc.nick
+ s = "default"
+ ;;
+ elif args.len == 3
+ match findsrv(irc, args[2])
+ | `std.Some srv:
+ n = &srv.nick
+ s = srv.ds
+ | `std.None:
+ status(irc, irc.self, "no server '{}'", args[2])+ -> void
+ ;;
+ else
status(irc, irc.self, "/nick: invalid args {j= }", args)-> void
;;
- match cursrv(irc)
- | `std.None:
- std.slfree(irc.nick)
- irc.nick = std.sldup(args[0])
- status(irc, irc.self, "default nick changed: {}", args[0])- | `std.Some srv:
- std.slfree(irc.nick)
- srv.nick = std.sldup(args[0])
- send(irc, srv, "NICK {}\r\n", srv.nick)- status(irc, irc.self, "nick changed for {}: {}", srv.ds, args[0])- ;;
+
+ std.slfree(n#)
+ n# = std.sldup(args[0])
+ status(irc, irc.self, "{} changed to {}", s, n#)}
const changeuser = {irc, argsif args.len != 1
- status(irc, irc.self, "/nick: invalid args {j= }", args)+ status(irc, irc.self, "/user: invalid args {j= }", args)-> void
;;
@@ -384,7 +407,7 @@
const changeserver = {irc, argsif args.len != 1
- status(irc, irc.self, "/nick: invalid args {j= }", args)+ status(irc, irc.self, "/server: invalid args {j= }", args)-> void
;;
match findsrv(irc, args[0])
@@ -670,7 +693,7 @@
elif msg.len > 3 && std.eq(msg[1], "-srv")
match findsrv(irc, msg[2])
| `std.Some s: srv = s
- | `std.None: -> status(irc, irc.self, "can't message: no server '{}", msg[1])+ | `std.None: -> status(irc, irc.self, "can't message: no server '{}'", msg[2]);;
txt = std.fmt("{j= }", msg[3:])else
--- a/main.myr
+++ b/main.myr
@@ -46,17 +46,32 @@
elif fd >= 0
io(irc, fd)
;;
+ ping(irc)
redial(irc)
;;
}
+const ping = {irc+ for s : irc.srv
+ if s.death == 0 && (std.now() - s.ping) > 60*std.Sec
+ send(irc, s, "PING irc.myr")
+ /* let's not flood */
+ s.ping = std.now()
+ ;;
+ ;;
+}
+
const redial = {ircvar pingtime, droptime
for s : irc.srv
- droptime = std.now() - s.death
+ droptime = s.death == 0 ? 0 : std.now() - s.death
pingtime = std.now() - s.ping
- if pingtime < 600*std.Sec || s.death == 0 || droptime < 60*std.Sec
+ if droptime >= 60*std.Sec
+ status(irc, irc.self, "{}: connection dropped\n", s.ds)+ elif pingtime >= 300*std.Sec
+ status(irc, irc.self, "{}: ping timed out\n", s.ds)+ else
continue
;;
std.close(s.fd)
@@ -65,7 +80,7 @@
| `std.Ok fd:
s.fd = fd
handshake(irc, s)
- s.death = 0
+ s.death = std.now()
for c : irc.onconn
do(irc, c)
redraw(irc)
--
⑨