mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-22 11:59:40 +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",
|
url="https://github.com/ircv3/ircv3-specifications/pull/489",
|
||||||
standard="draft IRCv3",
|
standard="draft IRCv3",
|
||||||
),
|
),
|
||||||
|
CapDef(
|
||||||
|
identifier="Persistence",
|
||||||
|
name="draft/persistence",
|
||||||
|
url="https://gist.github.com/slingamn/e3645a0d0418b736b755746bfd65f2a6",
|
||||||
|
standard="proposed IRCv3",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
def validate_defs():
|
def validate_defs():
|
||||||
|
@ -7,7 +7,7 @@ package caps
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// number of recognized capabilities:
|
// number of recognized capabilities:
|
||||||
numCapabs = 29
|
numCapabs = 30
|
||||||
// length of the uint64 array that represents the bitset:
|
// length of the uint64 array that represents the bitset:
|
||||||
bitsetLen = 1
|
bitsetLen = 1
|
||||||
)
|
)
|
||||||
@ -61,6 +61,10 @@ const (
|
|||||||
// https://github.com/ircv3/ircv3-specifications/pull/398
|
// https://github.com/ircv3/ircv3-specifications/pull/398
|
||||||
Multiline Capability = iota
|
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":
|
// ReadMarker is the draft IRCv3 capability named "draft/read-marker":
|
||||||
// https://github.com/ircv3/ircv3-specifications/pull/489
|
// https://github.com/ircv3/ircv3-specifications/pull/489
|
||||||
ReadMarker Capability = iota
|
ReadMarker Capability = iota
|
||||||
@ -145,6 +149,7 @@ var (
|
|||||||
"draft/event-playback",
|
"draft/event-playback",
|
||||||
"draft/languages",
|
"draft/languages",
|
||||||
"draft/multiline",
|
"draft/multiline",
|
||||||
|
"draft/persistence",
|
||||||
"draft/read-marker",
|
"draft/read-marker",
|
||||||
"draft/relaymsg",
|
"draft/relaymsg",
|
||||||
"echo-message",
|
"echo-message",
|
||||||
|
@ -233,6 +233,10 @@ func init() {
|
|||||||
usablePreReg: true,
|
usablePreReg: true,
|
||||||
minParams: 1,
|
minParams: 1,
|
||||||
},
|
},
|
||||||
|
"PERSISTENCE": {
|
||||||
|
handler: persistenceHandler,
|
||||||
|
minParams: 1,
|
||||||
|
},
|
||||||
"PING": {
|
"PING": {
|
||||||
handler: pingHandler,
|
handler: pingHandler,
|
||||||
usablePreReg: true,
|
usablePreReg: true,
|
||||||
|
@ -2599,6 +2599,81 @@ func passHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respons
|
|||||||
return false
|
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...]
|
// PING [params...]
|
||||||
func pingHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
func pingHandler(server *Server, client *Client, msg ircmsg.Message, rb *ResponseBuffer) bool {
|
||||||
rb.Add(nil, server.name, "PONG", server.name, msg.Params[0])
|
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
|
When the server requires a connection password to join, used to send us the
|
||||||
password.`,
|
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": {
|
"ping": {
|
||||||
text: `PING <args>...
|
text: `PING <args>...
|
||||||
|
@ -420,6 +420,9 @@ func (server *Server) playRegistrationBurst(session *Session) {
|
|||||||
|
|
||||||
rb := NewResponseBuffer(session)
|
rb := NewResponseBuffer(session)
|
||||||
server.RplISupport(c, rb)
|
server.RplISupport(c, rb)
|
||||||
|
if session.capabilities.Has(caps.Persistence) {
|
||||||
|
reportPersistenceStatus(c, rb)
|
||||||
|
}
|
||||||
server.Lusers(c, rb)
|
server.Lusers(c, rb)
|
||||||
server.MOTD(c, rb)
|
server.MOTD(c, rb)
|
||||||
rb.Send(true)
|
rb.Send(true)
|
||||||
|
Loading…
Reference in New Issue
Block a user