|
@@ -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)
|