浏览代码

Clean up BaseCommand interface. Make NickServ a Service.

tags/v0.1.0
Jeremy Latt 11 年前
父节点
当前提交
39f815df01
共有 5 个文件被更改,包括 79 次插入77 次删除
  1. 0
    5
      src/irc/client.go
  2. 46
    38
      src/irc/commands.go
  3. 11
    11
      src/irc/nickserv.go
  4. 17
    17
      src/irc/server.go
  5. 5
    6
      src/irc/service.go

+ 0
- 5
src/irc/client.go 查看文件

@@ -27,11 +27,6 @@ type Client struct {
27 27
 	replies    chan<- Reply
28 28
 }
29 29
 
30
-type ClientMessage interface {
31
-	Client() *Client
32
-	SetClient(*Client)
33
-}
34
-
35 30
 type ClientSet map[*Client]bool
36 31
 
37 32
 func NewClient(server *Server, conn net.Conn) *Client {

+ 46
- 38
src/irc/commands.go 查看文件

@@ -14,17 +14,25 @@ type BaseCommand struct {
14 14
 	client *Client
15 15
 }
16 16
 
17
-func (base *BaseCommand) Client() *Client {
17
+func (base BaseCommand) Client() *Client {
18 18
 	return base.client
19 19
 }
20 20
 
21 21
 func (base *BaseCommand) SetClient(c *Client) {
22
+	if base.client != nil {
23
+		panic("SetClient called twice!")
24
+	}
22 25
 	base.client = c
23 26
 }
24 27
 
28
+type EditableCommand interface {
29
+	Command
30
+	SetClient(*Client)
31
+}
32
+
25 33
 var (
26 34
 	ErrParseCommand   = errors.New("failed to parse message")
27
-	parseCommandFuncs = map[string]func([]string) (Command, error){
35
+	parseCommandFuncs = map[string]func([]string) (EditableCommand, error){
28 36
 		"JOIN":    NewJoinCommand,
29 37
 		"MODE":    NewModeCommand,
30 38
 		"NICK":    NewNickCommand,
@@ -39,7 +47,7 @@ var (
39 47
 	}
40 48
 )
41 49
 
42
-func ParseCommand(line string) (Command, error) {
50
+func ParseCommand(line string) (EditableCommand, error) {
43 51
 	command, args := parseLine(line)
44 52
 	constructor := parseCommandFuncs[command]
45 53
 	if constructor == nil {
@@ -77,14 +85,14 @@ func parseLine(line string) (command string, args []string) {
77 85
 // <command> [args...]
78 86
 
79 87
 type UnknownCommand struct {
80
-	*BaseCommand
88
+	BaseCommand
81 89
 	command string
82 90
 	args    []string
83 91
 }
84 92
 
85 93
 func NewUnknownCommand(command string, args []string) *UnknownCommand {
86 94
 	return &UnknownCommand{
87
-		BaseCommand: &BaseCommand{},
95
+		BaseCommand: BaseCommand{},
88 96
 		command:     command,
89 97
 		args:        args,
90 98
 	}
@@ -93,17 +101,17 @@ func NewUnknownCommand(command string, args []string) *UnknownCommand {
93 101
 // PING <server1> [ <server2> ]
94 102
 
95 103
 type PingCommand struct {
96
-	*BaseCommand
104
+	BaseCommand
97 105
 	server  string
98 106
 	server2 string
99 107
 }
100 108
 
101
-func NewPingCommand(args []string) (Command, error) {
109
+func NewPingCommand(args []string) (EditableCommand, error) {
102 110
 	if len(args) < 1 {
103 111
 		return nil, NotEnoughArgsError
104 112
 	}
105 113
 	msg := &PingCommand{
106
-		BaseCommand: &BaseCommand{},
114
+		BaseCommand: BaseCommand{},
107 115
 		server:      args[0],
108 116
 	}
109 117
 	if len(args) > 1 {
@@ -115,17 +123,17 @@ func NewPingCommand(args []string) (Command, error) {
115 123
 // PONG <server> [ <server2> ]
116 124
 
117 125
 type PongCommand struct {
118
-	*BaseCommand
126
+	BaseCommand
119 127
 	server1 string
120 128
 	server2 string
121 129
 }
122 130
 
123
-func NewPongCommand(args []string) (Command, error) {
131
+func NewPongCommand(args []string) (EditableCommand, error) {
124 132
 	if len(args) < 1 {
125 133
 		return nil, NotEnoughArgsError
126 134
 	}
127 135
 	message := &PongCommand{
128
-		BaseCommand: &BaseCommand{},
136
+		BaseCommand: BaseCommand{},
129 137
 		server1:     args[0],
130 138
 	}
131 139
 	if len(args) > 1 {
@@ -137,16 +145,16 @@ func NewPongCommand(args []string) (Command, error) {
137 145
 // PASS <password>
138 146
 
139 147
 type PassCommand struct {
140
-	*BaseCommand
148
+	BaseCommand
141 149
 	password string
142 150
 }
143 151
 
144
-func NewPassCommand(args []string) (Command, error) {
152
+func NewPassCommand(args []string) (EditableCommand, error) {
145 153
 	if len(args) < 1 {
146 154
 		return nil, NotEnoughArgsError
147 155
 	}
148 156
 	return &PassCommand{
149
-		BaseCommand: &BaseCommand{},
157
+		BaseCommand: BaseCommand{},
150 158
 		password:    args[0],
151 159
 	}, nil
152 160
 }
@@ -154,16 +162,16 @@ func NewPassCommand(args []string) (Command, error) {
154 162
 // NICK <nickname>
155 163
 
156 164
 type NickCommand struct {
157
-	*BaseCommand
165
+	BaseCommand
158 166
 	nickname string
159 167
 }
160 168
 
161
-func NewNickCommand(args []string) (Command, error) {
169
+func NewNickCommand(args []string) (EditableCommand, error) {
162 170
 	if len(args) != 1 {
163 171
 		return nil, NotEnoughArgsError
164 172
 	}
165 173
 	return &NickCommand{
166
-		BaseCommand: &BaseCommand{},
174
+		BaseCommand: BaseCommand{},
167 175
 		nickname:    args[0],
168 176
 	}, nil
169 177
 }
@@ -171,19 +179,19 @@ func NewNickCommand(args []string) (Command, error) {
171 179
 // USER <user> <mode> <unused> <realname>
172 180
 
173 181
 type UserMsgCommand struct {
174
-	*BaseCommand
182
+	BaseCommand
175 183
 	user     string
176 184
 	mode     uint8
177 185
 	unused   string
178 186
 	realname string
179 187
 }
180 188
 
181
-func NewUserMsgCommand(args []string) (Command, error) {
189
+func NewUserMsgCommand(args []string) (EditableCommand, error) {
182 190
 	if len(args) != 4 {
183 191
 		return nil, NotEnoughArgsError
184 192
 	}
185 193
 	msg := &UserMsgCommand{
186
-		BaseCommand: &BaseCommand{},
194
+		BaseCommand: BaseCommand{},
187 195
 		user:        args[0],
188 196
 		unused:      args[2],
189 197
 		realname:    args[3],
@@ -198,13 +206,13 @@ func NewUserMsgCommand(args []string) (Command, error) {
198 206
 // QUIT [ <Quit Command> ]
199 207
 
200 208
 type QuitCommand struct {
201
-	*BaseCommand
209
+	BaseCommand
202 210
 	message string
203 211
 }
204 212
 
205
-func NewQuitCommand(args []string) (Command, error) {
213
+func NewQuitCommand(args []string) (EditableCommand, error) {
206 214
 	msg := &QuitCommand{
207
-		BaseCommand: &BaseCommand{},
215
+		BaseCommand: BaseCommand{},
208 216
 	}
209 217
 	if len(args) > 0 {
210 218
 		msg.message = args[0]
@@ -215,14 +223,14 @@ func NewQuitCommand(args []string) (Command, error) {
215 223
 // JOIN ( <channel> *( "," <channel> ) [ <key> *( "," <key> ) ] ) / "0"
216 224
 
217 225
 type JoinCommand struct {
218
-	*BaseCommand
226
+	BaseCommand
219 227
 	channels map[string]string
220 228
 	zero     bool
221 229
 }
222 230
 
223
-func NewJoinCommand(args []string) (Command, error) {
231
+func NewJoinCommand(args []string) (EditableCommand, error) {
224 232
 	msg := &JoinCommand{
225
-		BaseCommand: &BaseCommand{},
233
+		BaseCommand: BaseCommand{},
226 234
 		channels:    make(map[string]string),
227 235
 	}
228 236
 
@@ -252,17 +260,17 @@ func NewJoinCommand(args []string) (Command, error) {
252 260
 // PART <channel> *( "," <channel> ) [ <Part Command> ]
253 261
 
254 262
 type PartCommand struct {
255
-	*BaseCommand
263
+	BaseCommand
256 264
 	channels []string
257 265
 	message  string
258 266
 }
259 267
 
260
-func NewPartCommand(args []string) (Command, error) {
268
+func NewPartCommand(args []string) (EditableCommand, error) {
261 269
 	if len(args) < 1 {
262 270
 		return nil, NotEnoughArgsError
263 271
 	}
264 272
 	msg := &PartCommand{
265
-		BaseCommand: &BaseCommand{},
273
+		BaseCommand: BaseCommand{},
266 274
 		channels:    strings.Split(args[0], ","),
267 275
 	}
268 276
 	if len(args) > 1 {
@@ -274,17 +282,17 @@ func NewPartCommand(args []string) (Command, error) {
274 282
 // PRIVMSG <target> <message>
275 283
 
276 284
 type PrivMsgCommand struct {
277
-	*BaseCommand
285
+	BaseCommand
278 286
 	target  string
279 287
 	message string
280 288
 }
281 289
 
282
-func NewPrivMsgCommand(args []string) (Command, error) {
290
+func NewPrivMsgCommand(args []string) (EditableCommand, error) {
283 291
 	if len(args) < 2 {
284 292
 		return nil, NotEnoughArgsError
285 293
 	}
286 294
 	return &PrivMsgCommand{
287
-		BaseCommand: &BaseCommand{},
295
+		BaseCommand: BaseCommand{},
288 296
 		target:      args[0],
289 297
 		message:     args[1],
290 298
 	}, nil
@@ -301,17 +309,17 @@ func (m *PrivMsgCommand) TargetIsChannel() bool {
301 309
 // TOPIC [newtopic]
302 310
 
303 311
 type TopicCommand struct {
304
-	*BaseCommand
312
+	BaseCommand
305 313
 	channel string
306 314
 	topic   string
307 315
 }
308 316
 
309
-func NewTopicCommand(args []string) (Command, error) {
317
+func NewTopicCommand(args []string) (EditableCommand, error) {
310 318
 	if len(args) < 1 {
311 319
 		return nil, NotEnoughArgsError
312 320
 	}
313 321
 	msg := &TopicCommand{
314
-		BaseCommand: &BaseCommand{},
322
+		BaseCommand: BaseCommand{},
315 323
 		channel:     args[0],
316 324
 	}
317 325
 	if len(args) > 1 {
@@ -321,18 +329,18 @@ func NewTopicCommand(args []string) (Command, error) {
321 329
 }
322 330
 
323 331
 type ModeCommand struct {
324
-	*BaseCommand
332
+	BaseCommand
325 333
 	nickname string
326 334
 	modes    string
327 335
 }
328 336
 
329
-func NewModeCommand(args []string) (Command, error) {
337
+func NewModeCommand(args []string) (EditableCommand, error) {
330 338
 	if len(args) == 0 {
331 339
 		return nil, NotEnoughArgsError
332 340
 	}
333 341
 
334 342
 	cmd := &ModeCommand{
335
-		BaseCommand: &BaseCommand{},
343
+		BaseCommand: BaseCommand{},
336 344
 		nickname:    args[0],
337 345
 	}
338 346
 

+ 11
- 11
src/irc/nickserv.go 查看文件

@@ -5,8 +5,9 @@ import (
5 5
 )
6 6
 
7 7
 type NickServCommand interface {
8
-	ClientMessage
9 8
 	HandleNickServ(*NickServ)
9
+	Client() *Client
10
+	SetClient(*Client)
10 11
 }
11 12
 
12 13
 type NickServ struct {
@@ -14,11 +15,9 @@ type NickServ struct {
14 15
 }
15 16
 
16 17
 func NewNickServ(s *Server) *NickServ {
17
-	ns := &NickServ{}
18
-	ns.Service = NewService(s, "NickServ", func(m *PrivMsgCommand) {
19
-		m.HandleNickServ(ns)
20
-	})
21
-	return ns
18
+	return &NickServ{
19
+		Service: NewService(s, "NickServ"),
20
+	}
22 21
 }
23 22
 
24 23
 var (
@@ -32,7 +31,7 @@ var (
32 31
 // commands
33 32
 //
34 33
 
35
-func (m *PrivMsgCommand) HandleNickServ(ns *NickServ) {
34
+func (ns *NickServ) HandleMsg(m *PrivMsgCommand) {
36 35
 	command, args := parseLine(m.message)
37 36
 	constructor := parseNickServCommandFuncs[command]
38 37
 	if constructor == nil {
@@ -48,6 +47,7 @@ func (m *PrivMsgCommand) HandleNickServ(ns *NickServ) {
48 47
 
49 48
 	cmd.SetClient(m.Client())
50 49
 	log.Printf("%s %T %+v", ns.Id(), cmd, cmd)
50
+
51 51
 	cmd.HandleNickServ(ns)
52 52
 }
53 53
 
@@ -56,7 +56,7 @@ func (m *PrivMsgCommand) HandleNickServ(ns *NickServ) {
56 56
 //
57 57
 
58 58
 type RegisterCommand struct {
59
-	*BaseCommand
59
+	BaseCommand
60 60
 	password string
61 61
 	email    string
62 62
 }
@@ -67,7 +67,7 @@ func NewRegisterCommand(args []string) (NickServCommand, error) {
67 67
 	}
68 68
 
69 69
 	cmd := &RegisterCommand{
70
-		BaseCommand: &BaseCommand{},
70
+		BaseCommand: BaseCommand{},
71 71
 		password:    args[0],
72 72
 	}
73 73
 	if len(args) > 1 {
@@ -100,7 +100,7 @@ func (m *RegisterCommand) HandleNickServ(ns *NickServ) {
100 100
 }
101 101
 
102 102
 type IdentifyCommand struct {
103
-	*BaseCommand
103
+	BaseCommand
104 104
 	password string
105 105
 }
106 106
 
@@ -110,7 +110,7 @@ func NewIdentifyCommand(args []string) (NickServCommand, error) {
110 110
 	}
111 111
 
112 112
 	return &IdentifyCommand{
113
-		BaseCommand: &BaseCommand{},
113
+		BaseCommand: BaseCommand{},
114 114
 		password:    args[0],
115 115
 	}, nil
116 116
 }

+ 17
- 17
src/irc/server.go 查看文件

@@ -13,8 +13,8 @@ type UserNameMap map[string]*User
13 13
 type ServiceNameMap map[string]*Service
14 14
 
15 15
 type Command interface {
16
-	ClientMessage
17
-	Handle(*Server)
16
+	Client() *Client
17
+	HandleServer(*Server)
18 18
 }
19 19
 
20 20
 type Server struct {
@@ -47,7 +47,7 @@ func (server *Server) receiveCommands(commands <-chan Command) {
47 47
 	for command := range commands {
48 48
 		log.Printf("%s %T %+v", server.Id(), command, command)
49 49
 		command.Client().atime = time.Now()
50
-		command.Handle(server)
50
+		command.HandleServer(server)
51 51
 	}
52 52
 }
53 53
 
@@ -127,19 +127,19 @@ func (s *Server) DeleteChannel(channel *Channel) {
127 127
 // commands
128 128
 //
129 129
 
130
-func (m *UnknownCommand) Handle(s *Server) {
130
+func (m *UnknownCommand) HandleServer(s *Server) {
131 131
 	m.Client().replies <- ErrUnknownCommand(s, m.command)
132 132
 }
133 133
 
134
-func (m *PingCommand) Handle(s *Server) {
134
+func (m *PingCommand) HandleServer(s *Server) {
135 135
 	m.Client().replies <- RplPong(s)
136 136
 }
137 137
 
138
-func (m *PongCommand) Handle(s *Server) {
138
+func (m *PongCommand) HandleServer(s *Server) {
139 139
 	// no-op
140 140
 }
141 141
 
142
-func (m *PassCommand) Handle(s *Server) {
142
+func (m *PassCommand) HandleServer(s *Server) {
143 143
 	err := bcrypt.CompareHashAndPassword(s.password, []byte(m.password))
144 144
 	if err != nil {
145 145
 		m.Client().replies <- ErrPasswdMismatch(s)
@@ -150,7 +150,7 @@ func (m *PassCommand) Handle(s *Server) {
150 150
 	// no reply?
151 151
 }
152 152
 
153
-func (m *NickCommand) Handle(s *Server) {
153
+func (m *NickCommand) HandleServer(s *Server) {
154 154
 	c := m.Client()
155 155
 	if c.user == nil {
156 156
 		c.replies <- RplNick(c, m.nickname)
@@ -162,7 +162,7 @@ func (m *NickCommand) Handle(s *Server) {
162 162
 	c.user.replies <- ErrNoPrivileges(s)
163 163
 }
164 164
 
165
-func (m *UserMsgCommand) Handle(s *Server) {
165
+func (m *UserMsgCommand) HandleServer(s *Server) {
166 166
 	c := m.Client()
167 167
 	if c.username != "" {
168 168
 		c.replies <- ErrAlreadyRegistered(s)
@@ -173,7 +173,7 @@ func (m *UserMsgCommand) Handle(s *Server) {
173 173
 	s.tryRegister(c)
174 174
 }
175 175
 
176
-func (m *QuitCommand) Handle(s *Server) {
176
+func (m *QuitCommand) HandleServer(s *Server) {
177 177
 	c := m.Client()
178 178
 
179 179
 	user := c.user
@@ -191,7 +191,7 @@ func (m *QuitCommand) Handle(s *Server) {
191 191
 	user.LogoutClient(c)
192 192
 	if !user.HasClients() {
193 193
 		cmd := &PartCommand{
194
-			BaseCommand: &BaseCommand{c},
194
+			BaseCommand: BaseCommand{c},
195 195
 		}
196 196
 		for channel := range user.channels {
197 197
 			channel.commands <- cmd
@@ -199,7 +199,7 @@ func (m *QuitCommand) Handle(s *Server) {
199 199
 	}
200 200
 }
201 201
 
202
-func (m *JoinCommand) Handle(s *Server) {
202
+func (m *JoinCommand) HandleServer(s *Server) {
203 203
 	c := m.Client()
204 204
 
205 205
 	if c.user == nil {
@@ -211,7 +211,7 @@ func (m *JoinCommand) Handle(s *Server) {
211 211
 
212 212
 	if m.zero {
213 213
 		cmd := &PartCommand{
214
-			BaseCommand: &BaseCommand{c},
214
+			BaseCommand: BaseCommand{c},
215 215
 		}
216 216
 		for channel := range c.user.channels {
217 217
 			channel.commands <- cmd
@@ -224,7 +224,7 @@ func (m *JoinCommand) Handle(s *Server) {
224 224
 	}
225 225
 }
226 226
 
227
-func (m *PartCommand) Handle(s *Server) {
227
+func (m *PartCommand) HandleServer(s *Server) {
228 228
 	user := m.Client().user
229 229
 
230 230
 	if user == nil {
@@ -246,7 +246,7 @@ func (m *PartCommand) Handle(s *Server) {
246 246
 	}
247 247
 }
248 248
 
249
-func (m *TopicCommand) Handle(s *Server) {
249
+func (m *TopicCommand) HandleServer(s *Server) {
250 250
 	user := m.Client().user
251 251
 
252 252
 	if user == nil {
@@ -263,7 +263,7 @@ func (m *TopicCommand) Handle(s *Server) {
263 263
 	channel.commands <- m
264 264
 }
265 265
 
266
-func (m *PrivMsgCommand) Handle(s *Server) {
266
+func (m *PrivMsgCommand) HandleServer(s *Server) {
267 267
 	service := s.services[m.target]
268 268
 	if service != nil {
269 269
 		service.commands <- m
@@ -296,6 +296,6 @@ func (m *PrivMsgCommand) Handle(s *Server) {
296 296
 	target.commands <- m
297 297
 }
298 298
 
299
-func (m *ModeCommand) Handle(s *Server) {
299
+func (m *ModeCommand) HandleServer(s *Server) {
300 300
 	m.Client().replies <- RplUModeIs(s, m.Client())
301 301
 }

+ 5
- 6
src/irc/service.go 查看文件

@@ -10,28 +10,27 @@ type ServiceCommand interface {
10 10
 	HandleService(*Service)
11 11
 }
12 12
 
13
-type PrivMsgCommandFunc func(*PrivMsgCommand)
14
-
15 13
 type Service struct {
16 14
 	server   *Server
17 15
 	name     string
18 16
 	commands chan<- ServiceCommand
19
-	Handle   PrivMsgCommandFunc
20 17
 }
21 18
 
22
-func NewService(s *Server, name string, Handle PrivMsgCommandFunc) *Service {
19
+func NewService(s *Server, name string) *Service {
23 20
 	commands := make(chan ServiceCommand)
24 21
 	service := &Service{
25 22
 		server:   s,
26 23
 		name:     name,
27 24
 		commands: commands,
28
-		Handle:   Handle,
29 25
 	}
30 26
 	go service.receiveCommands(commands)
31 27
 	s.services[name] = service
32 28
 	return service
33 29
 }
34 30
 
31
+func (service *Service) HandleMsg(m *PrivMsgCommand) {
32
+}
33
+
35 34
 func (service *Service) receiveCommands(commands <-chan ServiceCommand) {
36 35
 	for command := range commands {
37 36
 		log.Printf("%s %T %+V", service.Id(), command, command)
@@ -60,5 +59,5 @@ func (service *Service) Reply(client *Client, message string) {
60 59
 //
61 60
 
62 61
 func (m *PrivMsgCommand) HandleService(s *Service) {
63
-	s.Handle(m)
62
+	s.HandleMsg(m)
64 63
 }

正在加载...
取消
保存