fix(privacy): let the channel grid actually decide what is stored

IsAllowedForStorage applied the unknown-channel failsafe to known
channels too. Untick Say in the grid, leave "Save unknown channel types"
on, and Say kept being written -- and that failsafe is on by default.

So a config that never met the wizard ran with the filter enabled, an
empty list and the failsafe on, which stored everything while the
filter's own description promised "only messages from allowed channels
are written to the database". The grid was inert for exactly the users
who had not been walked through the wizard.

The rule now reads: on the list, or unknown and the failsafe allows it.
A known channel the user did not pick stays out.

That correction alone would turn "stores everything" into "stores
nothing" for those same configs, so two things move with it:

- Config v24 switches the filter off where it was on with nothing
  picked. Same behaviour as before, stated where the user can see it,
  and one line in the log saying so. A config that does have picks keeps
  them and starts honouring them, which is the point of the change.
- A fresh config seeds the list from PrivacyFirstWhitelist instead of
  starting empty. Privacy by Default was already the documented intent;
  it just relied on the hole to stay usable.

The rule lives in its own type now. Configuration implements a Dalamud
interface, and the build suite cannot load Dalamud.dll -- the runtime
resolves the declaring type before reaching the method body, so even a
static call on it fails. Fifteen cases pin the truth table and the
migration condition; the self-test checks the running config is not in
the state the migration exists to undo.
This commit is contained in:
2026-08-18 21:32:02 +02:00
parent d59ee62223
commit 94af81a961
4 changed files with 103 additions and 24 deletions
+28 -2
View File
@@ -283,7 +283,33 @@ public sealed class Plugin : IAsyncDalamudPlugin
{
Config.MainWindowLayoutMode = MainWindowLayoutMode.TopTabs;
}
Config.Version = 23;
// v24 migration: the privacy filter used to route a known but unticked
// channel through the unknown-type failsafe, so the channel grid was
// inert whenever that failsafe was on. Corrected in v1.12.0. A config
// that never picked a channel was storing everything through that hole,
// and the corrected rule would store nothing at all -- so the intent is
// carried forward as a filter that is honestly switched off.
if (
Config.Version < 24
&& Privacy.StorageRule.ShouldDisableFilterOnV24(
Config.PrivacyFilterEnabled,
Config.PrivacyPersistUnknownChannels,
Config.PrivacyPersistChannels.Count
)
)
{
Config.PrivacyFilterEnabled = false;
// Log, not LogProxy: this runs in Phase-0 and the proxy is only
// resolved from the container further down.
Log.Information(
"Privacy filter switched off during the v24 migration: it was on with no channels "
+ "picked, which stored everything through the unknown-channel failsafe. Pick "
+ "channels in Settings to switch it back on."
);
}
Config.Version = 24;
// Unpinned TempTabs are session-only and dropped on every load. Pinned
// TempTabs survive reload — Jin's tester feedback (v1.4.7).
@@ -444,7 +470,7 @@ public sealed class Plugin : IAsyncDalamudPlugin
new SelfTests.SettingsWindowOpenStep(this),
new SelfTests.OnOpenMainUiRoutesMainWindowStep(this),
new SelfTests.TypingIpcStateStep(this),
new SelfTests.ConfigMigrationV23Step(this),
new SelfTests.ConfigMigrationV24Step(this),
new SelfTests.ChannelPopoutBindStep(this),
new SelfTests.HoverStateFootprintStep(),
new SelfTests.HonorificHeaderRenderStep(this),