Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: "setup go"
uses: "actions/setup-go@v2"
with:
go-version: "1.17"
go-version: "1.18"
- name: "install python3-pytest"
run: "sudo apt install -y python3-pytest"
- name: "make install"
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## build ergo binary
FROM golang:1.17-alpine3.13 AS build-env
FROM golang:1.18-alpine3.13 AS build-env

RUN apk add -U --force-refresh --no-cache --purge --clean-protected -l -u make git

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/ergochat/ergo

go 1.17
go 1.18

require (
code.cloudfoundry.org/bytefmt v0.0.0-20200131002437-cf55d5288a48
Expand Down
5 changes: 1 addition & 4 deletions irc/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,7 @@ func (channel *Channel) ExportRegistration(includeFlags uint) (info RegisteredCh
info.Bans = channel.lists[modes.BanMask].Masks()
info.Invites = channel.lists[modes.InviteMask].Masks()
info.Excepts = channel.lists[modes.ExceptMask].Masks()
info.AccountToUMode = make(map[string]modes.Mode)
for account, mode := range channel.accountToUMode {
info.AccountToUMode[account] = mode
}
info.AccountToUMode = utils.CopyMap(channel.accountToUMode)
}

if includeFlags&IncludeSettings != 0 {
Expand Down
14 changes: 7 additions & 7 deletions irc/channelmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ type ChannelManager struct {
sync.RWMutex // tier 2
// chans is the main data structure, mapping casefolded name -> *Channel
chans map[string]*channelManagerEntry
chansSkeletons utils.StringSet // skeletons of *unregistered* chans
registeredChannels utils.StringSet // casefolds of registered chans
registeredSkeletons utils.StringSet // skeletons of registered chans
purgedChannels utils.StringSet // casefolds of purged chans
chansSkeletons utils.HashSet[string] // skeletons of *unregistered* chans
registeredChannels utils.HashSet[string] // casefolds of registered chans
registeredSkeletons utils.HashSet[string] // skeletons of registered chans
purgedChannels utils.HashSet[string] // casefolds of purged chans
server *Server
}

// NewChannelManager returns a new ChannelManager.
func (cm *ChannelManager) Initialize(server *Server) {
cm.chans = make(map[string]*channelManagerEntry)
cm.chansSkeletons = make(utils.StringSet)
cm.chansSkeletons = make(utils.HashSet[string])
cm.server = server

// purging should work even if registration is disabled
Expand Down Expand Up @@ -66,8 +66,8 @@ func (cm *ChannelManager) loadRegisteredChannels(config *Config) {
cm.Lock()
defer cm.Unlock()

cm.registeredChannels = make(utils.StringSet, len(rawNames))
cm.registeredSkeletons = make(utils.StringSet, len(rawNames))
cm.registeredChannels = make(utils.HashSet[string], len(rawNames))
cm.registeredSkeletons = make(utils.HashSet[string], len(rawNames))
for _, name := range rawNames {
cfname, err := CasefoldChannel(name)
if err == nil {
Expand Down
4 changes: 2 additions & 2 deletions irc/channelreg.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ func (reg *ChannelRegistry) AllChannels() (result []string) {
}

// PurgedChannels returns the set of all casefolded channel names that have been purged
func (reg *ChannelRegistry) PurgedChannels() (result utils.StringSet) {
result = make(utils.StringSet)
func (reg *ChannelRegistry) PurgedChannels() (result utils.HashSet[string]) {
result = make(utils.HashSet[string])

prefix := fmt.Sprintf(keyChannelPurged, "")
reg.server.store.View(func(tx *buntdb.Tx) error {
Expand Down
12 changes: 6 additions & 6 deletions irc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -994,8 +994,8 @@ func (client *Client) ModeString() (str string) {
}

// Friends refers to clients that share a channel with this client.
func (client *Client) Friends(capabs ...caps.Capability) (result map[*Session]empty) {
result = make(map[*Session]empty)
func (client *Client) Friends(capabs ...caps.Capability) (result utils.HashSet[*Session]) {
result = make(utils.HashSet[*Session])

// look at the client's own sessions
addFriendsToSet(result, client, capabs...)
Expand All @@ -1010,19 +1010,19 @@ func (client *Client) Friends(capabs ...caps.Capability) (result map[*Session]em
}

// Friends refers to clients that share a channel or extended-monitor this client.
func (client *Client) FriendsMonitors(capabs ...caps.Capability) (result map[*Session]empty) {
func (client *Client) FriendsMonitors(capabs ...caps.Capability) (result utils.HashSet[*Session]) {
result = client.Friends(capabs...)
client.server.monitorManager.AddMonitors(result, client.nickCasefolded, capabs...)
return
}

// helper for Friends
func addFriendsToSet(set map[*Session]empty, client *Client, capabs ...caps.Capability) {
func addFriendsToSet(set utils.HashSet[*Session], client *Client, capabs ...caps.Capability) {
client.stateMutex.RLock()
defer client.stateMutex.RUnlock()
for _, session := range client.sessions {
if session.capabilities.HasAll(capabs...) {
set[session] = empty{}
set.Add(session)
}
}
}
Expand Down Expand Up @@ -1575,7 +1575,7 @@ func (client *Client) addChannel(channel *Channel, simulated bool) (err error) {
} else if client.oper == nil && len(client.channels) >= config.Channels.MaxChannelsPerClient {
err = errTooManyChannels
} else {
client.channels[channel] = empty{} // success
client.channels.Add(channel) // success
}
client.stateMutex.Unlock()

Expand Down
2 changes: 1 addition & 1 deletion irc/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

func TestGenerateBatchID(t *testing.T) {
var session Session
s := make(utils.StringSet)
s := make(utils.HashSet[string])

count := 100000
for i := 0; i < count; i++ {
Expand Down
6 changes: 3 additions & 3 deletions irc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -704,8 +704,8 @@ type Config struct {
// OperClass defines an assembled operator class.
type OperClass struct {
Title string
WhoisLine string `yaml:"whois-line"`
Capabilities utils.StringSet // map to make lookups much easier
WhoisLine string `yaml:"whois-line"`
Capabilities utils.HashSet[string] // map to make lookups much easier
}

// OperatorClasses returns a map of assembled operator classes from the given config.
Expand Down Expand Up @@ -743,7 +743,7 @@ func (conf *Config) OperatorClasses() (map[string]*OperClass, error) {

// create new operclass
var oc OperClass
oc.Capabilities = make(utils.StringSet)
oc.Capabilities = make(utils.HashSet[string])

// get inhereted info from other operclasses
if len(info.Extends) > 0 {
Expand Down
4 changes: 2 additions & 2 deletions irc/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3424,7 +3424,7 @@ func whoHandler(server *Server, client *Client, msg ircmsg.Message, rb *Response
// Construct set of channels the client is in.
userChannels := make(ChannelSet)
for _, channel := range client.Channels() {
userChannels[channel] = empty{}
userChannels.Add(channel)
}

// Another client is a friend if they share at least one channel, or they are the same client.
Expand All @@ -3437,7 +3437,7 @@ func whoHandler(server *Server, client *Client, msg ircmsg.Message, rb *Response
if channel.flags.HasMode(modes.Auditorium) {
return false // TODO this should respect +v etc.
}
if _, present := userChannels[channel]; present {
if userChannels.Has(channel) {
return true
}
}
Expand Down
2 changes: 1 addition & 1 deletion irc/history/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func (list *Buffer) betweenHelper(start, end Selector, cutoff time.Time, pred Pr

// returns all correspondents, in reverse time order
func (list *Buffer) allCorrespondents() (results []TargetListing) {
seen := make(utils.StringSet)
seen := make(utils.HashSet[string])

list.RLock()
defer list.RUnlock()
Expand Down
4 changes: 2 additions & 2 deletions irc/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type databaseImport struct {
Channels map[string]channelImport
}

func serializeAmodes(raw map[string]string, validCfUsernames utils.StringSet) (result []byte, err error) {
func serializeAmodes(raw map[string]string, validCfUsernames utils.HashSet[string]) (result []byte, err error) {
processed := make(map[string]int, len(raw))
for accountName, mode := range raw {
if len(mode) != 1 {
Expand All @@ -80,7 +80,7 @@ func doImportDBGeneric(config *Config, dbImport databaseImport, credsType Creden
tx.Set(keySchemaVersion, strconv.Itoa(importDBSchemaVersion), nil)
tx.Set(keyCloakSecret, utils.GenerateSecretKey(), nil)

cfUsernames := make(utils.StringSet)
cfUsernames := make(utils.HashSet[string])
skeletonToUsername := make(map[string]string)
warnSkeletons := false

Expand Down
17 changes: 9 additions & 8 deletions irc/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"sync"

"github.com/ergochat/ergo/irc/caps"
"github.com/ergochat/ergo/irc/utils"

"github.com/ergochat/irc-go/ircmsg"
)
Expand All @@ -17,21 +18,21 @@ type MonitorManager struct {
// client -> (casefolded nick it's watching -> uncasefolded nick)
watching map[*Session]map[string]string
// casefolded nick -> clients watching it
watchedby map[string]map[*Session]empty
watchedby map[string]utils.HashSet[*Session]
}

func (mm *MonitorManager) Initialize() {
mm.watching = make(map[*Session]map[string]string)
mm.watchedby = make(map[string]map[*Session]empty)
mm.watchedby = make(map[string]utils.HashSet[*Session])
}

// AddMonitors adds clients using extended-monitor monitoring `client`'s nick to the passed user set.
func (manager *MonitorManager) AddMonitors(users map[*Session]empty, cfnick string, capabs ...caps.Capability) {
func (manager *MonitorManager) AddMonitors(users utils.HashSet[*Session], cfnick string, capabs ...caps.Capability) {
manager.RLock()
defer manager.RUnlock()
for session := range manager.watchedby[cfnick] {
if session.capabilities.Has(caps.ExtendedMonitor) && session.capabilities.HasAll(capabs...) {
users[session] = empty{}
users.Add(session)
}
}
}
Expand Down Expand Up @@ -70,15 +71,15 @@ func (manager *MonitorManager) Add(session *Session, nick string, limit int) err
manager.watching[session] = make(map[string]string)
}
if manager.watchedby[cfnick] == nil {
manager.watchedby[cfnick] = make(map[*Session]empty)
manager.watchedby[cfnick] = make(utils.HashSet[*Session])
}

if len(manager.watching[session]) >= limit {
return errMonitorLimitExceeded
}

manager.watching[session][cfnick] = nick
manager.watchedby[cfnick][session] = empty{}
manager.watchedby[cfnick].Add(session)
return nil
}

Expand All @@ -92,7 +93,7 @@ func (manager *MonitorManager) Remove(session *Session, nick string) (err error)
manager.Lock()
defer manager.Unlock()
delete(manager.watching[session], cfnick)
delete(manager.watchedby[cfnick], session)
manager.watchedby[cfnick].Remove(session)
return nil
}

Expand All @@ -102,7 +103,7 @@ func (manager *MonitorManager) RemoveAll(session *Session) {
defer manager.Unlock()

for cfnick := range manager.watching[session] {
delete(manager.watchedby[cfnick], session)
manager.watchedby[cfnick].Remove(session)
}
delete(manager.watching, session)
}
Expand Down
4 changes: 2 additions & 2 deletions irc/nickname.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ var (
"MemoServ", "BotServ", "OperServ",
}

restrictedCasefoldedNicks = make(utils.StringSet)
restrictedSkeletons = make(utils.StringSet)
restrictedCasefoldedNicks = make(utils.HashSet[string])
restrictedSkeletons = make(utils.HashSet[string])
)

func performNickChange(server *Server, client *Client, target *Client, session *Session, nickname string, rb *ResponseBuffer) error {
Expand Down
23 changes: 3 additions & 20 deletions irc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,11 @@ import (
"time"

"github.com/ergochat/ergo/irc/modes"
"github.com/ergochat/ergo/irc/utils"
)

type empty struct{}

// ClientSet is a set of clients.
type ClientSet map[*Client]empty

// Add adds the given client to this set.
func (clients ClientSet) Add(client *Client) {
clients[client] = empty{}
}

// Remove removes the given client from this set.
func (clients ClientSet) Remove(client *Client) {
delete(clients, client)
}

// Has returns true if the given client is in this set.
func (clients ClientSet) Has(client *Client) bool {
_, ok := clients[client]
return ok
}
type ClientSet = utils.HashSet[*Client]

type memberData struct {
modes *modes.ModeSet
Expand Down Expand Up @@ -60,4 +43,4 @@ func (members MemberSet) Has(member *Client) bool {
}

// ChannelSet is a set of channels.
type ChannelSet map[*Channel]empty
type ChannelSet = utils.HashSet[*Channel]
22 changes: 17 additions & 5 deletions irc/utils/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,25 @@ package utils

type empty struct{}

type StringSet map[string]empty
type HashSet[T comparable] map[T]empty

func (s StringSet) Has(str string) bool {
_, ok := s[str]
func (s HashSet[T]) Has(elem T) bool {
_, ok := s[elem]
return ok
}

func (s StringSet) Add(str string) {
s[str] = empty{}
func (s HashSet[T]) Add(elem T) {
s[elem] = empty{}
}

func (s HashSet[T]) Remove(elem T) {
delete(s, elem)
}

func CopyMap[K comparable, V any](input map[K]V) (result map[K]V) {
result = make(map[K]V, len(input))
for key, value := range input {
result[key] = value
}
return
}
6 changes: 3 additions & 3 deletions irc/znc.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func timeToZncWireTime(t time.Time) (result string) {
type zncPlaybackTimes struct {
start time.Time
end time.Time
targets utils.StringSet // nil for "*" (everything), otherwise the channel names
targets utils.HashSet[string] // nil for "*" (everything), otherwise the channel names
setAt time.Time
}

Expand Down Expand Up @@ -134,7 +134,7 @@ func zncPlaybackPlayHandler(client *Client, command string, params []string, rb
end = zncWireTimeToTime(params[3])
}

var targets utils.StringSet
var targets utils.HashSet[string]
var nickTargets []string

// three cases:
Expand All @@ -157,7 +157,7 @@ func zncPlaybackPlayHandler(client *Client, command string, params []string, rb
if params[1] == "*" {
playPrivmsgs = true // XXX nil `targets` means "every channel"
} else {
targets = make(utils.StringSet)
targets = make(utils.HashSet[string])
for _, targetName := range strings.Split(targetString, ",") {
if strings.HasPrefix(targetName, "#") {
if cfTarget, err := CasefoldChannel(targetName); err == nil {
Expand Down