Giter VIP home page Giter VIP logo

goirc's People

Contributors

3onyc avatar boaz0 avatar bramp avatar cgt avatar dependabot[bot] avatar eviltwin avatar fluffle avatar gentux avatar gundalow avatar housek avatar iopred avatar jakebailey avatar jasonkeene avatar kidanger avatar krayons avatar momo-aux avatar nictuku avatar ostafen avatar shammash avatar slymas avatar soul9 avatar stalkr avatar stapelberg avatar stephan-gh avatar supertassu avatar sztanpet avatar tmcarr avatar wathiede avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

goirc's Issues

Can read messages but can't seem to send?

I've been trying to use this library with Twitch's IRC, and everything was going fine until I started trying to send messages.

My code is pretty much the same as the one in the client.go file, but changed to just take the input and send it as a privmsg to the channel.

	go func () {
		message := <- in
		fmt.Println(message)

		if message == "quit"{
			reallyquit = true
			c.Close()
		}

		c.Privmsg(channel, message)
	}()

channel is equal to "#silentserenity", and I've also tried it with just "#"

I can read all incoming messages, and when I input something the input is received and printed correctly, but the privmsg just doesn't seem to work.

Any help would be greatly appreciated, as I just can't seem to figure it out.

goirc disconnects (actively) after 5 minutes of inactivity

In issue #5, a default timeout of 5 minutes was introduced. The comment stated that there should be a PING within 5 minutes anyway. While it is probably true that most IRC servers are configured with a pingfreq of some value less than 5 minutes, this does not mean that there actually is a PING within 5 minutes:

At least with Unreal3.2.8.1, a ping will be sent after $pingfreq seconds of inactivity. I run a goirc bot on a server where pingfreq is 260. When the goirc bot posts a line, the server will register this is activity. Therefore, for 260 seconds, no PING will be sent. However, since this was a write and not a read, and the IRC connection is otherwise absolutely quiet, goirc will eventually run into a timeout, close the connection (the IRC server says "Client exited"), signal the error "irc.recv(): read tcp 127.0.0.1:6667: resource temporarily unavailable" and reconnect (due to my code). I can reliably reproduce this every time.

Therefore, I propose goirc sending a PING request to the server every 250 seconds (or whatever value you think is sufficient) to make the timeout not lead to a disconnect in situations like the one I described above. Unfortunately, I’m not very familiar with neither Go nor goirc’s code structure, otherwise I would have sent a pull request.

Thanks!

question only.

Hello, what will be the best practices to monitor for channel commands like !time or whatever new funtions I will like to add to a irc client/bot etc? basically best way to use your framework to monitor private chat and channel chat for bot commands.

Thanks.

state unit tests are failing

$ go test github.com/fluffle/goirc/state/...
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x4934e6]

goroutine 41 [running]:
github.com/fluffle/goirc/state.TestSTRaces.func2(0xc820010680, 0xc8200a6be0, 0xc8200a6ca0, 0x1)
    github.com/fluffle/goirc/state/tracker_test.go:582 +0x106
created by github.com/fluffle/goirc/state.TestSTRaces
    github.com/fluffle/goirc/state/tracker_test.go:584 +0x41e

State tracking is REALLY racey

If I run a client with state tracking enabled and GOMAXPROCS > 1, I get a lot of messages like this:

2013/05/23 09:01:37 state_handlers.go:167: WARN irc.352(): received WHO reply for unknown nick luz

Using the new race detector with go run -race main.go <opts> shows lots of races:

==================
WARNING: DATA RACE
Read by goroutine 15:
  github.com/neeee/goirc/client.(*Conn).h_433()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/handlers.go:72 +0x1a6
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 14:
  github.com/neeee/goirc/state.(*stateTracker).ReNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:86 +0x154
  github.com/neeee/goirc/client.(*Conn).h_433()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/handlers.go:74 +0x29c
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 15 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 14 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Read by goroutine 15:
  runtime.mapaccess2_faststr()
      /usr/lib/go/src/pkg/runtime/hashmap.c:473 +0x0
  github.com/neeee/goirc/state.(*stateTracker).ReNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:84 +0x80
  github.com/neeee/goirc/client.(*Conn).h_433()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/handlers.go:74 +0x29c
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 14:
  runtime.mapdelete()
      /usr/lib/go/src/pkg/runtime/hashmap.c:1307 +0x0
  github.com/neeee/goirc/state.(*stateTracker).ReNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:87 +0x1c0
  github.com/neeee/goirc/client.(*Conn).h_433()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/handlers.go:74 +0x29c
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 15 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 14 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Write by goroutine 19:
  github.com/neeee/goirc/state.(*Nick).ParseModes()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/nick.go:106 +0x2ef
  github.com/neeee/goirc/client.(*Conn).h_MODE()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:113 +0x56b
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 18:
  github.com/neeee/goirc/state.(*Nick).ParseModes()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/nick.go:106 +0x2ef
  github.com/neeee/goirc/client.(*Conn).h_MODE()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:113 +0x56b
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 19 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 18 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Write by goroutine 20:
  runtime.mapassign1()
      /usr/lib/go/src/pkg/runtime/hashmap.c:1289 +0x0
  github.com/neeee/goirc/state.(*Nick).addChannel()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/nick.go:71 +0xe3
  github.com/neeee/goirc/state.(*stateTracker).Associate()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:214 +0x3cd
  github.com/neeee/goirc/client.(*Conn).h_JOIN()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:79 +0x590
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous read by goroutine 14:
  runtime.mapiterinit()
      /usr/lib/go/src/pkg/runtime/hashmap.c:1356 +0x0
  github.com/neeee/goirc/state.(*stateTracker).ReNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:89 +0x259
  github.com/neeee/goirc/client.(*Conn).h_433()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/handlers.go:74 +0x29c
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 20 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 14 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Read by goroutine 21:
  runtime.mapaccess2_faststr()
      /usr/lib/go/src/pkg/runtime/hashmap.c:473 +0x0
  github.com/neeee/goirc/state.(*stateTracker).GetChannel()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:148 +0x60
  github.com/neeee/goirc/client.(*Conn).h_353()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:193 +0xd7
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 20:
  runtime.mapassign1()
      /usr/lib/go/src/pkg/runtime/hashmap.c:1289 +0x0
  github.com/neeee/goirc/state.(*stateTracker).NewChannel()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:142 +0x315
  github.com/neeee/goirc/client.(*Conn).h_JOIN()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:61 +0x3ac
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 21 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 20 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Read by goroutine 21:
  github.com/neeee/goirc/client.(*Conn).h_353()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:210 +0x35c
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 20:
  github.com/neeee/goirc/state.(*stateTracker).NewChannel()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:142 +0x1b2
  github.com/neeee/goirc/client.(*Conn).h_JOIN()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:61 +0x3ac
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 21 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 20 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Read by goroutine 21:
  github.com/neeee/goirc/state.(*Channel).addNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/channel.go:121 +0x3b
  github.com/neeee/goirc/state.(*stateTracker).Associate()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:213 +0x3a2
  github.com/neeee/goirc/client.(*Conn).h_353()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:213 +0x3f1
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 20:
  github.com/neeee/goirc/state.(*stateTracker).NewChannel()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:142 +0x1fe
  github.com/neeee/goirc/client.(*Conn).h_JOIN()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:61 +0x3ac
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 21 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 20 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Read by goroutine 21:
  runtime.mapaccess2_fast64()
      /usr/lib/go/src/pkg/runtime/hashmap.c:235 +0x0
  github.com/neeee/goirc/state.(*Channel).addNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/channel.go:121 +0x65
  github.com/neeee/goirc/state.(*stateTracker).Associate()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:213 +0x3a2
  github.com/neeee/goirc/client.(*Conn).h_353()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:213 +0x3f1
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 20:
  runtime.mapassign1()
      /usr/lib/go/src/pkg/runtime/hashmap.c:1289 +0x0
  github.com/neeee/goirc/state.(*Channel).addNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/channel.go:122 +0xe3
  github.com/neeee/goirc/state.(*stateTracker).Associate()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:213 +0x3a2
  github.com/neeee/goirc/client.(*Conn).h_JOIN()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:79 +0x590
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 21 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 20 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Read by goroutine 21:
  github.com/neeee/goirc/state.(*Channel).addNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/channel.go:123 +0xfa
  github.com/neeee/goirc/state.(*stateTracker).Associate()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:213 +0x3a2
  github.com/neeee/goirc/client.(*Conn).h_353()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:213 +0x3f1
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 20:
  github.com/neeee/goirc/state.(*stateTracker).NewChannel()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:142 +0x1eb
  github.com/neeee/goirc/client.(*Conn).h_JOIN()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:61 +0x3ac
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 21 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 20 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Write by goroutine 21:
  runtime.mapassign1()
      /usr/lib/go/src/pkg/runtime/hashmap.c:1289 +0x0
  github.com/neeee/goirc/state.(*Channel).addNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/channel.go:123 +0x141
  github.com/neeee/goirc/state.(*stateTracker).Associate()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:213 +0x3a2
  github.com/neeee/goirc/client.(*Conn).h_353()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:213 +0x3f1
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 20:
  runtime.mapassign1()
      /usr/lib/go/src/pkg/runtime/hashmap.c:1289 +0x0
  github.com/neeee/goirc/state.(*Channel).addNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/channel.go:123 +0x141
  github.com/neeee/goirc/state.(*stateTracker).Associate()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:213 +0x3a2
  github.com/neeee/goirc/client.(*Conn).h_JOIN()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:79 +0x590
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 21 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 20 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Write by goroutine 25:
  github.com/neeee/goirc/client.(*Conn).h_352()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:173 +0x274
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 21:
  github.com/neeee/goirc/state.(*stateTracker).NewNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:69 +0x1cb
  github.com/neeee/goirc/client.(*Conn).h_353()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:208 +0x32d
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 25 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 21 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Write by goroutine 25:
  github.com/neeee/goirc/client.(*Conn).h_352()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:174 +0x2fe
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 21:
  github.com/neeee/goirc/state.(*stateTracker).NewNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:69 +0x1de
  github.com/neeee/goirc/client.(*Conn).h_353()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:208 +0x32d
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 25 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 21 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Write by goroutine 25:
  github.com/neeee/goirc/client.(*Conn).h_352()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:179 +0x465
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 21:
  github.com/neeee/goirc/state.(*stateTracker).NewNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:69 +0x1f1
  github.com/neeee/goirc/client.(*Conn).h_353()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:208 +0x32d
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 25 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 21 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================
==================
WARNING: DATA RACE
Read by goroutine 25:
  github.com/neeee/goirc/client.(*Conn).h_352()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:184 +0x638
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Previous write by goroutine 21:
  github.com/neeee/goirc/state.(*stateTracker).NewNick()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/state/tracker.go:69 +0x204
  github.com/neeee/goirc/client.(*Conn).h_353()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/state_handlers.go:208 +0x32d
  github.com/neeee/goirc/client.HandlerFunc.Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:24 +0x41
  github.com/neeee/goirc/client.(*hNode).Handle()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:52 +0xb6
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 25 (running) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

Goroutine 21 (finished) created at:
  github.com/neeee/goirc/client.(*hSet).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:125 +0x171
  github.com/neeee/goirc/client.(*Conn).dispatch()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/dispatch.go:144 +0x58
  github.com/neeee/goirc/client.(*Conn).runLoop()
      /home/lucy/src/go/pkg/src/github.com/neeee/goirc/client/connection.go:298 +0x96
  gosched0()
      /usr/lib/go/src/pkg/runtime/proc.c:1224 +0x9f

==================

Client gets very confused when nickname is longer than NICKLEN

When a client is created with a nickname longer than the server's 005 NICKLEN, it does not understand that its username will be truncated by the server. This breaks any further nick-related operation because h_NICK() and h_433() do not recognize the truncated username.

The client should probably become aware of at least some 005 parameters, as suggested in

// XXX: do we need 005 protocol support message parsing here?

Incorrect CTCP line parsing

If I parse the following CTCP line:

":USER!EXAMPLE@server PRIVMSG tim :\x01HELLO WORLD\x01"

It produces the following *Line:

&Line{
    // ...
    Cmd:"CTCP",
    Raw:":USER!EXAMPLE@server PRIVMSG tim :\x01HELLO WORLD\x01",
    Args:[]string{"HELLO", "tim", "WORLD"},
    // ...
}

My thought would be that Line.Args should equal []string{"HELLO", "WORLD"}. Is this expected behaviour?

TestPing is unstable...

...for the reason you expected yourself according to your comments, the 49-51ms window to check for your ping is too tight.

go test github.com/fluffle/...
ok      github.com/fluffle/goevent/event        0.578s
?       github.com/fluffle/goirc        [no test files]
--- FAIL: TestPing (0.21s)
        connection_test.go:426: Line not output after another 2ms.
        connection_test.go:440: Line output after ping stopped.
FAIL
FAIL    github.com/fluffle/goirc/client 0.313s
?       github.com/fluffle/goirc/logging        [no test files]
?       github.com/fluffle/goirc/logging/glog   [no test files]
ok      github.com/fluffle/goirc/state  0.025s

So I'm creating the issue as detailed in the comments (connection_test.go l.422)

Deadlock on disconnect prevents reconnection

I'm trying to implement reconnection on disconnect, from the handler for the DISCONNECT event. After some frustration with not getting it to work, I narrowed it down to a problem in the shutdown sequence. Assuming the server goes away, the error will (among other possibilities) be detected in a write() call. The call sequence will be something like

conn.send() -> conn.write() -> conn.io.WriteString() [returns error] -> conn.shutdown()

conn.shutdown() will close the socket and signal the cSend, cLoop and cPing channels to stop those goroutines. However the send() routine is blocked in shutdown() from above, so the conn.cSend <- true in shutdown() will deadlock.

panic when PONG-ing on a dead channel

panic: runtime error: send on closed channel

runtime.panic+0xac /home/raylu/go/src/pkg/runtime/proc.c:1060
    runtime.panic(0x56e560, 0xf84016dbb0)
runtime.panicstring+0xa3 /home/raylu/go/src/pkg/runtime/runtime.c:116
    runtime.panicstring(0x6a39a0, 0xf84016a390)
runtime.chansend+0xc9 /home/raylu/go/src/pkg/runtime/chan.c:272
    runtime.chansend(0xf84003c000, 0x7f316cfe2f50, 0x0, 0xf8401057e0, 0xf800000021, ...)
runtime.chansend1+0x5b /home/raylu/go/src/pkg/runtime/chan.c:410
    runtime.chansend1(0xf84003c000, 0xf8401057e0)
github%2ecom/fluffle/goirc/client.*Conn·Raw+0x3d /home/raylu/rbot/client/commands.go:14
    github%2ecom/fluffle/goirc/client.*Conn·Raw(0xf84005d000, 0xf8401057e0, 0xf800000021, 0xf8401058a6)
github%2ecom/fluffle/goirc/client.*Conn·h_PING+0x70 /home/raylu/rbot/client/handlers.go:73
    github%2ecom/fluffle/goirc/client.*Conn·h_PING(0xf84005d000, 0xf84017a080, 0x0, 0x0)
runtime.goexit /home/raylu/go/src/pkg/runtime/proc.c:178
    runtime.goexit()
----- goroutine created by -----
github%2ecom/fluffle/goirc/client.*Conn·dispatchEvent+0x37d /home/raylu/rbot/client/handlers.go:66```

Invalid/expired certificate

When trying to connect to an IRC server with SSL, I get the following error:

Connection error x509: certificate has expired or is not yet valid: current time 2022-02-02T23:01:43-05:00 is after 2022-02-01T07:44:35Z

I suspect the issue might be with the library? I compiled my program, which uses goirc, on two, different operating systems, and I still get the error.

Any guidance would be appreciated.

messages are not escaped

currently messages are not escaped, thus
conn.Notice("asd", "I’m a troll\r\n\/quit")
will cause it to exit. If I understood the RFCs correctly \r or \n aren’t allowed except to end a message. Lines may also not exceed 512 chars including the cr-lf at the end.

None of this is currently checked. I can provide a patch, but I’m new to Go and not sure how this should be handled – i.e. silently omitting illegal characters or producing an error when invalid characters are given to one of the command functions?

fix is broken

On master branch:
$ go build ./fix
fix/goirc.go:16: undefined: register
fix/goirc.go:19: undefined: fix
fix/goirc.go:97: undefined: importSpec
fix/goirc.go:105: undefined: renameFixTab
fix/goirc.go:105: undefined: rename
fix/goirc.go:114: undefined: importSpec
fix/goirc.go:153: undefined: walk
fix/goirc.go:160: undefined: isPkgDot
fix/goirc.go:187: undefined: isPtrPkgDot
fix/goirc.go:194: undefined: isPkgDot
fix/goirc.go:194: too many errors

Doesn't build on weekly

I tried to fix it in a fork, but your build hierarchy is.... quite complex, and I wasn't able to figure it out.

Can you please fix for weekly, or (failing that) give me some easy instructions so that I can build a fork and thereby fix it myself (and supply a pull request)?

Conn:String method deadlock

case:

registered the "register" fg event, and then in the event handle call println(c.String()), the deadlock occus.

can use conn.connected var directly in Connected() ? no lock version.

and i also think, the fghandler will occus more deadlock.

Can I handle event RECONNECT?

I wrote a bot with goirc, and in the CONNECTED event, it joins a couple of rooms. But sometime the connection to irc server got break, and goirc will reconnect it, but cannot receive messages from these rooms anymore.

How could I catch and handle the RECONNECTED (if any) event, so that the bot can rejoin the rooms and receive messages?

Thanks!

ERROR message from the server is not handled

I had a client that was calling client.Connect() and was receiving irc.DISCONNECT events with a line that had no information. Once I turned on debug logging, I saw:

2016/11/17 09:18:04 connection.go:334: INFO irc.Connect(): Connecting to irc.example.com:6697.                                                                    2016/11/17 09:18:04 connection.go:343: INFO irc.Connect(): Performing SSL handshake.                                                                            2016/11/17 09:18:04 connection.go:483: DEBUG -> NICK fooey
2016/11/17 09:18:04 connection.go:418: DEBUG <- :irc.example.com NOTICE * :*** Looking up your hostname...
2016/11/17 09:18:04 connection.go:418: DEBUG <- :irc.example.com NOTICE * :*** Checking Ident                                                                    2016/11/17 09:18:04 connection.go:418: DEBUG <- :irc.example.com NOTICE * :*** Found your hostname
2016/11/17 09:18:04 connection.go:418: DEBUG <- :irc.example.com NOTICE * :*** No Ident response
2016/11/17 09:18:06 connection.go:483: DEBUG -> USER fooey 12 * :fooey
2016/11/17 09:18:06 connection.go:418: DEBUG <- ERROR :Closing Link: example.org (Too many user connections (global))
2016/11/17 09:18:06 connection.go:517: INFO irc.Close(): Disconnected from server.

It seems like ERROR responses are fairly well-defined? It is mentioned in https://en.wikipedia.org/wiki/List_of_Internet_Relay_Chat_commands#ERROR and in RFC 1459.

It'd be nice if these were handled by goirc automatically, with the ability for me to override a handler. (At the very least, it'd be nice if ERROR were one of the constants defined for message types.)

Unable to 'go get'

When trying to go get github.com/fluffle/goirc/client, it fails and reports the following:

# github.com/fluffle/goirc/client
../../fluffle/goirc/client/connection.go:303: undefined: tls.DialWithDialer

Allow rate limiting code to be changed.

The rate limit code is hard-coded for hybrid's algorithm currently. Other servers probably use different algorithms. Twitch's "IRC" server won't let you send more than 20 messages in 30 seconds, for example, amusingly this is less conservative than hybrid!

Allow registering a global handler

I'm working on a bot plugin framework and it would be useful to register a handler which gets all events so I can dispatch the events with a different handler type (so my own Bot object is available).

Add a way to choose how new nicknames are generated

Add a way to control how the replacement nicknames (for when a nickname is already in use) are generated. For example, one might want to use a completely different name instead of just adding an underscore.

Getting IRC Nicks

So I'm trying to get nicks via IRC and keep a live sync / feed of them in my system. Is this the proper way?

c := irc.Client(cfg)
c.EnableStateTracking()

c := conn.StateTracker().GetChannel(*channel)
if c == nil {
    log.Println("failed to get channel, skipping..")
    return
}

nicks := c.NicksStr()
fmt.Printf("adding %d nicks to monitor\n", len(nicks))

I also noticed that the GetChannel randomly returns empty.

I'm catching "366" and trying to catch after /names runs on a channel.

.connected should be exposed

In the example provided in the README.md, the connected variable mirrors the conn.connected variable so we might as well expose it. There also may be a race if it is not exposed.

install failed on go 1

This is probably pretty obvious, but it doesn't install on go1:

goinstall github.com/fluffle/goirc

goinstall doesn't exist anymore

The obvious change of "go install github.com/fluffle/goirc" didn't work either.

TLS issues not detected at connection time

Hi Alex,

I am playing with goirc/client. I have noticed that the Connect() method of Conn{} does not return an error upon TLS issues because the handshake happens only after the first read/write.

Could you please consider performing the handshake at connection time, so SSL issues are detected straight away?

This should be enough:

    if conn.cfg.SSL {
            logging.Info("irc.Connect(): Performing SSL handshake.")
            tls_conn := tls.Client(conn.sock, conn.cfg.SSLConfig)
            if err := tls_conn.Handshake(); err != nil {
                    return err
            }
            conn.sock = tls_conn
    }

Thank you,

Luca

Failing Reconnect

After the client is once connected and the state tracker does a WHO on all users, the conn.Me.Ident string is changed to "~" + identity if you're IDENT check failed.
After a disconnect and reconnect the IRC server rejects the connection because a '' is a illegal identity character.
You may change conn.User() to this:
func (conn *Conn) User(ident, name string) {
if strings.HasPrefix(ident, "
") {
ident = ident[1:]
}
conn.out <- "USER " + ident + " 12 * :" + name
}

NewNick handler needs a max length check

If you use the NewNick handler and return a nick with a length that's longer than 16 chars, the whole lib breaks, in particular the NAMES/353 responses no longer work and you get ghosts in your code.

Ask me how I know...

There should be a doc patch to mention this, and probably some sort of error propagation in here.

It's possible that 16 is a server specific limit-- I just found this empirically when using Freenode.

HTH's someone else.

strange issue with statetracker when connecting to miltiple servers

I get a weird problem when connecting to multiple servers: on one server everything looks fine, the client connects and joins channels and does it's business, but on the second server the client connects, seems to join the channel but does not show up on the channel list, and some other strangeness happens.

This is the log I've managed to extract from the problem:

nick.go:129] Nick.ParseModes(): unknown mode char Z
channel.go:233] Channel.ParseModes(): unknown mode char c
channel.go:233] Channel.ParseModes(): unknown mode char c

Edit: looks like +Z and +c is normal for freenode and goirc doesn't know what it means. This should not be the reason for the strange behaviour.

The order of the servers doesn't really look deterministic: sometimes it's one of the servers that behaves strangely, other times the other.

xdcc client

Hi, first of all, thank you for the library. I'm not sure if this is the right place for this.
I wrote an xdcc command line tool (based on this package) which allows to search and retrieve irc files in a user friendly way:
https://github.com/ostafen/xdcc-cli

I would appreciate if you could add a link to my client in a section reporting all the projects related to your IRC package.
Thank you in advance

disconnect event delay too much

when i reconnect my wifi, after about 260 seconds, another irc client see goirc deamon timeout.
but the goirc daemon emit disconnect event after about 15 minutes.
want to known is this normal?

Disconnected handler getting the connection in a still connected state

I would like to reconnect to the server in my DISCONNECT handler, but cannot do so because the connection is still in a connected state

Is this not how it is supposed to be done? Should I re-create the whole connection?

Forgot to add that I am using the master branch at HEAD (bf726bf)
(conn.String() and line.String() is racey when printing it from the DISCONNECT handler btw)

Allow user to close connection if server doesn't close after to QUIT.

It seems the only way to initiate a teardown of the connection is to call conn.Quit() which just sends the QUIT command to the server. If the server ignores this they can force connections to stay open until max file descriptors is hit. It would probably be best to send the QUIT command, wait for tcp close from the server, if it doesn't happen call Close on the net.Conn.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.