3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-12-22 10:42:52 +01:00
This commit is contained in:
Shivaram Lingamneni 2019-03-19 03:35:49 -04:00
parent 29db70fa7b
commit 18a8b075ea
6 changed files with 116 additions and 221 deletions

View File

@ -377,25 +377,25 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
hasPrivs := isSajoin || (founder != "" && founder == details.account) || (persistentMode != 0 && persistentMode != modes.Voice)
if !hasPrivs && limit != 0 && chcount >= limit {
rb.Add(nil, client.server.name, ERR_CHANNELISFULL, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "l"))
rb.Add(nil, client.server.name, ERR_CHANNELISFULL, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "l"))
return
}
if !hasPrivs && chkey != "" && !utils.SecretTokensMatch(chkey, key) {
rb.Add(nil, client.server.name, ERR_BADCHANNELKEY, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "k"))
rb.Add(nil, client.server.name, ERR_BADCHANNELKEY, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "k"))
return
}
isInvited := client.CheckInvited(chcfname) || channel.lists[modes.InviteMask].Match(details.nickMaskCasefolded)
if !hasPrivs && channel.flags.HasMode(modes.InviteOnly) && !isInvited {
rb.Add(nil, client.server.name, ERR_INVITEONLYCHAN, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "i"))
rb.Add(nil, client.server.name, ERR_INVITEONLYCHAN, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "i"))
return
}
if !hasPrivs && channel.lists[modes.BanMask].Match(details.nickMaskCasefolded) &&
!isInvited &&
!channel.lists[modes.ExceptMask].Match(details.nickMaskCasefolded) {
rb.Add(nil, client.server.name, ERR_BANNEDFROMCHAN, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "b"))
rb.Add(nil, client.server.name, ERR_BANNEDFROMCHAN, details.nick, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "b"))
return
}
@ -482,7 +482,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
func (channel *Channel) Part(client *Client, message string, rb *ResponseBuffer) {
chname := channel.Name()
if !channel.hasClient(client) {
rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, chname, client.t("You're not on that channel"))
rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.Nick(), chname, client.t("You're not on that channel"))
return
}
@ -645,7 +645,7 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
// `sendNoTopic` controls whether RPL_NOTOPIC is sent when the topic is unset
func (channel *Channel) SendTopic(client *Client, rb *ResponseBuffer, sendNoTopic bool) {
if !channel.hasClient(client) {
rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.nick, channel.name, client.t("You're not on that channel"))
rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.Nick(), channel.name, client.t("You're not on that channel"))
return
}
@ -670,12 +670,12 @@ func (channel *Channel) SendTopic(client *Client, rb *ResponseBuffer, sendNoTopi
// SetTopic sets the topic of this channel, if the client is allowed to do so.
func (channel *Channel) SetTopic(client *Client, topic string, rb *ResponseBuffer) {
if !(client.HasMode(modes.Operator) || channel.hasClient(client)) {
rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, channel.name, client.t("You're not on that channel"))
rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.Nick(), channel.Name(), client.t("You're not on that channel"))
return
}
if channel.flags.HasMode(modes.OpOnlyTopic) && !channel.ClientIsAtLeast(client, modes.ChannelOperator) {
rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, client.t("You're not a channel operator"))
rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, client.Nick(), channel.Name(), client.t("You're not a channel operator"))
return
}
@ -719,22 +719,30 @@ func (channel *Channel) CanSpeak(client *Client) bool {
return true
}
func (channel *Channel) SendSplitMessage(command string, minPrefix *modes.Mode, clientOnlyTags map[string]string, client *Client, message utils.SplitMessage, rb *ResponseBuffer) {
var histType history.ItemType
func msgCommandToHistType(server *Server, command string) (history.ItemType, error) {
switch command {
case "PRIVMSG":
histType = history.Privmsg
return history.Privmsg, nil
case "NOTICE":
histType = history.Notice
return history.Notice, nil
case "TAGMSG":
histType = history.Tagmsg
return history.Tagmsg, nil
default:
channel.server.logger.Error("internal", "unrecognized Channel.SendSplitMessage command", command)
server.logger.Error("internal", "unrecognized messaging command", command)
return history.ItemType(0), errInvalidParams
}
}
func (channel *Channel) SendSplitMessage(command string, minPrefix *modes.Mode, clientOnlyTags map[string]string, client *Client, message utils.SplitMessage, rb *ResponseBuffer) {
histType, err := msgCommandToHistType(channel.server, command)
if err != nil {
return
}
if !channel.CanSpeak(client) {
rb.Add(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, client.t("Cannot send to channel"))
if histType != history.Notice {
rb.Add(nil, client.server.name, ERR_CANNOTSENDTOCHAN, client.Nick(), channel.Name(), client.t("Cannot send to channel"))
}
return
}
@ -751,7 +759,7 @@ func (channel *Channel) SendSplitMessage(command string, minPrefix *modes.Mode,
}
nickMaskString := client.NickMaskString()
accountName := client.AccountName()
if command == "TAGMSG" && client.capabilities.Has(caps.MessageTags) {
if histType == history.Tagmsg && client.capabilities.Has(caps.MessageTags) {
rb.AddFromClient(message.Msgid, nickMaskString, accountName, tagsToUse, command, channel.name)
} else {
rb.AddSplitMessageFromClient(nickMaskString, accountName, tagsToUse, command, channel.name, message)
@ -775,11 +783,11 @@ func (channel *Channel) SendSplitMessage(command string, minPrefix *modes.Mode,
var tagsToUse map[string]string
if member.capabilities.Has(caps.MessageTags) {
tagsToUse = clientOnlyTags
} else if command == "TAGMSG" {
} else if histType == history.Tagmsg {
continue
}
if command == "TAGMSG" {
if histType == history.Tagmsg {
member.sendFromClientInternal(false, now, message.Msgid, nickmask, account, tagsToUse, command, channel.name)
} else {
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.
}
if !channel.ClientIsAtLeast(client, modes.ChannelOperator) {
rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, client.t("You're not a channel operator"))
rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, client.Nick(), channel.Name(), client.t("You're not a channel operator"))
return false
}
@ -898,15 +906,15 @@ func (channel *Channel) Quit(client *Client) {
func (channel *Channel) Kick(client *Client, target *Client, comment string, rb *ResponseBuffer) {
if !(client.HasMode(modes.Operator) || channel.hasClient(client)) {
rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, channel.name, client.t("You're not on that channel"))
rb.Add(nil, client.server.name, ERR_NOTONCHANNEL, client.Nick(), channel.Name(), client.t("You're not on that channel"))
return
}
if !channel.hasClient(target) {
rb.Add(nil, client.server.name, ERR_USERNOTINCHANNEL, client.nick, channel.name, client.t("They aren't on that channel"))
rb.Add(nil, client.server.name, ERR_USERNOTINCHANNEL, client.Nick(), channel.Name(), client.t("They aren't on that channel"))
return
}
if !channel.ClientHasPrivsOver(client, target) {
rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, channel.name, client.t("You don't have enough channel privileges"))
rb.Add(nil, client.server.name, ERR_CHANOPRIVSNEEDED, client.Nick(), channel.Name(), client.t("You don't have enough channel privileges"))
return
}
@ -938,12 +946,12 @@ func (channel *Channel) Kick(client *Client, target *Client, comment string, rb
func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuffer) {
chname := channel.Name()
if channel.flags.HasMode(modes.InviteOnly) && !channel.ClientIsAtLeast(inviter, modes.ChannelOperator) {
rb.Add(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, chname, inviter.t("You're not a channel operator"))
rb.Add(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, inviter.Nick(), channel.Name(), inviter.t("You're not a channel operator"))
return
}
if !channel.hasClient(inviter) {
rb.Add(nil, inviter.server.name, ERR_NOTONCHANNEL, chname, inviter.t("You're not on that channel"))
rb.Add(nil, inviter.server.name, ERR_NOTONCHANNEL, inviter.Nick(), channel.Name(), inviter.t("You're not on that channel"))
return
}

View File

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

View File

@ -23,7 +23,7 @@ type Command struct {
// Run runs this command with the given client/message.
func (cmd *Command) Run(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
if !client.registered && !cmd.usablePreReg {
client.Send(nil, server.name, ERR_NOTREGISTERED, client.nick, client.t("You need to register before you can use that command"))
client.Send(nil, server.name, ERR_NOTREGISTERED, "*", client.t("You need to register before you can use that command"))
return false
}
if cmd.oper && !client.HasMode(modes.Operator) {
@ -184,7 +184,7 @@ func init() {
minParams: 1,
},
"NOTICE": {
handler: noticeHandler,
handler: messageHandler,
minParams: 2,
},
"NPC": {
@ -221,7 +221,7 @@ func init() {
leaveClientIdle: true,
},
"PRIVMSG": {
handler: privmsgHandler,
handler: messageHandler,
minParams: 2,
},
"RENAME": {
@ -257,7 +257,7 @@ func init() {
minParams: 1,
},
"TAGMSG": {
handler: tagmsgHandler,
handler: messageHandler,
minParams: 1,
},
"QUIT": {

View File

@ -242,7 +242,7 @@ func accVerifyHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb
if err == nil {
sendSuccessfulRegResponse(client, rb, false)
} else {
rb.Add(nil, server.name, code, client.nick, account, client.t(message))
rb.Add(nil, server.name, code, client.Nick(), account, client.t(message))
}
return false
@ -1873,17 +1873,38 @@ func nickHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
}
// NOTICE <target>{,<target>} <message>
func noticeHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
// PRIVMSG <target>{,<target>} <message>
// TAGMSG <target>{,<target>}
func messageHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
histType, err := msgCommandToHistType(server, msg.Command)
if err != nil {
return false
}
cnick := client.Nick()
clientOnlyTags := msg.ClientOnlyTags()
if histType == history.Tagmsg && len(clientOnlyTags) == 0 {
// nothing to do
return false
}
targets := strings.Split(msg.Params[0], ",")
message := msg.Params[1]
var message string
if len(msg.Params) > 1 {
message = msg.Params[1]
}
// note that error replies are never sent for NOTICE
if client.isTor && isRestrictedCTCPMessage(message) {
rb.Add(nil, server.name, "NOTICE", client.t("CTCP messages are disabled over Tor"))
if histType != history.Notice {
rb.Add(nil, server.name, "NOTICE", client.t("CTCP messages are disabled over Tor"))
}
return false
}
splitMsg := utils.MakeSplitMessage(message, !client.capabilities.Has(caps.MaxLine))
now := time.Now().UTC()
for i, targetString := range targets {
// max of four targets per privmsg
@ -1893,52 +1914,66 @@ func noticeHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
prefixes, targetString := modes.SplitChannelMembershipPrefixes(targetString)
lowestPrefix := modes.GetLowestChannelModePrefix(prefixes)
target, cerr := CasefoldChannel(targetString)
if cerr == nil {
channel := server.channels.Get(target)
if len(targetString) == 0 {
continue
} else if targetString[0] == '#' {
channel := server.channels.Get(targetString)
if channel == nil {
// errors silently ignored with NOTICE as per RFC
if histType != history.Notice {
rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, cnick, targetString, client.t("No such channel"))
}
continue
}
if !channel.CanSpeak(client) {
// errors silently ignored with NOTICE as per RFC
continue
}
channel.SendSplitMessage("NOTICE", lowestPrefix, clientOnlyTags, client, splitMsg, rb)
channel.SendSplitMessage(msg.Command, lowestPrefix, clientOnlyTags, client, splitMsg, rb)
} else {
target, err := CasefoldName(targetString)
if err != nil {
if service, isService := OragonoServices[strings.ToLower(targetString)]; isService {
// NOTICE and TAGMSG to services are ignored
if histType == history.Privmsg {
servicePrivmsgHandler(service, server, client, message, rb)
}
continue
}
// NOTICEs sent to services are ignored
if _, isService := OragonoServices[target]; isService {
continue
}
user := server.clients.Get(target)
user := server.clients.Get(targetString)
if user == nil {
// errors silently ignored with NOTICE as per RFC
if histType != history.Notice {
rb.Add(nil, server.name, ERR_NOSUCHNICK, cnick, targetString, "No such nick")
}
continue
}
if !user.capabilities.Has(caps.MessageTags) {
clientOnlyTags = nil
tnick := user.Nick()
if histType == history.Tagmsg && !user.capabilities.Has(caps.MessageTags) {
continue // nothing to do
}
nickMaskString := client.NickMaskString()
accountName := client.AccountName()
// restrict messages appropriately when +R is set
// intentionally make the sending user think the message went through fine
allowedPlusR := !user.HasMode(modes.RegisteredOnly) || client.LoggedIntoAccount()
allowedTor := !user.isTor || !isRestrictedCTCPMessage(message)
if allowedPlusR && allowedTor {
user.SendSplitMsgFromClient(client, clientOnlyTags, "NOTICE", user.nick, splitMsg)
if histType == history.Tagmsg {
user.sendFromClientInternal(false, now, splitMsg.Msgid, nickMaskString, accountName, clientOnlyTags, msg.Command, tnick)
} else {
user.SendSplitMsgFromClient(client, clientOnlyTags, msg.Command, tnick, splitMsg)
}
}
nickMaskString := client.NickMaskString()
accountName := client.AccountName()
if client.capabilities.Has(caps.EchoMessage) {
rb.AddSplitMessageFromClient(nickMaskString, accountName, clientOnlyTags, "NOTICE", user.nick, splitMsg)
if histType == history.Tagmsg && client.capabilities.Has(caps.MessageTags) {
rb.AddFromClient(splitMsg.Msgid, nickMaskString, accountName, clientOnlyTags, msg.Command, tnick)
} else {
rb.AddSplitMessageFromClient(nickMaskString, accountName, clientOnlyTags, msg.Command, tnick, splitMsg)
}
}
if histType != history.Notice && user.HasMode(modes.Away) {
//TODO(dan): possibly implement cooldown of away notifications to users
rb.Add(nil, server.name, RPL_AWAY, cnick, tnick, user.AwayMessage())
}
user.history.Add(history.Item{
Type: history.Notice,
Type: histType,
Message: splitMsg,
Nick: nickMaskString,
AccountName: accountName,
@ -1988,7 +2023,7 @@ func npcaHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
// OPER <name> <password>
func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
if client.HasMode(modes.Operator) == true {
rb.Add(nil, server.name, ERR_UNKNOWNERROR, "OPER", client.t("You're already opered-up!"))
rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.Nick(), "OPER", client.t("You're already opered-up!"))
return false
}
@ -1999,7 +2034,7 @@ func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
authorized = (bcrypt.CompareHashAndPassword(oper.Pass, password) == nil)
}
if !authorized {
rb.Add(nil, server.name, ERR_PASSWDMISMATCH, client.nick, client.t("Password incorrect"))
rb.Add(nil, server.name, ERR_PASSWDMISMATCH, client.Nick(), client.t("Password incorrect"))
client.Quit(client.t("Password incorrect"))
return true
}
@ -2090,90 +2125,6 @@ func isRestrictedCTCPMessage(message string) bool {
return strings.HasPrefix(message, "\x01") && !strings.HasPrefix(message, "\x01ACTION")
}
// PRIVMSG <target>{,<target>} <message>
func privmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
clientOnlyTags := msg.ClientOnlyTags()
targets := strings.Split(msg.Params[0], ",")
message := msg.Params[1]
if client.isTor && isRestrictedCTCPMessage(message) {
rb.Add(nil, server.name, "NOTICE", client.t("CTCP messages are disabled over Tor"))
return false
}
// split privmsg
splitMsg := utils.MakeSplitMessage(message, !client.capabilities.Has(caps.MaxLine))
cnick := client.Nick()
for i, targetString := range targets {
// max of four targets per privmsg
if i > maxTargets-1 {
break
}
prefixes, targetString := modes.SplitChannelMembershipPrefixes(targetString)
lowestPrefix := modes.GetLowestChannelModePrefix(prefixes)
// eh, no need to notify them
if len(targetString) < 1 {
continue
}
target, err := CasefoldChannel(targetString)
if err == nil {
channel := server.channels.Get(target)
if channel == nil {
rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, cnick, targetString, client.t("No such channel"))
continue
}
if !channel.CanSpeak(client) {
rb.Add(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, client.t("Cannot send to channel"))
continue
}
channel.SendSplitMessage("PRIVMSG", lowestPrefix, clientOnlyTags, client, splitMsg, rb)
} else {
target, err = CasefoldName(targetString)
if service, isService := OragonoServices[target]; isService {
servicePrivmsgHandler(service, server, client, message, rb)
continue
}
user := server.clients.Get(target)
if err != nil || user == nil {
if len(target) > 0 {
client.Send(nil, server.name, ERR_NOSUCHNICK, cnick, target, "No such nick")
}
continue
}
if !user.capabilities.Has(caps.MessageTags) {
clientOnlyTags = nil
}
// restrict messages appropriately when +R is set
// intentionally make the sending user think the message went through fine
allowedPlusR := !user.HasMode(modes.RegisteredOnly) || client.LoggedIntoAccount()
allowedTor := !user.isTor || !isRestrictedCTCPMessage(message)
if allowedPlusR && allowedTor {
user.SendSplitMsgFromClient(client, clientOnlyTags, "PRIVMSG", user.nick, splitMsg)
}
nickMaskString := client.NickMaskString()
accountName := client.AccountName()
if client.capabilities.Has(caps.EchoMessage) {
rb.AddSplitMessageFromClient(nickMaskString, accountName, clientOnlyTags, "PRIVMSG", user.nick, splitMsg)
}
if user.HasMode(modes.Away) {
//TODO(dan): possibly implement cooldown of away notifications to users
rb.Add(nil, server.name, RPL_AWAY, cnick, user.Nick(), user.AwayMessage())
}
user.history.Add(history.Item{
Type: history.Privmsg,
Message: splitMsg,
Nick: nickMaskString,
AccountName: accountName,
})
}
}
return false
}
// QUIT [<reason>]
func quitHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
reason := "Quit"
@ -2346,71 +2297,6 @@ func setnameHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *R
return false
}
// TAGMSG <target>{,<target>}
func tagmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
clientOnlyTags := msg.ClientOnlyTags()
// no client-only tags, so we can drop it
if clientOnlyTags == nil {
return false
}
targets := strings.Split(msg.Params[0], ",")
cnick := client.Nick()
message := utils.MakeSplitMessage("", true) // assign consistent message ID
for i, targetString := range targets {
// max of four targets per privmsg
if i > maxTargets-1 {
break
}
prefixes, targetString := modes.SplitChannelMembershipPrefixes(targetString)
lowestPrefix := modes.GetLowestChannelModePrefix(prefixes)
// eh, no need to notify them
if len(targetString) < 1 {
continue
}
target, err := CasefoldChannel(targetString)
if err == nil {
channel := server.channels.Get(target)
if channel == nil {
rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, cnick, targetString, client.t("No such channel"))
continue
}
if !channel.CanSpeak(client) {
rb.Add(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, client.t("Cannot send to channel"))
continue
}
channel.SendSplitMessage("TAGMSG", lowestPrefix, clientOnlyTags, client, message, rb)
} else {
target, err = CasefoldName(targetString)
user := server.clients.Get(target)
if err != nil || user == nil {
if len(target) > 0 {
client.Send(nil, server.name, ERR_NOSUCHNICK, cnick, target, client.t("No such nick"))
}
continue
}
// end user can't receive tagmsgs
if !user.capabilities.Has(caps.MessageTags) {
continue
}
unick := user.Nick()
user.SendSplitMsgFromClient(client, clientOnlyTags, "TAGMSG", unick, message)
if client.capabilities.Has(caps.EchoMessage) {
rb.AddSplitMessageFromClient(client.NickMaskString(), client.AccountName(), clientOnlyTags, "TAGMSG", unick, message)
}
if user.HasMode(modes.Away) {
//TODO(dan): possibly implement cooldown of away notifications to users
rb.Add(nil, server.name, RPL_AWAY, cnick, unick, user.AwayMessage())
}
}
}
return false
}
// TIME
func timeHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
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
// USER <username> * 0 <realname>
func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
if client.registered {
rb.Add(nil, server.name, ERR_ALREADYREGISTRED, client.nick, client.t("You may not reregister"))
rb.Add(nil, server.name, ERR_ALREADYREGISTRED, client.Nick(), client.t("You may not reregister"))
return false
}
@ -2513,7 +2399,7 @@ func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
if client.preregNick == msg.Params[0] {
client.SetNames("user", msg.Params[3], false)
} else {
rb.Add(nil, server.name, ERR_INVALIDUSERNAME, client.t("Malformed username"))
rb.Add(nil, server.name, ERR_INVALIDUSERNAME, client.Nick(), client.t("Malformed username"))
}
}
@ -2631,7 +2517,7 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Respo
if len(msg.Params) > 0 {
casefoldedMask, err := Casefold(msg.Params[0])
if err != nil {
rb.Add(nil, server.name, ERR_UNKNOWNERROR, "WHO", client.t("Mask isn't valid"))
rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.Nick(), "WHO", client.t("Mask isn't valid"))
return false
}
mask = casefoldedMask

View File

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

View File

@ -26,14 +26,15 @@ var (
func performNickChange(server *Server, client *Client, target *Client, newnick string, rb *ResponseBuffer) bool {
nickname := strings.TrimSpace(newnick)
cfnick, err := CasefoldName(nickname)
currentNick := client.Nick()
if len(nickname) < 1 {
rb.Add(nil, server.name, ERR_NONICKNAMEGIVEN, client.nick, client.t("No nickname given"))
rb.Add(nil, server.name, ERR_NONICKNAMEGIVEN, currentNick, client.t("No nickname given"))
return false
}
if err != nil || len(nickname) > server.Limits().NickLen || restrictedNicknames[cfnick] {
rb.Add(nil, server.name, ERR_ERRONEUSNICKNAME, client.nick, nickname, client.t("Erroneous nickname"))
rb.Add(nil, server.name, ERR_ERRONEUSNICKNAME, currentNick, nickname, client.t("Erroneous nickname"))
return false
}
@ -46,13 +47,13 @@ func performNickChange(server *Server, client *Client, target *Client, newnick s
whowas := client.WhoWas()
err = client.server.clients.SetNick(target, nickname)
if err == errNicknameInUse {
rb.Add(nil, server.name, ERR_NICKNAMEINUSE, client.nick, nickname, client.t("Nickname is already in use"))
rb.Add(nil, server.name, ERR_NICKNAMEINUSE, currentNick, nickname, client.t("Nickname is already in use"))
return false
} else if err == errNicknameReserved {
rb.Add(nil, server.name, ERR_NICKNAMEINUSE, client.nick, nickname, client.t("Nickname is reserved by a different account"))
rb.Add(nil, server.name, ERR_NICKNAMEINUSE, currentNick, nickname, client.t("Nickname is reserved by a different account"))
return false
} else if err != nil {
rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.nick, "NICK", fmt.Sprintf(client.t("Could not set or change nickname: %s"), err.Error()))
rb.Add(nil, server.name, ERR_UNKNOWNERROR, currentNick, "NICK", fmt.Sprintf(client.t("Could not set or change nickname: %s"), err.Error()))
return false
}