|
@@ -8,7 +8,7 @@ import (
|
8
|
8
|
|
9
|
9
|
type Channel struct {
|
10
|
10
|
flags ChannelModeSet
|
11
|
|
- lists map[ChannelMode]UserMaskSet
|
|
11
|
+ lists map[ChannelMode]*UserMaskSet
|
12
|
12
|
key string
|
13
|
13
|
members MemberSet
|
14
|
14
|
name string
|
|
@@ -26,10 +26,10 @@ func IsChannel(target string) bool {
|
26
|
26
|
func NewChannel(s *Server, name string) *Channel {
|
27
|
27
|
channel := &Channel{
|
28
|
28
|
flags: make(ChannelModeSet),
|
29
|
|
- lists: map[ChannelMode]UserMaskSet{
|
30
|
|
- BanMask: make(UserMaskSet),
|
31
|
|
- ExceptMask: make(UserMaskSet),
|
32
|
|
- InviteMask: make(UserMaskSet),
|
|
29
|
+ lists: map[ChannelMode]*UserMaskSet{
|
|
30
|
+ BanMask: NewUserMaskSet(),
|
|
31
|
+ ExceptMask: NewUserMaskSet(),
|
|
32
|
+ InviteMask: NewUserMaskSet(),
|
33
|
33
|
},
|
34
|
34
|
members: make(MemberSet),
|
35
|
35
|
name: strings.ToLower(name),
|
|
@@ -151,6 +151,19 @@ func (channel *Channel) Join(client *Client, key string) {
|
151
|
151
|
return
|
152
|
152
|
}
|
153
|
153
|
|
|
154
|
+ isInvited := channel.lists[InviteMask].Match(client.UserHost())
|
|
155
|
+ if channel.flags[InviteOnly] && !isInvited {
|
|
156
|
+ client.ErrInviteOnlyChan(channel)
|
|
157
|
+ return
|
|
158
|
+ }
|
|
159
|
+
|
|
160
|
+ if channel.lists[BanMask].Match(client.UserHost()) &&
|
|
161
|
+ !isInvited &&
|
|
162
|
+ !channel.lists[ExceptMask].Match(client.UserHost()) {
|
|
163
|
+ client.ErrBannedFromChan(channel)
|
|
164
|
+ return
|
|
165
|
+ }
|
|
166
|
+
|
154
|
167
|
client.channels.Add(channel)
|
155
|
168
|
channel.members.Add(client)
|
156
|
169
|
if !channel.flags[Persistent] && (len(channel.members) == 1) {
|
|
@@ -213,7 +226,7 @@ func (channel *Channel) SetTopic(client *Client, topic string) {
|
213
|
226
|
}
|
214
|
227
|
|
215
|
228
|
if err := channel.Persist(); err != nil {
|
216
|
|
- log.Println(err)
|
|
229
|
+ log.Println("Channel.Persist:", channel, err)
|
217
|
230
|
}
|
218
|
231
|
}
|
219
|
232
|
|
|
@@ -310,15 +323,35 @@ func (channel *Channel) applyModeMember(client *Client, mode ChannelMode,
|
310
|
323
|
return false
|
311
|
324
|
}
|
312
|
325
|
|
|
326
|
+func (channel *Channel) applyModeMask(client *Client, mode ChannelMode, op ModeOp, mask string) bool {
|
|
327
|
+ if !channel.ClientIsOperator(client) {
|
|
328
|
+ client.ErrChanOPrivIsNeeded(channel)
|
|
329
|
+ return false
|
|
330
|
+ }
|
|
331
|
+
|
|
332
|
+ list := channel.lists[mode]
|
|
333
|
+ if list == nil {
|
|
334
|
+ // This should never happen, but better safe than panicky.
|
|
335
|
+ return false
|
|
336
|
+ }
|
|
337
|
+
|
|
338
|
+ if op == Add {
|
|
339
|
+ list.Add(mask)
|
|
340
|
+ } else if op == Remove {
|
|
341
|
+ list.Remove(mask)
|
|
342
|
+ }
|
|
343
|
+
|
|
344
|
+ for lmask := range channel.lists[mode].masks {
|
|
345
|
+ client.RplMaskList(mode, channel, lmask)
|
|
346
|
+ }
|
|
347
|
+ client.RplEndOfMaskList(mode, channel)
|
|
348
|
+ return true
|
|
349
|
+}
|
|
350
|
+
|
313
|
351
|
func (channel *Channel) applyMode(client *Client, change *ChannelModeChange) bool {
|
314
|
352
|
switch change.mode {
|
315
|
353
|
case BanMask, ExceptMask, InviteMask:
|
316
|
|
- // TODO add/remove
|
317
|
|
-
|
318
|
|
- for mask := range channel.lists[change.mode] {
|
319
|
|
- client.RplMaskList(change.mode, channel, mask)
|
320
|
|
- }
|
321
|
|
- client.RplEndOfMaskList(change.mode, channel)
|
|
354
|
+ return channel.applyModeMask(client, change.mode, change.op, change.arg)
|
322
|
355
|
|
323
|
356
|
case Moderated, NoOutside, OpOnlyTopic, Persistent, Private:
|
324
|
357
|
return channel.applyModeFlag(client, change.mode, change.op)
|
|
@@ -390,7 +423,7 @@ func (channel *Channel) Mode(client *Client, changes ChannelModeChanges) {
|
390
|
423
|
}
|
391
|
424
|
|
392
|
425
|
if err := channel.Persist(); err != nil {
|
393
|
|
- log.Println(err)
|
|
426
|
+ log.Println("Channel.Persist:", channel, err)
|
394
|
427
|
}
|
395
|
428
|
}
|
396
|
429
|
}
|
|
@@ -464,6 +497,13 @@ func (channel *Channel) Invite(invitee *Client, inviter *Client) {
|
464
|
497
|
return
|
465
|
498
|
}
|
466
|
499
|
|
|
500
|
+ if channel.flags[InviteOnly] {
|
|
501
|
+ channel.lists[InviteMask].Add(invitee.UserHost())
|
|
502
|
+ if err := channel.Persist(); err != nil {
|
|
503
|
+ log.Println("Channel.Persist:", channel, err)
|
|
504
|
+ }
|
|
505
|
+ }
|
|
506
|
+
|
467
|
507
|
inviter.RplInviting(invitee, channel.name)
|
468
|
508
|
invitee.Reply(RplInviteMsg(inviter, invitee, channel.name))
|
469
|
509
|
if invitee.flags[Away] {
|