mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 18:52:41 +01:00
use ModeOp everywhere
This commit is contained in:
parent
93f4b6859a
commit
20257ec624
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type editableCommand interface {
|
type editableCommand interface {
|
||||||
@ -374,15 +373,11 @@ func NewTopicCommand(args []string) (editableCommand, error) {
|
|||||||
|
|
||||||
type ModeChange struct {
|
type ModeChange struct {
|
||||||
mode UserMode
|
mode UserMode
|
||||||
add bool // false => remove
|
op ModeOp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (change *ModeChange) String() string {
|
func (change *ModeChange) String() string {
|
||||||
sig := "+"
|
return fmt.Sprintf("%s%s", change.op, change.mode)
|
||||||
if !change.add {
|
|
||||||
sig = "-"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s%s", sig, change.mode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ModeCommand struct {
|
type ModeCommand struct {
|
||||||
@ -391,21 +386,32 @@ type ModeCommand struct {
|
|||||||
changes []ModeChange
|
changes []ModeChange
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *ModeCommand) String() string {
|
// MODE <nickname> *( ( "+" / "-" ) *( "i" / "w" / "o" / "O" / "r" ) )
|
||||||
return fmt.Sprintf("MODE(nickname=%s, changes=%s)", cmd.nickname, cmd.changes)
|
func NewUserModeCommand(args []string) (editableCommand, error) {
|
||||||
|
cmd := &ModeCommand{
|
||||||
|
nickname: args[0],
|
||||||
|
changes: make([]ModeChange, 0),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, modeChange := range args[1:] {
|
||||||
|
op := ModeOp(modeChange[0])
|
||||||
|
if (op != Add) && (op != Remove) {
|
||||||
|
return nil, ErrParseCommand
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, mode := range modeChange[1:] {
|
||||||
|
cmd.changes = append(cmd.changes, ModeChange{
|
||||||
|
mode: UserMode(mode),
|
||||||
|
op: op,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func stringToRunes(str string) <-chan rune {
|
func (cmd *ModeCommand) String() string {
|
||||||
runes := make(chan rune)
|
return fmt.Sprintf("MODE(nickname=%s, changes=%s)", cmd.nickname, cmd.changes)
|
||||||
go func() {
|
|
||||||
for len(str) > 0 {
|
|
||||||
rune, size := utf8.DecodeRuneInString(str)
|
|
||||||
runes <- rune
|
|
||||||
str = str[size:]
|
|
||||||
}
|
|
||||||
close(runes)
|
|
||||||
}()
|
|
||||||
return runes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChannelModeOp struct {
|
type ChannelModeOp struct {
|
||||||
@ -434,23 +440,22 @@ func NewChannelModeCommand(args []string) (editableCommand, error) {
|
|||||||
|
|
||||||
for len(args) > 0 {
|
for len(args) > 0 {
|
||||||
modeArg := args[0]
|
modeArg := args[0]
|
||||||
op := List
|
|
||||||
switch modeArg[0] {
|
op := ModeOp(modeArg[0])
|
||||||
case '+':
|
if (op == Add) || (op == Remove) {
|
||||||
op = Add
|
|
||||||
modeArg = modeArg[1:]
|
|
||||||
case '-':
|
|
||||||
op = Remove
|
|
||||||
modeArg = modeArg[1:]
|
modeArg = modeArg[1:]
|
||||||
|
} else {
|
||||||
|
op = List
|
||||||
}
|
}
|
||||||
|
|
||||||
skipArgs := 1
|
skipArgs := 1
|
||||||
for mode := range stringToRunes(modeArg) {
|
for _, mode := range modeArg {
|
||||||
modeOp := ChannelModeOp{
|
modeOp := ChannelModeOp{
|
||||||
mode: ChannelMode(mode),
|
mode: ChannelMode(mode),
|
||||||
op: op,
|
op: op,
|
||||||
}
|
}
|
||||||
switch modeOp.mode {
|
switch modeOp.mode {
|
||||||
case Key, BanMask, ExceptionMask, InviteMask:
|
case Key, BanMask, ExceptionMask, InviteMask, UserLimit:
|
||||||
if len(args) > skipArgs {
|
if len(args) > skipArgs {
|
||||||
modeOp.arg = args[skipArgs]
|
modeOp.arg = args[skipArgs]
|
||||||
skipArgs += 1
|
skipArgs += 1
|
||||||
@ -468,35 +473,6 @@ func (msg *ChannelModeCommand) String() string {
|
|||||||
return fmt.Sprintf("MODE(channel=%s, modeOps=%s)", msg.channel, msg.modeOps)
|
return fmt.Sprintf("MODE(channel=%s, modeOps=%s)", msg.channel, msg.modeOps)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MODE <nickname> *( ( "+" / "-" ) *( "i" / "w" / "o" / "O" / "r" ) )
|
|
||||||
func NewUserModeCommand(args []string) (editableCommand, error) {
|
|
||||||
cmd := &ModeCommand{
|
|
||||||
nickname: args[0],
|
|
||||||
changes: make([]ModeChange,
|
|
||||||
utf8.RuneCountInString(strings.Join(args[1:], ""))-len(args[1:])),
|
|
||||||
}
|
|
||||||
|
|
||||||
index := 0
|
|
||||||
for _, arg := range args[1:] {
|
|
||||||
modeChange := stringToRunes(arg)
|
|
||||||
sig := <-modeChange
|
|
||||||
if sig != '+' && sig != '-' {
|
|
||||||
return nil, ErrParseCommand
|
|
||||||
}
|
|
||||||
|
|
||||||
add := sig == '+'
|
|
||||||
for mode := range modeChange {
|
|
||||||
cmd.changes[index] = ModeChange{
|
|
||||||
mode: UserMode(mode),
|
|
||||||
add: add,
|
|
||||||
}
|
|
||||||
index += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmd, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewModeCommand(args []string) (editableCommand, error) {
|
func NewModeCommand(args []string) (editableCommand, error) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return nil, NotEnoughArgsError
|
return nil, NotEnoughArgsError
|
||||||
@ -543,7 +519,7 @@ func (msg *WhoisCommand) String() string {
|
|||||||
|
|
||||||
type WhoCommand struct {
|
type WhoCommand struct {
|
||||||
BaseCommand
|
BaseCommand
|
||||||
mask string
|
mask Mask
|
||||||
operatorOnly bool
|
operatorOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,7 +528,7 @@ func NewWhoCommand(args []string) (editableCommand, error) {
|
|||||||
cmd := &WhoCommand{}
|
cmd := &WhoCommand{}
|
||||||
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
cmd.mask = args[0]
|
cmd.mask = Mask(args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len(args) > 1) && (args[1] == "o") {
|
if (len(args) > 1) && (args[1] == "o") {
|
||||||
|
@ -158,32 +158,32 @@ const (
|
|||||||
RPL_PRIVMSG = "PRIVMSG"
|
RPL_PRIVMSG = "PRIVMSG"
|
||||||
RPL_QUIT = "QUIT"
|
RPL_QUIT = "QUIT"
|
||||||
|
|
||||||
List ModeOp = 'l'
|
Add ModeOp = '+'
|
||||||
Add ModeOp = 'a'
|
List ModeOp = '='
|
||||||
Remove ModeOp = 'r'
|
Remove ModeOp = '-'
|
||||||
|
|
||||||
Away UserMode = 'a'
|
Away UserMode = 'a'
|
||||||
Invisible UserMode = 'i'
|
Invisible UserMode = 'i'
|
||||||
WallOps UserMode = 'w'
|
|
||||||
Restricted UserMode = 'r'
|
|
||||||
Operator UserMode = 'o'
|
|
||||||
LocalOperator UserMode = 'O'
|
LocalOperator UserMode = 'O'
|
||||||
|
Operator UserMode = 'o'
|
||||||
|
Restricted UserMode = 'r'
|
||||||
ServerNotice UserMode = 's'
|
ServerNotice UserMode = 's'
|
||||||
|
WallOps UserMode = 'w'
|
||||||
|
|
||||||
Anonymous ChannelMode = 'a'
|
Anonymous ChannelMode = 'a'
|
||||||
|
BanMask ChannelMode = 'b' // arg
|
||||||
|
ExceptionMask ChannelMode = 'e' // arg
|
||||||
|
InviteMask ChannelMode = 'i' // arg
|
||||||
InviteOnly ChannelMode = 'i'
|
InviteOnly ChannelMode = 'i'
|
||||||
|
Key ChannelMode = 'k' // arg
|
||||||
Moderated ChannelMode = 'm'
|
Moderated ChannelMode = 'm'
|
||||||
NoOutside ChannelMode = 'n'
|
NoOutside ChannelMode = 'n'
|
||||||
Quiet ChannelMode = 'q'
|
|
||||||
Private ChannelMode = 'p'
|
|
||||||
Secret ChannelMode = 's'
|
|
||||||
ReOp ChannelMode = 'r'
|
|
||||||
OpOnlyTopic ChannelMode = 't'
|
OpOnlyTopic ChannelMode = 't'
|
||||||
Key ChannelMode = 'k'
|
Private ChannelMode = 'p'
|
||||||
UserLimit ChannelMode = 'l'
|
Quiet ChannelMode = 'q'
|
||||||
BanMask ChannelMode = 'b'
|
ReOp ChannelMode = 'r'
|
||||||
ExceptionMask ChannelMode = 'e'
|
Secret ChannelMode = 's'
|
||||||
InviteMask ChannelMode = 'i'
|
UserLimit ChannelMode = 'l' // arg
|
||||||
|
|
||||||
ChannelCreator UserChannelMode = 'O'
|
ChannelCreator UserChannelMode = 'O'
|
||||||
ChannelOperator UserChannelMode = 'o'
|
ChannelOperator UserChannelMode = 'o'
|
||||||
|
@ -271,7 +271,12 @@ func (m *ModeCommand) HandleServer(s *Server) {
|
|||||||
if client.Nick() == m.nickname {
|
if client.Nick() == m.nickname {
|
||||||
for _, change := range m.changes {
|
for _, change := range m.changes {
|
||||||
if change.mode == Invisible {
|
if change.mode == Invisible {
|
||||||
client.invisible = change.add
|
switch change.op {
|
||||||
|
case Add:
|
||||||
|
client.invisible = true
|
||||||
|
case Remove:
|
||||||
|
client.invisible = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
client.replies <- RplUModeIs(s, client)
|
client.replies <- RplUModeIs(s, client)
|
||||||
@ -320,21 +325,22 @@ func (msg *WhoCommand) HandleServer(server *Server) {
|
|||||||
client := msg.Client()
|
client := msg.Client()
|
||||||
// TODO implement wildcard matching
|
// TODO implement wildcard matching
|
||||||
|
|
||||||
if msg.mask == "" {
|
mask := string(msg.mask)
|
||||||
|
if mask == "" {
|
||||||
for _, channel := range server.channels {
|
for _, channel := range server.channels {
|
||||||
whoChannel(client, server, channel)
|
whoChannel(client, server, channel)
|
||||||
}
|
}
|
||||||
} else if IsChannel(msg.mask) {
|
} else if IsChannel(mask) {
|
||||||
channel := server.channels[msg.mask]
|
channel := server.channels[mask]
|
||||||
if channel != nil {
|
if channel != nil {
|
||||||
whoChannel(client, server, channel)
|
whoChannel(client, server, channel)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mclient := server.clients[msg.mask]
|
mclient := server.clients[mask]
|
||||||
if mclient != nil {
|
if mclient != nil {
|
||||||
client.replies <- RplWhoReply(server, mclient.channels.First(), mclient)
|
client.replies <- RplWhoReply(server, mclient.channels.First(), mclient)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client.replies <- RplEndOfWho(server, msg.mask)
|
client.replies <- RplEndOfWho(server, mask)
|
||||||
}
|
}
|
||||||
|
27
irc/types.go
27
irc/types.go
@ -4,16 +4,31 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//
|
||||||
// simple types
|
// simple types
|
||||||
|
//
|
||||||
|
|
||||||
type ModeOp rune
|
// a string with wildcards
|
||||||
type UserMode rune
|
|
||||||
type ChannelMode rune
|
|
||||||
type UserChannelMode rune
|
|
||||||
type Mask string
|
type Mask string
|
||||||
|
|
||||||
// interfaces
|
// add, remove, list modes
|
||||||
|
type ModeOp rune
|
||||||
|
|
||||||
|
// user mode flags
|
||||||
|
type UserMode rune
|
||||||
|
|
||||||
|
// channel mode flags
|
||||||
|
type ChannelMode rune
|
||||||
|
|
||||||
|
// user-channel mode flags
|
||||||
|
type UserChannelMode rune
|
||||||
|
|
||||||
|
//
|
||||||
|
// interfaces
|
||||||
|
//
|
||||||
|
|
||||||
|
// commands the server understands
|
||||||
|
// TODO rename ServerCommand
|
||||||
type Command interface {
|
type Command interface {
|
||||||
Client() *Client
|
Client() *Client
|
||||||
Source() Identifier
|
Source() Identifier
|
||||||
@ -21,7 +36,9 @@ type Command interface {
|
|||||||
HandleServer(*Server)
|
HandleServer(*Server)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// structs
|
// structs
|
||||||
|
//
|
||||||
|
|
||||||
type UserMask struct {
|
type UserMask struct {
|
||||||
nickname Mask
|
nickname Mask
|
||||||
|
Loading…
Reference in New Issue
Block a user