mirror of
https://github.com/ergochat/ergo.git
synced 2025-10-10 12:37:24 +02:00
server: Implement TAGMSG draft command
This commit is contained in:
parent
f6185fa336
commit
62dc3c8f66
@ -371,17 +371,22 @@ func (channel *Channel) CanSpeak(client *Client) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TagMsg sends a tag message to everyone in this channel who can accept them.
|
||||||
|
func (channel *Channel) TagMsg(minPrefix *ChannelMode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client) {
|
||||||
|
channel.sendMessage("TAGMSG", []Capability{MessageTags}, minPrefix, clientOnlyTags, client, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// PrivMsg sends a private message to everyone in this channel.
|
// PrivMsg sends a private message to everyone in this channel.
|
||||||
func (channel *Channel) PrivMsg(minPrefix *ChannelMode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client, message string) {
|
func (channel *Channel) PrivMsg(minPrefix *ChannelMode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client, message string) {
|
||||||
channel.sendMessage("PRIVMSG", minPrefix, clientOnlyTags, client, message)
|
channel.sendMessage("PRIVMSG", nil, minPrefix, clientOnlyTags, client, &message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notice sends a private message to everyone in this channel.
|
// Notice sends a private message to everyone in this channel.
|
||||||
func (channel *Channel) Notice(minPrefix *ChannelMode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client, message string) {
|
func (channel *Channel) Notice(minPrefix *ChannelMode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client, message string) {
|
||||||
channel.sendMessage("NOTICE", minPrefix, clientOnlyTags, client, message)
|
channel.sendMessage("NOTICE", nil, minPrefix, clientOnlyTags, client, &message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (channel *Channel) sendMessage(cmd string, minPrefix *ChannelMode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client, message string) {
|
func (channel *Channel) sendMessage(cmd string, requiredCaps []Capability, minPrefix *ChannelMode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client, message *string) {
|
||||||
if !channel.CanSpeak(client) {
|
if !channel.CanSpeak(client) {
|
||||||
client.Send(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, "Cannot send to channel")
|
client.Send(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, "Cannot send to channel")
|
||||||
return
|
return
|
||||||
@ -403,10 +408,29 @@ func (channel *Channel) sendMessage(cmd string, minPrefix *ChannelMode, clientOn
|
|||||||
if member == client && !client.capabilities[EchoMessage] {
|
if member == client && !client.capabilities[EchoMessage] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canReceive := true
|
||||||
|
for _, capName := range requiredCaps {
|
||||||
|
if !member.capabilities[capName] {
|
||||||
|
canReceive = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !canReceive {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if member.capabilities[MessageTags] {
|
if member.capabilities[MessageTags] {
|
||||||
member.SendFromClient(client, clientOnlyTags, client.nickMaskString, cmd, channel.name, message)
|
if message == nil {
|
||||||
|
member.SendFromClient(client, clientOnlyTags, client.nickMaskString, cmd, channel.name)
|
||||||
|
} else {
|
||||||
|
member.SendFromClient(client, clientOnlyTags, client.nickMaskString, cmd, channel.name, *message)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
member.SendFromClient(client, nil, client.nickMaskString, cmd, channel.name, message)
|
if message == nil {
|
||||||
|
member.SendFromClient(client, nil, client.nickMaskString, cmd, channel.name)
|
||||||
|
} else {
|
||||||
|
member.SendFromClient(client, nil, client.nickMaskString, cmd, channel.name, *message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,6 +191,10 @@ var Commands = map[string]Command{
|
|||||||
handler: sceneHandler,
|
handler: sceneHandler,
|
||||||
minParams: 2,
|
minParams: 2,
|
||||||
},
|
},
|
||||||
|
"TAGMSG": {
|
||||||
|
handler: tagmsgHandler,
|
||||||
|
minParams: 1,
|
||||||
|
},
|
||||||
"QUIT": {
|
"QUIT": {
|
||||||
handler: quitHandler,
|
handler: quitHandler,
|
||||||
usablePreReg: true,
|
usablePreReg: true,
|
||||||
|
@ -300,6 +300,12 @@ Gives the given user a new nickname.`,
|
|||||||
text: `SCENE <target> <text to be sent>
|
text: `SCENE <target> <text to be sent>
|
||||||
|
|
||||||
The SCENE command is used to send a scene notification to the given target.`,
|
The SCENE command is used to send a scene notification to the given target.`,
|
||||||
|
},
|
||||||
|
"tagmsg": {
|
||||||
|
text: `@+client-only-tags TAGMSG <target>{,<target>}
|
||||||
|
|
||||||
|
Sends the given client-only tags to the given targets as a TAGMSG. See the IRCv3
|
||||||
|
specs for more info: http://ircv3.net/specs/core/message-tags-3.3.html`,
|
||||||
},
|
},
|
||||||
"quit": {
|
"quit": {
|
||||||
text: `QUIT [reason]
|
text: `QUIT [reason]
|
||||||
|
@ -19,5 +19,9 @@ func GetClientOnlyTags(tags map[string]ircmsg.TagValue) *map[string]ircmsg.TagVa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(clientOnlyTags) < 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return &clientOnlyTags
|
return &clientOnlyTags
|
||||||
}
|
}
|
||||||
|
@ -338,7 +338,7 @@ func (server *Server) setISupport() {
|
|||||||
server.isupport.Add("RPCHAN", "E")
|
server.isupport.Add("RPCHAN", "E")
|
||||||
server.isupport.Add("RPUSER", "E")
|
server.isupport.Add("RPUSER", "E")
|
||||||
server.isupport.Add("STATUSMSG", "~&@%+")
|
server.isupport.Add("STATUSMSG", "~&@%+")
|
||||||
server.isupport.Add("TARGMAX", fmt.Sprintf("NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:%s,NOTICE:%s,MONITOR:", maxTargetsString, maxTargetsString))
|
server.isupport.Add("TARGMAX", fmt.Sprintf("NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:%s,TAGMSG:%s,NOTICE:%s,MONITOR:", maxTargetsString, maxTargetsString, maxTargetsString))
|
||||||
server.isupport.Add("TOPICLEN", strconv.Itoa(server.limits.TopicLen))
|
server.isupport.Add("TOPICLEN", strconv.Itoa(server.limits.TopicLen))
|
||||||
|
|
||||||
// account registration
|
// account registration
|
||||||
@ -963,6 +963,63 @@ func privmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TAGMSG <target>{,<target>}
|
||||||
|
func tagmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||||
|
clientOnlyTags := GetClientOnlyTags(msg.Tags)
|
||||||
|
// no client-only tags, so we can drop it
|
||||||
|
if clientOnlyTags == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
targets := strings.Split(msg.Params[0], ",")
|
||||||
|
|
||||||
|
for i, targetString := range targets {
|
||||||
|
// max of four targets per privmsg
|
||||||
|
if i > maxTargets-1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
prefixes, targetString := SplitChannelMembershipPrefixes(targetString)
|
||||||
|
lowestPrefix := 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 {
|
||||||
|
client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, targetString, "No such channel")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
channel.TagMsg(lowestPrefix, clientOnlyTags, client)
|
||||||
|
} 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, target, "No such nick")
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// end user can't receive tagmsgs
|
||||||
|
if !user.capabilities[MessageTags] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
user.SendFromClient(client, clientOnlyTags, "TAGMSG", user.nick)
|
||||||
|
if client.capabilities[EchoMessage] {
|
||||||
|
client.SendFromClient(client, clientOnlyTags, "TAGMSG", user.nick)
|
||||||
|
}
|
||||||
|
if user.flags[Away] {
|
||||||
|
//TODO(dan): possibly implement cooldown of away notifications to users
|
||||||
|
client.Send(nil, server.name, RPL_AWAY, user.nick, user.awayMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (client *Client) WhoisChannelsNames(target *Client) []string {
|
func (client *Client) WhoisChannelsNames(target *Client) []string {
|
||||||
isMultiPrefix := target.capabilities[MultiPrefix]
|
isMultiPrefix := target.capabilities[MultiPrefix]
|
||||||
var chstrs []string
|
var chstrs []string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user