Skip to content

Commit

Permalink
fix #616
Browse files Browse the repository at this point in the history
  • Loading branch information
slingamn committed Dec 18, 2019
1 parent 9d56677 commit 6740222
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 18 deletions.
26 changes: 25 additions & 1 deletion irc/accounts.go
Expand Up @@ -1331,11 +1331,35 @@ const (
BouncerAllowedByUser
)

// controls whether/when clients without event-playback support see fake
// PRIVMSGs for JOINs
type ReplayJoinsSetting uint

const (
ReplayJoinsCommandsOnly = iota // replay in HISTORY or CHATHISTORY output
ReplayJoinsAlways // replay in HISTORY, CHATHISTORY, or autoreplay
ReplayJoinsNever // never replay
)

func replayJoinsSettingFromString(str string) (result ReplayJoinsSetting, err error) {
switch strings.ToLower(str) {
case "commands-only":
result = ReplayJoinsCommandsOnly
case "always":
result = ReplayJoinsAlways
case "never":
result = ReplayJoinsNever
default:
err = errInvalidParams
}
return
}

type AccountSettings struct {
AutoreplayLines *int
NickEnforcement NickEnforcementMethod
AllowBouncer BouncerAllowedSetting
AutoreplayJoins bool
ReplayJoins ReplayJoinsSetting
}

// ClientAccount represents a user account.
Expand Down
19 changes: 15 additions & 4 deletions irc/channel.go
Expand Up @@ -786,15 +786,26 @@ func stripMaskFromNick(nickMask string) (nick string) {
}

func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.Item, autoreplay bool) {
if len(items) == 0 {
return
}

chname := channel.Name()
client := rb.target
eventPlayback := rb.session.capabilities.Has(caps.EventPlayback)
extendedJoin := rb.session.capabilities.Has(caps.ExtendedJoin)
playJoinsAsPrivmsg := (!autoreplay || client.AccountSettings().AutoreplayJoins)

if len(items) == 0 {
return
var playJoinsAsPrivmsg bool
if !eventPlayback {
switch client.AccountSettings().ReplayJoins {
case ReplayJoinsCommandsOnly:
playJoinsAsPrivmsg = !autoreplay
case ReplayJoinsAlways:
playJoinsAsPrivmsg = true
case ReplayJoinsNever:
playJoinsAsPrivmsg = false
}
}

batchID := rb.StartNestedHistoryBatch(chname)
defer rb.EndNestedBatch(batchID)

Expand Down
60 changes: 59 additions & 1 deletion irc/database.go
Expand Up @@ -22,7 +22,7 @@ const (
// 'version' of the database schema
keySchemaVersion = "db.version"
// latest schema of the db
latestDbSchema = "7"
latestDbSchema = "8"
)

type SchemaChanger func(*Config, *buntdb.Tx) error
Expand Down Expand Up @@ -500,6 +500,59 @@ func schemaChangeV6ToV7(config *Config, tx *buntdb.Tx) error {
return nil
}

type accountSettingsLegacyV7 struct {
AutoreplayLines *int
NickEnforcement NickEnforcementMethod
AllowBouncer BouncerAllowedSetting
AutoreplayJoins bool
}

type accountSettingsLegacyV8 struct {
AutoreplayLines *int
NickEnforcement NickEnforcementMethod
AllowBouncer BouncerAllowedSetting
ReplayJoins ReplayJoinsSetting
}

// #616: change autoreplay-joins to replay-joins
func schemaChangeV7ToV8(config *Config, tx *buntdb.Tx) error {
prefix := "account.settings "
var accounts, blobs []string
tx.AscendGreaterOrEqual("", prefix, func(key, value string) bool {
var legacy accountSettingsLegacyV7
var current accountSettingsLegacyV8
if !strings.HasPrefix(key, prefix) {
return false
}
account := strings.TrimPrefix(key, prefix)
err := json.Unmarshal([]byte(value), &legacy)
if err != nil {
log.Printf("corrupt record for %s: %v\n", account, err)
return true
}
current.AutoreplayLines = legacy.AutoreplayLines
current.NickEnforcement = legacy.NickEnforcement
current.AllowBouncer = legacy.AllowBouncer
if legacy.AutoreplayJoins {
current.ReplayJoins = ReplayJoinsAlways
} else {
current.ReplayJoins = ReplayJoinsCommandsOnly
}
blob, err := json.Marshal(current)
if err != nil {
log.Printf("could not marshal record for %s: %v\n", account, err)
return true
}
accounts = append(accounts, account)
blobs = append(blobs, string(blob))
return true
})
for i, account := range accounts {
tx.Set(prefix+account, blobs[i], nil)
}
return nil
}

func init() {
allChanges := []SchemaChange{
{
Expand Down Expand Up @@ -532,6 +585,11 @@ func init() {
TargetVersion: "7",
Changer: schemaChangeV6ToV7,
},
{
InitialVersion: "7",
TargetVersion: "8",
Changer: schemaChangeV7ToV8,
},
}

// build the index
Expand Down
29 changes: 17 additions & 12 deletions irc/nickserv.go
Expand Up @@ -236,10 +236,12 @@ be replayed to you automatically when joining a channel. Your options are any
positive number, 0 to disable the feature, and 'default' to use the server
default.`,

`$bAUTOREPLAY-JOINS$b
'autoreplay-joins' controls whether autoreplayed channel history will include
`$bREPLAY-JOINS$b
'replay-joins' controls whether replayed channel history will include
lines for join and part. This provides more information about the context of
messages, but may be spammy. Your options are 'on' and 'off'.`,
messages, but may be spammy. Your options are 'always', 'never', and the default
of 'commands-only' (the messages will be replayed in /HISTORY output, but not
during autoreplay).`,
},
authRequired: true,
enabled: servCmdRequiresAccreg,
Expand Down Expand Up @@ -302,11 +304,14 @@ func displaySetting(settingName string, settings AccountSettings, client *Client
} else {
nsNotice(rb, fmt.Sprintf(client.t("You will receive %d lines of autoreplayed history"), *settings.AutoreplayLines))
}
case "autoreplay-joins":
if settings.AutoreplayJoins {
nsNotice(rb, client.t("You will see JOINs and PARTs in autoreplayed history lines"))
} else {
nsNotice(rb, client.t("You will not see JOINs and PARTs in autoreplayed history lines"))
case "replay-joins":
switch settings.ReplayJoins {
case ReplayJoinsCommandsOnly:
nsNotice(rb, client.t("You will see JOINs and PARTs in /HISTORY output, but not in autoreplay"))
case ReplayJoinsAlways:
nsNotice(rb, client.t("You will see JOINs and PARTs in /HISTORY output and in autoreplay"))
case ReplayJoinsNever:
nsNotice(rb, client.t("You will not see JOINs and PARTs in /HISTORY output or in autoreplay"))
}
case "bouncer":
if !config.Accounts.Bouncer.Enabled {
Expand Down Expand Up @@ -395,13 +400,13 @@ func nsSetHandler(server *Server, client *Client, command string, params []strin
return
}
}
case "autoreplay-joins":
var newValue bool
newValue, err = utils.StringToBool(params[1])
case "replay-joins":
var newValue ReplayJoinsSetting
newValue, err = replayJoinsSettingFromString(params[1])
if err == nil {
munger = func(in AccountSettings) (out AccountSettings, err error) {
out = in
out.AutoreplayJoins = newValue
out.ReplayJoins = newValue
return
}
}
Expand Down

0 comments on commit 6740222

Please sign in to comment.