Przeglądaj źródła

cleanup and reorganization

tags/v0.1.0
Jeremy Latt 11 lat temu
rodzic
commit
55f7c89468
8 zmienionych plików z 254 dodań i 196 usunięć
  1. 6
    0
      README.md
  2. 28
    5
      src/irc/channel.go
  3. 15
    6
      src/irc/client.go
  4. 140
    2
      src/irc/commands.go
  5. 19
    18
      src/irc/constants.go
  6. 25
    153
      src/irc/parse.go
  7. 4
    3
      src/irc/reply.go
  8. 17
    9
      src/irc/server.go

+ 6
- 0
README.md Wyświetl plik

@@ -11,3 +11,9 @@ I wanted to learn Go.
11 11
 ### What's with the name?
12 12
 
13 13
 "Ergonomadic" is an anagram of "Go IRC Daemon".
14
+
15
+### Helpful Documentation
16
+
17
+- [IRC Channel Management](http://tools.ietf.org/html/rfc2811)
18
+- [IRC Client Protocol](http://tools.ietf.org/html/rfc2812)
19
+- [IRC Server Protocol](http://tools.ietf.org/html/rfc2813)

+ 28
- 5
src/irc/channel.go Wyświetl plik

@@ -1,5 +1,9 @@
1 1
 package irc
2 2
 
3
+import (
4
+	"sort"
5
+)
6
+
3 7
 type Channel struct {
4 8
 	name       string
5 9
 	key        string
@@ -12,10 +16,19 @@ type Channel struct {
12 16
 
13 17
 type ChannelSet map[*Channel]bool
14 18
 
19
+// NewChannel creates a new channel from a `Server` and a `name` string, which
20
+// must be unique on the server.
15 21
 func NewChannel(s *Server, name string) *Channel {
16
-	return &Channel{name: name, members: make(ClientSet), invites: make(map[string]bool), server: s}
22
+	return &Channel{
23
+		name:    name,
24
+		members: make(ClientSet),
25
+		invites: make(map[string]bool),
26
+		server:  s,
27
+	}
17 28
 }
18 29
 
30
+// Send a `Reply` to all `Client`s of the `Channel`. Skip `fromClient`, if it is
31
+// provided.
19 32
 func (ch *Channel) Send(reply Reply, fromClient *Client) {
20 33
 	for client := range ch.members {
21 34
 		if client != fromClient {
@@ -24,7 +37,20 @@ func (ch *Channel) Send(reply Reply, fromClient *Client) {
24 37
 	}
25 38
 }
26 39
 
40
+func (ch *Channel) Nicks() []string {
41
+	nicks := make([]string, len(ch.members))
42
+	i := 0
43
+	for member := range ch.members {
44
+		nicks[i] = member.Nick()
45
+		i++
46
+	}
47
+	sort.Strings(nicks)
48
+	return nicks
49
+}
50
+
51
+//
27 52
 // channel functionality
53
+//
28 54
 
29 55
 func (ch *Channel) Join(cl *Client, key string) {
30 56
 	if ch.key != key {
@@ -42,10 +68,7 @@ func (ch *Channel) Join(cl *Client, key string) {
42 68
 
43 69
 	ch.Send(RplJoin(ch, cl), nil)
44 70
 	ch.GetTopic(cl)
45
-
46
-	for member := range ch.members {
47
-		cl.send <- RplNamReply(ch, member)
48
-	}
71
+	cl.send <- RplNamReply(ch)
49 72
 	cl.send <- RplEndOfNames(ch.server)
50 73
 }
51 74
 

+ 15
- 6
src/irc/client.go Wyświetl plik

@@ -16,12 +16,19 @@ type Client struct {
16 16
 	registered bool
17 17
 	invisible  bool
18 18
 	channels   ChannelSet
19
+	server     *Server
19 20
 }
20 21
 
21 22
 type ClientSet map[*Client]bool
22 23
 
23
-func NewClient(conn net.Conn) *Client {
24
-	client := &Client{conn: conn, recv: StringReadChan(conn), channels: make(ChannelSet), hostname: LookupHostname(conn.RemoteAddr())}
24
+func NewClient(server *Server, conn net.Conn) *Client {
25
+	client := &Client{
26
+		channels: make(ChannelSet),
27
+		conn:     conn,
28
+		hostname: LookupHostname(conn.RemoteAddr()),
29
+		recv:     StringReadChan(conn),
30
+		server:   server,
31
+	}
25 32
 	client.SetReplyToStringChan()
26 33
 	return client
27 34
 }
@@ -38,12 +45,14 @@ func (c *Client) SetReplyToStringChan() {
38 45
 }
39 46
 
40 47
 // Adapt `chan string` to a `chan Message`.
41
-func (c *Client) Communicate(server *Server) {
48
+func (c *Client) Communicate() {
42 49
 	for str := range c.recv {
43
-		m := ParseMessage(str)
44
-		if m != nil {
45
-			server.recv <- &ClientMessage{c, m}
50
+		m, err := ParseMessage(str)
51
+		if err != nil {
52
+			// TODO handle error
53
+			return
46 54
 		}
55
+		c.server.recv <- &ClientMessage{c, m}
47 56
 	}
48 57
 }
49 58
 

+ 140
- 2
src/irc/commands.go Wyświetl plik

@@ -1,15 +1,30 @@
1 1
 package irc
2 2
 
3
+import (
4
+	"errors"
5
+	"fmt"
6
+	"regexp"
7
+	"strconv"
8
+	"strings"
9
+)
10
+
3 11
 type Message interface {
4 12
 	Handle(s *Server, c *Client)
5 13
 }
6 14
 
15
+var (
16
+	ErrNotEnoughArgs    = errors.New("not enough arguments")
17
+	ErrUModeUnknownFlag = errors.New("unknown umode flag")
18
+)
19
+
7 20
 // unknown
8 21
 
9 22
 type UnknownMessage struct {
10 23
 	command string
11 24
 }
12 25
 
26
+// NB: no constructor, created on demand in parser for invalid messages.
27
+
13 28
 func (m *UnknownMessage) Handle(s *Server, c *Client) {
14 29
 	c.send <- ErrUnknownCommand(s, m.command)
15 30
 }
@@ -21,6 +36,17 @@ type PingMessage struct {
21 36
 	server2 string
22 37
 }
23 38
 
39
+func NewPingMessage(args []string) (Message, error) {
40
+	if len(args) < 1 {
41
+		return nil, ErrNotEnoughArgs
42
+	}
43
+	msg := &PingMessage{server: args[0]}
44
+	if len(args) > 1 {
45
+		msg.server2 = args[1]
46
+	}
47
+	return msg, nil
48
+}
49
+
24 50
 func (m *PingMessage) Handle(s *Server, c *Client) {
25 51
 	c.send <- RplPong(s)
26 52
 }
@@ -32,8 +58,19 @@ type PongMessage struct {
32 58
 	server2 string
33 59
 }
34 60
 
61
+func NewPongMessage(args []string) (Message, error) {
62
+	if len(args) < 1 {
63
+		return nil, ErrNotEnoughArgs
64
+	}
65
+	message := &PongMessage{server1: args[0]}
66
+	if len(args) > 1 {
67
+		message.server2 = args[1]
68
+	}
69
+	return message, nil
70
+}
71
+
35 72
 func (m *PongMessage) Handle(s *Server, c *Client) {
36
-	// TODO update client atime
73
+	// no-op
37 74
 }
38 75
 
39 76
 // NICK
@@ -42,6 +79,13 @@ type NickMessage struct {
42 79
 	nickname string
43 80
 }
44 81
 
82
+func NewNickMessage(args []string) (Message, error) {
83
+	if len(args) != 1 {
84
+		return nil, ErrNotEnoughArgs
85
+	}
86
+	return &NickMessage{args[0]}, nil
87
+}
88
+
45 89
 func (m *NickMessage) Handle(s *Server, c *Client) {
46 90
 	s.ChangeNick(c, m.nickname)
47 91
 }
@@ -55,8 +99,24 @@ type UserMessage struct {
55 99
 	realname string
56 100
 }
57 101
 
102
+func NewUserMessage(args []string) (Message, error) {
103
+	if len(args) != 4 {
104
+		return nil, ErrNotEnoughArgs
105
+	}
106
+	msg := &UserMessage{
107
+		user:     args[0],
108
+		unused:   args[2],
109
+		realname: args[3],
110
+	}
111
+	mode, err := strconv.ParseUint(args[1], 10, 8)
112
+	if err == nil {
113
+		msg.mode = uint8(mode)
114
+	}
115
+	return msg, nil
116
+}
117
+
58 118
 func (m *UserMessage) Handle(s *Server, c *Client) {
59
-	s.Register(c, m.user, m.realname)
119
+	s.UserLogin(c, m.user, m.realname)
60 120
 }
61 121
 
62 122
 // QUIT
@@ -65,6 +125,14 @@ type QuitMessage struct {
65 125
 	message string
66 126
 }
67 127
 
128
+func NewQuitMessage(args []string) (Message, error) {
129
+	msg := &QuitMessage{}
130
+	if len(args) > 0 {
131
+		msg.message = args[0]
132
+	}
133
+	return msg, nil
134
+}
135
+
68 136
 func (m *QuitMessage) Handle(s *Server, c *Client) {
69 137
 	s.Quit(c, m.message)
70 138
 }
@@ -76,6 +144,28 @@ type ModeMessage struct {
76 144
 	modes    []string
77 145
 }
78 146
 
147
+var MODE_RE = regexp.MustCompile("^[-+][a-zA-Z]+$")
148
+
149
+func NewModeMessage(args []string) (Message, error) {
150
+	if len(args) < 1 {
151
+		return nil, ErrNotEnoughArgs
152
+	}
153
+	msg := &ModeMessage{
154
+		nickname: args[0],
155
+	}
156
+	for _, arg := range args[1:] {
157
+		if !MODE_RE.MatchString(arg) {
158
+			return nil, ErrUModeUnknownFlag
159
+		}
160
+		prefix := arg[0]
161
+		for _, c := range arg[1:] {
162
+			mode := fmt.Sprintf("%c%c", prefix, c)
163
+			msg.modes = append(msg.modes, mode)
164
+		}
165
+	}
166
+	return msg, nil
167
+}
168
+
79 169
 func (m *ModeMessage) Handle(s *Server, c *Client) {
80 170
 	if m.nickname != c.nick {
81 171
 		c.send <- ErrUsersDontMatch(s)
@@ -92,6 +182,22 @@ type JoinMessage struct {
92 182
 	zero     bool
93 183
 }
94 184
 
185
+func NewJoinMessage(args []string) (Message, error) {
186
+	msg := &JoinMessage{}
187
+	if len(args) > 0 {
188
+		if args[0] == "0" {
189
+			msg.zero = true
190
+		} else {
191
+			msg.channels = strings.Split(args[0], ",")
192
+		}
193
+
194
+		if len(args) > 1 {
195
+			msg.keys = strings.Split(args[1], ",")
196
+		}
197
+	}
198
+	return msg, nil
199
+}
200
+
95 201
 func (m *JoinMessage) Handle(s *Server, c *Client) {
96 202
 	if m.zero {
97 203
 		for channel := range c.channels {
@@ -116,6 +222,17 @@ type PartMessage struct {
116 222
 	message  string
117 223
 }
118 224
 
225
+func NewPartMessage(args []string) (Message, error) {
226
+	if len(args) < 1 {
227
+		return nil, ErrNotEnoughArgs
228
+	}
229
+	msg := &PartMessage{channels: strings.Split(args[0], ",")}
230
+	if len(args) > 1 {
231
+		msg.message = args[1]
232
+	}
233
+	return msg, nil
234
+}
235
+
119 236
 func (m *PartMessage) Handle(s *Server, c *Client) {
120 237
 	for _, chname := range m.channels {
121 238
 		channel := s.channels[chname]
@@ -136,6 +253,16 @@ type PrivMsgMessage struct {
136 253
 	message string
137 254
 }
138 255
 
256
+func NewPrivMsgMessage(args []string) (Message, error) {
257
+	if len(args) < 2 {
258
+		return nil, ErrNotEnoughArgs
259
+	}
260
+	return &PrivMsgMessage{
261
+		target:  args[0],
262
+		message: args[1],
263
+	}, nil
264
+}
265
+
139 266
 func (m *PrivMsgMessage) TargetIsChannel() bool {
140 267
 	switch m.target[0] {
141 268
 	case '&', '#', '+', '!':
@@ -169,6 +296,17 @@ type TopicMessage struct {
169 296
 	topic   string
170 297
 }
171 298
 
299
+func NewTopicMessage(args []string) (Message, error) {
300
+	if len(args) < 1 {
301
+		return nil, ErrNotEnoughArgs
302
+	}
303
+	msg := &TopicMessage{channel: args[0]}
304
+	if len(args) > 1 {
305
+		msg.topic = args[1]
306
+	}
307
+	return msg, nil
308
+}
309
+
172 310
 func (m *TopicMessage) Handle(s *Server, c *Client) {
173 311
 	channel := s.channels[m.channel]
174 312
 	if channel == nil {

+ 19
- 18
src/irc/constants.go Wyświetl plik

@@ -1,6 +1,3 @@
1
-// channel management: http://tools.ietf.org/html/rfc2811
2
-// client protocol:    http://tools.ietf.org/html/rfc2812
3
-// server protocol:    http://tools.ietf.org/html/rfc2813
4 1
 package irc
5 2
 
6 3
 const (
@@ -8,16 +5,19 @@ const (
8 5
 )
9 6
 
10 7
 const (
11
-	RPL_WELCOME           = "001"
12
-	RPL_YOURHOST          = "002"
13
-	RPL_CREATED           = "003"
14
-	RPL_MYINFO            = "004"
15
-	RPL_UMODEIS           = "221"
16
-	RPL_NOTOPIC           = "331"
17
-	RPL_TOPIC             = "332"
18
-	RPL_NAMREPLY          = "353"
19
-	RPL_ENDOFNAMES        = "366"
20
-	RPL_INFO              = "371"
8
+	// # numeric codes
9
+	// ## reply codes
10
+	RPL_WELCOME    = "001"
11
+	RPL_YOURHOST   = "002"
12
+	RPL_CREATED    = "003"
13
+	RPL_MYINFO     = "004"
14
+	RPL_UMODEIS    = "221"
15
+	RPL_NOTOPIC    = "331"
16
+	RPL_TOPIC      = "332"
17
+	RPL_NAMREPLY   = "353"
18
+	RPL_ENDOFNAMES = "366"
19
+	RPL_INFO       = "371"
20
+	// ## error codes
21 21
 	ERR_NOSUCHNICK        = "401"
22 22
 	ERR_NOSUCHSERVER      = "402"
23 23
 	ERR_NOSUCHCHANNEL     = "403"
@@ -29,9 +29,10 @@ const (
29 29
 	ERR_INVITEONLYCHANNEL = "473"
30 30
 	ERR_BADCHANNELKEY     = "475"
31 31
 	ERR_USERSDONTMATCH    = "502"
32
-	RPL_JOIN              = "JOIN"
33
-	RPL_NICK              = "NICK"
34
-	RPL_PART              = "PART"
35
-	RPL_PONG              = "PONG"
36
-	RPL_PRIVMSG           = "PRIVMSG"
32
+	// # message codes
33
+	RPL_JOIN    = "JOIN"
34
+	RPL_NICK    = "NICK"
35
+	RPL_PART    = "PART"
36
+	RPL_PONG    = "PONG"
37
+	RPL_PRIVMSG = "PRIVMSG"
37 38
 )

+ 25
- 153
src/irc/parse.go Wyświetl plik

@@ -1,13 +1,11 @@
1 1
 package irc
2 2
 
3 3
 import (
4
-	"fmt"
5
-	"regexp"
6
-	"strconv"
4
+	"errors"
7 5
 	"strings"
8 6
 )
9 7
 
10
-var commands = map[string]func([]string) Message{
8
+var commands = map[string]func([]string) (Message, error){
11 9
 	"JOIN":    NewJoinMessage,
12 10
 	"MODE":    NewModeMessage,
13 11
 	"NICK":    NewNickMessage,
@@ -20,169 +18,43 @@ var commands = map[string]func([]string) Message{
20 18
 	"USER":    NewUserMessage,
21 19
 }
22 20
 
23
-func ParseMessage(line string) Message {
21
+var (
22
+	ErrParseMessage = errors.New("failed to parse message")
23
+)
24
+
25
+func ParseMessage(line string) (msg Message, err error) {
24 26
 	command, args := parseLine(line)
25 27
 	constructor, ok := commands[command]
26
-	var msg Message
27
-	if ok {
28
-		msg = constructor(args)
29
-	}
30
-	if msg == nil {
28
+	if !ok {
31 29
 		msg = &UnknownMessage{command}
30
+		return
32 31
 	}
33
-	return msg
32
+	msg, err = constructor(args)
33
+	return
34 34
 }
35 35
 
36
-func parseArg(line string) (string, string) {
36
+func parseArg(line string) (arg string, rest string) {
37 37
 	if line == "" {
38
-		return "", ""
38
+		return
39 39
 	}
40 40
 
41 41
 	if strings.HasPrefix(line, ":") {
42
-		return line[1:], ""
43
-	}
44
-
45
-	parts := strings.SplitN(line, " ", 2)
46
-	arg := parts[0]
47
-	rest := ""
48
-	if len(parts) > 1 {
49
-		rest = parts[1]
42
+		arg = line[1:]
43
+	} else {
44
+		parts := strings.SplitN(line, " ", 2)
45
+		arg = parts[0]
46
+		if len(parts) > 1 {
47
+			rest = parts[1]
48
+		}
50 49
 	}
51
-	return arg, rest
50
+	return
52 51
 }
53 52
 
54
-func parseLine(line string) (string, []string) {
55
-	args := make([]string, 0)
53
+func parseLine(line string) (command string, args []string) {
54
+	args = make([]string, 0)
56 55
 	for arg, rest := parseArg(line); arg != ""; arg, rest = parseArg(rest) {
57 56
 		args = append(args, arg)
58 57
 	}
59
-	return args[0], args[1:]
60
-}
61
-
62
-// []string => Message constructors
63
-
64
-func NewNickMessage(args []string) Message {
65
-	if len(args) != 1 {
66
-		return nil
67
-	}
68
-	return &NickMessage{args[0]}
69
-}
70
-
71
-func NewPingMessage(args []string) Message {
72
-	if len(args) < 1 {
73
-		return nil
74
-	}
75
-	message := &PingMessage{server: args[0]}
76
-	if len(args) > 1 {
77
-		message.server2 = args[1]
78
-	}
79
-	return message
80
-}
81
-
82
-func NewPongMessage(args []string) Message {
83
-	if len(args) < 1 {
84
-		return nil
85
-	}
86
-	message := &PongMessage{server1: args[0]}
87
-	if len(args) > 1 {
88
-		message.server2 = args[1]
89
-	}
90
-	return message
91
-}
92
-
93
-func NewQuitMessage(args []string) Message {
94
-	msg := QuitMessage{}
95
-	if len(args) > 0 {
96
-		msg.message = args[0]
97
-	}
98
-	return &msg
99
-}
100
-
101
-func NewUserMessage(args []string) Message {
102
-	if len(args) != 4 {
103
-		return nil
104
-	}
105
-	msg := new(UserMessage)
106
-	msg.user = args[0]
107
-	mode, err := strconv.ParseUint(args[1], 10, 8)
108
-	if err == nil {
109
-		msg.mode = uint8(mode)
110
-	}
111
-	msg.unused = args[2]
112
-	msg.realname = args[3]
113
-	return msg
114
-}
115
-
116
-var MODE_RE = regexp.MustCompile("^[-+][a-zA-Z]+$")
117
-
118
-func NewModeMessage(args []string) Message {
119
-	if len(args) < 1 {
120
-		return nil
121
-	}
122
-	msg := new(ModeMessage)
123
-	msg.nickname = args[0]
124
-	for _, arg := range args[1:] {
125
-		if !MODE_RE.MatchString(arg) {
126
-			// TODO invalid args
127
-			return nil
128
-		}
129
-		prefix := arg[0]
130
-		for _, c := range arg[1:] {
131
-			mode := fmt.Sprintf("%c%c", prefix, c)
132
-			msg.modes = append(msg.modes, mode)
133
-		}
134
-	}
135
-	return msg
136
-}
137
-
138
-func NewJoinMessage(args []string) Message {
139
-	msg := new(JoinMessage)
140
-
141
-	if len(args) > 0 {
142
-		if args[0] == "0" {
143
-			msg.zero = true
144
-		} else {
145
-			msg.channels = strings.Split(args[0], ",")
146
-		}
147
-
148
-		if len(args) > 1 {
149
-			msg.keys = strings.Split(args[1], ",")
150
-		}
151
-	}
152
-
153
-	return msg
154
-}
155
-
156
-func NewPartMessage(args []string) Message {
157
-	if len(args) < 1 {
158
-		return nil
159
-	}
160
-	msg := new(PartMessage)
161
-	msg.channels = strings.Split(args[0], ",")
162
-
163
-	if len(args) > 1 {
164
-		msg.message = args[1]
165
-	}
166
-
167
-	return msg
168
-}
169
-
170
-func NewPrivMsgMessage(args []string) Message {
171
-	if len(args) < 2 {
172
-		return nil
173
-	}
174
-
175
-	return &PrivMsgMessage{target: args[0], message: args[1]}
176
-}
177
-
178
-func NewTopicMessage(args []string) Message {
179
-	if len(args) < 1 {
180
-		return nil
181
-	}
182
-
183
-	message := &TopicMessage{channel: args[0]}
184
-	if len(args) > 1 {
185
-		message.topic = args[1]
186
-	}
187
-	return message
58
+	command, args = args[0], args[1:]
59
+	return
188 60
 }

+ 4
- 3
src/irc/reply.go Wyświetl plik

@@ -2,6 +2,7 @@ package irc
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"strings"
5 6
 	"time"
6 7
 )
7 8
 
@@ -75,7 +76,7 @@ func RplCreated(server *Server) Reply {
75 76
 }
76 77
 
77 78
 func RplMyInfo(server *Server) Reply {
78
-	return NewReply(server, RPL_MYINFO, server.name+" i ik")
79
+	return NewReply(server, RPL_MYINFO, fmt.Sprintf("%s %s i ik", server.name, VERSION))
79 80
 }
80 81
 
81 82
 func RplUModeIs(server *Server, client *Client) Reply {
@@ -92,9 +93,9 @@ func RplTopic(channel *Channel) Reply {
92 93
 	return &ChannelReply{NewReply(channel.server, RPL_TOPIC, fmt.Sprintf("%s :%s", channel.name, channel.topic)), channel}
93 94
 }
94 95
 
95
-func RplNamReply(channel *Channel, client *Client) Reply {
96
+func RplNamReply(channel *Channel) Reply {
96 97
 	// TODO multiple names and splitting based on message size
97
-	return NewReply(channel.server, RPL_NAMREPLY, fmt.Sprintf("=%s :+%s", channel.name, client.Nick()))
98
+	return NewReply(channel.server, RPL_NAMREPLY, fmt.Sprintf("= %s :%s", channel.name, strings.Join(channel.Nicks(), " ")))
98 99
 }
99 100
 
100 101
 func RplEndOfNames(source Identifier) Reply {

+ 17
- 9
src/irc/server.go Wyświetl plik

@@ -22,7 +22,13 @@ type ClientMessage struct {
22 22
 
23 23
 func NewServer(name string) *Server {
24 24
 	recv := make(chan *ClientMessage)
25
-	server := &Server{ctime: time.Now(), name: name, recv: recv, nicks: make(map[string]*Client), channels: make(map[string]*Channel)}
25
+	server := &Server{
26
+		ctime:    time.Now(),
27
+		name:     name,
28
+		recv:     recv,
29
+		nicks:    make(map[string]*Client),
30
+		channels: make(map[string]*Channel),
31
+	}
26 32
 	go func() {
27 33
 		for m := range recv {
28 34
 			m.message.Handle(server, m.client)
@@ -47,7 +53,7 @@ func (s *Server) Listen(addr string) {
47 53
 			continue
48 54
 		}
49 55
 		log.Print("Server.Listen: accepted ", conn.RemoteAddr())
50
-		go NewClient(conn).Communicate(s)
56
+		go NewClient(s, conn).Communicate()
51 57
 	}
52 58
 }
53 59
 
@@ -65,6 +71,7 @@ func (s *Server) GetOrMakeChannel(name string) *Channel {
65 71
 // Send a message to clients of channels fromClient is a member.
66 72
 func (s *Server) SendToInterestedClients(fromClient *Client, reply Reply) {
67 73
 	clients := make(map[*Client]bool)
74
+	clients[fromClient] = true
68 75
 	for channel := range fromClient.channels {
69 76
 		for client := range channel.members {
70 77
 			clients[client] = true
@@ -84,28 +91,29 @@ func (s *Server) ChangeNick(c *Client, newNick string) {
84 91
 		return
85 92
 	}
86 93
 
87
-	s.SendToInterestedClients(c, RplNick(c, newNick))
88
-
89 94
 	if c.nick != "" {
90 95
 		delete(s.nicks, c.nick)
91 96
 	}
92
-	c.nick = newNick
93 97
 	s.nicks[c.nick] = c
94 98
 
95
-	s.TryRegister(c)
99
+	s.SendToInterestedClients(c, RplNick(c, newNick))
100
+
101
+	c.nick = newNick
102
+
103
+	s.tryRegister(c)
96 104
 }
97 105
 
98
-func (s *Server) Register(c *Client, user string, realName string) {
106
+func (s *Server) UserLogin(c *Client, user string, realName string) {
99 107
 	if c.username != "" {
100 108
 		c.send <- ErrAlreadyRegistered(s)
101 109
 		return
102 110
 	}
103 111
 
104 112
 	c.username, c.realname = user, realName
105
-	s.TryRegister(c)
113
+	s.tryRegister(c)
106 114
 }
107 115
 
108
-func (s *Server) TryRegister(c *Client) {
116
+func (s *Server) tryRegister(c *Client) {
109 117
 	if !c.registered && c.HasNick() && c.HasUser() {
110 118
 		c.registered = true
111 119
 		c.send <- RplWelcome(s, c)

Ładowanie…
Anuluj
Zapisz