Browse Source

add all channel mask list replies

tags/v0.1.0
Jeremy Latt 10 years ago
parent
commit
f482b6b82f
4 changed files with 118 additions and 56 deletions
  1. 67
    51
      irc/channel.go
  2. 1
    1
      irc/commands.go
  3. 1
    1
      irc/constants.go
  4. 49
    3
      irc/reply.go

+ 67
- 51
irc/channel.go View File

@@ -5,8 +5,8 @@ import (
5 5
 )
6 6
 
7 7
 type Channel struct {
8
-	banList   []UserMask
9 8
 	flags     ChannelModeSet
9
+	lists     map[ChannelMode][]UserMask
10 10
 	key       string
11 11
 	members   MemberSet
12 12
 	name      string
@@ -23,8 +23,12 @@ func IsChannel(target string) bool {
23 23
 // string, which must be unique on the server.
24 24
 func NewChannel(s *Server, name string) *Channel {
25 25
 	channel := &Channel{
26
-		banList: make([]UserMask, 0),
27
-		flags:   make(ChannelModeSet),
26
+		flags: make(ChannelModeSet),
27
+		lists: map[ChannelMode][]UserMask{
28
+			BanMask:    []UserMask{},
29
+			ExceptMask: []UserMask{},
30
+			InviteMask: []UserMask{},
31
+		},
28 32
 		members: make(MemberSet),
29 33
 		name:    name,
30 34
 		server:  s,
@@ -228,31 +232,72 @@ func (channel *Channel) PrivMsg(client *Client, message string) {
228 232
 	}
229 233
 }
230 234
 
235
+func (channel *Channel) applyModeFlag(client *Client, mode ChannelMode,
236
+	op ModeOp) bool {
237
+	if !channel.ClientIsOperator(client) {
238
+		client.ErrChanOPrivIsNeeded(channel)
239
+		return false
240
+	}
241
+
242
+	switch op {
243
+	case Add:
244
+		channel.flags[mode] = true
245
+		return true
246
+
247
+	case Remove:
248
+		delete(channel.flags, mode)
249
+		return true
250
+	}
251
+	return false
252
+}
253
+
254
+func (channel *Channel) applyModeMember(client *Client, mode ChannelMode,
255
+	op ModeOp, nick string) bool {
256
+	if !channel.ClientIsOperator(client) {
257
+		client.ErrChanOPrivIsNeeded(channel)
258
+		return false
259
+	}
260
+
261
+	if nick == "" {
262
+		client.ErrNeedMoreParams("MODE")
263
+		return false
264
+	}
265
+
266
+	target := channel.server.clients.Get(nick)
267
+	if target == nil {
268
+		client.ErrNoSuchNick(nick)
269
+		return false
270
+	}
271
+
272
+	if !channel.members.Has(target) {
273
+		client.ErrUserNotInChannel(channel, target)
274
+		return false
275
+	}
276
+
277
+	switch op {
278
+	case Add:
279
+		channel.members[target][mode] = true
280
+		return true
281
+
282
+	case Remove:
283
+		channel.members[target][mode] = false
284
+		return true
285
+	}
286
+	return false
287
+}
288
+
231 289
 func (channel *Channel) applyMode(client *Client, change ChannelModeChange) bool {
232 290
 	switch change.mode {
233
-	case BanMask:
291
+	case BanMask, ExceptMask, InviteMask:
234 292
 		// TODO add/remove
235 293
 
236
-		for _, banMask := range channel.banList {
237
-			client.RplBanList(channel, banMask)
294
+		for _, mask := range channel.lists[change.mode] {
295
+			client.RplMaskList(change.mode, channel, mask)
238 296
 		}
239
-		client.RplEndOfBanList(channel)
297
+		client.RplEndOfMaskList(change.mode, channel)
240 298
 
241 299
 	case Moderated, NoOutside, OpOnlyTopic, Private:
242
-		if !channel.ClientIsOperator(client) {
243
-			client.ErrChanOPrivIsNeeded(channel)
244
-			return false
245
-		}
246
-
247
-		switch change.op {
248
-		case Add:
249
-			channel.flags[change.mode] = true
250
-			return true
251
-
252
-		case Remove:
253
-			delete(channel.flags, change.mode)
254
-			return true
255
-		}
300
+		return channel.applyModeFlag(client, change.mode, change.op)
256 301
 
257 302
 	case Key:
258 303
 		if !channel.ClientIsOperator(client) {
@@ -289,36 +334,7 @@ func (channel *Channel) applyMode(client *Client, change ChannelModeChange) bool
289 334
 		return true
290 335
 
291 336
 	case ChannelOperator, Voice:
292
-		if !channel.ClientIsOperator(client) {
293
-			client.ErrChanOPrivIsNeeded(channel)
294
-			return false
295
-		}
296
-
297
-		if change.arg == "" {
298
-			client.ErrNeedMoreParams("MODE")
299
-			return false
300
-		}
301
-
302
-		target := channel.server.clients.Get(change.arg)
303
-		if target == nil {
304
-			client.ErrNoSuchNick(change.arg)
305
-			return false
306
-		}
307
-
308
-		if !channel.members.Has(target) {
309
-			client.ErrUserNotInChannel(channel, target)
310
-			return false
311
-		}
312
-
313
-		switch change.op {
314
-		case Add:
315
-			channel.members[target][change.mode] = true
316
-			return true
317
-
318
-		case Remove:
319
-			channel.members[target][change.mode] = false
320
-			return true
321
-		}
337
+		return channel.applyModeMember(client, change.mode, change.op, change.arg)
322 338
 
323 339
 	default:
324 340
 		client.ErrUnknownMode(change.mode, channel)

+ 1
- 1
irc/commands.go View File

@@ -566,7 +566,7 @@ func NewChannelModeCommand(args []string) (editableCommand, error) {
566 566
 				op:   op,
567 567
 			}
568 568
 			switch change.mode {
569
-			case Key, BanMask, ExceptionMask, InviteMask, UserLimit,
569
+			case Key, BanMask, ExceptMask, InviteMask, UserLimit,
570 570
 				ChannelOperator, ChannelCreator, Voice:
571 571
 				if len(args) > skipArgs {
572 572
 					change.arg = args[skipArgs]

+ 1
- 1
irc/constants.go View File

@@ -212,7 +212,7 @@ const (
212 212
 	BanMask         ChannelMode = 'b' // arg
213 213
 	ChannelCreator  ChannelMode = 'O' // flag
214 214
 	ChannelOperator ChannelMode = 'o' // arg
215
-	ExceptionMask   ChannelMode = 'e' // arg
215
+	ExceptMask      ChannelMode = 'e' // arg
216 216
 	InviteMask      ChannelMode = 'I' // arg
217 217
 	InviteOnly      ChannelMode = 'i' // flag
218 218
 	Key             ChannelMode = 'k' // flag arg

+ 49
- 3
irc/reply.go View File

@@ -253,14 +253,60 @@ func (target *Client) RplEndOfWho(name string) {
253 253
 		"%s :End of WHO list", name)
254 254
 }
255 255
 
256
-func (target *Client) RplBanList(channel *Channel, ban UserMask) {
256
+func (target *Client) RplMaskList(mode ChannelMode, channel *Channel, mask UserMask) {
257
+	switch mode {
258
+	case BanMask:
259
+		target.RplBanList(channel, mask)
260
+
261
+	case ExceptMask:
262
+		target.RplExceptList(channel, mask)
263
+
264
+	case InviteMask:
265
+		target.RplInviteList(channel, mask)
266
+	}
267
+}
268
+
269
+func (target *Client) RplEndOfMaskList(mode ChannelMode, channel *Channel) {
270
+	switch mode {
271
+	case BanMask:
272
+		target.RplEndOfBanList(channel)
273
+
274
+	case ExceptMask:
275
+		target.RplEndOfExceptList(channel)
276
+
277
+	case InviteMask:
278
+		target.RplEndOfInviteList(channel)
279
+	}
280
+}
281
+
282
+func (target *Client) RplBanList(channel *Channel, mask UserMask) {
257 283
 	target.NumericReply(RPL_BANLIST,
258
-		"%s %s", channel.name, ban)
284
+		"%s %s", channel, mask)
259 285
 }
260 286
 
261 287
 func (target *Client) RplEndOfBanList(channel *Channel) {
262 288
 	target.NumericReply(RPL_ENDOFBANLIST,
263
-		"%s :End of channel ban list", channel.name)
289
+		"%s :End of channel ban list", channel)
290
+}
291
+
292
+func (target *Client) RplExceptList(channel *Channel, mask UserMask) {
293
+	target.NumericReply(RPL_EXCEPTLIST,
294
+		"%s %s", channel, mask)
295
+}
296
+
297
+func (target *Client) RplEndOfExceptList(channel *Channel) {
298
+	target.NumericReply(RPL_ENDOFEXCEPTLIST,
299
+		"%s :End of channel exception list", channel)
300
+}
301
+
302
+func (target *Client) RplInviteList(channel *Channel, mask UserMask) {
303
+	target.NumericReply(RPL_INVITELIST,
304
+		"%s %s", channel, mask)
305
+}
306
+
307
+func (target *Client) RplEndOfInviteList(channel *Channel) {
308
+	target.NumericReply(RPL_ENDOFINVITELIST,
309
+		"%s :End of channel invite list", channel)
264 310
 }
265 311
 
266 312
 func (target *Client) RplNowAway() {

Loading…
Cancel
Save