From b1b6facde1ea2cc2f4c410ff0c7044ac2d47b45c Mon Sep 17 00:00:00 2001 From: Liam Stanley Date: Mon, 9 Jan 2017 06:40:58 -0500 Subject: [PATCH 1/5] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 0507b6c..724d49b 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,16 @@ - [ ] write more function-specific examples as the api becomes much more stable - [ ] client should support ping tracking (sending `PING`'s to the server) - [ ] with this, we can potentially find lag. `Client.Lag()` would be useful + - [ ] allow support for changing the frequency of this? - [ ] users need to be exposed in state somehow (other than `GetChannels()`) - [ ] `MODE` tracking on a per-channel basis - [ ] `Client.AddTmpCallback()` for one time use callbacks? - [ ] add option to enable PRIVMSG/NOTICE text wrapping (and maybe per-default?) (`Config.DisableResponseWrap`?) +- [ ] optional flood toggle which uses `EventLimiter` so the user doesn't have to implement it themselves? +- [ ] allow users to supply a custom `VERSION` for the CTCP reply so they don't have to implement their own CTCP `VERSION` handler? +- [ ] allow support for proxy URLs (passing to `golang.org/x/net/proxy`?) +- [ ] allow users to specify a local/bind address using `net.Dialer{}.LocalAddr` +- [ ] add more generic helpers: `Away()`, `Invite()`, `Kick()`, `Oper()`, generic `Ping()` and `Pong()`, `VHost()`, `Whois()` and `Who()` ## Installing From 3a576d1db9095b266d579cbe4e198ec692468127 Mon Sep 17 00:00:00 2001 From: Liam Stanley Date: Thu, 12 Jan 2017 02:34:29 -0500 Subject: [PATCH 2/5] implement version config option to override default ctcp version --- README.md | 1 - client.go | 4 ++++ ctcp.go | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 724d49b..845dfe4 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,6 @@ - [ ] `Client.AddTmpCallback()` for one time use callbacks? - [ ] add option to enable PRIVMSG/NOTICE text wrapping (and maybe per-default?) (`Config.DisableResponseWrap`?) - [ ] optional flood toggle which uses `EventLimiter` so the user doesn't have to implement it themselves? -- [ ] allow users to supply a custom `VERSION` for the CTCP reply so they don't have to implement their own CTCP `VERSION` handler? - [ ] allow support for proxy URLs (passing to `golang.org/x/net/proxy`?) - [ ] allow users to specify a local/bind address using `net.Dialer{}.LocalAddr` - [ ] add more generic helpers: `Away()`, `Invite()`, `Kick()`, `Oper()`, generic `Ping()` and `Pong()`, `VHost()`, `Whois()` and `Who()` diff --git a/client.go b/client.go index ae660dc..eb789a3 100644 --- a/client.go +++ b/client.go @@ -74,6 +74,10 @@ type Config struct { // support. Only use this if DisableTracking and DisableCapTracking are // not enabled, otherwise you will need to handle CAP negotiation yourself. SupportedCaps []string + // Version is the application version information that will be used in + // response to a CTCP VERSION, if default CTCP replies have not been + // overwritten or a VERSION handler was already supplied. + Version string // ReconnectDelay is the a duration of time to delay before attempting a // reconnection. Defaults to 10s (minimum of 10s). ReconnectDelay time.Duration diff --git a/ctcp.go b/ctcp.go index 7ee0eec..e292291 100644 --- a/ctcp.go +++ b/ctcp.go @@ -251,6 +251,11 @@ func handleCTCPPong(client *Client, ctcp CTCPEvent) { // as the os type (darwin, linux, windows, etc) and architecture type (x86, // arm, etc). func handleCTCPVersion(client *Client, ctcp CTCPEvent) { + if client.Config.Version != "" { + client.SendCTCPReply(ctcp.Source.Name, CTCP_VERSION, client.Config.Version) + return + } + client.SendCTCPReplyf( ctcp.Source.Name, CTCP_VERSION, "girc (github.com/lrstanley/girc) using %s (%s, %s)", From 18969f93c09002362d9464ed3bf570d5f4f433da Mon Sep 17 00:00:00 2001 From: Liam Stanley Date: Thu, 12 Jan 2017 03:21:38 -0500 Subject: [PATCH 3/5] too messy --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 845dfe4..fcec5b4 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,6 @@ - [ ] users need to be exposed in state somehow (other than `GetChannels()`) - [ ] `MODE` tracking on a per-channel basis - [ ] `Client.AddTmpCallback()` for one time use callbacks? -- [ ] add option to enable PRIVMSG/NOTICE text wrapping (and maybe per-default?) (`Config.DisableResponseWrap`?) - [ ] optional flood toggle which uses `EventLimiter` so the user doesn't have to implement it themselves? - [ ] allow support for proxy URLs (passing to `golang.org/x/net/proxy`?) - [ ] allow users to specify a local/bind address using `net.Dialer{}.LocalAddr` From 8bf23fd61feec23cf28866d1296a0df6443d457e Mon Sep 17 00:00:00 2001 From: Liam Stanley Date: Thu, 12 Jan 2017 04:19:35 -0500 Subject: [PATCH 4/5] implement default rate limiting for events; update readme --- README.md | 22 +++++++++++++++------- client.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index fcec5b4..94add47 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,20 @@ ## Features -- Focuses on simplicity, yet tries to still be flexible -- Only requires standard packages -- Event based triggering/responses -- Documentation is mostly on par -- At this time, **expect breaking changes to occur frequently**. +- Focuses on simplicity, yet tries to still be flexible. +- Only requires standard library packages. +- Event based triggering/responses (and CTCP too!). +- Documentation is mostly on par. +- Full support for the IRCv3 spec. [**WIP**] +- Channel and user tracking. Easily find what users are in a channel, if a user is away, or if they are authenticated. +- Client state/capability tracking. Easy methods to access capability data. +- Built-in support for things you would commmonly have to implement yourself. + - Nick collision detection and prevention. + - Event/message rate limiting. + - Channel, nick, and user validation on connection methods. + - CTCP handling and auto-responses. + +- At this time, **expect breaking changes to occur frequently**. girc has **not hit version 1.0.0 yet!** ## TODO @@ -31,10 +40,9 @@ - [ ] client should support ping tracking (sending `PING`'s to the server) - [ ] with this, we can potentially find lag. `Client.Lag()` would be useful - [ ] allow support for changing the frequency of this? -- [ ] users need to be exposed in state somehow (other than `GetChannels()`) +- [ ] users need to be exposed in state some how (other than `GetChannels()`) - [ ] `MODE` tracking on a per-channel basis - [ ] `Client.AddTmpCallback()` for one time use callbacks? -- [ ] optional flood toggle which uses `EventLimiter` so the user doesn't have to implement it themselves? - [ ] allow support for proxy URLs (passing to `golang.org/x/net/proxy`?) - [ ] allow users to specify a local/bind address using `net.Dialer{}.LocalAddr` - [ ] add more generic helpers: `Away()`, `Invite()`, `Kick()`, `Oper()`, generic `Ping()` and `Pong()`, `VHost()`, `Whois()` and `Who()` diff --git a/client.go b/client.go index eb789a3..8d244fc 100644 --- a/client.go +++ b/client.go @@ -36,6 +36,8 @@ type Client struct { // tries represents the internal reconnect count to the IRC server. tries int + // limiter is a configurable EventLimiter by the end user. + limiter *EventLimiter // log is used if a writer is supplied for Client.Config.Logger. log *log.Logger // quitChan is used to stop the read loop. See Client.Quit(). @@ -67,6 +69,9 @@ type Config struct { // MaxRetries is the number of times the client will attempt to reconnect // to the server after the last disconnect. MaxRetries int + // RateLimit is the delay in seconds between events sent to the server, + // with a burst of 4 messages. Set to -1 to disable. + RateLimit int // Logger is an optional, user supplied logger to log the raw lines sent // from the server. Useful for debugging. Defaults to ioutil.Discard. Logger io.Writer @@ -131,6 +136,13 @@ func New(config Config) *Client { } client.log = log.New(client.Config.Logger, "", log.Ldate|log.Ltime|log.Lshortfile) + // Setup a rate limiter if they requested one. + if client.Config.RateLimit == 0 { + client.limiter = NewEventLimiter(4, 1*time.Second, client.write) + } else if client.Config.RateLimit > 0 { + client.limiter = NewEventLimiter(4, time.Duration(client.Config.RateLimit)*time.Second, client.write) + } + // Give ourselves a new state. client.state = newState() @@ -164,6 +176,12 @@ func (c *Client) Quit(message string) { // Stop exits the clients main loop. Use Client.Quit() first if you want to // disconnect the client from the server/connection. func (c *Client) Stop() { + // Close and limiters they have, otherwise the client could be easily + // held in memory. + if c.limiter != nil { + c.limiter.Stop() + } + // Send to the stop channel, so if Client.Loop() is being used, this will // return. c.stopChan <- struct{}{} @@ -358,6 +376,17 @@ func (c *Client) Lifetime() time.Duration { // Send sends an event to the server. Use Client.RunCallback() if you are // simply looking to trigger callbacks with an event. func (c *Client) Send(event *Event) error { + // if the client wants us to rate limit incoming events, do so, otherwise + // simply use the underlying send functionality. + if c.limiter != nil { + return c.limiter.Send(event) + } + + return c.write(event) +} + +// write is the lower level function to write an event. +func (c *Client) write(event *Event) error { // log the event if !event.Sensitive { c.log.Print("--> ", StripRaw(event.Raw())) From 2f5c16b1be5747e7204fe03e311b38dcec35b1c3 Mon Sep 17 00:00:00 2001 From: Liam Stanley Date: Thu, 12 Jan 2017 08:53:56 -0500 Subject: [PATCH 5/5] Update README.md --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 94add47..5ce457d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ -## girc is a flexible IRC library for Go - -[![Build Status](https://travis-ci.org/lrstanley/girc.svg?branch=master)](https://travis-ci.org/lrstanley/girc) -[![GoDoc](https://godoc.org/github.com/lrstanley/girc?status.png)](https://godoc.org/github.com/lrstanley/girc) -[![Go Report Card](https://goreportcard.com/badge/github.com/lrstanley/girc)](https://goreportcard.com/report/github.com/lrstanley/girc) -[![IRC Chat](https://img.shields.io/badge/ByteIRC-%23L-blue.svg)](http://byteirc.org/channel/L) -[![GitHub Issues](https://img.shields.io/github/issues/lrstanley/girc.svg)](https://github.com/lrstanley/girc/issues) -[![license](https://img.shields.io/github/license/lrstanley/girc.svg)](https://raw.githubusercontent.com/lrstanley/girc/master/LICENSE) +

+

girc -- A flexible IRC library for Go

+

+ Build Status + GoDoc + Go Report Card + IRC Chat + GitHub Issues + License +

## Features