ソースを参照

fix #425 and #395

tags/v1.1.0-rc1
Shivaram Lingamneni 5年前
コミット
18a8b075ea
6個のファイルの変更116行の追加221行の削除
  1. 32
    24
      irc/channel.go
  2. 3
    3
      irc/client.go
  3. 4
    4
      irc/commands.go
  4. 69
    183
      irc/handlers.go
  5. 2
    2
      irc/modes.go
  6. 6
    5
      irc/nickname.go

+ 32
- 24
irc/channel.go ファイルの表示

@@ -377,25 +377,25 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
377 377
 	hasPrivs := isSajoin || (founder != "" && founder == details.account) || (persistentMode != 0 && persistentMode != modes.Voice)
378 378
 
379 379
 	if !hasPrivs && limit != 0 && chcount >= limit {
380
-		rb.Add(nil, client.server.name, ERR_CHANNELISFULL, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "l"))
380
+		rb.Add(nil, client.server.name, ERR_CHANNELISFULL, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "l"))
381 381
 		return
382 382
 	}
383 383
 
384 384
 	if !hasPrivs && chkey != "" && !utils.SecretTokensMatch(chkey, key) {
385
-		rb.Add(nil, client.server.name, ERR_BADCHANNELKEY, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "k"))
385
+		rb.Add(nil, client.server.name, ERR_BADCHANNELKEY, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "k"))
386 386
 		return
387 387
 	}
388 388
 
389 389
 	isInvited := client.CheckInvited(chcfname) || channel.lists[modes.InviteMask].Match(details.nickMaskCasefolded)
390 390
 	if !hasPrivs && channel.flags.HasMode(modes.InviteOnly) && !isInvited {
391
-		rb.Add(nil, client.server.name, ERR_INVITEONLYCHAN, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "i"))
391
+		rb.Add(nil, client.server.name, ERR_INVITEONLYCHAN, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "i"))
392 392
 		return
393 393
 	}
394 394
 
395 395
 	if !hasPrivs && channel.lists[modes.BanMask].Match(details.nickMaskCasefolded) &&
396 396
 		!isInvited &&
397 397
 		!channel.lists[modes.ExceptMask].Match(details.nickMaskCasefolded) {
398
-		rb.Add(nil, client.server.name, ERR_BANNEDFROMCHAN, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "b"))
398
+		rb.Add(nil, client.server.name, ERR_BANNEDFROMCHAN, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "b"))
399 399
 		return
400 400
 	}
401 401
 
@@ -482,7 +482,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
482 482
 func (channel *Channel) Part(client *Client, message string, rb *ResponseBuffer) {
483 483
 	chname := channel.Name()
484 484
 	if !channel.hasClient(client) {
485
-		rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, chname, client.t("You're not on that channel"))
485
+		rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.Nick(), chname, client.t("You're not on that channel"))
486 486
 		return
487 487
 	}
488 488
 
@@ -645,7 +645,7 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
645 645
 // `sendNoTopic` controls whether RPL_NOTOPIC is sent when the topic is unset
646 646
 func (channel *Channel) SendTopic(client *Client, rb *ResponseBuffer, sendNoTopic bool) {
647 647
 	if !channel.hasClient(client) {
648
-		rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.nick, channel.name, client.t("You're not on that channel"))
648
+		rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.Nick(), channel.name, client.t("You're not on that channel"))
649 649
 		return
650 650
 	}
651 651
 
@@ -670,12 +670,12 @@ func (channel *Channel) SendTopic(client *Client, rb *ResponseBuffer, sendNoTopi
670 670
 // SetTopic sets the topic of this channel, if the client is allowed to do so.
671 671
 func (channel *Channel) SetTopic(client *Client, topic string, rb *ResponseBuffer) {
672 672
 	if !(client.HasMode(modes.Operator) || channel.hasClient(client)) {
673
-		rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, channel.name, client.t("You're not on that channel"))
673
+		rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.Nick(), channel.Name(), client.t("You're not on that channel"))
674 674
 		return
675 675
 	}
676 676
 
677 677
 	if channel.flags.HasMode(modes.OpOnlyTopic) && !channel.ClientIsAtLeast(client, modes.ChannelOperator) {
678
-		rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, client.t("You're not a channel operator"))
678
+		rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, client.Nick(), channel.Name(), client.t("You're not a channel operator"))
679 679
 		return
680 680
 	}
681 681
 
@@ -719,22 +719,30 @@ func (channel *Channel) CanSpeak(client *Client) bool {
719 719
 	return true
720 720
 }
721 721
 
722
-func (channel *Channel) SendSplitMessage(command string, minPrefix *modes.Mode, clientOnlyTags map[string]string, client *Client, message utils.SplitMessage, rb *ResponseBuffer) {
723
-	var histType history.ItemType
722
+func msgCommandToHistType(server *Server, command string) (history.ItemType, error) {
724 723
 	switch command {
725 724
 	case "PRIVMSG":
726
-		histType = history.Privmsg
725
+		return history.Privmsg, nil
727 726
 	case "NOTICE":
728
-		histType = history.Notice
727
+		return history.Notice, nil
729 728
 	case "TAGMSG":
730
-		histType = history.Tagmsg
729
+		return history.Tagmsg, nil
731 730
 	default:
732
-		channel.server.logger.Error("internal", "unrecognized Channel.SendSplitMessage command", command)
731
+		server.logger.Error("internal", "unrecognized messaging command", command)
732
+		return history.ItemType(0), errInvalidParams
733
+	}
734
+}
735
+
736
+func (channel *Channel) SendSplitMessage(command string, minPrefix *modes.Mode, clientOnlyTags map[string]string, client *Client, message utils.SplitMessage, rb *ResponseBuffer) {
737
+	histType, err := msgCommandToHistType(channel.server, command)
738
+	if err != nil {
733 739
 		return
734 740
 	}
735 741
 
736 742
 	if !channel.CanSpeak(client) {
737
-		rb.Add(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, client.t("Cannot send to channel"))
743
+		if histType != history.Notice {
744
+			rb.Add(nil, client.server.name, ERR_CANNOTSENDTOCHAN, client.Nick(), channel.Name(), client.t("Cannot send to channel"))
745
+		}
738 746
 		return
739 747
 	}
740 748
 
@@ -751,7 +759,7 @@ func (channel *Channel) SendSplitMessage(command string, minPrefix *modes.Mode,
751 759
 		}
752 760
 		nickMaskString := client.NickMaskString()
753 761
 		accountName := client.AccountName()
754
-		if command == "TAGMSG" && client.capabilities.Has(caps.MessageTags) {
762
+		if histType == history.Tagmsg && client.capabilities.Has(caps.MessageTags) {
755 763
 			rb.AddFromClient(message.Msgid, nickMaskString, accountName, tagsToUse, command, channel.name)
756 764
 		} else {
757 765
 			rb.AddSplitMessageFromClient(nickMaskString, accountName, tagsToUse, command, channel.name, message)
@@ -775,11 +783,11 @@ func (channel *Channel) SendSplitMessage(command string, minPrefix *modes.Mode,
775 783
 		var tagsToUse map[string]string
776 784
 		if member.capabilities.Has(caps.MessageTags) {
777 785
 			tagsToUse = clientOnlyTags
778
-		} else if command == "TAGMSG" {
786
+		} else if histType == history.Tagmsg {
779 787
 			continue
780 788
 		}
781 789
 
782
-		if command == "TAGMSG" {
790
+		if histType == history.Tagmsg {
783 791
 			member.sendFromClientInternal(false, now, message.Msgid, nickmask, account, tagsToUse, command, channel.name)
784 792
 		} else {
785 793
 			member.sendSplitMsgFromClientInternal(false, now, nickmask, account, tagsToUse, command, channel.name, message)
@@ -861,7 +869,7 @@ func (channel *Channel) applyModeMask(client *Client, mode modes.Mode, op modes.
861 869
 	}
862 870
 
863 871
 	if !channel.ClientIsAtLeast(client, modes.ChannelOperator) {
864
-		rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, client.t("You're not a channel operator"))
872
+		rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, client.Nick(), channel.Name(), client.t("You're not a channel operator"))
865 873
 		return false
866 874
 	}
867 875
 
@@ -898,15 +906,15 @@ func (channel *Channel) Quit(client *Client) {
898 906
 
899 907
 func (channel *Channel) Kick(client *Client, target *Client, comment string, rb *ResponseBuffer) {
900 908
 	if !(client.HasMode(modes.Operator) || channel.hasClient(client)) {
901
-		rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, channel.name, client.t("You're not on that channel"))
909
+		rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.Nick(), channel.Name(), client.t("You're not on that channel"))
902 910
 		return
903 911
 	}
904 912
 	if !channel.hasClient(target) {
905
-		rb.Add(nil, client.server.name, ERR_USERNOTINCHANNEL, client.nick, channel.name, client.t("They aren't on that channel"))
913
+		rb.Add(nil, client.server.name, ERR_USERNOTINCHANNEL, client.Nick(), channel.Name(), client.t("They aren't on that channel"))
906 914
 		return
907 915
 	}
908 916
 	if !channel.ClientHasPrivsOver(client, target) {
909
-		rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, client.t("You don't have enough channel privileges"))
917
+		rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, client.Nick(), channel.Name(), client.t("You don't have enough channel privileges"))
910 918
 		return
911 919
 	}
912 920
 
@@ -938,12 +946,12 @@ func (channel *Channel) Kick(client *Client, target *Client, comment string, rb
938 946
 func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuffer) {
939 947
 	chname := channel.Name()
940 948
 	if channel.flags.HasMode(modes.InviteOnly) && !channel.ClientIsAtLeast(inviter, modes.ChannelOperator) {
941
-		rb.Add(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, chname, inviter.t("You're not a channel operator"))
949
+		rb.Add(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, inviter.Nick(), channel.Name(), inviter.t("You're not a channel operator"))
942 950
 		return
943 951
 	}
944 952
 
945 953
 	if !channel.hasClient(inviter) {
946
-		rb.Add(nil, inviter.server.name, ERR_NOTONCHANNEL, chname, inviter.t("You're not on that channel"))
954
+		rb.Add(nil, inviter.server.name, ERR_NOTONCHANNEL, inviter.Nick(), channel.Name(), inviter.t("You're not on that channel"))
947 955
 		return
948 956
 	}
949 957
 

+ 3
- 3
irc/client.go ファイルの表示

@@ -325,7 +325,7 @@ func (client *Client) run() {
325 325
 		if err == ircmsg.ErrorLineIsEmpty {
326 326
 			continue
327 327
 		} else if err == ircmsg.ErrorLineTooLong {
328
-			client.Send(nil, client.server.name, ERR_INPUTTOOLONG, client.nick, client.t("Input line too long"))
328
+			client.Send(nil, client.server.name, ERR_INPUTTOOLONG, client.Nick(), client.t("Input line too long"))
329 329
 			continue
330 330
 		} else if err != nil {
331 331
 			client.Quit(client.t("Received malformed line"))
@@ -335,9 +335,9 @@ func (client *Client) run() {
335 335
 		cmd, exists := Commands[msg.Command]
336 336
 		if !exists {
337 337
 			if len(msg.Command) > 0 {
338
-				client.Send(nil, client.server.name, ERR_UNKNOWNCOMMAND, client.nick, msg.Command, client.t("Unknown command"))
338
+				client.Send(nil, client.server.name, ERR_UNKNOWNCOMMAND, client.Nick(), msg.Command, client.t("Unknown command"))
339 339
 			} else {
340
-				client.Send(nil, client.server.name, ERR_UNKNOWNCOMMAND, client.nick, "lastcmd", client.t("No command given"))
340
+				client.Send(nil, client.server.name, ERR_UNKNOWNCOMMAND, client.Nick(), "lastcmd", client.t("No command given"))
341 341
 			}
342 342
 			continue
343 343
 		}

+ 4
- 4
irc/commands.go ファイルの表示

@@ -23,7 +23,7 @@ type Command struct {
23 23
 // Run runs this command with the given client/message.
24 24
 func (cmd *Command) Run(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
25 25
 	if !client.registered && !cmd.usablePreReg {
26
-		client.Send(nil, server.name, ERR_NOTREGISTERED, client.nick, client.t("You need to register before you can use that command"))
26
+		client.Send(nil, server.name, ERR_NOTREGISTERED, "*", client.t("You need to register before you can use that command"))
27 27
 		return false
28 28
 	}
29 29
 	if cmd.oper && !client.HasMode(modes.Operator) {
@@ -184,7 +184,7 @@ func init() {
184 184
 			minParams:    1,
185 185
 		},
186 186
 		"NOTICE": {
187
-			handler:   noticeHandler,
187
+			handler:   messageHandler,
188 188
 			minParams: 2,
189 189
 		},
190 190
 		"NPC": {
@@ -221,7 +221,7 @@ func init() {
221 221
 			leaveClientIdle: true,
222 222
 		},
223 223
 		"PRIVMSG": {
224
-			handler:   privmsgHandler,
224
+			handler:   messageHandler,
225 225
 			minParams: 2,
226 226
 		},
227 227
 		"RENAME": {
@@ -257,7 +257,7 @@ func init() {
257 257
 			minParams: 1,
258 258
 		},
259 259
 		"TAGMSG": {
260
-			handler:   tagmsgHandler,
260
+			handler:   messageHandler,
261 261
 			minParams: 1,
262 262
 		},
263 263
 		"QUIT": {

+ 69
- 183
irc/handlers.go ファイルの表示

@@ -242,7 +242,7 @@ func accVerifyHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb
242 242
 	if err == nil {
243 243
 		sendSuccessfulRegResponse(client, rb, false)
244 244
 	} else {
245
-		rb.Add(nil, server.name, code, client.nick, account, client.t(message))
245
+		rb.Add(nil, server.name, code, client.Nick(), account, client.t(message))
246 246
 	}
247 247
 
248 248
 	return false
@@ -1873,17 +1873,38 @@ func nickHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
1873 1873
 }
1874 1874
 
1875 1875
 // NOTICE <target>{,<target>} <message>
1876
-func noticeHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
1876
+// PRIVMSG <target>{,<target>} <message>
1877
+// TAGMSG <target>{,<target>}
1878
+func messageHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
1879
+	histType, err := msgCommandToHistType(server, msg.Command)
1880
+	if err != nil {
1881
+		return false
1882
+	}
1883
+
1884
+	cnick := client.Nick()
1877 1885
 	clientOnlyTags := msg.ClientOnlyTags()
1886
+	if histType == history.Tagmsg && len(clientOnlyTags) == 0 {
1887
+		// nothing to do
1888
+		return false
1889
+	}
1890
+
1878 1891
 	targets := strings.Split(msg.Params[0], ",")
1879
-	message := msg.Params[1]
1892
+	var message string
1893
+	if len(msg.Params) > 1 {
1894
+		message = msg.Params[1]
1895
+	}
1896
+
1897
+	// note that error replies are never sent for NOTICE
1880 1898
 
1881 1899
 	if client.isTor && isRestrictedCTCPMessage(message) {
1882
-		rb.Add(nil, server.name, "NOTICE", client.t("CTCP messages are disabled over Tor"))
1900
+		if histType != history.Notice {
1901
+			rb.Add(nil, server.name, "NOTICE", client.t("CTCP messages are disabled over Tor"))
1902
+		}
1883 1903
 		return false
1884 1904
 	}
1885 1905
 
1886 1906
 	splitMsg := utils.MakeSplitMessage(message, !client.capabilities.Has(caps.MaxLine))
1907
+	now := time.Now().UTC()
1887 1908
 
1888 1909
 	for i, targetString := range targets {
1889 1910
 		// max of four targets per privmsg
@@ -1893,52 +1914,66 @@ func noticeHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
1893 1914
 		prefixes, targetString := modes.SplitChannelMembershipPrefixes(targetString)
1894 1915
 		lowestPrefix := modes.GetLowestChannelModePrefix(prefixes)
1895 1916
 
1896
-		target, cerr := CasefoldChannel(targetString)
1897
-		if cerr == nil {
1898
-			channel := server.channels.Get(target)
1917
+		if len(targetString) == 0 {
1918
+			continue
1919
+		} else if targetString[0] == '#' {
1920
+			channel := server.channels.Get(targetString)
1899 1921
 			if channel == nil {
1900
-				// errors silently ignored with NOTICE as per RFC
1901
-				continue
1902
-			}
1903
-			if !channel.CanSpeak(client) {
1904
-				// errors silently ignored with NOTICE as per RFC
1922
+				if histType != history.Notice {
1923
+					rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, cnick, targetString, client.t("No such channel"))
1924
+				}
1905 1925
 				continue
1906 1926
 			}
1907
-			channel.SendSplitMessage("NOTICE", lowestPrefix, clientOnlyTags, client, splitMsg, rb)
1927
+			channel.SendSplitMessage(msg.Command, lowestPrefix, clientOnlyTags, client, splitMsg, rb)
1908 1928
 		} else {
1909
-			target, err := CasefoldName(targetString)
1910
-			if err != nil {
1911
-				continue
1912
-			}
1913
-
1914
-			// NOTICEs sent to services are ignored
1915
-			if _, isService := OragonoServices[target]; isService {
1929
+			if service, isService := OragonoServices[strings.ToLower(targetString)]; isService {
1930
+				// NOTICE and TAGMSG to services are ignored
1931
+				if histType == history.Privmsg {
1932
+					servicePrivmsgHandler(service, server, client, message, rb)
1933
+				}
1916 1934
 				continue
1917 1935
 			}
1918 1936
 
1919
-			user := server.clients.Get(target)
1937
+			user := server.clients.Get(targetString)
1920 1938
 			if user == nil {
1921
-				// errors silently ignored with NOTICE as per RFC
1939
+				if histType != history.Notice {
1940
+					rb.Add(nil, server.name, ERR_NOSUCHNICK, cnick, targetString, "No such nick")
1941
+				}
1922 1942
 				continue
1923 1943
 			}
1924
-			if !user.capabilities.Has(caps.MessageTags) {
1925
-				clientOnlyTags = nil
1944
+			tnick := user.Nick()
1945
+
1946
+			if histType == history.Tagmsg && !user.capabilities.Has(caps.MessageTags) {
1947
+				continue // nothing to do
1926 1948
 			}
1949
+
1950
+			nickMaskString := client.NickMaskString()
1951
+			accountName := client.AccountName()
1927 1952
 			// restrict messages appropriately when +R is set
1928 1953
 			// intentionally make the sending user think the message went through fine
1929 1954
 			allowedPlusR := !user.HasMode(modes.RegisteredOnly) || client.LoggedIntoAccount()
1930 1955
 			allowedTor := !user.isTor || !isRestrictedCTCPMessage(message)
1931 1956
 			if allowedPlusR && allowedTor {
1932
-				user.SendSplitMsgFromClient(client, clientOnlyTags, "NOTICE", user.nick, splitMsg)
1957
+				if histType == history.Tagmsg {
1958
+					user.sendFromClientInternal(false, now, splitMsg.Msgid, nickMaskString, accountName, clientOnlyTags, msg.Command, tnick)
1959
+				} else {
1960
+					user.SendSplitMsgFromClient(client, clientOnlyTags, msg.Command, tnick, splitMsg)
1961
+				}
1933 1962
 			}
1934
-			nickMaskString := client.NickMaskString()
1935
-			accountName := client.AccountName()
1936 1963
 			if client.capabilities.Has(caps.EchoMessage) {
1937
-				rb.AddSplitMessageFromClient(nickMaskString, accountName, clientOnlyTags, "NOTICE", user.nick, splitMsg)
1964
+				if histType == history.Tagmsg && client.capabilities.Has(caps.MessageTags) {
1965
+					rb.AddFromClient(splitMsg.Msgid, nickMaskString, accountName, clientOnlyTags, msg.Command, tnick)
1966
+				} else {
1967
+					rb.AddSplitMessageFromClient(nickMaskString, accountName, clientOnlyTags, msg.Command, tnick, splitMsg)
1968
+				}
1969
+			}
1970
+			if histType != history.Notice && user.HasMode(modes.Away) {
1971
+				//TODO(dan): possibly implement cooldown of away notifications to users
1972
+				rb.Add(nil, server.name, RPL_AWAY, cnick, tnick, user.AwayMessage())
1938 1973
 			}
1939 1974
 
1940 1975
 			user.history.Add(history.Item{
1941
-				Type:        history.Notice,
1976
+				Type:        histType,
1942 1977
 				Message:     splitMsg,
1943 1978
 				Nick:        nickMaskString,
1944 1979
 				AccountName: accountName,
@@ -1988,7 +2023,7 @@ func npcaHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
1988 2023
 // OPER <name> <password>
1989 2024
 func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
1990 2025
 	if client.HasMode(modes.Operator) == true {
1991
-		rb.Add(nil, server.name, ERR_UNKNOWNERROR, "OPER", client.t("You're already opered-up!"))
2026
+		rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.Nick(), "OPER", client.t("You're already opered-up!"))
1992 2027
 		return false
1993 2028
 	}
1994 2029
 
@@ -1999,7 +2034,7 @@ func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
1999 2034
 		authorized = (bcrypt.CompareHashAndPassword(oper.Pass, password) == nil)
2000 2035
 	}
2001 2036
 	if !authorized {
2002
-		rb.Add(nil, server.name, ERR_PASSWDMISMATCH, client.nick, client.t("Password incorrect"))
2037
+		rb.Add(nil, server.name, ERR_PASSWDMISMATCH, client.Nick(), client.t("Password incorrect"))
2003 2038
 		client.Quit(client.t("Password incorrect"))
2004 2039
 		return true
2005 2040
 	}
@@ -2090,90 +2125,6 @@ func isRestrictedCTCPMessage(message string) bool {
2090 2125
 	return strings.HasPrefix(message, "\x01") && !strings.HasPrefix(message, "\x01ACTION")
2091 2126
 }
2092 2127
 
2093
-// PRIVMSG <target>{,<target>} <message>
2094
-func privmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2095
-	clientOnlyTags := msg.ClientOnlyTags()
2096
-	targets := strings.Split(msg.Params[0], ",")
2097
-	message := msg.Params[1]
2098
-
2099
-	if client.isTor && isRestrictedCTCPMessage(message) {
2100
-		rb.Add(nil, server.name, "NOTICE", client.t("CTCP messages are disabled over Tor"))
2101
-		return false
2102
-	}
2103
-
2104
-	// split privmsg
2105
-	splitMsg := utils.MakeSplitMessage(message, !client.capabilities.Has(caps.MaxLine))
2106
-
2107
-	cnick := client.Nick()
2108
-	for i, targetString := range targets {
2109
-		// max of four targets per privmsg
2110
-		if i > maxTargets-1 {
2111
-			break
2112
-		}
2113
-		prefixes, targetString := modes.SplitChannelMembershipPrefixes(targetString)
2114
-		lowestPrefix := modes.GetLowestChannelModePrefix(prefixes)
2115
-
2116
-		// eh, no need to notify them
2117
-		if len(targetString) < 1 {
2118
-			continue
2119
-		}
2120
-
2121
-		target, err := CasefoldChannel(targetString)
2122
-		if err == nil {
2123
-			channel := server.channels.Get(target)
2124
-			if channel == nil {
2125
-				rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, cnick, targetString, client.t("No such channel"))
2126
-				continue
2127
-			}
2128
-			if !channel.CanSpeak(client) {
2129
-				rb.Add(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, client.t("Cannot send to channel"))
2130
-				continue
2131
-			}
2132
-			channel.SendSplitMessage("PRIVMSG", lowestPrefix, clientOnlyTags, client, splitMsg, rb)
2133
-		} else {
2134
-			target, err = CasefoldName(targetString)
2135
-			if service, isService := OragonoServices[target]; isService {
2136
-				servicePrivmsgHandler(service, server, client, message, rb)
2137
-				continue
2138
-			}
2139
-			user := server.clients.Get(target)
2140
-			if err != nil || user == nil {
2141
-				if len(target) > 0 {
2142
-					client.Send(nil, server.name, ERR_NOSUCHNICK, cnick, target, "No such nick")
2143
-				}
2144
-				continue
2145
-			}
2146
-			if !user.capabilities.Has(caps.MessageTags) {
2147
-				clientOnlyTags = nil
2148
-			}
2149
-			// restrict messages appropriately when +R is set
2150
-			// intentionally make the sending user think the message went through fine
2151
-			allowedPlusR := !user.HasMode(modes.RegisteredOnly) || client.LoggedIntoAccount()
2152
-			allowedTor := !user.isTor || !isRestrictedCTCPMessage(message)
2153
-			if allowedPlusR && allowedTor {
2154
-				user.SendSplitMsgFromClient(client, clientOnlyTags, "PRIVMSG", user.nick, splitMsg)
2155
-			}
2156
-			nickMaskString := client.NickMaskString()
2157
-			accountName := client.AccountName()
2158
-			if client.capabilities.Has(caps.EchoMessage) {
2159
-				rb.AddSplitMessageFromClient(nickMaskString, accountName, clientOnlyTags, "PRIVMSG", user.nick, splitMsg)
2160
-			}
2161
-			if user.HasMode(modes.Away) {
2162
-				//TODO(dan): possibly implement cooldown of away notifications to users
2163
-				rb.Add(nil, server.name, RPL_AWAY, cnick, user.Nick(), user.AwayMessage())
2164
-			}
2165
-
2166
-			user.history.Add(history.Item{
2167
-				Type:        history.Privmsg,
2168
-				Message:     splitMsg,
2169
-				Nick:        nickMaskString,
2170
-				AccountName: accountName,
2171
-			})
2172
-		}
2173
-	}
2174
-	return false
2175
-}
2176
-
2177 2128
 // QUIT [<reason>]
2178 2129
 func quitHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2179 2130
 	reason := "Quit"
@@ -2346,71 +2297,6 @@ func setnameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *R
2346 2297
 	return false
2347 2298
 }
2348 2299
 
2349
-// TAGMSG <target>{,<target>}
2350
-func tagmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2351
-	clientOnlyTags := msg.ClientOnlyTags()
2352
-	// no client-only tags, so we can drop it
2353
-	if clientOnlyTags == nil {
2354
-		return false
2355
-	}
2356
-
2357
-	targets := strings.Split(msg.Params[0], ",")
2358
-
2359
-	cnick := client.Nick()
2360
-	message := utils.MakeSplitMessage("", true) // assign consistent message ID
2361
-	for i, targetString := range targets {
2362
-		// max of four targets per privmsg
2363
-		if i > maxTargets-1 {
2364
-			break
2365
-		}
2366
-		prefixes, targetString := modes.SplitChannelMembershipPrefixes(targetString)
2367
-		lowestPrefix := modes.GetLowestChannelModePrefix(prefixes)
2368
-
2369
-		// eh, no need to notify them
2370
-		if len(targetString) < 1 {
2371
-			continue
2372
-		}
2373
-
2374
-		target, err := CasefoldChannel(targetString)
2375
-		if err == nil {
2376
-			channel := server.channels.Get(target)
2377
-			if channel == nil {
2378
-				rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, cnick, targetString, client.t("No such channel"))
2379
-				continue
2380
-			}
2381
-			if !channel.CanSpeak(client) {
2382
-				rb.Add(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, client.t("Cannot send to channel"))
2383
-				continue
2384
-			}
2385
-			channel.SendSplitMessage("TAGMSG", lowestPrefix, clientOnlyTags, client, message, rb)
2386
-		} else {
2387
-			target, err = CasefoldName(targetString)
2388
-			user := server.clients.Get(target)
2389
-			if err != nil || user == nil {
2390
-				if len(target) > 0 {
2391
-					client.Send(nil, server.name, ERR_NOSUCHNICK, cnick, target, client.t("No such nick"))
2392
-				}
2393
-				continue
2394
-			}
2395
-
2396
-			// end user can't receive tagmsgs
2397
-			if !user.capabilities.Has(caps.MessageTags) {
2398
-				continue
2399
-			}
2400
-			unick := user.Nick()
2401
-			user.SendSplitMsgFromClient(client, clientOnlyTags, "TAGMSG", unick, message)
2402
-			if client.capabilities.Has(caps.EchoMessage) {
2403
-				rb.AddSplitMessageFromClient(client.NickMaskString(), client.AccountName(), clientOnlyTags, "TAGMSG", unick, message)
2404
-			}
2405
-			if user.HasMode(modes.Away) {
2406
-				//TODO(dan): possibly implement cooldown of away notifications to users
2407
-				rb.Add(nil, server.name, RPL_AWAY, cnick, unick, user.AwayMessage())
2408
-			}
2409
-		}
2410
-	}
2411
-	return false
2412
-}
2413
-
2414 2300
 // TIME
2415 2301
 func timeHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2416 2302
 	rb.Add(nil, server.name, RPL_TIME, client.nick, server.name, time.Now().Format(time.RFC1123))
@@ -2502,7 +2388,7 @@ func unKLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *R
2502 2388
 // USER <username> * 0 <realname>
2503 2389
 func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2504 2390
 	if client.registered {
2505
-		rb.Add(nil, server.name, ERR_ALREADYREGISTRED, client.nick, client.t("You may not reregister"))
2391
+		rb.Add(nil, server.name, ERR_ALREADYREGISTRED, client.Nick(), client.t("You may not reregister"))
2506 2392
 		return false
2507 2393
 	}
2508 2394
 
@@ -2513,7 +2399,7 @@ func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
2513 2399
 		if client.preregNick == msg.Params[0] {
2514 2400
 			client.SetNames("user", msg.Params[3], false)
2515 2401
 		} else {
2516
-			rb.Add(nil, server.name, ERR_INVALIDUSERNAME, client.t("Malformed username"))
2402
+			rb.Add(nil, server.name, ERR_INVALIDUSERNAME, client.Nick(), client.t("Malformed username"))
2517 2403
 		}
2518 2404
 	}
2519 2405
 
@@ -2631,7 +2517,7 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Respo
2631 2517
 	if len(msg.Params) > 0 {
2632 2518
 		casefoldedMask, err := Casefold(msg.Params[0])
2633 2519
 		if err != nil {
2634
-			rb.Add(nil, server.name, ERR_UNKNOWNERROR, "WHO", client.t("Mask isn't valid"))
2520
+			rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.Nick(), "WHO", client.t("Mask isn't valid"))
2635 2521
 			return false
2636 2522
 		}
2637 2523
 		mask = casefoldedMask

+ 2
- 2
irc/modes.go ファイルの表示

@@ -150,7 +150,7 @@ func (channel *Channel) ApplyChannelModeChanges(client *Client, isSamode bool, c
150 150
 		if !hasPrivs(change) {
151 151
 			if !alreadySentPrivError {
152 152
 				alreadySentPrivError = true
153
-				rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, client.t("You're not a channel operator"))
153
+				rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, client.Nick(), channel.name, client.t("You're not a channel operator"))
154 154
 			}
155 155
 			continue
156 156
 		}
@@ -226,7 +226,7 @@ func (channel *Channel) ApplyChannelModeChanges(client *Client, isSamode bool, c
226 226
 
227 227
 			nick := change.Arg
228 228
 			if nick == "" {
229
-				rb.Add(nil, client.server.name, ERR_NEEDMOREPARAMS, "MODE", client.t("Not enough parameters"))
229
+				rb.Add(nil, client.server.name, ERR_NEEDMOREPARAMS, client.Nick(), "MODE", client.t("Not enough parameters"))
230 230
 				return nil
231 231
 			}
232 232
 

+ 6
- 5
irc/nickname.go ファイルの表示

@@ -26,14 +26,15 @@ var (
26 26
 func performNickChange(server *Server, client *Client, target *Client, newnick string, rb *ResponseBuffer) bool {
27 27
 	nickname := strings.TrimSpace(newnick)
28 28
 	cfnick, err := CasefoldName(nickname)
29
+	currentNick := client.Nick()
29 30
 
30 31
 	if len(nickname) < 1 {
31
-		rb.Add(nil, server.name, ERR_NONICKNAMEGIVEN, client.nick, client.t("No nickname given"))
32
+		rb.Add(nil, server.name, ERR_NONICKNAMEGIVEN, currentNick, client.t("No nickname given"))
32 33
 		return false
33 34
 	}
34 35
 
35 36
 	if err != nil || len(nickname) > server.Limits().NickLen || restrictedNicknames[cfnick] {
36
-		rb.Add(nil, server.name, ERR_ERRONEUSNICKNAME, client.nick, nickname, client.t("Erroneous nickname"))
37
+		rb.Add(nil, server.name, ERR_ERRONEUSNICKNAME, currentNick, nickname, client.t("Erroneous nickname"))
37 38
 		return false
38 39
 	}
39 40
 
@@ -46,13 +47,13 @@ func performNickChange(server *Server, client *Client, target *Client, newnick s
46 47
 	whowas := client.WhoWas()
47 48
 	err = client.server.clients.SetNick(target, nickname)
48 49
 	if err == errNicknameInUse {
49
-		rb.Add(nil, server.name, ERR_NICKNAMEINUSE, client.nick, nickname, client.t("Nickname is already in use"))
50
+		rb.Add(nil, server.name, ERR_NICKNAMEINUSE, currentNick, nickname, client.t("Nickname is already in use"))
50 51
 		return false
51 52
 	} else if err == errNicknameReserved {
52
-		rb.Add(nil, server.name, ERR_NICKNAMEINUSE, client.nick, nickname, client.t("Nickname is reserved by a different account"))
53
+		rb.Add(nil, server.name, ERR_NICKNAMEINUSE, currentNick, nickname, client.t("Nickname is reserved by a different account"))
53 54
 		return false
54 55
 	} else if err != nil {
55
-		rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.nick, "NICK", fmt.Sprintf(client.t("Could not set or change nickname: %s"), err.Error()))
56
+		rb.Add(nil, server.name, ERR_UNKNOWNERROR, currentNick, "NICK", fmt.Sprintf(client.t("Could not set or change nickname: %s"), err.Error()))
56 57
 		return false
57 58
 	}
58 59
 

読み込み中…
キャンセル
保存