add data structures for decoding mode messages

This commit is contained in:
Jeremy Latt 2014-02-08 14:20:23 -08:00
parent b9cb539219
commit 3f9495cda0
4 changed files with 75 additions and 10 deletions

View File

@ -6,7 +6,7 @@ import (
)
func main() {
name := flag.String("name", "localhost", "A name for the server")
name := flag.String("name", "ergonomadic", "A name for the server")
listen := flag.String("listen", ":6667", "interface to listen on")
flag.BoolVar(&irc.DEBUG_NET, "dnet", false, "debug net")
flag.BoolVar(&irc.DEBUG_CLIENT, "dclient", false, "debug client")

View File

@ -13,6 +13,7 @@ type Client struct {
channels ChannelSet
conn net.Conn
hostname string
invisible bool
nick string
realname string
registered bool
@ -30,11 +31,12 @@ func NewClient(server *Server, conn net.Conn) *Client {
replies := make(chan Reply)
client := &Client{
channels: make(ChannelSet),
conn: conn,
hostname: LookupHostname(conn.RemoteAddr()),
replies: replies,
server: server,
channels: make(ChannelSet),
conn: conn,
hostname: LookupHostname(conn.RemoteAddr()),
replies: replies,
server: server,
serverPass: server.password == "",
}
go client.readConn(read)
@ -86,6 +88,9 @@ func (c *Client) Nick() string {
}
func (c *Client) UModeString() string {
if c.invisible {
return "i"
}
return ""
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
"strconv"
"strings"
"unicode/utf8"
)
type Command interface {
@ -371,14 +372,52 @@ func NewTopicCommand(args []string) (EditableCommand, error) {
return msg, nil
}
type Mode rune
const (
Away Mode = 'a'
Invisible Mode = 'i'
WallOps Mode = 'w'
Restricted Mode = 'r'
Operator Mode = 'o'
LocalOperator Mode = 'O'
ServerNotice Mode = 's'
)
type ModeChange struct {
mode Mode
add bool // false => remove
}
func (change *ModeChange) String() string {
sig := "+"
if !change.add {
sig = "-"
}
return fmt.Sprintf("%s%s", sig, change.mode)
}
type ModeCommand struct {
BaseCommand
nickname string
modes string
changes []ModeChange
}
func (cmd *ModeCommand) String() string {
return fmt.Sprintf("MODE(nickname=%s, modes=%s)", cmd.nickname, cmd.modes)
return fmt.Sprintf("MODE(nickname=%s, changes=%s)", cmd.nickname, cmd.changes)
}
func stringToRunes(str string) <-chan rune {
runes := make(chan rune)
go func() {
for len(str) > 0 {
rune, size := utf8.DecodeRuneInString(str)
runes <- rune
str = str[size:]
}
close(runes)
}()
return runes
}
func NewModeCommand(args []string) (EditableCommand, error) {
@ -388,10 +427,26 @@ func NewModeCommand(args []string) (EditableCommand, error) {
cmd := &ModeCommand{
nickname: args[0],
changes: make([]ModeChange,
utf8.RuneCountInString(strings.Join(args[1:], ""))-len(args[1:])),
}
if len(args) > 1 {
cmd.modes = 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: Mode(mode),
add: add,
}
index += 1
}
}
return cmd, nil

View File

@ -266,5 +266,10 @@ func (m *PrivMsgCommand) HandleServer(s *Server) {
}
func (m *ModeCommand) HandleServer(s *Server) {
for _, change := range m.changes {
if change.mode == Invisible {
m.Client().invisible = change.add
}
}
m.Client().replies <- RplUModeIs(s, m.Client())
}