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

initial implementation of draft/persistence

This commit is contained in:
Shivaram Lingamneni 2022-07-15 00:04:35 -04:00
parent fa3de3e149
commit 99d27ff737
6 changed files with 101 additions and 1 deletions

View File

@ -189,6 +189,12 @@ CAPDEFS = [
url="https://github.com/ircv3/ircv3-specifications/pull/489",
standard="draft IRCv3",
),
CapDef(
identifier="Persistence",
name="draft/persistence",
url="https://gist.github.com/slingamn/e3645a0d0418b736b755746bfd65f2a6",
standard="proposed IRCv3",
),
]
def validate_defs():

View File

@ -7,7 +7,7 @@ package caps
const (
// number of recognized capabilities:
numCapabs = 29
numCapabs = 30
// length of the uint64 array that represents the bitset:
bitsetLen = 1
)
@ -61,6 +61,10 @@ const (
// https://github.com/ircv3/ircv3-specifications/pull/398
Multiline Capability = iota
// Persistence is the proposed IRCv3 capability named "draft/persistence":
// https://gist.github.com/slingamn/e3645a0d0418b736b755746bfd65f2a6
Persistence Capability = iota
// ReadMarker is the draft IRCv3 capability named "draft/read-marker":
// https://github.com/ircv3/ircv3-specifications/pull/489
ReadMarker Capability = iota
@ -145,6 +149,7 @@ var (
"draft/event-playback",
"draft/languages",
"draft/multiline",
"draft/persistence",
"draft/read-marker",
"draft/relaymsg",
"echo-message",

View File

@ -233,6 +233,10 @@ func init() {
usablePreReg: true,
minParams: 1,
},
"PERSISTENCE": {
handler: persistenceHandler,
minParams: 1,
},
"PING": {
handler: pingHandler,
usablePreReg: true,

View File

@ -2599,6 +2599,81 @@ func passHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respons
return false
}
// PERSISTENCE <subcommand> [params...]
func persistenceHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
account := client.Account()
if account == "" {
rb.Add(nil, server.name, "FAIL", "PERSISTENCE", "ACCOUNT_REQUIRED", client.t("You're not logged into an account"))
return false
}
switch strings.ToUpper(msg.Params[0]) {
case "GET":
reportPersistenceStatus(client, rb)
case "SET":
if len(msg.Params) == 1 {
goto fail
}
var desiredSetting PersistentStatus
switch strings.ToUpper(msg.Params[1]) {
case "DEFAULT":
desiredSetting = PersistentUnspecified
case "OFF":
desiredSetting = PersistentDisabled
case "ON":
desiredSetting = PersistentMandatory
default:
goto fail
}
_, err := server.accounts.ModifyAccountSettings(account,
func(input AccountSettings) (output AccountSettings, err error) {
output = input
output.AlwaysOn = desiredSetting
return
})
if err != nil {
server.logger.Error("internal", "couldn't modify persistence setting", err.Error())
rb.Add(nil, server.name, "FAIL", "PERSISTENCE", "UNKNOWN_ERROR", client.t("An error occurred"))
return false
}
reportPersistenceStatus(client, rb)
default:
goto fail
}
return false
fail:
rb.Add(nil, server.name, "FAIL", "PERSISTENCE", "INVALID_PARAMS", client.t("Invalid parameters"))
return false
}
func reportPersistenceStatus(client *Client, rb *ResponseBuffer) {
settings := client.AccountSettings()
serverSetting := client.server.Config().Accounts.Multiclient.AlwaysOn
effectiveSetting := persistenceEnabled(serverSetting, settings.AlwaysOn)
toString := func(setting PersistentStatus) string {
switch setting {
case PersistentUnspecified:
return "DEFAULT"
case PersistentDisabled:
return "OFF"
case PersistentMandatory:
return "ON"
default:
return "*" // impossible
}
}
effectiveSettingStr := "OFF"
if effectiveSetting {
effectiveSettingStr = "ON"
}
rb.Add(nil, client.server.name, "PERSISTENCE", "STATUS", toString(settings.AlwaysOn), effectiveSettingStr)
}
// PING [params...]
func pingHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
rb.Add(nil, server.name, "PONG", server.name, msg.Params[0])

View File

@ -413,6 +413,13 @@ Leaves the given channels and shows people the given reason.`,
When the server requires a connection password to join, used to send us the
password.`,
},
"persistence": {
text: `PERSISTENCE [params]
PERSISTENCE is a command associated with an IRC protocol extension for
persistent connections. End users should probably use /NS GET ALWAYS-ON
and /NS SET ALWAYS-ON instead.`,
},
"ping": {
text: `PING <args>...

View File

@ -420,6 +420,9 @@ func (server *Server) playRegistrationBurst(session *Session) {
rb := NewResponseBuffer(session)
server.RplISupport(c, rb)
if session.capabilities.Has(caps.Persistence) {
reportPersistenceStatus(c, rb)
}
server.Lusers(c, rb)
server.MOTD(c, rb)
rb.Send(true)