Pārlūkot izejas kodu

implement SAJOIN, allow channel founders to join unconditionally

tags/v0.12.0
Shivaram Lingamneni 6 gadus atpakaļ
vecāks
revīzija
495705f538
6 mainītis faili ar 60 papildinājumiem un 12 dzēšanām
  1. 12
    9
      irc/channel.go
  2. 2
    2
      irc/channelmanager.go
  3. 5
    0
      irc/commands.go
  4. 33
    1
      irc/handlers.go
  5. 7
    0
      irc/help.go
  6. 1
    0
      oragono.yaml

+ 12
- 9
irc/channel.go Parādīt failu

@@ -350,32 +350,36 @@ func (channel *Channel) IsEmpty() bool {
350 350
 }
351 351
 
352 352
 // Join joins the given client to this channel (if they can be joined).
353
-//TODO(dan): /SAJOIN and maybe a ForceJoin function?
354
-func (channel *Channel) Join(client *Client, key string, rb *ResponseBuffer) {
353
+func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *ResponseBuffer) {
355 354
 	if channel.hasClient(client) {
356 355
 		// already joined, no message needs to be sent
357 356
 		return
358 357
 	}
359 358
 
360
-	chname := channel.Name()
359
+	channel.stateMutex.RLock()
360
+	chname := channel.name
361
+	founder := channel.registeredFounder
362
+	channel.stateMutex.RUnlock()
363
+	account := client.Account()
364
+	hasPrivs := isSajoin || (founder != "" && founder == account)
361 365
 
362
-	if channel.IsFull() {
366
+	if !hasPrivs && channel.IsFull() {
363 367
 		rb.Add(nil, client.server.name, ERR_CHANNELISFULL, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "l"))
364 368
 		return
365 369
 	}
366 370
 
367
-	if !channel.CheckKey(key) {
371
+	if !hasPrivs && !channel.CheckKey(key) {
368 372
 		rb.Add(nil, client.server.name, ERR_BADCHANNELKEY, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "k"))
369 373
 		return
370 374
 	}
371 375
 
372 376
 	isInvited := channel.lists[modes.InviteMask].Match(client.nickMaskCasefolded)
373
-	if channel.flags.HasMode(modes.InviteOnly) && !isInvited {
377
+	if !hasPrivs && channel.flags.HasMode(modes.InviteOnly) && !isInvited {
374 378
 		rb.Add(nil, client.server.name, ERR_INVITEONLYCHAN, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "i"))
375 379
 		return
376 380
 	}
377 381
 
378
-	if channel.lists[modes.BanMask].Match(client.nickMaskCasefolded) &&
382
+	if !hasPrivs && channel.lists[modes.BanMask].Match(client.nickMaskCasefolded) &&
379 383
 		!isInvited &&
380 384
 		!channel.lists[modes.ExceptMask].Match(client.nickMaskCasefolded) {
381 385
 		rb.Add(nil, client.server.name, ERR_BANNEDFROMCHAN, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "b"))
@@ -389,7 +393,6 @@ func (channel *Channel) Join(client *Client, key string, rb *ResponseBuffer) {
389 393
 		defer channel.joinPartMutex.Unlock()
390 394
 
391 395
 		func() {
392
-			account := client.Account()
393 396
 			channel.stateMutex.Lock()
394 397
 			defer channel.stateMutex.Unlock()
395 398
 
@@ -779,7 +782,7 @@ func (channel *Channel) Kick(client *Client, target *Client, comment string, rb
779 782
 		return
780 783
 	}
781 784
 	if !channel.ClientHasPrivsOver(client, target) {
782
-		rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, client.t("You're not a channel operator"))
785
+		rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, client.t("You don't have enough channel privileges"))
783 786
 		return
784 787
 	}
785 788
 

+ 2
- 2
irc/channelmanager.go Parādīt failu

@@ -45,7 +45,7 @@ func (cm *ChannelManager) Get(name string) *Channel {
45 45
 }
46 46
 
47 47
 // Join causes `client` to join the channel named `name`, creating it if necessary.
48
-func (cm *ChannelManager) Join(client *Client, name string, key string, rb *ResponseBuffer) error {
48
+func (cm *ChannelManager) Join(client *Client, name string, key string, isSajoin bool, rb *ResponseBuffer) error {
49 49
 	server := client.server
50 50
 	casefoldedName, err := CasefoldChannel(name)
51 51
 	if err != nil || len(casefoldedName) > server.Limits().ChannelLen {
@@ -74,7 +74,7 @@ func (cm *ChannelManager) Join(client *Client, name string, key string, rb *Resp
74 74
 	entry.pendingJoins += 1
75 75
 	cm.Unlock()
76 76
 
77
-	entry.channel.Join(client, key, rb)
77
+	entry.channel.Join(client, key, isSajoin, rb)
78 78
 
79 79
 	cm.maybeCleanup(entry.channel, true)
80 80
 

+ 5
- 0
irc/commands.go Parādīt failu

@@ -229,6 +229,11 @@ func init() {
229 229
 			usablePreReg: true,
230 230
 			minParams:    1,
231 231
 		},
232
+		"SAJOIN": {
233
+			handler:   sajoinHandler,
234
+			minParams: 1,
235
+			capabs:    []string{"sajoin"},
236
+		},
232 237
 		"SANICK": {
233 238
 			handler:   sanickHandler,
234 239
 			minParams: 2,

+ 33
- 1
irc/handlers.go Parādīt failu

@@ -889,7 +889,7 @@ func joinHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
889 889
 		if len(keys) > i {
890 890
 			key = keys[i]
891 891
 		}
892
-		err := server.channels.Join(client, name, key, rb)
892
+		err := server.channels.Join(client, name, key, false, rb)
893 893
 		if err == errNoSuchChannel {
894 894
 			rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, client.Nick(), name, client.t("No such channel"))
895 895
 		}
@@ -897,6 +897,38 @@ func joinHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
897 897
 	return false
898 898
 }
899 899
 
900
+// SAJOIN [nick] #channel{,#channel}
901
+func sajoinHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
902
+	var target *Client
903
+	var channelString string
904
+	if strings.HasPrefix(msg.Params[0], "#") {
905
+		target = client
906
+		channelString = msg.Params[0]
907
+	} else {
908
+		if len(msg.Params) == 1 {
909
+			rb.Add(nil, server.name, ERR_NEEDMOREPARAMS, client.Nick(), "KICK", client.t("Not enough parameters"))
910
+			return false
911
+		} else {
912
+			target = server.clients.Get(msg.Params[0])
913
+			if target == nil {
914
+				rb.Add(nil, server.name, ERR_NOSUCHNICK, client.Nick(), msg.Params[0], "No such nick")
915
+				return false
916
+			}
917
+			channelString = msg.Params[1]
918
+			rb = NewResponseBuffer(target)
919
+		}
920
+	}
921
+
922
+	channels := strings.Split(channelString, ",")
923
+	for _, chname := range channels {
924
+		server.channels.Join(target, chname, "", true, rb)
925
+	}
926
+	if client != target {
927
+		rb.Send()
928
+	}
929
+	return false
930
+}
931
+
900 932
 // KICK <channel>{,<channel>} <user>{,<user>} [<comment>]
901 933
 func kickHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
902 934
 	channels := strings.Split(msg.Params[0], ",")

+ 7
- 0
irc/help.go Parādīt failu

@@ -400,6 +400,13 @@ Renames the given channel with the given reason, if possible.
400 400
 
401 401
 For example:
402 402
 	RENAME #ircv2 #ircv3 :Protocol upgrades!`,
403
+	},
404
+	"sajoin": {
405
+		oper: true,
406
+		text: `SAJOIN [nick] #channel{,#channel}
407
+
408
+Forcibly joins a user to a channel, ignoring restrictions like bans, user limits
409
+and channel keys. If [nick] is omitted, it defaults to the operator.`,
403 410
 	},
404 411
 	"sanick": {
405 412
 		oper: true,

+ 1
- 0
oragono.yaml Parādīt failu

@@ -281,6 +281,7 @@ oper-classes:
281 281
             - "oper:rehash"
282 282
             - "oper:die"
283 283
             - "unregister"
284
+            - "sajoin"
284 285
             - "samode"
285 286
             - "vhosts"
286 287
 

Notiek ielāde…
Atcelt
Saglabāt