mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-25 21:39:25 +01:00
Fix #1562
Implement the new bot mode spec: https://github.com/ircv3/ircv3-specifications/pull/439
This commit is contained in:
parent
507d53c507
commit
1efde964e1
@ -60,6 +60,8 @@ const (
|
|||||||
MultilineConcatTag = "draft/multiline-concat"
|
MultilineConcatTag = "draft/multiline-concat"
|
||||||
// draft/relaymsg:
|
// draft/relaymsg:
|
||||||
RelaymsgTagName = "draft/relaymsg"
|
RelaymsgTagName = "draft/relaymsg"
|
||||||
|
// BOT mode: https://github.com/ircv3/ircv3-specifications/pull/439
|
||||||
|
BotTagName = "draft/bot"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -729,6 +729,7 @@ func (channel *Channel) AddHistoryItem(item history.Item, account string) (err e
|
|||||||
// Join joins the given client to this channel (if they can be joined).
|
// Join joins the given client to this channel (if they can be joined).
|
||||||
func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *ResponseBuffer) (joinErr error, forward string) {
|
func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *ResponseBuffer) (joinErr error, forward string) {
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
|
|
||||||
channel.stateMutex.RLock()
|
channel.stateMutex.RLock()
|
||||||
chname := channel.name
|
chname := channel.name
|
||||||
@ -824,6 +825,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
Nick: details.nickMask,
|
Nick: details.nickMask,
|
||||||
AccountName: details.accountName,
|
AccountName: details.accountName,
|
||||||
Message: message,
|
Message: message,
|
||||||
|
IsBot: isBot,
|
||||||
}
|
}
|
||||||
histItem.Params[0] = details.realname
|
histItem.Params[0] = details.realname
|
||||||
channel.AddHistoryItem(histItem, details.account)
|
channel.AddHistoryItem(histItem, details.account)
|
||||||
@ -840,7 +842,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
|
|
||||||
// cache the most common case (JOIN without extended-join)
|
// cache the most common case (JOIN without extended-join)
|
||||||
var cache MessageCache
|
var cache MessageCache
|
||||||
cache.Initialize(channel.server, message.Time, message.Msgid, details.nickMask, details.accountName, nil, "JOIN", chname)
|
cache.Initialize(channel.server, message.Time, message.Msgid, details.nickMask, details.accountName, isBot, nil, "JOIN", chname)
|
||||||
isAway, awayMessage := client.Away()
|
isAway, awayMessage := client.Away()
|
||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
if respectAuditorium {
|
if respectAuditorium {
|
||||||
@ -859,7 +861,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if session.capabilities.Has(caps.ExtendedJoin) {
|
if session.capabilities.Has(caps.ExtendedJoin) {
|
||||||
session.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, nil, "JOIN", chname, details.accountName, details.realname)
|
session.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, isBot, nil, "JOIN", chname, details.accountName, details.realname)
|
||||||
} else {
|
} else {
|
||||||
cache.Send(session)
|
cache.Send(session)
|
||||||
}
|
}
|
||||||
@ -867,15 +869,15 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
session.Send(nil, client.server.name, "MODE", chname, modestr, details.nick)
|
session.Send(nil, client.server.name, "MODE", chname, modestr, details.nick)
|
||||||
}
|
}
|
||||||
if isAway && session.capabilities.Has(caps.AwayNotify) {
|
if isAway && session.capabilities.Has(caps.AwayNotify) {
|
||||||
session.sendFromClientInternal(false, time.Time{}, "", details.nickMask, details.accountName, nil, "AWAY", awayMessage)
|
session.sendFromClientInternal(false, time.Time{}, "", details.nickMask, details.accountName, isBot, nil, "AWAY", awayMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if rb.session.capabilities.Has(caps.ExtendedJoin) {
|
if rb.session.capabilities.Has(caps.ExtendedJoin) {
|
||||||
rb.AddFromClient(message.Time, message.Msgid, details.nickMask, details.accountName, nil, "JOIN", chname, details.accountName, details.realname)
|
rb.AddFromClient(message.Time, message.Msgid, details.nickMask, details.accountName, isBot, nil, "JOIN", chname, details.accountName, details.realname)
|
||||||
} else {
|
} else {
|
||||||
rb.AddFromClient(message.Time, message.Msgid, details.nickMask, details.accountName, nil, "JOIN", chname)
|
rb.AddFromClient(message.Time, message.Msgid, details.nickMask, details.accountName, isBot, nil, "JOIN", chname)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rb.session.client == client {
|
if rb.session.client == client {
|
||||||
@ -988,6 +990,7 @@ func (channel *Channel) Part(client *Client, message string, rb *ResponseBuffer)
|
|||||||
splitMessage := utils.MakeMessage(message)
|
splitMessage := utils.MakeMessage(message)
|
||||||
|
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
params := make([]string, 1, 2)
|
params := make([]string, 1, 2)
|
||||||
params[0] = chname
|
params[0] = chname
|
||||||
if message != "" {
|
if message != "" {
|
||||||
@ -996,7 +999,7 @@ func (channel *Channel) Part(client *Client, message string, rb *ResponseBuffer)
|
|||||||
respectAuditorium := channel.flags.HasMode(modes.Auditorium) &&
|
respectAuditorium := channel.flags.HasMode(modes.Auditorium) &&
|
||||||
clientData.modes.HighestChannelUserMode() == modes.Mode(0)
|
clientData.modes.HighestChannelUserMode() == modes.Mode(0)
|
||||||
var cache MessageCache
|
var cache MessageCache
|
||||||
cache.Initialize(channel.server, splitMessage.Time, splitMessage.Msgid, details.nickMask, details.accountName, nil, "PART", params...)
|
cache.Initialize(channel.server, splitMessage.Time, splitMessage.Msgid, details.nickMask, details.accountName, isBot, nil, "PART", params...)
|
||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
if respectAuditorium {
|
if respectAuditorium {
|
||||||
channel.stateMutex.RLock()
|
channel.stateMutex.RLock()
|
||||||
@ -1010,10 +1013,10 @@ func (channel *Channel) Part(client *Client, message string, rb *ResponseBuffer)
|
|||||||
cache.Send(session)
|
cache.Send(session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rb.AddFromClient(splitMessage.Time, splitMessage.Msgid, details.nickMask, details.accountName, nil, "PART", params...)
|
rb.AddFromClient(splitMessage.Time, splitMessage.Msgid, details.nickMask, details.accountName, isBot, nil, "PART", params...)
|
||||||
for _, session := range client.Sessions() {
|
for _, session := range client.Sessions() {
|
||||||
if session != rb.session {
|
if session != rb.session {
|
||||||
session.sendFromClientInternal(false, splitMessage.Time, splitMessage.Msgid, details.nickMask, details.accountName, nil, "PART", params...)
|
session.sendFromClientInternal(false, splitMessage.Time, splitMessage.Msgid, details.nickMask, details.accountName, isBot, nil, "PART", params...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1023,6 +1026,7 @@ func (channel *Channel) Part(client *Client, message string, rb *ResponseBuffer)
|
|||||||
Nick: details.nickMask,
|
Nick: details.nickMask,
|
||||||
AccountName: details.accountName,
|
AccountName: details.accountName,
|
||||||
Message: splitMessage,
|
Message: splitMessage,
|
||||||
|
IsBot: isBot,
|
||||||
}, details.account)
|
}, details.account)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1133,19 +1137,19 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
|||||||
nick := NUHToNick(item.Nick)
|
nick := NUHToNick(item.Nick)
|
||||||
switch item.Type {
|
switch item.Type {
|
||||||
case history.Privmsg:
|
case history.Privmsg:
|
||||||
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.Tags, "PRIVMSG", chname, item.Message)
|
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.IsBot, item.Tags, "PRIVMSG", chname, item.Message)
|
||||||
case history.Notice:
|
case history.Notice:
|
||||||
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.Tags, "NOTICE", chname, item.Message)
|
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.IsBot, item.Tags, "NOTICE", chname, item.Message)
|
||||||
case history.Tagmsg:
|
case history.Tagmsg:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.Tags, "TAGMSG", chname, item.Message)
|
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.IsBot, item.Tags, "TAGMSG", chname, item.Message)
|
||||||
}
|
}
|
||||||
case history.Join:
|
case history.Join:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
if extendedJoin {
|
if extendedJoin {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "JOIN", chname, item.AccountName, item.Params[0])
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "JOIN", chname, item.AccountName, item.Params[0])
|
||||||
} else {
|
} else {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "JOIN", chname)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "JOIN", chname)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !playJoinsAsPrivmsg {
|
if !playJoinsAsPrivmsg {
|
||||||
@ -1157,48 +1161,48 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
|||||||
} else {
|
} else {
|
||||||
message = fmt.Sprintf(client.t("%[1]s [account: %[2]s] joined the channel"), nick, item.AccountName)
|
message = fmt.Sprintf(client.t("%[1]s [account: %[2]s] joined the channel"), nick, item.AccountName)
|
||||||
}
|
}
|
||||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
case history.Part:
|
case history.Part:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "PART", chname, item.Message.Message)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "PART", chname, item.Message.Message)
|
||||||
} else {
|
} else {
|
||||||
if !playJoinsAsPrivmsg {
|
if !playJoinsAsPrivmsg {
|
||||||
continue // #474
|
continue // #474
|
||||||
}
|
}
|
||||||
message := fmt.Sprintf(client.t("%[1]s left the channel (%[2]s)"), nick, item.Message.Message)
|
message := fmt.Sprintf(client.t("%[1]s left the channel (%[2]s)"), nick, item.Message.Message)
|
||||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
case history.Kick:
|
case history.Kick:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "KICK", chname, item.Params[0], item.Message.Message)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "KICK", chname, item.Params[0], item.Message.Message)
|
||||||
} else {
|
} else {
|
||||||
message := fmt.Sprintf(client.t("%[1]s kicked %[2]s (%[3]s)"), nick, item.Params[0], item.Message.Message)
|
message := fmt.Sprintf(client.t("%[1]s kicked %[2]s (%[3]s)"), nick, item.Params[0], item.Message.Message)
|
||||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
case history.Quit:
|
case history.Quit:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "QUIT", item.Message.Message)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "QUIT", item.Message.Message)
|
||||||
} else {
|
} else {
|
||||||
if !playJoinsAsPrivmsg {
|
if !playJoinsAsPrivmsg {
|
||||||
continue // #474
|
continue // #474
|
||||||
}
|
}
|
||||||
message := fmt.Sprintf(client.t("%[1]s quit (%[2]s)"), nick, item.Message.Message)
|
message := fmt.Sprintf(client.t("%[1]s quit (%[2]s)"), nick, item.Message.Message)
|
||||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
case history.Nick:
|
case history.Nick:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "NICK", item.Params[0])
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "NICK", item.Params[0])
|
||||||
} else {
|
} else {
|
||||||
message := fmt.Sprintf(client.t("%[1]s changed nick to %[2]s"), nick, item.Params[0])
|
message := fmt.Sprintf(client.t("%[1]s changed nick to %[2]s"), nick, item.Params[0])
|
||||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
case history.Topic:
|
case history.Topic:
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "TOPIC", chname, item.Message.Message)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "TOPIC", chname, item.Message.Message)
|
||||||
} else {
|
} else {
|
||||||
message := fmt.Sprintf(client.t("%[1]s set the channel topic to: %[2]s"), nick, item.Message.Message)
|
message := fmt.Sprintf(client.t("%[1]s set the channel topic to: %[2]s"), nick, item.Message.Message)
|
||||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
case history.Mode:
|
case history.Mode:
|
||||||
params := make([]string, len(item.Message.Split)+1)
|
params := make([]string, len(item.Message.Split)+1)
|
||||||
@ -1207,10 +1211,10 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I
|
|||||||
params[i+1] = pair.Message
|
params[i+1] = pair.Message
|
||||||
}
|
}
|
||||||
if eventPlayback {
|
if eventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "MODE", params...)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "MODE", params...)
|
||||||
} else {
|
} else {
|
||||||
message := fmt.Sprintf(client.t("%[1]s set channel modes: %[2]s"), nick, strings.Join(params[1:], " "))
|
message := fmt.Sprintf(client.t("%[1]s set channel modes: %[2]s"), nick, strings.Join(params[1:], " "))
|
||||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", chname, message)
|
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1268,12 +1272,13 @@ func (channel *Channel) SetTopic(client *Client, topic string, rb *ResponseBuffe
|
|||||||
channel.stateMutex.Unlock()
|
channel.stateMutex.Unlock()
|
||||||
|
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
message := utils.MakeMessage(topic)
|
message := utils.MakeMessage(topic)
|
||||||
rb.AddFromClient(message.Time, message.Msgid, details.nickMask, details.accountName, nil, "TOPIC", chname, topic)
|
rb.AddFromClient(message.Time, message.Msgid, details.nickMask, details.accountName, isBot, nil, "TOPIC", chname, topic)
|
||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
for _, session := range member.Sessions() {
|
for _, session := range member.Sessions() {
|
||||||
if session != rb.session {
|
if session != rb.session {
|
||||||
session.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, nil, "TOPIC", chname, topic)
|
session.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, isBot, nil, "TOPIC", chname, topic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1397,7 +1402,7 @@ func (channel *Channel) SendSplitMessage(command string, minPrefixMode modes.Mod
|
|||||||
rb.addEchoMessage(clientOnlyTags, details.nickMask, details.accountName, command, chname, message)
|
rb.addEchoMessage(clientOnlyTags, details.nickMask, details.accountName, command, chname, message)
|
||||||
|
|
||||||
var cache MessageCache
|
var cache MessageCache
|
||||||
cache.InitializeSplitMessage(channel.server, details.nickMask, details.accountName, clientOnlyTags, command, chname, message)
|
cache.InitializeSplitMessage(channel.server, details.nickMask, details.accountName, client.HasMode(modes.Bot), clientOnlyTags, command, chname, message)
|
||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
if minPrefixMode != modes.Mode(0) && !channel.ClientIsAtLeast(member, minPrefixMode) {
|
if minPrefixMode != modes.Mode(0) && !channel.ClientIsAtLeast(member, minPrefixMode) {
|
||||||
// STATUSMSG or OpModerated
|
// STATUSMSG or OpModerated
|
||||||
@ -1519,23 +1524,25 @@ func (channel *Channel) Kick(client *Client, target *Client, comment string, rb
|
|||||||
|
|
||||||
message := utils.MakeMessage(comment)
|
message := utils.MakeMessage(comment)
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
|
|
||||||
targetNick := target.Nick()
|
targetNick := target.Nick()
|
||||||
chname := channel.Name()
|
chname := channel.Name()
|
||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
for _, session := range member.Sessions() {
|
for _, session := range member.Sessions() {
|
||||||
if session != rb.session {
|
if session != rb.session {
|
||||||
session.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, nil, "KICK", chname, targetNick, comment)
|
session.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, isBot, nil, "KICK", chname, targetNick, comment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rb.AddFromClient(message.Time, message.Msgid, details.nickMask, details.accountName, nil, "KICK", chname, targetNick, comment)
|
rb.AddFromClient(message.Time, message.Msgid, details.nickMask, details.accountName, isBot, nil, "KICK", chname, targetNick, comment)
|
||||||
|
|
||||||
histItem := history.Item{
|
histItem := history.Item{
|
||||||
Type: history.Kick,
|
Type: history.Kick,
|
||||||
Nick: details.nickMask,
|
Nick: details.nickMask,
|
||||||
AccountName: details.accountName,
|
AccountName: details.accountName,
|
||||||
Message: message,
|
Message: message,
|
||||||
|
IsBot: isBot,
|
||||||
}
|
}
|
||||||
histItem.Params[0] = targetNick
|
histItem.Params[0] = targetNick
|
||||||
channel.AddHistoryItem(histItem, details.account)
|
channel.AddHistoryItem(histItem, details.account)
|
||||||
@ -1563,7 +1570,7 @@ func (channel *Channel) Purge(source string) {
|
|||||||
tnick := member.Nick()
|
tnick := member.Nick()
|
||||||
msgid := utils.GenerateSecretToken()
|
msgid := utils.GenerateSecretToken()
|
||||||
for _, session := range member.Sessions() {
|
for _, session := range member.Sessions() {
|
||||||
session.sendFromClientInternal(false, now, msgid, source, "*", nil, "KICK", chname, tnick, member.t("This channel has been purged by the server administrators and cannot be used"))
|
session.sendFromClientInternal(false, now, msgid, source, "*", false, nil, "KICK", chname, tnick, member.t("This channel has been purged by the server administrators and cannot be used"))
|
||||||
}
|
}
|
||||||
member.removeChannel(channel)
|
member.removeChannel(channel)
|
||||||
}
|
}
|
||||||
@ -1600,6 +1607,7 @@ func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuf
|
|||||||
}
|
}
|
||||||
|
|
||||||
details := inviter.Details()
|
details := inviter.Details()
|
||||||
|
isBot := inviter.HasMode(modes.Bot)
|
||||||
tDetails := invitee.Details()
|
tDetails := invitee.Details()
|
||||||
tnick := invitee.Nick()
|
tnick := invitee.Nick()
|
||||||
message := utils.MakeMessage(chname)
|
message := utils.MakeMessage(chname)
|
||||||
@ -1614,13 +1622,15 @@ func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuf
|
|||||||
}
|
}
|
||||||
for _, session := range member.Sessions() {
|
for _, session := range member.Sessions() {
|
||||||
if session.capabilities.Has(caps.InviteNotify) {
|
if session.capabilities.Has(caps.InviteNotify) {
|
||||||
session.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, nil, "INVITE", tnick, chname)
|
session.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, isBot, nil, "INVITE", tnick, chname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rb.Add(nil, inviter.server.name, RPL_INVITING, details.nick, tnick, chname)
|
rb.Add(nil, inviter.server.name, RPL_INVITING, details.nick, tnick, chname)
|
||||||
invitee.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, nil, "INVITE", tnick, chname)
|
for _, iSession := range invitee.Sessions() {
|
||||||
|
iSession.sendFromClientInternal(false, message.Time, message.Msgid, details.nickMask, details.accountName, isBot, nil, "INVITE", tnick, chname)
|
||||||
|
}
|
||||||
if away, awayMessage := invitee.Away(); away {
|
if away, awayMessage := invitee.Away(); away {
|
||||||
rb.Add(nil, inviter.server.name, RPL_AWAY, details.nick, tnick, awayMessage)
|
rb.Add(nil, inviter.server.name, RPL_AWAY, details.nick, tnick, awayMessage)
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ func csAmodeHandler(service *ircService, server *Server, client *Client, command
|
|||||||
if member.Account() == change.Arg {
|
if member.Account() == change.Arg {
|
||||||
applied, change := channel.applyModeToMember(client, change, rb)
|
applied, change := channel.applyModeToMember(client, change, rb)
|
||||||
if applied {
|
if applied {
|
||||||
announceCmodeChanges(channel, modes.ModeChanges{change}, server.name, "*", "", rb)
|
announceCmodeChanges(channel, modes.ModeChanges{change}, server.name, "*", "", false, rb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,7 +334,7 @@ func csOpHandler(service *ircService, server *Server, client *Client, command st
|
|||||||
},
|
},
|
||||||
rb)
|
rb)
|
||||||
if applied {
|
if applied {
|
||||||
announceCmodeChanges(channelInfo, modes.ModeChanges{change}, server.name, "*", "", rb)
|
announceCmodeChanges(channelInfo, modes.ModeChanges{change}, server.name, "*", "", false, rb)
|
||||||
}
|
}
|
||||||
|
|
||||||
service.Notice(rb, client.t("Successfully granted operator privileges"))
|
service.Notice(rb, client.t("Successfully granted operator privileges"))
|
||||||
@ -386,7 +386,8 @@ func csDeopHandler(service *ircService, server *Server, client *Client, command
|
|||||||
// the changes as coming from chanserv
|
// the changes as coming from chanserv
|
||||||
applied := channel.ApplyChannelModeChanges(client, false, modeChanges, rb)
|
applied := channel.ApplyChannelModeChanges(client, false, modeChanges, rb)
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
announceCmodeChanges(channel, applied, details.nickMask, details.accountName, details.account, rb)
|
isBot := client.HasMode(modes.Bot)
|
||||||
|
announceCmodeChanges(channel, applied, details.nickMask, details.accountName, details.account, isBot, rb)
|
||||||
|
|
||||||
if len(applied) == 0 {
|
if len(applied) == 0 {
|
||||||
return
|
return
|
||||||
@ -437,7 +438,7 @@ func csRegisterHandler(service *ircService, server *Server, client *Client, comm
|
|||||||
},
|
},
|
||||||
rb)
|
rb)
|
||||||
if applied {
|
if applied {
|
||||||
announceCmodeChanges(channelInfo, modes.ModeChanges{change}, service.prefix, "*", "", rb)
|
announceCmodeChanges(channelInfo, modes.ModeChanges{change}, service.prefix, "*", "", false, rb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1095,9 +1095,9 @@ func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.I
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if hasEventPlayback {
|
if hasEventPlayback {
|
||||||
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "INVITE", nick, item.Message.Message)
|
rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, item.IsBot, nil, "INVITE", nick, item.Message.Message)
|
||||||
} else {
|
} else {
|
||||||
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", fmt.Sprintf(client.t("%[1]s invited you to channel %[2]s"), NUHToNick(item.Nick), item.Message.Message))
|
rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", false, nil, "PRIVMSG", fmt.Sprintf(client.t("%[1]s invited you to channel %[2]s"), NUHToNick(item.Nick), item.Message.Message))
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
case history.Privmsg:
|
case history.Privmsg:
|
||||||
@ -1118,11 +1118,11 @@ func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.I
|
|||||||
tags = item.Tags
|
tags = item.Tags
|
||||||
}
|
}
|
||||||
if !isSelfMessage(&item) {
|
if !isSelfMessage(&item) {
|
||||||
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, tags, command, nick, item.Message)
|
rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.IsBot, tags, command, nick, item.Message)
|
||||||
} else {
|
} else {
|
||||||
// this message was sent *from* the client to another nick; the target is item.Params[0]
|
// this message was sent *from* the client to another nick; the target is item.Params[0]
|
||||||
// substitute client's current nickmask in case client changed nick
|
// substitute client's current nickmask in case client changed nick
|
||||||
rb.AddSplitMessageFromClient(details.nickMask, item.AccountName, tags, command, item.Params[0], item.Message)
|
rb.AddSplitMessageFromClient(details.nickMask, item.AccountName, item.IsBot, tags, command, item.Params[0], item.Message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1244,8 +1244,9 @@ func (client *Client) SetOper(oper *Oper) {
|
|||||||
// this is annoying to do correctly
|
// this is annoying to do correctly
|
||||||
func (client *Client) sendChghost(oldNickMask string, vhost string) {
|
func (client *Client) sendChghost(oldNickMask string, vhost string) {
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
for fClient := range client.Friends(caps.ChgHost) {
|
for fClient := range client.Friends(caps.ChgHost) {
|
||||||
fClient.sendFromClientInternal(false, time.Time{}, "", oldNickMask, details.accountName, nil, "CHGHOST", details.username, vhost)
|
fClient.sendFromClientInternal(false, time.Time{}, "", oldNickMask, details.accountName, isBot, nil, "CHGHOST", details.username, vhost)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1594,14 +1595,16 @@ func (client *Client) destroy(session *Session) {
|
|||||||
quitMessage = "Exited"
|
quitMessage = "Exited"
|
||||||
}
|
}
|
||||||
splitQuitMessage := utils.MakeMessage(quitMessage)
|
splitQuitMessage := utils.MakeMessage(quitMessage)
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
quitItem = history.Item{
|
quitItem = history.Item{
|
||||||
Type: history.Quit,
|
Type: history.Quit,
|
||||||
Nick: details.nickMask,
|
Nick: details.nickMask,
|
||||||
AccountName: details.accountName,
|
AccountName: details.accountName,
|
||||||
Message: splitQuitMessage,
|
Message: splitQuitMessage,
|
||||||
|
IsBot: isBot,
|
||||||
}
|
}
|
||||||
var cache MessageCache
|
var cache MessageCache
|
||||||
cache.Initialize(client.server, splitQuitMessage.Time, splitQuitMessage.Msgid, details.nickMask, details.accountName, nil, "QUIT", quitMessage)
|
cache.Initialize(client.server, splitQuitMessage.Time, splitQuitMessage.Msgid, details.nickMask, details.accountName, isBot, nil, "QUIT", quitMessage)
|
||||||
for friend := range friends {
|
for friend := range friends {
|
||||||
for _, session := range friend.Sessions() {
|
for _, session := range friend.Sessions() {
|
||||||
cache.Send(session)
|
cache.Send(session)
|
||||||
@ -1615,12 +1618,12 @@ func (client *Client) destroy(session *Session) {
|
|||||||
|
|
||||||
// SendSplitMsgFromClient sends an IRC PRIVMSG/NOTICE coming from a specific client.
|
// SendSplitMsgFromClient sends an IRC PRIVMSG/NOTICE coming from a specific client.
|
||||||
// Adds account-tag to the line as well.
|
// Adds account-tag to the line as well.
|
||||||
func (session *Session) sendSplitMsgFromClientInternal(blocking bool, nickmask, accountName string, tags map[string]string, command, target string, message utils.SplitMessage) {
|
func (session *Session) sendSplitMsgFromClientInternal(blocking bool, nickmask, accountName string, isBot bool, tags map[string]string, command, target string, message utils.SplitMessage) {
|
||||||
if message.Is512() {
|
if message.Is512() {
|
||||||
session.sendFromClientInternal(blocking, message.Time, message.Msgid, nickmask, accountName, tags, command, target, message.Message)
|
session.sendFromClientInternal(blocking, message.Time, message.Msgid, nickmask, accountName, isBot, tags, command, target, message.Message)
|
||||||
} else {
|
} else {
|
||||||
if session.capabilities.Has(caps.Multiline) {
|
if session.capabilities.Has(caps.Multiline) {
|
||||||
for _, msg := range composeMultilineBatch(session.generateBatchID(), nickmask, accountName, tags, command, target, message) {
|
for _, msg := range composeMultilineBatch(session.generateBatchID(), nickmask, accountName, isBot, tags, command, target, message) {
|
||||||
session.SendRawMessage(msg, blocking)
|
session.SendRawMessage(msg, blocking)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1634,24 +1637,13 @@ func (session *Session) sendSplitMsgFromClientInternal(blocking bool, nickmask,
|
|||||||
msgidSent = true
|
msgidSent = true
|
||||||
msgid = message.Msgid
|
msgid = message.Msgid
|
||||||
}
|
}
|
||||||
session.sendFromClientInternal(blocking, message.Time, msgid, nickmask, accountName, tags, command, target, messagePair.Message)
|
session.sendFromClientInternal(blocking, message.Time, msgid, nickmask, accountName, isBot, tags, command, target, messagePair.Message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends a line with `nickmask` as the prefix, adding `time` and `account` tags if supported
|
func (session *Session) sendFromClientInternal(blocking bool, serverTime time.Time, msgid string, nickmask, accountName string, isBot bool, tags map[string]string, command string, params ...string) (err error) {
|
||||||
func (client *Client) sendFromClientInternal(blocking bool, serverTime time.Time, msgid string, nickmask, accountName string, tags map[string]string, command string, params ...string) (err error) {
|
|
||||||
for _, session := range client.Sessions() {
|
|
||||||
err_ := session.sendFromClientInternal(blocking, serverTime, msgid, nickmask, accountName, tags, command, params...)
|
|
||||||
if err_ != nil {
|
|
||||||
err = err_
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (session *Session) sendFromClientInternal(blocking bool, serverTime time.Time, msgid string, nickmask, accountName string, tags map[string]string, command string, params ...string) (err error) {
|
|
||||||
msg := ircmsg.MakeMessage(tags, nickmask, command, params...)
|
msg := ircmsg.MakeMessage(tags, nickmask, command, params...)
|
||||||
// attach account-tag
|
// attach account-tag
|
||||||
if session.capabilities.Has(caps.AccountTag) && accountName != "*" {
|
if session.capabilities.Has(caps.AccountTag) && accountName != "*" {
|
||||||
@ -1663,17 +1655,24 @@ func (session *Session) sendFromClientInternal(blocking bool, serverTime time.Ti
|
|||||||
}
|
}
|
||||||
// attach server-time
|
// attach server-time
|
||||||
session.setTimeTag(&msg, serverTime)
|
session.setTimeTag(&msg, serverTime)
|
||||||
|
// attach bot tag
|
||||||
|
if isBot && session.capabilities.Has(caps.MessageTags) {
|
||||||
|
msg.SetTag(caps.BotTagName, "")
|
||||||
|
}
|
||||||
|
|
||||||
return session.SendRawMessage(msg, blocking)
|
return session.SendRawMessage(msg, blocking)
|
||||||
}
|
}
|
||||||
|
|
||||||
func composeMultilineBatch(batchID, fromNickMask, fromAccount string, tags map[string]string, command, target string, message utils.SplitMessage) (result []ircmsg.Message) {
|
func composeMultilineBatch(batchID, fromNickMask, fromAccount string, isBot bool, tags map[string]string, command, target string, message utils.SplitMessage) (result []ircmsg.Message) {
|
||||||
batchStart := ircmsg.MakeMessage(tags, fromNickMask, "BATCH", "+"+batchID, caps.MultilineBatchType, target)
|
batchStart := ircmsg.MakeMessage(tags, fromNickMask, "BATCH", "+"+batchID, caps.MultilineBatchType, target)
|
||||||
batchStart.SetTag("time", message.Time.Format(IRCv3TimestampFormat))
|
batchStart.SetTag("time", message.Time.Format(IRCv3TimestampFormat))
|
||||||
batchStart.SetTag("msgid", message.Msgid)
|
batchStart.SetTag("msgid", message.Msgid)
|
||||||
if fromAccount != "*" {
|
if fromAccount != "*" {
|
||||||
batchStart.SetTag("account", fromAccount)
|
batchStart.SetTag("account", fromAccount)
|
||||||
}
|
}
|
||||||
|
if isBot {
|
||||||
|
batchStart.SetTag(caps.BotTagName, "")
|
||||||
|
}
|
||||||
result = append(result, batchStart)
|
result = append(result, batchStart)
|
||||||
|
|
||||||
for _, msg := range message.Split {
|
for _, msg := range message.Split {
|
||||||
|
@ -367,11 +367,12 @@ func awayHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respons
|
|||||||
func dispatchAwayNotify(client *Client, isAway bool, awayMessage string) {
|
func dispatchAwayNotify(client *Client, isAway bool, awayMessage string) {
|
||||||
// dispatch away-notify
|
// dispatch away-notify
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
for session := range client.Friends(caps.AwayNotify) {
|
for session := range client.Friends(caps.AwayNotify) {
|
||||||
if isAway {
|
if isAway {
|
||||||
session.sendFromClientInternal(false, time.Time{}, "", details.nickMask, details.accountName, nil, "AWAY", awayMessage)
|
session.sendFromClientInternal(false, time.Time{}, "", details.nickMask, details.accountName, isBot, nil, "AWAY", awayMessage)
|
||||||
} else {
|
} else {
|
||||||
session.sendFromClientInternal(false, time.Time{}, "", details.nickMask, details.accountName, nil, "AWAY")
|
session.sendFromClientInternal(false, time.Time{}, "", details.nickMask, details.accountName, isBot, nil, "AWAY")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1689,12 +1690,13 @@ func cmodeHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respon
|
|||||||
// process mode changes, include list operations (an empty set of changes does a list)
|
// process mode changes, include list operations (an empty set of changes does a list)
|
||||||
applied := channel.ApplyChannelModeChanges(client, msg.Command == "SAMODE", changes, rb)
|
applied := channel.ApplyChannelModeChanges(client, msg.Command == "SAMODE", changes, rb)
|
||||||
details := client.Details()
|
details := client.Details()
|
||||||
announceCmodeChanges(channel, applied, details.nickMask, details.accountName, details.account, rb)
|
isBot := client.HasMode(modes.Bot)
|
||||||
|
announceCmodeChanges(channel, applied, details.nickMask, details.accountName, details.account, isBot, rb)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func announceCmodeChanges(channel *Channel, applied modes.ModeChanges, source, accountName, account string, rb *ResponseBuffer) {
|
func announceCmodeChanges(channel *Channel, applied modes.ModeChanges, source, accountName, account string, isBot bool, rb *ResponseBuffer) {
|
||||||
// send out changes
|
// send out changes
|
||||||
if len(applied) > 0 {
|
if len(applied) > 0 {
|
||||||
message := utils.MakeMessage("")
|
message := utils.MakeMessage("")
|
||||||
@ -1703,11 +1705,11 @@ func announceCmodeChanges(channel *Channel, applied modes.ModeChanges, source, a
|
|||||||
message.Split = append(message.Split, utils.MessagePair{Message: changeString})
|
message.Split = append(message.Split, utils.MessagePair{Message: changeString})
|
||||||
}
|
}
|
||||||
args := append([]string{channel.name}, changeStrings...)
|
args := append([]string{channel.name}, changeStrings...)
|
||||||
rb.AddFromClient(message.Time, message.Msgid, source, accountName, nil, "MODE", args...)
|
rb.AddFromClient(message.Time, message.Msgid, source, accountName, isBot, nil, "MODE", args...)
|
||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
for _, session := range member.Sessions() {
|
for _, session := range member.Sessions() {
|
||||||
if session != rb.session {
|
if session != rb.session {
|
||||||
session.sendFromClientInternal(false, message.Time, message.Msgid, source, accountName, nil, "MODE", args...)
|
session.sendFromClientInternal(false, message.Time, message.Msgid, source, accountName, isBot, nil, "MODE", args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1716,6 +1718,7 @@ func announceCmodeChanges(channel *Channel, applied modes.ModeChanges, source, a
|
|||||||
Nick: source,
|
Nick: source,
|
||||||
AccountName: accountName,
|
AccountName: accountName,
|
||||||
Message: message,
|
Message: message,
|
||||||
|
IsBot: isBot,
|
||||||
}, account)
|
}, account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2204,17 +2207,18 @@ func dispatchMessageToTarget(client *Client, tags map[string]string, histType hi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
for _, session := range deliverySessions {
|
for _, session := range deliverySessions {
|
||||||
hasTagsCap := session.capabilities.Has(caps.MessageTags)
|
hasTagsCap := session.capabilities.Has(caps.MessageTags)
|
||||||
// don't send TAGMSG at all if they don't have the tags cap
|
// don't send TAGMSG at all if they don't have the tags cap
|
||||||
if histType == history.Tagmsg && hasTagsCap {
|
if histType == history.Tagmsg && hasTagsCap {
|
||||||
session.sendFromClientInternal(false, message.Time, message.Msgid, nickMaskString, accountName, tags, command, tnick)
|
session.sendFromClientInternal(false, message.Time, message.Msgid, nickMaskString, accountName, isBot, tags, command, tnick)
|
||||||
} else if histType != history.Tagmsg && !(session.isTor && message.IsRestrictedCTCPMessage()) {
|
} else if histType != history.Tagmsg && !(session.isTor && message.IsRestrictedCTCPMessage()) {
|
||||||
tagsToSend := tags
|
tagsToSend := tags
|
||||||
if !hasTagsCap {
|
if !hasTagsCap {
|
||||||
tagsToSend = nil
|
tagsToSend = nil
|
||||||
}
|
}
|
||||||
session.sendSplitMsgFromClientInternal(false, nickMaskString, accountName, tagsToSend, command, tnick, message)
|
session.sendSplitMsgFromClientInternal(false, nickMaskString, accountName, isBot, tagsToSend, command, tnick, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2674,9 +2678,9 @@ func relaymsgHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res
|
|||||||
}
|
}
|
||||||
|
|
||||||
if session == rb.session {
|
if session == rb.session {
|
||||||
rb.AddSplitMessageFromClient(nick, "*", tagsToUse, "PRIVMSG", channelName, message)
|
rb.AddSplitMessageFromClient(nick, "*", false, tagsToUse, "PRIVMSG", channelName, message)
|
||||||
} else {
|
} else {
|
||||||
session.sendSplitMsgFromClientInternal(false, nick, "*", tagsToUse, "PRIVMSG", channelName, message)
|
session.sendSplitMsgFromClientInternal(false, nick, "*", false, tagsToUse, "PRIVMSG", channelName, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2835,11 +2839,12 @@ func setnameHandler(server *Server, client *Client, msg ircmsg.Message, rb *Resp
|
|||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
friends := client.Friends(caps.SetName)
|
friends := client.Friends(caps.SetName)
|
||||||
delete(friends, rb.session)
|
delete(friends, rb.session)
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
for session := range friends {
|
for session := range friends {
|
||||||
session.sendFromClientInternal(false, now, "", details.nickMask, details.accountName, nil, "SETNAME", details.realname)
|
session.sendFromClientInternal(false, now, "", details.nickMask, details.accountName, isBot, nil, "SETNAME", details.realname)
|
||||||
}
|
}
|
||||||
// respond to the user unconditionally, even if they don't have the cap
|
// respond to the user unconditionally, even if they don't have the cap
|
||||||
rb.AddFromClient(now, "", details.nickMask, details.accountName, nil, "SETNAME", details.realname)
|
rb.AddFromClient(now, "", details.nickMask, details.accountName, isBot, nil, "SETNAME", details.realname)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ type Item struct {
|
|||||||
// an incoming or outgoing message). this lets us emulate the "query buffer" functionality
|
// an incoming or outgoing message). this lets us emulate the "query buffer" functionality
|
||||||
// required by CHATHISTORY:
|
// required by CHATHISTORY:
|
||||||
CfCorrespondent string
|
CfCorrespondent string
|
||||||
|
IsBot bool `json:"IsBot,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasMsgid tests whether a message has the message id `msgid`.
|
// HasMsgid tests whether a message has the message id `msgid`.
|
||||||
|
@ -35,6 +35,7 @@ type MessageCache struct {
|
|||||||
tags map[string]string
|
tags map[string]string
|
||||||
source string
|
source string
|
||||||
command string
|
command string
|
||||||
|
isBot bool
|
||||||
|
|
||||||
params []string
|
params []string
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ type MessageCache struct {
|
|||||||
splitMessage utils.SplitMessage
|
splitMessage utils.SplitMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
func addAllTags(msg *ircmsg.Message, tags map[string]string, serverTime time.Time, msgid, accountName string) {
|
func addAllTags(msg *ircmsg.Message, tags map[string]string, serverTime time.Time, msgid, accountName string, isBot bool) {
|
||||||
msg.UpdateTags(tags)
|
msg.UpdateTags(tags)
|
||||||
msg.SetTag("time", serverTime.Format(IRCv3TimestampFormat))
|
msg.SetTag("time", serverTime.Format(IRCv3TimestampFormat))
|
||||||
if accountName != "*" {
|
if accountName != "*" {
|
||||||
@ -51,6 +52,9 @@ func addAllTags(msg *ircmsg.Message, tags map[string]string, serverTime time.Tim
|
|||||||
if msgid != "" {
|
if msgid != "" {
|
||||||
msg.SetTag("msgid", msgid)
|
msg.SetTag("msgid", msgid)
|
||||||
}
|
}
|
||||||
|
if isBot {
|
||||||
|
msg.SetTag(caps.BotTagName, "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MessageCache) handleErr(server *Server, err error) bool {
|
func (m *MessageCache) handleErr(server *Server, err error) bool {
|
||||||
@ -64,11 +68,12 @@ func (m *MessageCache) handleErr(server *Server, err error) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MessageCache) Initialize(server *Server, serverTime time.Time, msgid string, nickmask, accountName string, tags map[string]string, command string, params ...string) (err error) {
|
func (m *MessageCache) Initialize(server *Server, serverTime time.Time, msgid string, nickmask, accountName string, isBot bool, tags map[string]string, command string, params ...string) (err error) {
|
||||||
m.time = serverTime
|
m.time = serverTime
|
||||||
m.msgid = msgid
|
m.msgid = msgid
|
||||||
m.source = nickmask
|
m.source = nickmask
|
||||||
m.accountName = accountName
|
m.accountName = accountName
|
||||||
|
m.isBot = isBot
|
||||||
m.tags = tags
|
m.tags = tags
|
||||||
m.command = command
|
m.command = command
|
||||||
m.params = params
|
m.params = params
|
||||||
@ -87,7 +92,7 @@ func (m *MessageCache) Initialize(server *Server, serverTime time.Time, msgid st
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
addAllTags(&msg, tags, serverTime, msgid, accountName)
|
addAllTags(&msg, tags, serverTime, msgid, accountName, isBot)
|
||||||
m.fullTags, err = msg.LineBytesStrict(false, MaxLineLen)
|
m.fullTags, err = msg.LineBytesStrict(false, MaxLineLen)
|
||||||
if m.handleErr(server, err) {
|
if m.handleErr(server, err) {
|
||||||
return
|
return
|
||||||
@ -95,11 +100,12 @@ func (m *MessageCache) Initialize(server *Server, serverTime time.Time, msgid st
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MessageCache) InitializeSplitMessage(server *Server, nickmask, accountName string, tags map[string]string, command, target string, message utils.SplitMessage) (err error) {
|
func (m *MessageCache) InitializeSplitMessage(server *Server, nickmask, accountName string, isBot bool, tags map[string]string, command, target string, message utils.SplitMessage) (err error) {
|
||||||
m.time = message.Time
|
m.time = message.Time
|
||||||
m.msgid = message.Msgid
|
m.msgid = message.Msgid
|
||||||
m.source = nickmask
|
m.source = nickmask
|
||||||
m.accountName = accountName
|
m.accountName = accountName
|
||||||
|
m.isBot = isBot
|
||||||
m.tags = tags
|
m.tags = tags
|
||||||
m.command = command
|
m.command = command
|
||||||
m.target = target
|
m.target = target
|
||||||
@ -130,7 +136,7 @@ func (m *MessageCache) InitializeSplitMessage(server *Server, nickmask, accountN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addAllTags(&msg, tags, message.Time, message.Msgid, accountName)
|
addAllTags(&msg, tags, message.Time, message.Msgid, accountName, isBot)
|
||||||
m.fullTags, err = msg.LineBytesStrict(false, MaxLineLen)
|
m.fullTags, err = msg.LineBytesStrict(false, MaxLineLen)
|
||||||
if m.handleErr(server, err) {
|
if m.handleErr(server, err) {
|
||||||
return
|
return
|
||||||
@ -158,7 +164,7 @@ func (m *MessageCache) InitializeSplitMessage(server *Server, nickmask, accountN
|
|||||||
// so a collision isn't expected until there are on the order of 2**32
|
// so a collision isn't expected until there are on the order of 2**32
|
||||||
// concurrent batches being relayed:
|
// concurrent batches being relayed:
|
||||||
batchID := utils.GenerateSecretToken()[:utils.SecretTokenLength/2]
|
batchID := utils.GenerateSecretToken()[:utils.SecretTokenLength/2]
|
||||||
batch := composeMultilineBatch(batchID, nickmask, accountName, tags, command, target, message)
|
batch := composeMultilineBatch(batchID, nickmask, accountName, isBot, tags, command, target, message)
|
||||||
m.fullTagsMultiline = make([][]byte, len(batch))
|
m.fullTagsMultiline = make([][]byte, len(batch))
|
||||||
for i, msg := range batch {
|
for i, msg := range batch {
|
||||||
if forceTrailing {
|
if forceTrailing {
|
||||||
@ -184,7 +190,7 @@ func (m *MessageCache) Send(session *Session) {
|
|||||||
session.sendBytes(m.plain, false)
|
session.sendBytes(m.plain, false)
|
||||||
} else {
|
} else {
|
||||||
// slowpath
|
// slowpath
|
||||||
session.sendFromClientInternal(false, m.time, m.msgid, m.source, m.accountName, nil, m.command, m.params...)
|
session.sendFromClientInternal(false, m.time, m.msgid, m.source, m.accountName, m.isBot, nil, m.command, m.params...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if m.fullTagsMultiline != nil {
|
} else if m.fullTagsMultiline != nil {
|
||||||
@ -199,7 +205,7 @@ func (m *MessageCache) Send(session *Session) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// slowpath
|
// slowpath
|
||||||
session.sendSplitMsgFromClientInternal(false, m.source, m.accountName, m.tags, m.command, m.target, m.splitMessage)
|
session.sendSplitMsgFromClientInternal(false, m.source, m.accountName, m.isBot, m.tags, m.command, m.target, m.splitMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/goshuirc/irc-go/ircfmt"
|
"github.com/goshuirc/irc-go/ircfmt"
|
||||||
"github.com/oragono/oragono/irc/history"
|
"github.com/oragono/oragono/irc/history"
|
||||||
|
"github.com/oragono/oragono/irc/modes"
|
||||||
"github.com/oragono/oragono/irc/sno"
|
"github.com/oragono/oragono/irc/sno"
|
||||||
"github.com/oragono/oragono/irc/utils"
|
"github.com/oragono/oragono/irc/utils"
|
||||||
)
|
)
|
||||||
@ -101,10 +102,11 @@ func performNickChange(server *Server, client *Client, target *Client, session *
|
|||||||
target.server.snomasks.Send(sno.LocalNicks, fmt.Sprintf(ircfmt.Unescape("Operator %s changed nickname of $%s$r to %s"), client.Nick(), details.nick, assignedNickname))
|
target.server.snomasks.Send(sno.LocalNicks, fmt.Sprintf(ircfmt.Unescape("Operator %s changed nickname of $%s$r to %s"), client.Nick(), details.nick, assignedNickname))
|
||||||
}
|
}
|
||||||
target.server.whoWas.Append(details.WhoWas)
|
target.server.whoWas.Append(details.WhoWas)
|
||||||
rb.AddFromClient(message.Time, message.Msgid, origNickMask, details.accountName, nil, "NICK", assignedNickname)
|
isBot := !isSanick && client.HasMode(modes.Bot)
|
||||||
|
rb.AddFromClient(message.Time, message.Msgid, origNickMask, details.accountName, isBot, nil, "NICK", assignedNickname)
|
||||||
for session := range target.Friends() {
|
for session := range target.Friends() {
|
||||||
if session != rb.session {
|
if session != rb.session {
|
||||||
session.sendFromClientInternal(false, message.Time, message.Msgid, origNickMask, details.accountName, nil, "NICK", assignedNickname)
|
session.sendFromClientInternal(false, message.Time, message.Msgid, origNickMask, details.accountName, isBot, nil, "NICK", assignedNickname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func (rb *ResponseBuffer) Broadcast(tags map[string]string, prefix string, comma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddFromClient adds a new message from a specific client to our queue.
|
// AddFromClient adds a new message from a specific client to our queue.
|
||||||
func (rb *ResponseBuffer) AddFromClient(time time.Time, msgid string, fromNickMask string, fromAccount string, tags map[string]string, command string, params ...string) {
|
func (rb *ResponseBuffer) AddFromClient(time time.Time, msgid string, fromNickMask string, fromAccount string, isBot bool, tags map[string]string, command string, params ...string) {
|
||||||
msg := ircmsg.MakeMessage(nil, fromNickMask, command, params...)
|
msg := ircmsg.MakeMessage(nil, fromNickMask, command, params...)
|
||||||
if rb.session.capabilities.Has(caps.MessageTags) {
|
if rb.session.capabilities.Has(caps.MessageTags) {
|
||||||
msg.UpdateTags(tags)
|
msg.UpdateTags(tags)
|
||||||
@ -107,8 +107,13 @@ func (rb *ResponseBuffer) AddFromClient(time time.Time, msgid string, fromNickMa
|
|||||||
msg.SetTag("account", fromAccount)
|
msg.SetTag("account", fromAccount)
|
||||||
}
|
}
|
||||||
// attach message-id
|
// attach message-id
|
||||||
if len(msgid) > 0 && rb.session.capabilities.Has(caps.MessageTags) {
|
if rb.session.capabilities.Has(caps.MessageTags) {
|
||||||
msg.SetTag("msgid", msgid)
|
if len(msgid) != 0 {
|
||||||
|
msg.SetTag("msgid", msgid)
|
||||||
|
}
|
||||||
|
if isBot {
|
||||||
|
msg.SetTag(caps.BotTagName, "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// attach server-time
|
// attach server-time
|
||||||
rb.session.setTimeTag(&msg, time)
|
rb.session.setTimeTag(&msg, time)
|
||||||
@ -117,17 +122,17 @@ func (rb *ResponseBuffer) AddFromClient(time time.Time, msgid string, fromNickMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddSplitMessageFromClient adds a new split message from a specific client to our queue.
|
// AddSplitMessageFromClient adds a new split message from a specific client to our queue.
|
||||||
func (rb *ResponseBuffer) AddSplitMessageFromClient(fromNickMask string, fromAccount string, tags map[string]string, command string, target string, message utils.SplitMessage) {
|
func (rb *ResponseBuffer) AddSplitMessageFromClient(fromNickMask string, fromAccount string, isBot bool, tags map[string]string, command string, target string, message utils.SplitMessage) {
|
||||||
if message.Is512() {
|
if message.Is512() {
|
||||||
if message.Message == "" {
|
if message.Message == "" {
|
||||||
// XXX this is a TAGMSG
|
// XXX this is a TAGMSG
|
||||||
rb.AddFromClient(message.Time, message.Msgid, fromNickMask, fromAccount, tags, command, target)
|
rb.AddFromClient(message.Time, message.Msgid, fromNickMask, fromAccount, isBot, tags, command, target)
|
||||||
} else {
|
} else {
|
||||||
rb.AddFromClient(message.Time, message.Msgid, fromNickMask, fromAccount, tags, command, target, message.Message)
|
rb.AddFromClient(message.Time, message.Msgid, fromNickMask, fromAccount, isBot, tags, command, target, message.Message)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if rb.session.capabilities.Has(caps.Multiline) {
|
if rb.session.capabilities.Has(caps.Multiline) {
|
||||||
batch := composeMultilineBatch(rb.session.generateBatchID(), fromNickMask, fromAccount, tags, command, target, message)
|
batch := composeMultilineBatch(rb.session.generateBatchID(), fromNickMask, fromAccount, isBot, tags, command, target, message)
|
||||||
rb.setNestedBatchTag(&batch[0])
|
rb.setNestedBatchTag(&batch[0])
|
||||||
rb.setNestedBatchTag(&batch[len(batch)-1])
|
rb.setNestedBatchTag(&batch[len(batch)-1])
|
||||||
rb.messages = append(rb.messages, batch...)
|
rb.messages = append(rb.messages, batch...)
|
||||||
@ -137,25 +142,26 @@ func (rb *ResponseBuffer) AddSplitMessageFromClient(fromNickMask string, fromAcc
|
|||||||
if i == 0 {
|
if i == 0 {
|
||||||
msgid = message.Msgid
|
msgid = message.Msgid
|
||||||
}
|
}
|
||||||
rb.AddFromClient(message.Time, msgid, fromNickMask, fromAccount, tags, command, target, messagePair.Message)
|
rb.AddFromClient(message.Time, msgid, fromNickMask, fromAccount, isBot, tags, command, target, messagePair.Message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rb *ResponseBuffer) addEchoMessage(tags map[string]string, nickMask, accountName, command, target string, message utils.SplitMessage) {
|
func (rb *ResponseBuffer) addEchoMessage(tags map[string]string, nickMask, accountName, command, target string, message utils.SplitMessage) {
|
||||||
|
// TODO fix isBot here
|
||||||
if rb.session.capabilities.Has(caps.EchoMessage) {
|
if rb.session.capabilities.Has(caps.EchoMessage) {
|
||||||
hasTagsCap := rb.session.capabilities.Has(caps.MessageTags)
|
hasTagsCap := rb.session.capabilities.Has(caps.MessageTags)
|
||||||
if command == "TAGMSG" {
|
if command == "TAGMSG" {
|
||||||
if hasTagsCap {
|
if hasTagsCap {
|
||||||
rb.AddFromClient(message.Time, message.Msgid, nickMask, accountName, tags, command, target)
|
rb.AddFromClient(message.Time, message.Msgid, nickMask, accountName, false, tags, command, target)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tagsToSend := tags
|
tagsToSend := tags
|
||||||
if !hasTagsCap {
|
if !hasTagsCap {
|
||||||
tagsToSend = nil
|
tagsToSend = nil
|
||||||
}
|
}
|
||||||
rb.AddSplitMessageFromClient(nickMask, accountName, tagsToSend, command, target, message)
|
rb.AddSplitMessageFromClient(nickMask, accountName, false, tagsToSend, command, target, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,15 +92,16 @@ func sendRoleplayMessage(server *Server, client *Client, source string, targetSt
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
for _, session := range member.Sessions() {
|
for _, session := range member.Sessions() {
|
||||||
// see discussion on #865: clients do not understand how to do local echo
|
// see discussion on #865: clients do not understand how to do local echo
|
||||||
// of roleplay commands, so send them a copy whether they have echo-message
|
// of roleplay commands, so send them a copy whether they have echo-message
|
||||||
// or not
|
// or not
|
||||||
if rb.session == session {
|
if rb.session == session {
|
||||||
rb.AddSplitMessageFromClient(sourceMask, "", nil, "PRIVMSG", targetString, splitMessage)
|
rb.AddSplitMessageFromClient(sourceMask, "*", isBot, nil, "PRIVMSG", targetString, splitMessage)
|
||||||
} else {
|
} else {
|
||||||
session.sendSplitMsgFromClientInternal(false, sourceMask, "*", nil, "PRIVMSG", targetString, splitMessage)
|
session.sendSplitMsgFromClientInternal(false, sourceMask, "*", isBot, nil, "PRIVMSG", targetString, splitMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,8 +126,9 @@ func sendRoleplayMessage(server *Server, client *Client, source string, targetSt
|
|||||||
|
|
||||||
cnick := client.Nick()
|
cnick := client.Nick()
|
||||||
tnick := user.Nick()
|
tnick := user.Nick()
|
||||||
|
isBot := client.HasMode(modes.Bot)
|
||||||
for _, session := range user.Sessions() {
|
for _, session := range user.Sessions() {
|
||||||
session.sendSplitMsgFromClientInternal(false, sourceMask, "*", nil, "PRIVMSG", tnick, splitMessage)
|
session.sendSplitMsgFromClientInternal(false, sourceMask, "*", isBot, nil, "PRIVMSG", tnick, splitMessage)
|
||||||
}
|
}
|
||||||
if away, awayMessage := user.Away(); away {
|
if away, awayMessage := user.Away(); away {
|
||||||
//TODO(dan): possibly implement cooldown of away notifications to users
|
//TODO(dan): possibly implement cooldown of away notifications to users
|
||||||
|
Loading…
Reference in New Issue
Block a user