Skip to content
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

minor refactoring #2214

Merged
merged 8 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions irc/getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,13 @@ func (session *Session) SetAway(awayMessage string) (wasAway, nowAway string) {
return
}

func (session *Session) ConnID() string {
if session == nil {
return "*"
}
return session.connID
}

func (client *Client) autoAwayEnabledNoMutex(config *Config) bool {
return client.registered && client.alwaysOn &&
persistenceEnabled(config.Accounts.Multiclient.AutoAway, client.accountSettings.AutoAway)
Expand Down
12 changes: 6 additions & 6 deletions irc/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func sendSuccessfulAccountAuth(service *ircService, client *Client, rb *Response
}
}

client.server.logger.Info("accounts", "client", details.nick, "logged into account", details.accountName)
client.server.logger.Info("accounts", rb.session.ConnID(), details.nick, "logged into account", details.accountName)
}

func (server *Server) sendLoginSnomask(nickMask, accountName string) {
Expand Down Expand Up @@ -1852,14 +1852,14 @@ func cmodeHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respon
if 1 < len(msg.Params) {
// parse out real mode changes
params := msg.Params[1:]
var unknown map[rune]bool
var unknown []rune
changes, unknown = modes.ParseChannelModeChanges(params...)

// alert for unknown mode changes
for char := range unknown {
for _, char := range unknown {
rb.Add(nil, server.name, ERR_UNKNOWNMODE, client.nick, string(char), client.t("is an unknown mode character to me"))
}
if len(unknown) == 1 && len(changes) == 0 {
if len(unknown) != 0 && len(changes) == 0 {
return false
}
}
Expand Down Expand Up @@ -1943,10 +1943,10 @@ func umodeHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respon
changes, unknown := modes.ParseUserModeChanges(params...)

// alert for unknown mode changes
for char := range unknown {
for _, char := range unknown {
rb.Add(nil, server.name, ERR_UNKNOWNMODE, cDetails.nick, string(char), client.t("is an unknown mode character to me"))
}
if len(unknown) == 1 && len(changes) == 0 {
if len(unknown) != 0 && len(changes) == 0 {
return false
}

Expand Down
48 changes: 22 additions & 26 deletions irc/isupport/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package isupport

import (
"fmt"
"sort"
"slices"
"strings"
)

Expand Down Expand Up @@ -58,7 +58,7 @@ func getTokenString(name string, value string) string {

// GetDifference returns the difference between two token lists.
func (il *List) GetDifference(newil *List) [][]string {
var outTokens sort.StringSlice
var outTokens []string

// append removed tokens
for name := range il.Tokens {
Expand All @@ -84,7 +84,7 @@ func (il *List) GetDifference(newil *List) [][]string {
outTokens = append(outTokens, token)
}

sort.Sort(outTokens)
slices.Sort(outTokens)

// create output list
replies := make([][]string, 0)
Expand Down Expand Up @@ -117,38 +117,34 @@ func (il *List) GetDifference(newil *List) [][]string {

// RegenerateCachedReply regenerates the cached RPL_ISUPPORT reply
func (il *List) RegenerateCachedReply() (err error) {
il.CachedReply = make([][]string, 0)
var length int // Length of the current cache
var cache []string // Token list cache

// make sure we get a sorted list of tokens, needed for tests and looks nice
var tokens sort.StringSlice
for name := range il.Tokens {
tokens = append(tokens, name)
}
sort.Sort(tokens)

for _, name := range tokens {
token := getTokenString(name, il.Tokens[name])
var tokens []string
for name, value := range il.Tokens {
token := getTokenString(name, value)
if token[0] == ':' || strings.Contains(token, " ") {
err = fmt.Errorf("bad isupport token (cannot contain spaces or start with :): %s", token)
continue
}
tokens = append(tokens, token)
}
// make sure we get a sorted list of tokens, needed for tests and looks nice
slices.Sort(tokens)

if len(token)+length <= maxLastArgLength {
// account for the space separating tokens
if len(cache) > 0 {
length++
}
cache = append(cache, token)
length += len(token)
}
var cache []string // Tokens in current line
var length int // Length of the current line

if len(cache) == maxParameters || len(token)+length >= maxLastArgLength {
for _, token := range tokens {
// account for the space separating tokens
if len(cache) == maxParameters || (len(token)+1)+length > maxLastArgLength {
il.CachedReply = append(il.CachedReply, cache)
cache = make([]string, 0)
cache = nil
length = 0
}

if len(cache) > 0 {
length++
}
length += len(token)
cache = append(cache, token)
}

if len(cache) > 0 {
Expand Down
2 changes: 1 addition & 1 deletion irc/isupport/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestISUPPORT(t *testing.T) {
}

if !reflect.DeepEqual(tListLong.CachedReply, longReplies) {
t.Errorf("Multiple output replies did not match, got [%v]", longReplies)
t.Errorf("Multiple output replies did not match, got [%v]", tListLong.CachedReply)
}

// create first list
Expand Down
2 changes: 1 addition & 1 deletion irc/modes.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func ApplyUserModeChanges(client *Client, changes modes.ModeChanges, force bool,
}

// parseDefaultModes uses the provided mode change parser to parse the rawModes.
func parseDefaultModes(rawModes string, parser func(params ...string) (modes.ModeChanges, map[rune]bool)) modes.Modes {
func parseDefaultModes(rawModes string, parser func(params ...string) (modes.ModeChanges, []rune)) modes.Modes {
modeChangeStrings := strings.Fields(rawModes)
modeChanges, _ := parser(modeChangeStrings...)
defaultModes := make(modes.Modes, 0)
Expand Down
92 changes: 38 additions & 54 deletions irc/modes/modes.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package modes

import (
"fmt"
"sort"
"slices"
"strings"

"github.com/ergochat/ergo/irc/utils"
Expand Down Expand Up @@ -189,10 +189,7 @@ func GetLowestChannelModePrefix(prefixes string) (lowest Mode) {
//

// ParseUserModeChanges returns the valid changes, and the list of unknown chars.
func ParseUserModeChanges(params ...string) (ModeChanges, map[rune]bool) {
changes := make(ModeChanges, 0)
unknown := make(map[rune]bool)

func ParseUserModeChanges(params ...string) (changes ModeChanges, unknown []rune) {
op := List

if 0 < len(params) {
Expand All @@ -219,30 +216,19 @@ func ParseUserModeChanges(params ...string) (ModeChanges, map[rune]bool) {
}
}

var isKnown bool
for _, supportedMode := range SupportedUserModes {
if rune(supportedMode) == mode {
isKnown = true
break
}
}
if !isKnown {
unknown[mode] = true
continue
if slices.Contains(SupportedUserModes, Mode(mode)) {
changes = append(changes, change)
} else {
unknown = append(unknown, mode)
}

changes = append(changes, change)
}
}

return changes, unknown
}

// ParseChannelModeChanges returns the valid changes, and the list of unknown chars.
func ParseChannelModeChanges(params ...string) (ModeChanges, map[rune]bool) {
changes := make(ModeChanges, 0)
unknown := make(map[rune]bool)

func ParseChannelModeChanges(params ...string) (changes ModeChanges, unknown []rune) {
op := List

if 0 < len(params) {
Expand Down Expand Up @@ -304,25 +290,11 @@ func ParseChannelModeChanges(params ...string) (ModeChanges, map[rune]bool) {
}
}

var isKnown bool
for _, supportedMode := range SupportedChannelModes {
if rune(supportedMode) == mode {
isKnown = true
break
}
}
for _, supportedMode := range ChannelUserModes {
if rune(supportedMode) == mode {
isKnown = true
break
}
if slices.Contains(SupportedChannelModes, Mode(mode)) || slices.Contains(ChannelUserModes, Mode(mode)) {
changes = append(changes, change)
} else {
unknown = append(unknown, mode)
}
if !isKnown {
unknown[mode] = true
continue
}

changes = append(changes, change)
}
}

Expand Down Expand Up @@ -428,33 +400,37 @@ func (set *ModeSet) HighestChannelUserMode() (result Mode) {
return
}

type ByCodepoint Modes
var (
rplMyInfo1, rplMyInfo2, rplMyInfo3, chanmodesToken string
)

func (a ByCodepoint) Len() int { return len(a) }
func (a ByCodepoint) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByCodepoint) Less(i, j int) bool { return a[i] < a[j] }
func init() {
initRplMyInfo()
initChanmodesToken()
}

func RplMyInfo() (param1, param2, param3 string) {
func initRplMyInfo() {
// initialize constant strings published in initial numerics
userModes := make(Modes, len(SupportedUserModes), len(SupportedUserModes)+1)
copy(userModes, SupportedUserModes)
// TLS is not in SupportedUserModes because it can't be modified
userModes = append(userModes, TLS)
sort.Sort(ByCodepoint(userModes))
slices.Sort(userModes)

channelModes := make(Modes, len(SupportedChannelModes)+len(ChannelUserModes))
copy(channelModes, SupportedChannelModes)
copy(channelModes[len(SupportedChannelModes):], ChannelUserModes)
sort.Sort(ByCodepoint(channelModes))
slices.Sort(channelModes)

// XXX enumerate these by hand, i can't see any way to DRY this
channelParametrizedModes := Modes{BanMask, ExceptMask, InviteMask, Key, UserLimit, Forward}
channelParametrizedModes = append(channelParametrizedModes, ChannelUserModes...)
sort.Sort(ByCodepoint(channelParametrizedModes))
slices.Sort(channelParametrizedModes)

return userModes.String(), channelModes.String(), channelParametrizedModes.String()
rplMyInfo1, rplMyInfo2, rplMyInfo3 = userModes.String(), channelModes.String(), channelParametrizedModes.String()
}

func ChanmodesToken() (result string) {
func initChanmodesToken() {
// https://modern.ircdocs.horse#chanmodes-parameter
// type A: listable modes with parameters
A := Modes{BanMask, ExceptMask, InviteMask}
Expand All @@ -465,10 +441,18 @@ func ChanmodesToken() (result string) {
// type D: modes without parameters
D := Modes{InviteOnly, Moderated, NoOutside, OpOnlyTopic, ChanRoleplaying, Secret, NoCTCP, RegisteredOnly, RegisteredOnlySpeak, Auditorium, OpModerated}

sort.Sort(ByCodepoint(A))
sort.Sort(ByCodepoint(B))
sort.Sort(ByCodepoint(C))
sort.Sort(ByCodepoint(D))
slices.Sort(A)
slices.Sort(B)
slices.Sort(C)
slices.Sort(D)

return fmt.Sprintf("%s,%s,%s,%s", A.String(), B.String(), C.String(), D.String())
chanmodesToken = fmt.Sprintf("%s,%s,%s,%s", A.String(), B.String(), C.String(), D.String())
}

func RplMyInfo() (param1, param2, param3 string) {
return rplMyInfo1, rplMyInfo2, rplMyInfo3
}

func ChanmodesToken() (result string) {
return chanmodesToken
}
10 changes: 6 additions & 4 deletions irc/modes/modes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package modes

import (
"reflect"
"slices"
"strings"
"testing"
)
Expand All @@ -16,7 +17,7 @@ func assertEqual(supplied, expected interface{}, t *testing.T) {
}

func TestParseUserModeChanges(t *testing.T) {
emptyUnknown := make(map[rune]bool)
var emptyUnknown []rune
changes, unknown := ParseUserModeChanges("+i")
assertEqual(unknown, emptyUnknown, t)
assertEqual(changes, ModeChanges{ModeChange{Op: Add, Mode: Invisible}}, t)
Expand Down Expand Up @@ -48,10 +49,11 @@ func TestParseUserModeChanges(t *testing.T) {
}

func TestIssue874(t *testing.T) {
emptyUnknown := make(map[rune]bool)
var emptyModeChanges ModeChanges
var emptyUnknown []rune
modes, unknown := ParseChannelModeChanges("+k")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{}, t)
assertEqual(modes, emptyModeChanges, t)

modes, unknown = ParseChannelModeChanges("+k", "beer")
assertEqual(unknown, emptyUnknown, t)
Expand Down Expand Up @@ -151,7 +153,7 @@ func TestParseChannelModeChanges(t *testing.T) {
}

modes, unknown = ParseChannelModeChanges("+tx")
if len(unknown) != 1 || !unknown['x'] {
if len(unknown) != 1 || !slices.Contains(unknown, 'x') {
t.Errorf("expected that x is an unknown mode, instead: %v", unknown)
}
expected = ModeChange{
Expand Down
10 changes: 5 additions & 5 deletions irc/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"bytes"
"fmt"
"log"
"sort"
"slices"
"strings"
"time"

Expand Down Expand Up @@ -250,7 +250,7 @@ func serviceHelpHandler(service *ircService, server *Server, client *Client, par
client.t("Here are the commands you can use:"),
}...)
// show general help
var shownHelpLines sort.StringSlice
var shownHelpLines []string
var disabledCommands bool
for _, commandInfo := range service.Commands {
// skip commands user can't access
Expand All @@ -268,13 +268,13 @@ func serviceHelpHandler(service *ircService, server *Server, client *Client, par
shownHelpLines = append(shownHelpLines, " "+ircfmt.Unescape(client.t(commandInfo.helpShort)))
}

// sort help lines
slices.Sort(shownHelpLines)

if disabledCommands {
shownHelpLines = append(shownHelpLines, " "+client.t("... and other commands which have been disabled"))
}

// sort help lines
sort.Sort(shownHelpLines)

// push out help text
for _, line := range helpBannerLines {
sendNotice(line)
Expand Down