3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-21 19:39:43 +01:00

implement draft/extended-isupport (#2184)

This commit is contained in:
Shivaram Lingamneni 2024-09-27 06:40:56 +02:00 committed by GitHub
parent f68d32b4ee
commit 7586520032
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 57 additions and 10 deletions

View File

@ -219,6 +219,12 @@ CAPDEFS = [
url="https://github.com/ircv3/ircv3-specifications/pull/527", url="https://github.com/ircv3/ircv3-specifications/pull/527",
standard="proposed IRCv3", standard="proposed IRCv3",
), ),
CapDef(
identifier="ExtendedISupport",
name="draft/extended-isupport",
url="https://github.com/ircv3/ircv3-specifications/pull/543",
standard="proposed IRCv3",
),
] ]
def validate_defs(): def validate_defs():

View File

@ -64,10 +64,11 @@ const (
BotTagName = "bot" BotTagName = "bot"
// https://ircv3.net/specs/extensions/chathistory // https://ircv3.net/specs/extensions/chathistory
ChathistoryTargetsBatchType = "draft/chathistory-targets" ChathistoryTargetsBatchType = "draft/chathistory-targets"
ExtendedISupportBatchType = "draft/extended-isupport"
) )
func init() { func init() {
nameToCapability = make(map[string]Capability) nameToCapability = make(map[string]Capability, numCapabs)
for capab, name := range capabilityNames { for capab, name := range capabilityNames {
nameToCapability[name] = Capability(capab) nameToCapability[name] = Capability(capab)
} }

View File

@ -7,7 +7,7 @@ package caps
const ( const (
// number of recognized capabilities: // number of recognized capabilities:
numCapabs = 34 numCapabs = 35
// length of the uint32 array that represents the bitset: // length of the uint32 array that represents the bitset:
bitsetLen = 2 bitsetLen = 2
) )
@ -53,6 +53,10 @@ const (
// https://github.com/ircv3/ircv3-specifications/pull/362 // https://github.com/ircv3/ircv3-specifications/pull/362
EventPlayback Capability = iota EventPlayback Capability = iota
// ExtendedISupport is the proposed IRCv3 capability named "draft/extended-isupport":
// https://github.com/ircv3/ircv3-specifications/pull/543
ExtendedISupport Capability = iota
// Languages is the proposed IRCv3 capability named "draft/languages": // Languages is the proposed IRCv3 capability named "draft/languages":
// https://gist.github.com/DanielOaks/8126122f74b26012a3de37db80e4e0c6 // https://gist.github.com/DanielOaks/8126122f74b26012a3de37db80e4e0c6
Languages Capability = iota Languages Capability = iota
@ -163,6 +167,7 @@ var (
"draft/channel-rename", "draft/channel-rename",
"draft/chathistory", "draft/chathistory",
"draft/event-playback", "draft/event-playback",
"draft/extended-isupport",
"draft/languages", "draft/languages",
"draft/message-redaction", "draft/message-redaction",
"draft/multiline", "draft/multiline",

View File

@ -179,6 +179,8 @@ type Session struct {
batchCounter atomic.Uint32 batchCounter atomic.Uint32
isupportSentPrereg bool
quitMessage string quitMessage string
awayMessage string awayMessage string

View File

@ -152,6 +152,10 @@ func init() {
handler: isonHandler, handler: isonHandler,
minParams: 1, minParams: 1,
}, },
"ISUPPORT": {
handler: isupportHandler,
usablePreReg: true,
},
"JOIN": { "JOIN": {
handler: joinHandler, handler: joinHandler,
minParams: 1, minParams: 1,

View File

@ -1320,6 +1320,15 @@ func isonHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respons
return false return false
} }
// ISUPPORT
func isupportHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
server.RplISupport(client, rb)
if !client.registered {
rb.session.isupportSentPrereg = true
}
return false
}
// JOIN <channel>{,<channel>} [<key>{,<key>}] // JOIN <channel>{,<channel>} [<key>{,<key>}]
func joinHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool { func joinHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
// #1417: allow `JOIN 0` with a confirmation code // #1417: allow `JOIN 0` with a confirmation code

View File

@ -259,6 +259,11 @@ appropriate channel privs.`,
text: `ISON <nickname>{ <nickname>} text: `ISON <nickname>{ <nickname>}
Returns whether the given nicks exist on the network.`, Returns whether the given nicks exist on the network.`,
},
"isupport": {
text: `ISUPPORT
Returns RPL_ISUPPORT lines describing the server's capabilities.`,
}, },
"join": { "join": {
text: `JOIN <channel>{,<channel>} [<key>{,<key>}] text: `JOIN <channel>{,<channel>} [<key>{,<key>}]

View File

@ -434,7 +434,9 @@ func (server *Server) playRegistrationBurst(session *Session) {
session.Send(nil, server.name, RPL_MYINFO, d.nick, server.name, Ver, rplMyInfo1, rplMyInfo2, rplMyInfo3) session.Send(nil, server.name, RPL_MYINFO, d.nick, server.name, Ver, rplMyInfo1, rplMyInfo2, rplMyInfo3)
rb := NewResponseBuffer(session) rb := NewResponseBuffer(session)
server.RplISupport(c, rb) if !(rb.session.capabilities.Has(caps.ExtendedISupport) && rb.session.isupportSentPrereg) {
server.RplISupport(c, rb)
}
if d.account != "" && session.capabilities.Has(caps.Persistence) { if d.account != "" && session.capabilities.Has(caps.Persistence) {
reportPersistenceStatus(c, rb, false) reportPersistenceStatus(c, rb, false)
} }
@ -456,10 +458,17 @@ func (server *Server) playRegistrationBurst(session *Session) {
// RplISupport outputs our ISUPPORT lines to the client. This is used on connection and in VERSION responses. // RplISupport outputs our ISUPPORT lines to the client. This is used on connection and in VERSION responses.
func (server *Server) RplISupport(client *Client, rb *ResponseBuffer) { func (server *Server) RplISupport(client *Client, rb *ResponseBuffer) {
server.sendRplISupportLines(client, rb, server.Config().Server.isupport.CachedReply)
}
func (server *Server) sendRplISupportLines(client *Client, rb *ResponseBuffer, lines [][]string) {
if rb.session.capabilities.Has(caps.ExtendedISupport) {
batchID := rb.StartNestedBatch("chathistory", caps.ExtendedISupportBatchType)
defer rb.EndNestedBatch(batchID)
}
translatedISupport := client.t("are supported by this server") translatedISupport := client.t("are supported by this server")
nick := client.Nick() nick := client.Nick()
config := server.Config() for _, cachedTokenLine := range lines {
for _, cachedTokenLine := range config.Server.isupport.CachedReply {
length := len(cachedTokenLine) + 2 length := len(cachedTokenLine) + 2
tokenline := make([]string, length) tokenline := make([]string, length)
tokenline[0] = nick tokenline[0] = nick
@ -794,13 +803,19 @@ func (server *Server) applyConfig(config *Config) (err error) {
} }
if !initial { if !initial {
// push new info to all of our clients // send 005 updates (somewhat rare)
for _, sClient := range server.clients.AllClients() { if len(newISupportReplies) != 0 {
for _, tokenline := range newISupportReplies { for _, sClient := range server.clients.AllClients() {
sClient.Send(nil, server.name, RPL_ISUPPORT, append([]string{sClient.nick}, tokenline...)...) for _, session := range sClient.Sessions() {
rb := NewResponseBuffer(session)
server.sendRplISupportLines(sClient, rb, newISupportReplies)
rb.Send(false)
}
} }
}
if sendRawOutputNotice { if sendRawOutputNotice {
for _, sClient := range server.clients.AllClients() {
sClient.Notice(sClient.t("This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")) sClient.Notice(sClient.t("This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
} }
} }