diff --git a/.travis.yml b/.travis.yml index 96a1bb8..6673edb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,24 +1,24 @@ language: go go: -- 1.11.x -- tip + - 1.11.x + - tip before_install: -- go get -v golang.org/x/lint/golint + - go get -v golang.org/x/lint/golint script: -- $HOME/gopath/bin/golint -min_confidence 0.9 -set_exit_status -- GORACE="exitcode=1 halt_on_error=1" go test -v -coverprofile=coverage.txt -race -timeout 3m -count 3 -cpu 1,4 -- go vet -v . + - $HOME/gopath/bin/golint -min_confidence 0.9 -set_exit_status + - GORACE="exitcode=1 halt_on_error=1" go test -v -coverprofile=coverage.txt -race -timeout 3m -count 3 -cpu 1,4 + - go vet -v . after_success: - bash <(curl -s https://codecov.io/bash) branches: only: - - master + - master notifications: irc: channels: - - irc.byteirc.org#/dev/null + - irc.byteirc.org#/dev/null template: - - "%{repository} #%{build_number} %{branch}/%{commit}: %{author} -- %{message} + - "%{repository} #%{build_number} %{branch}/%{commit}: %{author} -- %{message} %{build_url}" on_success: change on_failure: change diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7913630..a87371b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,31 +2,24 @@ ## Issue submission - * When submitting an issue or bug report, please ensure to provide as much - information as possible, please ensure that you are running on the latest - stable version (tagged), or when using master, provide the specific commit - being used. - * Provide the minimum needed viable source to replicate the problem. +* When submitting an issue or bug report, please ensure to provide as much information as possible, please ensure that + you are running on the latest stable version (tagged), or when using master, provide the specific commit being used. +* Provide the minimum needed viable source to replicate the problem. ## Pull requests -To review what is currently being worked on, or looked into, feel free to head -over to the [issues list](../../issues). +To review what is currently being worked on, or looked into, feel free to head over to the [issues list](../../issues). -Below are a few guidelines if you would like to contribute. Keep the code -clean, standardized, and much of the quality should match Golang's standard -library and common idioms. +Below are a few guidelines if you would like to contribute. Keep the code clean, standardized, and much of the quality +should match Golang's standard library and common idioms. - * Always test using the latest Go version. - * Always use `gofmt` before committing anything. - * Always have proper documentation before committing. - * Keep the same whitespacing, documentation, and newline format as the - rest of the project. - * Only use 3rd party libraries if necessary. If only a small portion of - the library is needed, simply rewrite it within the library to prevent - useless imports. - * Also see [golang/go/wiki/CodeReviewComments](https://github.com/golang/go/wiki/CodeReviewComments) +* Always test using the latest Go version. +* Always use `gofmt` before committing anything. +* Always have proper documentation before committing. +* Keep the same whitespacing, documentation, and newline format as the rest of the project. +* Only use 3rd party libraries if necessary. If only a small portion of the library is needed, simply rewrite it within + the library to prevent useless imports. +* Also see [golang/go/wiki/CodeReviewComments](https://github.com/golang/go/wiki/CodeReviewComments) -If you would like to assist, and the pull request is quite large and/or it has -the potential of being a breaking change, please open an issue first so it can -be discussed. +If you would like to assist, and the pull request is quite large and/or it has the potential of being a breaking change, +please open an issue first so it can be discussed. diff --git a/README.md b/README.md index e81298c..63d2d4b 100644 --- a/README.md +++ b/README.md @@ -11,50 +11,57 @@ [Click here to see the changes in girc-atomic vs girc](https://github.com/lrstanley/girc/compare/master...yunginnanet:master) ## Status - -### ₜₕₑ ₛₖy ᵢₛ 𝆑ₐₗₗᵢₙg ʇɥǝ sʞʎ ᴉs ⅎɐʅʅᴉuƃ -### 𝚝𝚑𝚎𝚢 𝚜𝚑𝚘𝚞𝚕𝚍 𝚑𝚊𝚟𝚎 𝚕𝚒𝚜𝚝𝚎𝚗𝚎𝚍 -### ʇɥǝ sʞʎ ᴉs ⅎɐʅʅᴉuƃ ₜₕₑ ₛₖy ᵢₛ 𝆑ₐₗₗᵢₙg - -~~girc is fairly close to marking the 1.0.0 endpoint, which will be tagged as -necessary, so you will be able to use this with care knowing the specific tag -you're using won't have breaking changes~~ +### ₜₕₑ ₛₖy ᵢₛ 𝆑ₐₗₗᵢₙg ʇɥǝ sʞʎ ᴉs ⅎɐʅʅᴉuƃ + +### 𝚝𝚑𝚎𝚢 𝚜𝚑𝚘𝚞𝚕𝚍 𝚑𝚊𝚟𝚎 𝚕𝚒𝚜𝚝𝚎𝚗𝚎𝚍 + +### ʇɥǝ sʞʎ ᴉs ⅎɐʅʅᴉuƃ ₜₕₑ ₛₖy ᵢₛ 𝆑ₐₗₗᵢₙg + +~~girc is fairly close to marking the 1.0.0 endpoint, which will be tagged as necessary, so you will be able to use this +with care knowing the specific tag you're using won't have breaking changes~~ ## Features - Focuses on ~~simplicity~~ ʀᴀɪɴɪɴɢ ʜᴇʟʟғɪʀᴇ, yet tries to still be flexible. - Only requires [standard library packages](https://godoc.org/github.com/yunginnanet/girc-atomic?imports) -- Event based triggering/responses ([example](https://godoc.org/github.com/yunginnanet/girc-atomic#ex-package--Commands), and [CTCP too](https://godoc.org/github.com/yunginnanet/girc-atomic#Commands.SendCTCP)!) +- Event based triggering/responses ([example](https://godoc.org/github.com/yunginnanet/girc-atomic#ex-package--Commands) + , and [CTCP too](https://godoc.org/github.com/yunginnanet/girc-atomic#Commands.SendCTCP)!) - [Documentation](https://godoc.org/github.com/yunginnanet/girc-atomic) is _mostly_ complete. - Support for almost all of the [IRCv3 spec](http://ircv3.net/software/libraries.html). - - SASL Auth (currently only `PLAIN` and `EXTERNAL` is support by default, - however you can simply implement `SASLMech` yourself to support additional - mechanisms.) - - Message tags (things like `account-tag` on by default) - - `account-notify`, `away-notify`, `chghost`, `extended-join`, etc -- all handled seemlessly ([cap.go](https://github.com/yunginnanet/girc-atomic/blob/master/cap.go) for more info). -- Channel and user tracking. Easily find what users are in a channel, if a - user is away, or if they are authenticated (if the server supports it!) -- Client state/capability tracking. Easy methods to access capability data ([LookupChannel](https://godoc.org/github.com/yunginnanet/girc-atomic#Client.LookupChannel), [LookupUser](https://godoc.org/github.com/yunginnanet/girc-atomic#Client.LookupUser), [GetServerOption (ISUPPORT)](https://godoc.org/github.com/yunginnanet/girc-atomic#Client.GetServerOption), etc.) + - SASL Auth (currently only `PLAIN` and `EXTERNAL` is support by default, however you can simply + implement `SASLMech` yourself to support additional mechanisms.) + - Message tags (things like `account-tag` on by default) + - `account-notify`, `away-notify`, `chghost`, `extended-join`, etc -- all handled + seemlessly ([cap.go](https://github.com/yunginnanet/girc-atomic/blob/master/cap.go) for more info). +- Channel and user tracking. Easily find what users are in a channel, if a user is away, or if they are authenticated ( + if the server supports it!) +- Client state/capability tracking. Easy methods to access capability + data ([LookupChannel](https://godoc.org/github.com/yunginnanet/girc-atomic#Client.LookupChannel) + , [LookupUser](https://godoc.org/github.com/yunginnanet/girc-atomic#Client.LookupUser) + , [GetServerOption (ISUPPORT)](https://godoc.org/github.com/yunginnanet/girc-atomic#Client.GetServerOption), etc.) - Built-in support for things you would commonly have to implement yourself. - - Nick collision detection and prevention (also see [Config.HandleNickCollide](https://godoc.org/github.com/yunginnanet/girc-atomic#Config).) - - Event/message rate limiting. - - Channel, nick, and user validation methods ([IsValidChannel](https://godoc.org/github.com/yunginnanet/girc-atomic#IsValidChannel), [IsValidNick](https://godoc.org/github.com/yunginnanet/girc-atomic#IsValidNick), etc.) - - CTCP handling and auto-responses ([CTCP](https://godoc.org/github.com/yunginnanet/girc-atomic#CTCP)) - - ~~And more!~~ - - GOTTA GO FAST YOU GOTTA GO REALLY FAST - - you can power hundreds of clients at the same time with this now + - Nick collision detection and prevention (also + see [Config.HandleNickCollide](https://godoc.org/github.com/yunginnanet/girc-atomic#Config).) + - Event/message rate limiting. + - Channel, nick, and user validation + methods ([IsValidChannel](https://godoc.org/github.com/yunginnanet/girc-atomic#IsValidChannel) + , [IsValidNick](https://godoc.org/github.com/yunginnanet/girc-atomic#IsValidNick), etc.) + - CTCP handling and auto-responses ([CTCP](https://godoc.org/github.com/yunginnanet/girc-atomic#CTCP)) + - ~~And more!~~ + - GOTTA GO FAST YOU GOTTA GO REALLY FAST + - you can power hundreds of clients at the same time with this now ## Installing - ~~$ go get -u github.com/yunginnanet/girc-atomic~~ - just use go modules probably +~~$ go get -u github.com/yunginnanet/girc-atomic~~ +just use go modules probably ## Examples See [the examples](https://godoc.org/github.com/yunginnanet/girc-atomic#example-package--Bare) -within the documentation for real-world usecases. Here are a few real-world -usecases/examples/projects which utilize the real girc: +within the documentation for real-world usecases. Here are a few real-world usecases/examples/projects which utilize the +real girc: | Project | Description | | --- | --- | @@ -66,11 +73,10 @@ Working on a project and want to add it to the list? Submit a pull request! ## Contributing -~~Please review the [CONTRIBUTING](CONTRIBUTING.md) doc for submitting issues/a guide -on submitting pull requests and helping out.~~ - -**OH GOD PLEASE MAKE IT STOP** +~~Please review the [CONTRIBUTING](CONTRIBUTING.md) doc for submitting issues/a guide on submitting pull requests and +helping out.~~ +**OH GOD PLEASE MAKE IT STOP** ## License @@ -94,23 +100,26 @@ on submitting pull requests and helping out.~~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -girc artwork licensed under [CC 3.0](http://creativecommons.org/licenses/by/3.0/) based on Renee French under Creative Commons 3.0 Attributions... - - or so I'm told. Then it was defiled by [some idiot](https://github.com/yunginnanet). +girc artwork licensed under [CC 3.0](http://creativecommons.org/licenses/by/3.0/) based on Renee French under Creative +Commons 3.0 Attributions... + +or so I'm told. Then it was defiled by [some idiot](https://github.com/yunginnanet). ## References - * [IRCv3: Specification Docs](http://ircv3.net/irc/) - * [IRCv3: Specification Repo](https://github.com/ircv3/ircv3-specifications) - * [IRCv3 Capability Registry](http://ircv3.net/registry.html) - * [IRCv3: WEBIRC](https://ircv3.net/specs/extensions/webirc.html) - * [KiwiIRC: WEBIRC](https://kiwiirc.com/docs/webirc) - * [ISUPPORT Specification Docs](http://www.irc.org/tech_docs/005.html) ([alternative 1](http://defs.ircdocs.horse/defs/isupport.html), [alternative 2](https://github.com/grawity/irc-docs/blob/master/client/RPL_ISUPPORT/draft-hardy-irc-isupport-00.txt), [relevant draft](http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt)) - * [IRC Numerics List](http://defs.ircdocs.horse/defs/numerics.html) - * [Extended WHO (also known as WHOX)](https://github.com/quakenet/snircd/blob/master/doc/readme.who) - * [RFC1459: Internet Relay Chat Protocol](https://tools.ietf.org/html/rfc1459) - * [RFC2812: Internet Relay Chat: Client Protocol](https://tools.ietf.org/html/rfc2812) - * [RFC2813: Internet Relay Chat: Server Protocol](https://tools.ietf.org/html/rfc2813) - * [RFC7194: Default Port for Internet Relay Chat (IRC) via TLS/SSL](https://tools.ietf.org/html/rfc7194) - * [RFC4422: Simple Authentication and Security Layer](https://tools.ietf.org/html/rfc4422) ([SASL EXTERNAL](https://tools.ietf.org/html/rfc4422#appendix-A)) - * [RFC4616: The PLAIN SASL Mechanism](https://tools.ietf.org/html/rfc4616) +* [IRCv3: Specification Docs](http://ircv3.net/irc/) +* [IRCv3: Specification Repo](https://github.com/ircv3/ircv3-specifications) +* [IRCv3 Capability Registry](http://ircv3.net/registry.html) +* [IRCv3: WEBIRC](https://ircv3.net/specs/extensions/webirc.html) +* [KiwiIRC: WEBIRC](https://kiwiirc.com/docs/webirc) +* [ISUPPORT Specification Docs](http://www.irc.org/tech_docs/005.html) ([alternative 1](http://defs.ircdocs.horse/defs/isupport.html) + , [alternative 2](https://github.com/grawity/irc-docs/blob/master/client/RPL_ISUPPORT/draft-hardy-irc-isupport-00.txt) + , [relevant draft](http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt)) +* [IRC Numerics List](http://defs.ircdocs.horse/defs/numerics.html) +* [Extended WHO (also known as WHOX)](https://github.com/quakenet/snircd/blob/master/doc/readme.who) +* [RFC1459: Internet Relay Chat Protocol](https://tools.ietf.org/html/rfc1459) +* [RFC2812: Internet Relay Chat: Client Protocol](https://tools.ietf.org/html/rfc2812) +* [RFC2813: Internet Relay Chat: Server Protocol](https://tools.ietf.org/html/rfc2813) +* [RFC7194: Default Port for Internet Relay Chat (IRC) via TLS/SSL](https://tools.ietf.org/html/rfc7194) +* [RFC4422: Simple Authentication and Security Layer](https://tools.ietf.org/html/rfc4422) ([SASL EXTERNAL](https://tools.ietf.org/html/rfc4422#appendix-A)) +* [RFC4616: The PLAIN SASL Mechanism](https://tools.ietf.org/html/rfc4616) diff --git a/builtin.go b/builtin.go index d845675..ddb9fe2 100644 --- a/builtin.go +++ b/builtin.go @@ -417,6 +417,7 @@ func handleCREATED(c *Client, e Event) { split := strings.Split(e.String(), "created ") compiled, err := dateparse.ParseAny(split[0]) if err != nil { + c.IRCd.Compiled = time.Unix(0, 0) return } c.state.Lock() @@ -523,7 +524,7 @@ func handleNAMES(c *Client, e Event) { continue } - var s *Source = new(Source) + var s = new(Source) // If userhost-in-names. if strings.Contains(nick, "@") { @@ -570,14 +571,13 @@ func updateLastActive(c *Client, e Event) { } c.state.Lock() + defer c.state.Unlock() // Update the users last active time, if they exist. user := c.state.lookupUser(e.Source.Name) if user == nil { - c.state.Unlock() return } user.LastActive = time.Now() - c.state.Unlock() } diff --git a/cap.go b/cap.go index 7bd7cde..1efd55a 100644 --- a/cap.go +++ b/cap.go @@ -123,9 +123,9 @@ func handleCAP(c *Client, e Event) { if len(e.Params) >= 2 && e.Params[1] == CAP_DEL { caps := parseCap(e.Last()) - for cap := range caps { + for capab := range caps { // TODO: test the deletion. - delete(c.state.enabledCap, cap) + delete(c.state.enabledCap, capab) } return } @@ -194,11 +194,11 @@ func handleCAP(c *Client, e Event) { if len(e.Params) == 3 && e.Params[1] == CAP_ACK { enabled := strings.Split(e.Last(), " ") - for _, cap := range enabled { - if val, ok := c.state.tmpCap[cap]; ok { - c.state.enabledCap[cap] = val + for _, capab := range enabled { + if val, ok := c.state.tmpCap[capab]; ok { + c.state.enabledCap[capab] = val } else { - c.state.enabledCap[cap] = nil + c.state.enabledCap[capab] = nil } } diff --git a/client.go b/client.go index 661e834..5bb0607 100644 --- a/client.go +++ b/client.go @@ -50,7 +50,7 @@ type Client struct { // IRCd encapsulates IRC Server details. IRCd Server - + // stop is used to communicate with Connect(), letting it know that the // client wishes to cancel/close. stop context.CancelFunc @@ -286,9 +286,9 @@ func New(config Config) *Client { } c.IRCd = Server{ - Network: "", - Version: "", - UserCount: 0, + Network: "", + Version: "", + UserCount: 0, MaxUserCount: 0, } @@ -317,7 +317,7 @@ func New(config Config) *Client { c.debug.Print("initializing debugging") } - envDisableSTS, _ := strconv.ParseBool((os.Getenv("GIRC_DISABLE_STS"))) + envDisableSTS, _ := strconv.ParseBool(os.Getenv("GIRC_DISABLE_STS")) if envDisableSTS { c.Config.DisableSTS = envDisableSTS } diff --git a/commands.go b/commands.go index c6fe663..2c1914f 100644 --- a/commands.go +++ b/commands.go @@ -146,12 +146,17 @@ func (cmd *Commands) ReplyKick(event Event, reason string) { } } -// ReplyBan kicks the source of the event from the channel where the event originated +// ReplyBan kicks the source of the event from the channel where the event originated. +// Additionally, if a reason is provided, it will send a message to the channel. func (cmd *Commands) ReplyBan(event Event, reason string) { if event.Source == nil { panic(ErrInvalidSource) } + if reason != "" { + cmd.Replyf(event, "{red}{b}[BAN] {r}%s", reason) + } + if len(event.Params) > 0 && IsValidChannel(event.Params[0]) { cmd.Ban(event.Params[0], event.Source.Name) } @@ -378,7 +383,7 @@ func (cmd *Commands) List(channels ...string) { // Whowas sends a WHOWAS query to the server. amount is the amount of results // you want back. func (cmd *Commands) Whowas(user string, amount int) { - cmd.c.Send(&Event{Command: WHOWAS, Params: []string{user, string(fmt.Sprintf("%d", amount))}}) + cmd.c.Send(&Event{Command: WHOWAS, Params: []string{user, fmt.Sprintf("%d", amount)}}) } // Monitor sends a MONITOR query to the server. The results of the query diff --git a/ctcp.go b/ctcp.go index 5e1aa40..c925abc 100644 --- a/ctcp.go +++ b/ctcp.go @@ -196,7 +196,7 @@ func (c *CTCP) Set(cmd string, handler func(client *Client, ctcp CTCPEvent)) { c.mu.Lock() defer c.mu.Unlock() - c.handlers[cmd] = CTCPHandler(handler) + c.handlers[cmd] = handler } // SetBg is much like Set, however the handler is executed in the background, diff --git a/modes.go b/modes.go index 864df71..5335730 100644 --- a/modes.go +++ b/modes.go @@ -157,7 +157,7 @@ func (c *CModes) hasArg(set bool, mode byte) (hasArgs, isSetting bool) { // For example, the latter would mean applying an incoming MODE with the modes // stored for a channel. func (c *CModes) Apply(modes []CMode) { - var new []CMode + var newcm []CMode for j := 0; j < len(c.modes); j++ { isin := false @@ -166,14 +166,14 @@ func (c *CModes) Apply(modes []CMode) { continue } if c.modes[j].name == modes[i].name && modes[i].add { - new = append(new, modes[i]) + newcm = append(newcm, modes[i]) isin = true break } } if !isin { - new = append(new, c.modes[j]) + newcm = append(newcm, c.modes[j]) } } @@ -183,19 +183,19 @@ func (c *CModes) Apply(modes []CMode) { } isin := false - for j := 0; j < len(new); j++ { - if modes[i].name == new[j].name { + for j := 0; j < len(newcm); j++ { + if modes[i].name == newcm[j].name { isin = true break } } if !isin { - new = append(new, modes[i]) + newcm = append(newcm, modes[i]) } } - c.modes = new + c.modes = newcm } // Parse parses a set of flags and args, returning the necessary list of diff --git a/state.go b/state.go index 4bd84ac..275ade6 100644 --- a/state.go +++ b/state.go @@ -123,7 +123,7 @@ func (u User) Channels(c *Client) []*Channel { panic("nil Client provided") } - channels := []*Channel{} + var channels []*Channel c.state.RLock() for i := 0; i < len(u.ChannelList); i++ { @@ -237,7 +237,7 @@ func (ch Channel) Users(c *Client) []*User { panic("nil Client provided") } - users := []*User{} + var users []*User c.state.RLock() for i := 0; i < len(ch.UserList); i++ { @@ -258,7 +258,7 @@ func (ch Channel) Trusted(c *Client) []*User { panic("nil Client provided") } - users := []*User{} + var users []*User c.state.RLock() for i := 0; i < len(ch.UserList); i++ { @@ -285,7 +285,7 @@ func (ch Channel) Admins(c *Client) []*User { panic("nil Client provided") } - users := []*User{} + var users []*User c.state.RLock() for i := 0; i < len(ch.UserList); i++ {