-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue 75: IMPLEMENT NAMES sendraw and 353 and 366 callbacks #76
Conversation
A few things:
|
The GetNicksOnChan function is so the client can trigger RPL_NAMEREPLY etc... Issue 75: thoj invited a PR, I attempted. Do you have a better way of containing this functionality in the library and not the client? I won't be offended if you rip it to shreds or change it. (I'll likely just keep using my fork for the time being). I also used rfc2xxx because that's what was linked to me in issue 75. Feel free to change it and improve it. |
Sorry if I came across as harsh. It's awesome you were willing to do this. Also keep in mind that I'm not the owner of this repo, just someone with a vested interest in golang irc libraries. I haven't gotten around to implementing this in my go IRC library either because of how complicated it can be. I was imagining something similar to https://github.com/belak/python-seabird/blob/master/seabird/modules/track.py (store which nicks are in which channels) but without all the mode tracking, as it removes a bunch of race conditions, but that's a completely different direction. Both methods have downsides. Downsides of your method:
Downsides of the more complicated method:
|
If I change the 366 callback to blocking instead of a go-routine, it shouldn't leak, right? How does it lose nicks? No other callback other than 353 should be triggering it, so... what am I missing? :) |
Ok, I guess I misunderstood the code before and this should actually work. Really sorry about the confusion. :( The channel could be avoided completely by changing the maps to something like this:
Then, any time 353 is called, it would add the nicks to the It would be best to attach those to the You could avoid compiling the regex on each call of the hander by moving that to a global variable, as that's scoped to the package, not the handler. |
Thanks for the PR! :) This has given me some ideas 👍 I feel global variables are unnecessary. Why no store channel data in the Connection struct? If you do that you can create a Channel and User struct. Something like this: type Connection struct {
sync.WaitGroup
Debug bool
...Snip
Channels map[string]Channel
...Snip
}
type Channel struct {
Name string
Users map[string]User
etc...
}
type User struct {
Nick string
Host string
Name string //Real Name?
etc..?
} So when you get a 353 callback you just do something with with irc.Channels. Add channel and add Users etc. You also need to track users leaving and joining the channel to keep the list up to date. |
That is likely smart to do it in the Connection struct. Just haven't had time to do any more work on it. |
You where way to fast 👍 . I updated my comment. hehe. |
That does look good. :) |
My fault for not groking the Connection struct enough. |
Hacked together this: This patch breaks tests but it tracks users from the 353 callback. It dosent track joins and parts and we probably need to split out modes and stuff. Maybe you can build a bit on this? I need to go to bed. Hehe. |
+1 Love watching the progress guys. Let me know if any way I can contribute! |
@kevinpostal @jrmiller82 @belak New commit needs testing and comments: 9f2cfa5 on nick tracker branch. Seems to work fine for most stuff at my end. Se tests how to use. irccon.SetupNickTrack() will add the necessary callbacks that will populate irc.Channels. |
Example: package main
import (
"fmt"
"github.com/thoja/go-ircevent"
"sort"
"time"
)
const channel = "#whaterver"
const serverssl = "irc.whatevernet.net:6667"
func main() {
ircnick1 := "blatibalt1"
irccon := irc.IRC(ircnick1, "blatiblat")
irccon.VerboseCallbackHandler = true
irccon.Debug = true
irccon.AddCallback("001", func(e *irc.Event) { irccon.Join(channel) })
irccon.AddCallback("366", func(e *irc.Event) {})
irccon.SetupNickTrack()
err := irccon.Connect(serverssl)
if err != nil {
fmt.Printf("Err %s", err)
return
}
go func() {
t := time.NewTicker(1 * time.Second)
for {
<-t.C
var keys []string
if _, ok := irccon.Channels[channel]; ok == true {
for k, _ := range irccon.Channels[channel].Users {
keys = append(keys, k)
}
sort.Strings(keys)
fmt.Printf("%d: ", len(keys))
for _, k := range keys {
fmt.Printf("(%s)%s ", irccon.Channels[channel].Users[k].Mode, k)
}
fmt.Printf("\n")
}
}
}()
irccon.Loop()
} |
See #79 |
Here you go.
1 new func, 2 new callbacks, and 2 global vars.
There's likely a cleaner way to do the concurrency and the global vars, but you don't know how many 353 events you will have before a 366. Also, there may be use cases where someone is calling a ton of different irc channels and receiving 353 events from multiple channels (i.e. at initial connection to all channels).
It's a little dirty, but it's working fantastically for my single-irc-channel bot at the moment. Might need some concurrency cleaning up with mutexes / better channels than my implementation in the future.