irc/modes.go
Justin 2ef0464d1d Added proper parsing of channel modes.
Implemented parsing and storage of Channel Mode flags. Not all flags are currently being utilized.
2015-08-07 17:37:41 -07:00

211 lines
5.3 KiB
Go

package irc
import (
"fmt"
"sync"
)
// UserMode - RFC 1459 Section 4.2.3.2 and RFC 2812 Section 3.1.5
type UserMode rune
const (
UserModeAway UserMode = 'a'
UserModeInvisible UserMode = 'i'
UserModeWallOps UserMode = 'w'
UserModeRestricted UserMode = 'r'
UserModeOperator UserMode = 'o'
UserModeLocalOperator UserMode = 'O'
UserModeServerNotice UserMode = 's' //obsolete
)
// UserModes contains the supported User UserMode types
var UserModes = map[UserMode]interface{}{
UserModeAway: nil,
UserModeInvisible: nil,
UserModeWallOps: nil,
UserModeRestricted: nil,
UserModeOperator: nil,
UserModeLocalOperator: nil,
UserModeServerNotice: nil,
}
// UserModeSet provides means for storing and checking UserModes
type UserModeSet struct {
userModes map[UserMode]interface{}
mutex sync.RWMutex
}
// NewUserModeSet creates and returns a new UserModeSet
func NewUserModeSet() *UserModeSet {
u := UserModeSet{}
u.userModes = map[UserMode]interface{}{}
return &u
}
// AddMode adds a mode to the UserModeSet
func (u *UserModeSet) AddMode(mode UserMode) {
u.mutex.Lock()
defer u.mutex.Unlock()
u.userModes[mode] = nil
}
// RemoveMode removes a mode from the UserModeSet
func (u *UserModeSet) RemoveMode(mode UserMode) {
u.mutex.Lock()
defer u.mutex.Unlock()
delete(u.userModes, mode)
}
// HasMode detects if a UserMode is contained in the UserModeSet
func (u *UserModeSet) HasMode(mode UserMode) bool {
u.mutex.RLock()
defer u.mutex.RUnlock()
_, found := u.userModes[mode]
return found
}
// String formats the UserModeString to be returned for MODE queries
func (u *UserModeSet) String() string {
s := ""
if len(u.userModes) > 0 {
s = "+"
}
for m := range u.userModes {
s += string(m)
}
return s
}
// ModeModifier - RFC 1459 Section 4.2.3 and RFC 2812 Section 3.1.5
type ModeModifier rune
const (
ModeModifierAdd ModeModifier = '+'
ModeModifierRemove ModeModifier = '-'
)
// ChannelMode - RFC 1459 Section 4.2.3.1 and RFC 2812 Section 3.2.3 and RFC 2811 Section 4
type ChannelMode rune
const (
ChannelModeCreator ChannelMode = 'O'
ChannelModeOperator ChannelMode = 'o'
ChannelModeVoice ChannelMode = 'v'
ChannelModeAnonymous ChannelMode = 'a'
ChannelModeInviteOnly ChannelMode = 'i'
ChannelModeModerated ChannelMode = 'm'
ChannelModeNoOutsideMessages ChannelMode = 'n'
ChannelModeQuiet ChannelMode = 'q'
ChannelModePrivate ChannelMode = 'p'
ChannelModeSecret ChannelMode = 's'
ChannelModeReOp ChannelMode = 'r'
ChannelModeTopic ChannelMode = 't'
ChannelModeKey ChannelMode = 'k'
ChannelModeLimit ChannelMode = 'l'
ChannelModeBan ChannelMode = 'b'
ChannelModeExceptionMask ChannelMode = 'e'
ChannelModeInvitationMask ChannelMode = 'I'
)
// ChannelModes contains the supported channel modes
// Currently supported modes are just those in RFC 1459
var ChannelModes = map[ChannelMode]interface{}{
//ChannelModeCreator: nil,
ChannelModeOperator: nil,
ChannelModeVoice: nil,
//ChannelModeAnonymous: nil,
ChannelModeInviteOnly: nil,
ChannelModeModerated: nil,
ChannelModeNoOutsideMessages: nil,
//ChannelModeQuiet: nil,
ChannelModePrivate: nil,
ChannelModeSecret: nil,
//ChannelModeReOp: nil,
ChannelModeTopic: nil,
ChannelModeKey: nil,
ChannelModeLimit: nil,
ChannelModeBan: nil,
//ChannelModeExceptionMask: nil,
//ChannelModeInvitationMask: nil,
}
// ChannelModeSet represents a set of active ChannelModes
type ChannelModeSet struct {
modes map[ChannelMode]interface{}
mutex sync.RWMutex
}
// NewChannelModeSet creates and returns a new ChannelModeSet
func NewChannelModeSet() *ChannelModeSet {
c := ChannelModeSet{}
c.modes = map[ChannelMode]interface{}{}
return &c
}
// AddMode adds a ChannelMode as active
func (c *ChannelModeSet) AddMode(mode ChannelMode) {
c.mutex.Lock()
defer c.mutex.Unlock()
c.modes[mode] = nil
}
// AddModeWithValue adds a ChannelMode as active with a value
func (c *Channel) AddModeWithValue(mode ChannelMode, value interface{}) {
c.mutex.Lock()
defer c.mutex.Unlock()
c.modes[mode] = value
}
// RemoveMode removes the given mode from the active set
func (c *ChannelModeSet) RemoveMode(mode ChannelMode) {
c.mutex.Lock()
defer c.mutex.Unlock()
delete(c.modes, mode)
}
// HasMode determines if the ChannelModeSet contains the given ChannelMode
func (c *ChannelModeSet) HasMode(mode ChannelMode) bool {
c.mutex.RLock()
defer c.mutex.RUnlock()
_, found := c.modes[mode]
return found
}
// GetMode determines if the ChannelModeSet contains the given ChannelMode
func (c *ChannelModeSet) GetMode(mode ChannelMode) interface{} {
c.mutex.RLock()
defer c.mutex.RUnlock()
return c.modes[mode]
}
// String returns the ChannelModeSet formatted for the MODE queries
func (c *ChannelModeSet) String() string {
s := "+"
params := []interface{}{}
for m, param := range c.modes {
switch m {
case ChannelModeKey, ChannelModeLimit, ChannelModeModerated, ChannelModeAnonymous, ChannelModeInviteOnly, ChannelModePrivate, ChannelModeSecret, ChannelModeTopic:
default:
continue
}
s += string(m)
params = append(params, param)
}
for _, param := range params {
s += fmt.Sprintf(" %v", param)
}
return s
}