mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-15 00:19:29 +01:00
initial implementation of draft/persistence
This commit is contained in:
parent
fa3de3e149
commit
99d27ff737
@ -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():
|
||||
|
@ -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",
|
||||
|
@ -233,6 +233,10 @@ func init() {
|
||||
usablePreReg: true,
|
||||
minParams: 1,
|
||||
},
|
||||
"PERSISTENCE": {
|
||||
handler: persistenceHandler,
|
||||
minParams: 1,
|
||||
},
|
||||
"PING": {
|
||||
handler: pingHandler,
|
||||
usablePreReg: true,
|
||||
|
@ -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])
|
||||
|
@ -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>...
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user